|author||Amaury Pouly <firstname.lastname@example.org>||2016-05-02 21:57:55 +0100|
|committer||Gerrit Rockbox <email@example.com>||2016-06-01 22:55:37 +0200|
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')
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
@@ -24,7 +24,6 @@
@@ -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.
-/* start building a transfer, will acquire an exclusive lock */
-/* 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 */
+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 bytes from data, and then count bytes from data
+ * (if count > 0). The second stage is useful to avoid allocating a single
+ * buffer to hold address + data for example.
+ * - read: write count bytes from data, and then read count bytes from data.
+ * If count = 0 then the write stage is ignored.
+/** 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 *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; /* count: depends on mode */
+ void *data; /* 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__