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