aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/lib/i2c/i2cdev.c
diff options
context:
space:
mode:
authorAlex Williams <alex.williams@ni.com>2018-10-12 17:17:13 -0700
committerBrent Stapleton <bstapleton@g.hmc.edu>2018-10-19 10:17:08 -0700
commita830fab2a00acd158f14d716e3493ef50afd8aeb (patch)
tree96425e10026d94dfcef46ebbfa8cc5bccb5cf90f /mpm/lib/i2c/i2cdev.c
parent0e30a5ca0872762a36be15f030a763c7f67dd003 (diff)
downloaduhd-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.c84
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;
+}
+