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; +} + |