added stdio.h to includes for DBG compilation
[people/xl0/gpxe.git] / src / drivers / bitbash / i2c_bit.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <stdio.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <errno.h>
23 #include <assert.h>
24 #include <timer.h>
25 #include <gpxe/bitbash.h>
26 #include <gpxe/i2c.h>
27
28 /** @file
29  *
30  * I2C bit-bashing interface
31  *
32  * This implements a simple I2C master via a bit-bashing interface
33  * that provides two lines: SCL (clock) and SDA (data).
34  */
35
36 /**
37  * Delay between output state changes
38  *
39  * Max rated i2c speed (for the basic i2c protocol) is 100kbps,
40  * i.e. 200k clock transitions per second.
41  */
42 static void i2c_delay ( void ) {
43         udelay ( I2C_UDELAY );
44 }
45
46 /**
47  * Set state of I2C SCL line
48  *
49  * @v basher            Bit-bashing interface
50  * @v state             New state of SCL
51  */
52 static void setscl ( struct bit_basher *basher, int state ) {
53         write_bit ( basher, I2C_BIT_SCL, state );
54         i2c_delay();
55 }
56
57 /**
58  * Set state of I2C SDA line
59  *
60  * @v basher            Bit-bashing interface
61  * @v state             New state of SDA
62  */
63 static void setsda ( struct bit_basher *basher, int state ) {
64         write_bit ( basher, I2C_BIT_SDA, state );
65         i2c_delay();
66 }
67
68 /**
69  * Get state of I2C SDA line
70  *
71  * @v basher            Bit-bashing interface
72  * @ret state           State of SDA
73  */
74 static int getsda ( struct bit_basher *basher ) {
75         return read_bit ( basher, I2C_BIT_SDA );
76 }
77
78 /**
79  * Send an I2C start condition
80  *
81  * @v basher            Bit-bashing interface
82  */
83 static void i2c_start ( struct bit_basher *basher ) {
84         setscl ( basher, 1 );
85         setsda ( basher, 0 );
86         setscl ( basher, 0 );
87         setsda ( basher, 1 );
88 }
89
90 /**
91  * Send an I2C data bit
92  *
93  * @v basher            Bit-bashing interface
94  * @v bit               Bit to send
95  */
96 static void i2c_send_bit ( struct bit_basher *basher, int bit ) {
97         setsda ( basher, bit );
98         setscl ( basher, 1 );
99         setscl ( basher, 0 );
100         setsda ( basher, 1 );
101 }
102
103 /**
104  * Receive an I2C data bit
105  *
106  * @v basher            Bit-bashing interface
107  * @ret bit             Received bit
108  */
109 static int i2c_recv_bit ( struct bit_basher *basher ) {
110         int bit;
111
112         setscl ( basher, 1 );
113         bit = getsda ( basher );
114         setscl ( basher, 0 );
115         return bit;
116 }
117
118 /**
119  * Send an I2C stop condition
120  *
121  * @v basher            Bit-bashing interface
122  */
123 static void i2c_stop ( struct bit_basher *basher ) {
124         setsda ( basher, 0 );
125         setscl ( basher, 1 );
126         setsda ( basher, 1 );
127 }
128
129 /**
130  * Send byte via I2C bus and check for acknowledgement
131  *
132  * @v basher            Bit-bashing interface
133  * @v byte              Byte to send
134  * @ret rc              Return status code
135  *
136  * Sends a byte via the I2C bus and checks for an acknowledgement from
137  * the slave device.
138  */
139 static int i2c_send_byte ( struct bit_basher *basher, uint8_t byte ) {
140         int i;
141         
142         /* Send byte */
143         for ( i = 8 ; i ; i-- ) {
144                 i2c_send_bit ( basher, byte & 0x80 );
145                 byte <<= 1;
146         }
147
148         /* Check for acknowledgement from slave */
149         return ( i2c_recv_bit ( basher ) == 0 ? 0 : -EIO );
150 }
151
152 /**
153  * Receive byte via I2C bus
154  *
155  * @v basher            Bit-bashing interface
156  * @ret byte            Received byte
157  *
158  * Receives a byte via the I2C bus and sends NACK to the slave device.
159  */
160 static uint8_t i2c_recv_byte ( struct bit_basher *basher ) {
161         uint8_t value = 0;
162         int i;
163
164         /* Receive byte */
165         for ( i = 8 ; i ; i-- ) {
166                 value <<= 1;
167                 value |= ( i2c_recv_bit ( basher ) & 0x1 );
168         }
169
170         /* Send NACK */
171         i2c_send_bit ( basher, 1 );
172
173         return value;
174 }
175
176 /**
177  * Select I2C device for reading or writing
178  *
179  * @v basher            Bit-bashing interface
180  * @v i2cdev            I2C device
181  * @v direction         I2C_READ or I2C_WRITE
182  * @ret rc              Return status code
183  */
184 static int i2c_select ( struct bit_basher *basher, struct i2c_device *i2cdev,
185                         unsigned int direction ) {
186         unsigned int address;
187         int rc;
188
189         i2c_start ( basher );
190
191         /* First byte of the address */
192         address = i2cdev->address;
193         if ( i2cdev->tenbit ) {
194                 address |= I2C_TENBIT_ADDRESS;
195                 address >>= 8;
196         }
197         if ( ( rc = i2c_send_byte ( basher, 
198                                     ( ( address << 1 ) | direction ) ) ) != 0 )
199                 return rc;
200
201         /* Second byte of the address (10-bit addresses only) */
202         if ( i2cdev->tenbit ) {
203                 if ( ( rc = i2c_send_byte ( basher,
204                                             ( i2cdev->address & 0xff ) ) ) !=0)
205                         return rc;
206         }
207
208         return 0;
209 }
210
211 /**
212  * Read data from I2C device via bit-bashing interface
213  *
214  * @v i2c               I2C interface
215  * @v i2cdev            I2C device
216  * @v offset            Starting offset within the device
217  * @v data              Data buffer
218  * @v len               Length of data buffer
219  * @ret rc              Return status code
220  *
221  * Note that attempting to read zero bytes of data is a valid way to
222  * check for I2C device presence.
223  */
224 static int i2c_bit_read ( struct i2c_interface *i2c,
225                           struct i2c_device *i2cdev, unsigned int offset,
226                           uint8_t *data, unsigned int len ) {
227         struct i2c_bit_basher *i2cbit
228                 = container_of ( i2c, struct i2c_bit_basher, i2c );
229         struct bit_basher *basher = &i2cbit->basher;
230         int rc = 0;
231
232         DBG ( "Reading from I2C device %x: ", i2cdev->address );
233
234         while ( 1 ) {
235
236                 /* Select device for writing */
237                 if ( ( rc = i2c_select ( basher, i2cdev, I2C_WRITE ) ) != 0 )
238                         break;
239
240                 /* Abort at end of data */
241                 if ( ! ( len-- ) )
242                         break;
243
244                 /* Select offset */
245                 if ( ( rc = i2c_send_byte ( basher, offset++ ) ) != 0 )
246                         break;
247                 
248                 /* Select device for reading */
249                 if ( ( rc = i2c_select ( basher, i2cdev, I2C_READ ) ) != 0 )
250                         break;
251
252                 /* Read byte */
253                 *data++ = i2c_recv_byte ( basher );
254                 DBG ( "%02x ", *(data - 1) );
255         }
256         
257         DBG ( "%s\n", ( rc ? "failed" : "" ) );
258         i2c_stop ( basher );
259         return rc;
260 }
261
262 /**
263  * Write data to I2C device via bit-bashing interface
264  *
265  * @v i2c               I2C interface
266  * @v i2cdev            I2C device
267  * @v offset            Starting offset within the device
268  * @v data              Data buffer
269  * @v len               Length of data buffer
270  * @ret rc              Return status code
271  *
272  * Note that attempting to write zero bytes of data is a valid way to
273  * check for I2C device presence.
274  */
275 static int i2c_bit_write ( struct i2c_interface *i2c,
276                            struct i2c_device *i2cdev, unsigned int offset,
277                            const uint8_t *data, unsigned int len ) {
278         struct i2c_bit_basher *i2cbit
279                 = container_of ( i2c, struct i2c_bit_basher, i2c );
280         struct bit_basher *basher = &i2cbit->basher;
281         int rc = 0;
282
283         DBG ( "Writing to I2C device %x: ", i2cdev->address );
284
285         while ( 1 ) {
286
287                 /* Select device for writing */
288                 if ( ( rc = i2c_select ( basher, i2cdev, I2C_WRITE ) ) != 0 )
289                         break;
290                 
291                 /* Abort at end of data */
292                 if ( ! ( len-- ) )
293                         break;
294
295                 /* Select offset */
296                 if ( ( rc = i2c_send_byte ( basher, offset++ ) ) != 0 )
297                         break;
298                 
299                 /* Write data to device */
300                 DBG ( "%02x ", *data );
301                 if ( ( rc = i2c_send_byte ( basher, *data++ ) ) != 0 )
302                         break;
303         }
304         
305         DBG ( "%s\n", ( rc ? "failed" : "" ) );
306         i2c_stop ( basher );
307         return rc;
308 }
309
310 /**
311  * Initialise I2C bit-bashing interface
312  *
313  * @v i2cbit            I2C bit-bashing interface
314  */
315 void init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit ) {
316         struct bit_basher *basher = &i2cbit->basher;
317         
318         assert ( basher->read != NULL );
319         assert ( basher->write != NULL );
320         i2cbit->i2c.read = i2c_bit_read;
321         i2cbit->i2c.write = i2c_bit_write;
322         i2c_stop ( basher );
323 }