2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <gpxe/bitbash.h>
28 * I2C bit-bashing interface
30 * This implements a simple I2C master via a bit-bashing interface
31 * that provides two lines: SCL (clock) and SDA (data).
35 * Set state of I2C SCL line
37 * @v basher Bit-bashing interface
38 * @v state New state of SCL
40 static inline __attribute__ (( always_inline )) void
41 setscl ( struct bit_basher *basher, int state ) {
42 write_bit ( basher, I2C_BIT_SCL, state );
46 * Set state of I2C SDA line
48 * @v basher Bit-bashing interface
49 * @v state New state of SDA
51 static inline __attribute__ (( always_inline )) void
52 setsda ( struct bit_basher *basher, int state ) {
53 write_bit ( basher, I2C_BIT_SDA, state );
57 * Get state of I2C SDA line
59 * @v basher Bit-bashing interface
60 * @ret state State of SDA
62 static inline __attribute__ (( always_inline )) int
63 getsda ( struct bit_basher *basher ) {
64 return read_bit ( basher, I2C_BIT_SDA );
68 * Send an I2C start condition
70 * @v basher Bit-bashing interface
72 static void i2c_start ( struct bit_basher *basher ) {
80 * Send an I2C data bit
82 * @v basher Bit-bashing interface
85 static void i2c_send_bit ( struct bit_basher *basher, int bit ) {
86 setsda ( basher, bit );
93 * Receive an I2C data bit
95 * @v basher Bit-bashing interface
96 * @ret bit Received bit
98 static int i2c_recv_bit ( struct bit_basher *basher ) {
101 setscl ( basher, 1 );
102 bit = getsda ( basher );
103 setscl ( basher, 0 );
108 * Send an I2C stop condition
110 * @v basher Bit-bashing interface
112 static void i2c_stop ( struct bit_basher *basher ) {
113 setsda ( basher, 0 );
114 setscl ( basher, 1 );
115 setsda ( basher, 1 );
119 * Send byte via I2C bus and check for acknowledgement
121 * @v basher Bit-bashing interface
122 * @v byte Byte to send
123 * @ret rc Return status code
125 * Sends a byte via the I2C bus and checks for an acknowledgement from
128 static int i2c_send_byte ( struct bit_basher *basher, uint8_t byte ) {
132 for ( i = 8 ; i ; i-- ) {
133 i2c_send_bit ( basher, byte & 0x80 );
137 /* Check for acknowledgement from slave */
138 return ( i2c_recv_bit ( basher ) == 0 ? 0 : -EIO );
142 * Receive byte via I2C bus
144 * @v basher Bit-bashing interface
145 * @ret byte Received byte
147 * Receives a byte via the I2C bus and sends NACK to the slave device.
149 static uint8_t i2c_recv_byte ( struct bit_basher *basher ) {
154 for ( i = 8 ; i ; i-- ) {
156 value |= i2c_recv_bit ( basher );
160 i2c_send_bit ( basher, 1 );
166 * Select I2C device for reading or writing
168 * @v basher Bit-bashing interface
169 * @v i2cdev I2C device
170 * @v direction I2C_READ or I2C_WRITE
171 * @ret rc Return status code
173 static int i2c_select ( struct bit_basher *basher, struct i2c_device *i2cdev,
174 unsigned int direction ) {
175 unsigned int address;
178 i2c_start ( basher );
180 /* First byte of the address */
181 address = i2cdev->address;
182 if ( i2cdev->tenbit ) {
183 address |= I2C_TENBIT_ADDRESS;
186 if ( ( rc = i2c_send_byte ( basher,
187 ( ( address << 1 ) | direction ) ) ) != 0 )
190 /* Second byte of the address (10-bit addresses only) */
191 if ( i2cdev->tenbit ) {
192 if ( ( rc = i2c_send_byte ( basher,
193 ( i2cdev->address & 0xff ) ) ) !=0)
201 * Read data from I2C device via bit-bashing interface
203 * @v i2c I2C interface
204 * @v i2cdev I2C device
205 * @v offset Starting offset within the device
206 * @v data Data buffer
207 * @v len Length of data buffer
208 * @ret rc Return status code
210 * Note that attempting to read zero bytes of data is a valid way to
211 * check for I2C device presence.
213 static int i2c_bit_read ( struct i2c_interface *i2c,
214 struct i2c_device *i2cdev, unsigned int offset,
215 uint8_t *data, unsigned int len ) {
216 struct i2c_bit_basher *i2cbit
217 = container_of ( i2c, struct i2c_bit_basher, i2c );
218 struct bit_basher *basher = &i2cbit->basher;
221 DBG ( "Reading from I2C device %x: ", i2cdev->address );
225 /* Select device for writing */
226 if ( ( rc = i2c_select ( basher, i2cdev, I2C_WRITE ) ) != 0 )
229 /* Abort at end of data */
234 if ( ( rc = i2c_send_byte ( basher, offset++ ) ) != 0 )
237 /* Select device for reading */
238 if ( ( rc = i2c_select ( basher, i2cdev, I2C_READ ) ) != 0 )
242 *data++ = i2c_recv_byte ( basher );
243 DBG ( "%02x ", *(data - 1) );
246 DBG ( "%s\n", ( rc ? "failed" : "" ) );
252 * Write data to I2C device via bit-bashing interface
254 * @v i2c I2C interface
255 * @v i2cdev I2C device
256 * @v offset Starting offset within the device
257 * @v data Data buffer
258 * @v len Length of data buffer
259 * @ret rc Return status code
261 * Note that attempting to write zero bytes of data is a valid way to
262 * check for I2C device presence.
264 static int i2c_bit_write ( struct i2c_interface *i2c,
265 struct i2c_device *i2cdev, unsigned int offset,
266 const uint8_t *data, unsigned int len ) {
267 struct i2c_bit_basher *i2cbit
268 = container_of ( i2c, struct i2c_bit_basher, i2c );
269 struct bit_basher *basher = &i2cbit->basher;
272 DBG ( "Writing to I2C device %x: ", i2cdev->address );
276 /* Select device for writing */
277 if ( ( rc = i2c_select ( basher, i2cdev, I2C_WRITE ) ) != 0 )
280 /* Abort at end of data */
285 if ( ( rc = i2c_send_byte ( basher, offset++ ) ) != 0 )
288 /* Write data to device */
289 DBG ( "%02x ", *data );
290 if ( ( rc = i2c_send_byte ( basher, *data++ ) ) != 0 )
294 DBG ( "%s\n", ( rc ? "failed" : "" ) );
300 * Initialise I2C bit-bashing interface
302 * @v i2cbit I2C bit-bashing interface
304 void init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit ) {
305 struct bit_basher *basher = &i2cbit->basher;
307 assert ( basher->read != NULL );
308 assert ( basher->write != NULL );
309 i2cbit->i2c.read = i2c_bit_read;
310 i2cbit->i2c.write = i2c_bit_write;
311 basher->udelay = I2C_UDELAY;