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