1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __I2C_IMX233_H__
#define __I2C_IMX233_H__
#include "cpu.h"
#include "system.h"
#include "system-target.h"
enum imx233_i2c_error_t
{
I2C_SUCCESS = 0,
I2C_ERROR = -1,
I2C_TIMEOUT = -2,
I2C_MASTER_LOSS = -3,
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);
/** 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__
|