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   = &regaddr;
+
+       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   = &regaddr;
+
+       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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to