svn commit: r321583 - head/sys/dev/iicbus
Ian Lepore
ian at FreeBSD.org
Wed Jul 26 20:40:25 UTC 2017
Author: ian
Date: Wed Jul 26 20:40:24 2017
New Revision: 321583
URL: https://svnweb.freebsd.org/changeset/base/321583
Log:
Add a pair of convenience routines for doing simple "register" read/writes
on i2c devices, where the "register" can be any length.
Many (perhaps most) common i2c devices are organized as a collection of
(usually 1-byte-wide) registers, and are accessed by first writing a 1-byte
register index/offset number, then by reading or writing the data.
Generally there is an auto-increment feature so the when multiple bytes
are read or written, multiple contiguous registers are accessed.
Most existing slave device drivers allocate an array of iic_msg structures,
fill in all the transfer info, and invoke iicbus_transfer(). These new
functions commonize all that and reduce register access to a simple call
with a few arguments.
Modified:
head/sys/dev/iicbus/iiconf.c
head/sys/dev/iicbus/iiconf.h
Modified: head/sys/dev/iicbus/iiconf.c
==============================================================================
--- head/sys/dev/iicbus/iiconf.c Wed Jul 26 20:20:58 2017 (r321582)
+++ head/sys/dev/iicbus/iiconf.c Wed Jul 26 20:40:24 2017 (r321583)
@@ -470,3 +470,55 @@ iicbus_transfer_gen(device_t dev, struct iic_msg *msgs
iicbus_stop(bus);
return (error);
}
+
+int
+iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer,
+ uint16_t buflen, int waithow)
+{
+ struct iic_msg msgs[2];
+ uint8_t slaveaddr;
+
+ /*
+ * Two transfers back to back with a repeat-start between them; first we
+ * write the address-within-device, then we read from the device.
+ */
+ slaveaddr = iicbus_get_addr(slavedev);
+
+ msgs[0].slave = slaveaddr;
+ msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
+ msgs[0].len = 1;
+ msgs[0].buf = ®addr;
+
+ msgs[1].slave = slaveaddr;
+ msgs[1].flags = IIC_M_RD;
+ msgs[1].len = buflen;
+ msgs[1].buf = buffer;
+
+ return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
+}
+
+int iicdev_writeto(device_t slavedev, uint8_t regaddr, void *buffer,
+ uint16_t buflen, int waithow)
+{
+ struct iic_msg msgs[2];
+ uint8_t slaveaddr;
+
+ /*
+ * Two transfers back to back with no stop or start between them; first
+ * we write the address then we write the data to that address, all in a
+ * single transfer from two scattered buffers.
+ */
+ slaveaddr = iicbus_get_addr(slavedev);
+
+ msgs[0].slave = slaveaddr;
+ msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
+ msgs[0].len = 1;
+ msgs[0].buf = ®addr;
+
+ msgs[1].slave = slaveaddr;
+ msgs[1].flags = IIC_M_WR | IIC_M_NOSTART;
+ msgs[1].len = buflen;
+ msgs[1].buf = buffer;
+
+ return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
+}
Modified: head/sys/dev/iicbus/iiconf.h
==============================================================================
--- head/sys/dev/iicbus/iiconf.h Wed Jul 26 20:20:58 2017 (r321582)
+++ head/sys/dev/iicbus/iiconf.h Wed Jul 26 20:40:24 2017 (r321583)
@@ -133,6 +133,16 @@ int iicbus_transfer_excl(device_t bus, struct iic_msg
int how);
int iicbus_transfer_gen(device_t bus, struct iic_msg *msgs, uint32_t nmsgs);
+/*
+ * Simple register read/write routines, but the "register" can be any size.
+ * The transfers are done with iicbus_transfer_excl(). Reads use a repeat-start
+ * between sending the address and reading; writes use a single start/stop.
+ */
+int iicdev_readfrom(device_t _slavedev, uint8_t _regaddr, void *_buffer,
+ uint16_t _buflen, int _waithow);
+int iicdev_writeto(device_t _slavedev, uint8_t _regaddr, void *_buffer,
+ uint16_t _buflen, int _waithow);
+
#define IICBUS_MODVER 1
#define IICBUS_MINVER 1
#define IICBUS_MAXVER 1
More information about the svn-src-head
mailing list