LCOV - code coverage report
Current view: top level - src - i2cd.c (source / functions) Hit Total Coverage
Test: libi2cd 1.0.3 Lines: 47 49 95.9 %
Date: 2022-10-15 04:10:17 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1-or-later */
       2             : /*
       3             :  * Copyright (C) 2021 Steven Stallion <sstallion@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify
       6             :  * it under the terms of the GNU Lesser General Public License as published
       7             :  * by the Free Software Foundation; either version 2.1 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
      13             :  * the GNU Lesser General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, see <http://www.gnu.org/licenses/>.
      17             :  */
      18             : 
      19             : #include "i2cd-private.h"
      20             : 
      21             : #include <assert.h>
      22             : #include <errno.h>
      23             : #include <fcntl.h>
      24             : #include <limits.h>
      25             : #include <stdint.h>
      26             : #include <stdio.h>
      27             : #include <stdlib.h>
      28             : #include <string.h>
      29             : #include <unistd.h>
      30             : #include <sys/ioctl.h>
      31             : #include <sys/stat.h>
      32             : #include <sys/types.h>
      33             : #include <linux/i2c.h>
      34             : #include <linux/i2c-dev.h>
      35             : 
      36           6 : struct i2cd *i2cd_open(const char *path)
      37             : {
      38             :         struct i2cd *dev;
      39             :         int errsv;
      40             : 
      41             :         assert(path != NULL);
      42             : 
      43           6 :         dev = calloc(1, sizeof(*dev));
      44           6 :         if (dev == NULL)
      45           1 :                 return NULL;
      46             : 
      47           5 :         dev->path = strdup(path);
      48           5 :         if (dev->path == NULL)
      49           1 :                 goto err;
      50             : 
      51           4 :         dev->fd = open(dev->path, O_RDWR);
      52           4 :         if (dev->fd < 0)
      53           1 :                 goto err;
      54             : 
      55           3 :         return dev;
      56           2 : err:
      57           2 :         errsv = errno;
      58             : 
      59           2 :         if (dev->path != NULL)
      60           1 :                 free(dev->path);
      61             : 
      62           2 :         free(dev);
      63             : 
      64           2 :         errno = errsv;
      65           2 :         return NULL;
      66             : }
      67             : 
      68           1 : struct i2cd *i2cd_open_by_name(const char *name)
      69             : {
      70             :         char path[PATH_MAX];
      71             : 
      72             :         assert(name != NULL);
      73             : 
      74           1 :         snprintf(path, sizeof(path), "/dev/%s", name);
      75           1 :         return i2cd_open(path);
      76             : }
      77             : 
      78           1 : struct i2cd *i2cd_open_by_number(unsigned int num)
      79             : {
      80             :         char path[PATH_MAX];
      81             : 
      82           1 :         snprintf(path, sizeof(path), "/dev/i2c-%u", num);
      83           1 :         return i2cd_open(path);
      84             : }
      85             : 
      86           1 : void i2cd_close(struct i2cd *dev)
      87             : {
      88             :         assert(dev != NULL);
      89             : 
      90           1 :         close(dev->fd);
      91             : 
      92           1 :         free(dev->path);
      93           1 :         free(dev);
      94           1 : }
      95             : 
      96           0 : const char *i2cd_get_path(struct i2cd *dev)
      97             : {
      98             :         assert(dev != NULL);
      99             : 
     100           0 :         return dev->path;
     101             : }
     102             : 
     103           1 : int i2cd_set_retries(struct i2cd *dev, unsigned long retries)
     104             : {
     105             :         assert(dev != NULL);
     106             : 
     107           1 :         return ioctl(dev->fd, I2C_RETRIES, retries);
     108             : }
     109             : 
     110           1 : int i2cd_set_timeout(struct i2cd *dev, unsigned long timeout)
     111             : {
     112             :         assert(dev != NULL);
     113             : 
     114           1 :         return ioctl(dev->fd, I2C_TIMEOUT, timeout);
     115             : }
     116             : 
     117           1 : int i2cd_get_functionality(struct i2cd *dev, unsigned long *funcs)
     118             : {
     119             :         assert(dev != NULL);
     120             :         assert(funcs != NULL);
     121             : 
     122           1 :         return ioctl(dev->fd, I2C_FUNCS, funcs);
     123             : }
     124             : 
     125           3 : int i2cd_transfer(struct i2cd *dev, struct i2c_msg msgs[], size_t nmsgs)
     126             : {
     127           3 :         struct i2c_rdwr_ioctl_data msgset = {msgs, nmsgs};
     128             : 
     129             :         assert(dev != NULL);
     130             :         assert(msgs != NULL);
     131             :         assert(nmsgs <= I2C_RDWR_IOCTL_MAX_MSGS);
     132             : 
     133           3 :         return ioctl(dev->fd, I2C_RDWR, &msgset);
     134             : }
     135             : 
     136           1 : int i2cd_read(struct i2cd *dev, uint16_t addr, void *buf, size_t len)
     137             : {
     138           1 :         struct i2c_msg msgs[] = {
     139             :                 {
     140             :                         .addr   = addr,
     141             :                         .flags  = I2C_M_RD,
     142             :                         .len    = len,
     143             :                         .buf    = buf
     144             :                 }
     145             :         };
     146             : 
     147             :         assert(buf != NULL);
     148             :         assert(len <= UINT16_MAX);
     149             : 
     150           1 :         return i2cd_transfer(dev, msgs, ARRAY_SIZE(msgs));
     151             : }
     152             : 
     153           1 : int i2cd_write(struct i2cd *dev, uint16_t addr, const void *buf, size_t len)
     154             : {
     155           1 :         struct i2c_msg msgs[] = {
     156             :                 {
     157             :                         .addr   = addr,
     158             :                         .flags  = 0,
     159             :                         .len    = len,
     160             :                         .buf    = (void *)buf
     161             :                 }
     162             :         };
     163             : 
     164             :         assert(buf != NULL);
     165             :         assert(len <= UINT16_MAX);
     166             : 
     167           1 :         return i2cd_transfer(dev, msgs, ARRAY_SIZE(msgs));
     168             : }
     169             : 
     170           1 : int i2cd_write_read(struct i2cd *dev, uint16_t addr,
     171             :                 const void *write_buf, size_t write_len,
     172             :                 void *read_buf, size_t read_len)
     173             : {
     174           1 :         struct i2c_msg msgs[] = {
     175             :                 {
     176             :                         .addr   = addr,
     177             :                         .flags  = 0,
     178             :                         .len    = write_len,
     179             :                         .buf    = (void *)write_buf
     180             :                 },
     181             :                 {
     182             :                         .addr   = addr,
     183             :                         .flags  = I2C_M_RD,
     184             :                         .len    = read_len,
     185             :                         .buf    = read_buf
     186             :                 }
     187             :         };
     188             : 
     189             :         assert(write_buf != NULL);
     190             :         assert(write_len <= UINT16_MAX);
     191             :         assert(read_buf != NULL);
     192             :         assert(read_len <= UINT16_MAX);
     193             : 
     194           1 :         return i2cd_transfer(dev, msgs, ARRAY_SIZE(msgs));
     195             : }

Generated by: LCOV version 1.14