diff options
| author | Alex Williams <alex.williams@ni.com> | 2018-10-12 17:17:13 -0700 | 
|---|---|---|
| committer | Brent Stapleton <bstapleton@g.hmc.edu> | 2018-10-19 10:17:08 -0700 | 
| commit | a830fab2a00acd158f14d716e3493ef50afd8aeb (patch) | |
| tree | 96425e10026d94dfcef46ebbfa8cc5bccb5cf90f /mpm/lib/i2c/i2cdev.c | |
| parent | 0e30a5ca0872762a36be15f030a763c7f67dd003 (diff) | |
| download | uhd-a830fab2a00acd158f14d716e3493ef50afd8aeb.tar.gz uhd-a830fab2a00acd158f14d716e3493ef50afd8aeb.tar.bz2 uhd-a830fab2a00acd158f14d716e3493ef50afd8aeb.zip  | |
mpm: Add i2c APIs for simple transfers
Diffstat (limited to 'mpm/lib/i2c/i2cdev.c')
| -rw-r--r-- | mpm/lib/i2c/i2cdev.c | 84 | 
1 files changed, 84 insertions, 0 deletions
diff --git a/mpm/lib/i2c/i2cdev.c b/mpm/lib/i2c/i2cdev.c new file mode 100644 index 000000000..2ced96870 --- /dev/null +++ b/mpm/lib/i2c/i2cdev.c @@ -0,0 +1,84 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include "i2cdev.h" +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/ioctl.h> +#include <linux/i2c.h> +#include <linux/i2c-dev.h> +#include <stdio.h> + +int i2cdev_open(int *fd, const char *device, const unsigned int timeout_ms) +{ +    if (!fd) +    { +        fprintf(stderr, "%s: was passed a null pointer\n", +            __func__); +        return -EINVAL; +    } + +    *fd = open(device, O_RDWR); +    if (*fd < 0) { +        fprintf(stderr, "%s: Failed to open device. %s\n", +            __func__, strerror(*fd)); +        return *fd; +    } + +    if (ioctl(*fd, I2C_TIMEOUT, timeout_ms) < 0) +    { +        int err = errno; +        fprintf(stderr, "%s: Failed to set timeout. %s\n", +            __func__, strerror(err)); +        return err; +    } + +    return 0; +} + +int i2cdev_transfer(int fd, uint16_t addr, int ten_bit_addr, +                    uint8_t *tx, size_t tx_len, +                    uint8_t *rx, size_t rx_len) +{ +    int err; +    struct i2c_msg msgs[2]; +    int num_msgs = 0; +    struct i2c_rdwr_ioctl_data i2c_data = { +        .msgs = msgs, +    }; + +    if (tx && tx_len > 0) { +        msgs[num_msgs].addr = addr; +        msgs[num_msgs].buf = tx; +        msgs[num_msgs].len = tx_len; +        msgs[num_msgs].flags = ten_bit_addr ? I2C_M_TEN : 0; +        num_msgs++; +    } + +    if (rx && rx_len > 0) { +        msgs[num_msgs].addr = addr; +        msgs[num_msgs].buf = rx; +        msgs[num_msgs].len = rx_len; +        msgs[num_msgs].flags = ten_bit_addr ? I2C_M_TEN : 0; +        msgs[num_msgs].flags |= I2C_M_RD; +        num_msgs++; +    } + +    i2c_data.nmsgs = num_msgs; +    if (num_msgs <= 0) +        return -EINVAL; + +    err = ioctl(fd, I2C_RDWR, &i2c_data); +    if (err < 0) { +        fprintf(stderr, "%s: Failed I2C_RDWR: %d\n", __func__, err); +        perror("ioctl: \n"); +        return err; +    } + +    return 0; +} +  | 
