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.
This commit is contained in:
parent
c45b18681f
commit
7ec74c580d
@ -470,3 +470,55 @@ iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
|
||||
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));
|
||||
}
|
||||
|
@ -133,6 +133,16 @@ int iicbus_transfer_excl(device_t bus, struct iic_msg *msgs, uint32_t nmsgs,
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user