diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-05-02 21:57:55 +0100 |
---|---|---|
committer | Gerrit Rockbox <gerrit@rockbox.org> | 2016-06-01 22:55:37 +0200 |
commit | 4d42e3685c55a6de9d05003f8482f7fb1be022fd (patch) | |
tree | 121c5fbe8a7f63a452fc523571962ecc60bd625c /firmware/target/arm/imx233/i2c-imx233.h | |
parent | 615c638c7da1be395a13dd107be004b03a9c390d (diff) | |
download | rockbox-4d42e3685c55a6de9d05003f8482f7fb1be022fd.tar.gz rockbox-4d42e3685c55a6de9d05003f8482f7fb1be022fd.zip |
imx233: rewrite i2c driver
The new driver provides several new features:
- asynchronous transfer
- transactions (several transfers executed at once)
- queueing
The style still provides the legacy interface.
Change-Id: I6d8ecc89d1f7057847c9b2dc69b76cd45c9c8407
Diffstat (limited to 'firmware/target/arm/imx233/i2c-imx233.h')
-rw-r--r-- | firmware/target/arm/imx233/i2c-imx233.h | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/firmware/target/arm/imx233/i2c-imx233.h b/firmware/target/arm/imx233/i2c-imx233.h index 263e93aa77..33e38e38da 100644 --- a/firmware/target/arm/imx233/i2c-imx233.h +++ b/firmware/target/arm/imx233/i2c-imx233.h @@ -24,7 +24,6 @@ #include "cpu.h" #include "system.h" #include "system-target.h" -#include "i2c.h" enum imx233_i2c_error_t { @@ -35,14 +34,71 @@ enum imx233_i2c_error_t I2C_NO_SLAVE_ACK = -4, I2C_SLAVE_NAK = -5, I2C_BUFFER_FULL = -6, + I2C_SKIP = -7, /* transfer skipped before of previous error in transaction */ }; +/** Important notes on the driver. + * + * The driver supports both synchronous and asynchronous transfers. Asynchronous + * transfer functions can safely be called from IRQ context. Beware that the completion + * callback of asynchronous transfers may be called from IRQ context. + * + * The driver supports queuing so it is safe to call several transfer functions + * concurrently. + */ + void imx233_i2c_init(void); -/* start building a transfer, will acquire an exclusive lock */ -void imx233_i2c_begin(void); -/* add stage */ -enum imx233_i2c_error_t imx233_i2c_add(bool start, bool transmit, void *buffer, unsigned size, bool stop); -/* end building a transfer and start the transfer */ -enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout); + +/** legacy API: + * read/write functions return 0 on success */ +int i2c_write(int device, const unsigned char* buf, int count); +int i2c_read(int device, unsigned char* buf, int count); +int i2c_readmem(int device, int address, unsigned char* buf, int count); +int i2c_writemem(int device, int address, const unsigned char* buf, int count); + +/** Advanced API */ +struct imx233_i2c_xfer_t; +typedef void (*imx233_i2c_cb_t)(struct imx233_i2c_xfer_t *xfer, enum imx233_i2c_error_t status); + +/** Transfer mode. There are currently two types of transfers, to make + * programming simpler: + * - write: write count[0] bytes from data[0], and then count[1] bytes from data[1] + * (if count[1] > 0). The second stage is useful to avoid allocating a single + * buffer to hold address + data for example. + * - read: write count[0] bytes from data[0], and then read count[1] bytes from data[1]. + * If count[0] = 0 then the write stage is ignored. + */ +enum imx233_i2x_xfer_mode_t +{ + I2C_WRITE, + I2C_READ, +}; + +/** This data structure represents one transfer. The exact shape of the transfer + * depends on the mode. + * NOTE a single transfer is limited to 512 bytes of data (RX + TX) + * A transaction is made up of several transfers, chained together. + */ +struct imx233_i2c_xfer_t +{ + struct imx233_i2c_xfer_t *next; /* next transfer, or NULL */ + imx233_i2c_cb_t callback; /* NULL for no callack */ + int dev_addr; /* device address */ + bool fast_mode; /* 400 kHz 'fast' mode or 100 kHz 'normal' mode */ + enum imx233_i2x_xfer_mode_t mode; /* transfer mode */ + int count[2]; /* count: depends on mode */ + void *data[2]; /* data: depends on mode */ + unsigned tmo_ms; /* timeout in milliseconds (0 means infinite) */ + /* internal */ + struct imx233_i2c_xfer_t *last; /* last in transaction */ +}; + +/* Queue one or more tranfer. If several transfer are queued (transaction) + * they are guaranteed to be executed "as one" (ie without interleaving). Furthermore, + * if a transfer of the transfaction fails, the remaining transfers of the transactions + * will NOT be executed (and their callback will be called with SKIP status). + * Return 0 if queueing was successful. Note that the transfer may still fail, + * in which case the callback will have a nonzero status code. */ +void imx233_i2c_transfer(struct imx233_i2c_xfer_t *xfer); #endif // __I2C_IMX233_H__ |