]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /*!*************************************************************************** |
2 | *! | |
3 | *! FILE NAME : i2c.c | |
4 | *! | |
5 | *! DESCRIPTION: implements an interface for IIC/I2C, both directly from other | |
6 | *! kernel modules (i2c_writereg/readreg) and from userspace using | |
7 | *! ioctl()'s | |
8 | *! | |
9 | *! Nov 30 1998 Torbjorn Eliasson Initial version. | |
10 | *! Bjorn Wesen Elinux kernel version. | |
11 | *! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff - | |
12 | *! don't use PB_I2C if DS1302 uses same bits, | |
13 | *! use PB. | |
14 | *! $Log: i2c.c,v $ | |
7e920426 MS |
15 | *! Revision 1.13 2005/03/07 13:13:07 starvik |
16 | *! Added spinlocks to protect states etc | |
17 | *! | |
18 | *! Revision 1.12 2005/01/05 06:11:22 starvik | |
19 | *! No need to do local_irq_disable after local_irq_save. | |
20 | *! | |
21 | *! Revision 1.11 2004/12/13 12:21:52 starvik | |
22 | *! Added I/O and DMA allocators from Linux 2.4 | |
23 | *! | |
1da177e4 LT |
24 | *! Revision 1.9 2004/08/24 06:49:14 starvik |
25 | *! Whitespace cleanup | |
26 | *! | |
27 | *! Revision 1.8 2004/06/08 08:48:26 starvik | |
28 | *! Removed unused code | |
29 | *! | |
30 | *! Revision 1.7 2004/05/28 09:26:59 starvik | |
31 | *! Modified I2C initialization to work in 2.6. | |
32 | *! | |
33 | *! Revision 1.6 2004/05/14 07:58:03 starvik | |
34 | *! Merge of changes from 2.4 | |
35 | *! | |
36 | *! Revision 1.4 2002/12/11 13:13:57 starvik | |
37 | *! Added arch/ to v10 specific includes | |
38 | *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | |
39 | *! | |
40 | *! Revision 1.3 2002/11/20 11:56:11 starvik | |
41 | *! Merge of Linux 2.5.48 | |
42 | *! | |
43 | *! Revision 1.2 2002/11/18 13:16:06 starvik | |
44 | *! Linux 2.5 port of latest 2.4 drivers | |
45 | *! | |
46 | *! Revision 1.9 2002/10/31 15:32:26 starvik | |
47 | *! Update Port B register and shadow even when running with hardware support | |
48 | *! to avoid glitches when reading bits | |
49 | *! Never set direction to out in i2c_inbyte | |
0779bf2d | 50 | *! Removed incorrect clock toggling at end of i2c_inbyte |
1da177e4 LT |
51 | *! |
52 | *! Revision 1.8 2002/08/13 06:31:53 starvik | |
53 | *! Made SDA and SCL line configurable | |
54 | *! Modified i2c_inbyte to work with PCF8563 | |
55 | *! | |
56 | *! Revision 1.7 2001/04/04 13:11:36 markusl | |
57 | *! Updated according to review remarks | |
58 | *! | |
59 | *! Revision 1.6 2001/03/19 12:43:00 markusl | |
60 | *! Made some symbols unstatic (used by the eeprom driver) | |
61 | *! | |
62 | *! Revision 1.5 2001/02/27 13:52:48 bjornw | |
63 | *! malloc.h -> slab.h | |
64 | *! | |
65 | *! Revision 1.4 2001/02/15 07:17:40 starvik | |
66 | *! Corrected usage if port_pb_i2c_shadow | |
67 | *! | |
68 | *! Revision 1.3 2001/01/26 17:55:13 bjornw | |
69 | *! * Made I2C_USES_PB_NOT_PB_I2C a CONFIG option instead of assigning it | |
70 | *! magically. Config.in needs to set it for the options that need it, like | |
71 | *! Dallas 1302 support. Actually, it should be default since it screws up | |
72 | *! the PB bits even if you don't use I2C.. | |
73 | *! * Include linux/config.h to get the above | |
74 | *! | |
75 | *! Revision 1.2 2001/01/18 15:49:30 bjornw | |
76 | *! 2.4 port of I2C including some cleanups (untested of course) | |
77 | *! | |
78 | *! Revision 1.1 2001/01/18 15:35:25 bjornw | |
79 | *! Verbatim copy of the Etrax i2c driver, 2.0 elinux version | |
80 | *! | |
81 | *! | |
82 | *! --------------------------------------------------------------------------- | |
83 | *! | |
84 | *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN | |
85 | *! | |
86 | *!***************************************************************************/ | |
7e920426 | 87 | /* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */ |
1da177e4 LT |
88 | |
89 | /****************** INCLUDE FILES SECTION ***********************************/ | |
90 | ||
91 | #include <linux/module.h> | |
92 | #include <linux/sched.h> | |
93 | #include <linux/slab.h> | |
94 | #include <linux/errno.h> | |
95 | #include <linux/kernel.h> | |
96 | #include <linux/fs.h> | |
97 | #include <linux/string.h> | |
98 | #include <linux/init.h> | |
1da177e4 LT |
99 | |
100 | #include <asm/etraxi2c.h> | |
101 | ||
102 | #include <asm/system.h> | |
103 | #include <asm/arch/svinto.h> | |
104 | #include <asm/io.h> | |
105 | #include <asm/delay.h> | |
7e920426 | 106 | #include <asm/arch/io_interface_mux.h> |
1da177e4 LT |
107 | |
108 | #include "i2c.h" | |
109 | ||
110 | /****************** I2C DEFINITION SECTION *************************/ | |
111 | ||
112 | #define D(x) | |
113 | ||
114 | #define I2C_MAJOR 123 /* LOCAL/EXPERIMENTAL */ | |
115 | static const char i2c_name[] = "i2c"; | |
116 | ||
117 | #define CLOCK_LOW_TIME 8 | |
118 | #define CLOCK_HIGH_TIME 8 | |
119 | #define START_CONDITION_HOLD_TIME 8 | |
120 | #define STOP_CONDITION_HOLD_TIME 8 | |
121 | #define ENABLE_OUTPUT 0x01 | |
122 | #define ENABLE_INPUT 0x00 | |
123 | #define I2C_CLOCK_HIGH 1 | |
124 | #define I2C_CLOCK_LOW 0 | |
125 | #define I2C_DATA_HIGH 1 | |
126 | #define I2C_DATA_LOW 0 | |
127 | ||
128 | #ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C | |
129 | /* Use PB and not PB_I2C */ | |
130 | #ifndef CONFIG_ETRAX_I2C_DATA_PORT | |
131 | #define CONFIG_ETRAX_I2C_DATA_PORT 0 | |
132 | #endif | |
133 | #ifndef CONFIG_ETRAX_I2C_CLK_PORT | |
134 | #define CONFIG_ETRAX_I2C_CLK_PORT 1 | |
135 | #endif | |
136 | ||
137 | #define SDABIT CONFIG_ETRAX_I2C_DATA_PORT | |
138 | #define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT | |
139 | #define i2c_enable() | |
140 | #define i2c_disable() | |
141 | ||
142 | /* enable or disable output-enable, to select output or input on the i2c bus */ | |
143 | ||
144 | #define i2c_dir_out() \ | |
145 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 1) | |
146 | #define i2c_dir_in() \ | |
147 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 0) | |
148 | ||
149 | /* control the i2c clock and data signals */ | |
150 | ||
151 | #define i2c_clk(x) \ | |
152 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SCLBIT, x) | |
153 | #define i2c_data(x) \ | |
154 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SDABIT, x) | |
155 | ||
156 | /* read a bit from the i2c interface */ | |
157 | ||
158 | #define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT) | |
159 | ||
160 | #else | |
161 | /* enable or disable the i2c interface */ | |
162 | ||
163 | #define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en)) | |
164 | #define i2c_disable() *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_en)) | |
165 | ||
166 | /* enable or disable output-enable, to select output or input on the i2c bus */ | |
167 | ||
168 | #define i2c_dir_out() \ | |
169 | *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \ | |
170 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1); | |
171 | #define i2c_dir_in() \ | |
172 | *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \ | |
173 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0); | |
174 | ||
175 | /* control the i2c clock and data signals */ | |
176 | ||
177 | #define i2c_clk(x) \ | |
178 | *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \ | |
179 | ~IO_MASK(R_PORT_PB_I2C, i2c_clk)) | IO_FIELD(R_PORT_PB_I2C, i2c_clk, (x))); \ | |
180 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 1, x); | |
181 | ||
182 | #define i2c_data(x) \ | |
183 | *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \ | |
184 | ~IO_MASK(R_PORT_PB_I2C, i2c_d)) | IO_FIELD(R_PORT_PB_I2C, i2c_d, (x))); \ | |
185 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 0, x); | |
186 | ||
187 | /* read a bit from the i2c interface */ | |
188 | ||
189 | #define i2c_getbit() (*R_PORT_PB_READ & 0x1) | |
190 | #endif | |
191 | ||
192 | /* use the kernels delay routine */ | |
193 | ||
194 | #define i2c_delay(usecs) udelay(usecs) | |
195 | ||
7e920426 | 196 | static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */ |
1da177e4 LT |
197 | |
198 | /****************** FUNCTION DEFINITION SECTION *************************/ | |
199 | ||
200 | ||
201 | /* generate i2c start condition */ | |
202 | ||
203 | void | |
204 | i2c_start(void) | |
205 | { | |
206 | /* | |
207 | * SCL=1 SDA=1 | |
208 | */ | |
209 | i2c_dir_out(); | |
210 | i2c_delay(CLOCK_HIGH_TIME/6); | |
211 | i2c_data(I2C_DATA_HIGH); | |
212 | i2c_clk(I2C_CLOCK_HIGH); | |
213 | i2c_delay(CLOCK_HIGH_TIME); | |
214 | /* | |
215 | * SCL=1 SDA=0 | |
216 | */ | |
217 | i2c_data(I2C_DATA_LOW); | |
218 | i2c_delay(START_CONDITION_HOLD_TIME); | |
219 | /* | |
220 | * SCL=0 SDA=0 | |
221 | */ | |
222 | i2c_clk(I2C_CLOCK_LOW); | |
223 | i2c_delay(CLOCK_LOW_TIME); | |
224 | } | |
225 | ||
226 | /* generate i2c stop condition */ | |
227 | ||
228 | void | |
229 | i2c_stop(void) | |
230 | { | |
231 | i2c_dir_out(); | |
232 | ||
233 | /* | |
234 | * SCL=0 SDA=0 | |
235 | */ | |
236 | i2c_clk(I2C_CLOCK_LOW); | |
237 | i2c_data(I2C_DATA_LOW); | |
238 | i2c_delay(CLOCK_LOW_TIME*2); | |
239 | /* | |
240 | * SCL=1 SDA=0 | |
241 | */ | |
242 | i2c_clk(I2C_CLOCK_HIGH); | |
243 | i2c_delay(CLOCK_HIGH_TIME*2); | |
244 | /* | |
245 | * SCL=1 SDA=1 | |
246 | */ | |
247 | i2c_data(I2C_DATA_HIGH); | |
248 | i2c_delay(STOP_CONDITION_HOLD_TIME); | |
249 | ||
250 | i2c_dir_in(); | |
251 | } | |
252 | ||
253 | /* write a byte to the i2c interface */ | |
254 | ||
255 | void | |
256 | i2c_outbyte(unsigned char x) | |
257 | { | |
258 | int i; | |
259 | ||
260 | i2c_dir_out(); | |
261 | ||
262 | for (i = 0; i < 8; i++) { | |
263 | if (x & 0x80) { | |
264 | i2c_data(I2C_DATA_HIGH); | |
265 | } else { | |
266 | i2c_data(I2C_DATA_LOW); | |
267 | } | |
268 | ||
269 | i2c_delay(CLOCK_LOW_TIME/2); | |
270 | i2c_clk(I2C_CLOCK_HIGH); | |
271 | i2c_delay(CLOCK_HIGH_TIME); | |
272 | i2c_clk(I2C_CLOCK_LOW); | |
273 | i2c_delay(CLOCK_LOW_TIME/2); | |
274 | x <<= 1; | |
275 | } | |
276 | i2c_data(I2C_DATA_LOW); | |
277 | i2c_delay(CLOCK_LOW_TIME/2); | |
278 | ||
279 | /* | |
280 | * enable input | |
281 | */ | |
282 | i2c_dir_in(); | |
283 | } | |
284 | ||
285 | /* read a byte from the i2c interface */ | |
286 | ||
287 | unsigned char | |
288 | i2c_inbyte(void) | |
289 | { | |
290 | unsigned char aBitByte = 0; | |
291 | int i; | |
292 | ||
293 | /* Switch off I2C to get bit */ | |
294 | i2c_disable(); | |
295 | i2c_dir_in(); | |
296 | i2c_delay(CLOCK_HIGH_TIME/2); | |
297 | ||
298 | /* Get bit */ | |
299 | aBitByte |= i2c_getbit(); | |
300 | ||
301 | /* Enable I2C */ | |
302 | i2c_enable(); | |
303 | i2c_delay(CLOCK_LOW_TIME/2); | |
304 | ||
305 | for (i = 1; i < 8; i++) { | |
306 | aBitByte <<= 1; | |
307 | /* Clock pulse */ | |
308 | i2c_clk(I2C_CLOCK_HIGH); | |
309 | i2c_delay(CLOCK_HIGH_TIME); | |
310 | i2c_clk(I2C_CLOCK_LOW); | |
311 | i2c_delay(CLOCK_LOW_TIME); | |
312 | ||
313 | /* Switch off I2C to get bit */ | |
314 | i2c_disable(); | |
315 | i2c_dir_in(); | |
316 | i2c_delay(CLOCK_HIGH_TIME/2); | |
317 | ||
318 | /* Get bit */ | |
319 | aBitByte |= i2c_getbit(); | |
320 | ||
321 | /* Enable I2C */ | |
322 | i2c_enable(); | |
323 | i2c_delay(CLOCK_LOW_TIME/2); | |
324 | } | |
325 | i2c_clk(I2C_CLOCK_HIGH); | |
326 | i2c_delay(CLOCK_HIGH_TIME); | |
327 | ||
328 | /* | |
329 | * we leave the clock low, getbyte is usually followed | |
330 | * by sendack/nack, they assume the clock to be low | |
331 | */ | |
332 | i2c_clk(I2C_CLOCK_LOW); | |
333 | return aBitByte; | |
334 | } | |
335 | ||
336 | /*#--------------------------------------------------------------------------- | |
337 | *# | |
338 | *# FUNCTION NAME: i2c_getack | |
339 | *# | |
340 | *# DESCRIPTION : checks if ack was received from ic2 | |
341 | *# | |
342 | *#--------------------------------------------------------------------------*/ | |
343 | ||
344 | int | |
345 | i2c_getack(void) | |
346 | { | |
347 | int ack = 1; | |
348 | /* | |
349 | * enable output | |
350 | */ | |
351 | i2c_dir_out(); | |
352 | /* | |
353 | * Release data bus by setting | |
354 | * data high | |
355 | */ | |
356 | i2c_data(I2C_DATA_HIGH); | |
357 | /* | |
358 | * enable input | |
359 | */ | |
360 | i2c_dir_in(); | |
361 | i2c_delay(CLOCK_HIGH_TIME/4); | |
362 | /* | |
363 | * generate ACK clock pulse | |
364 | */ | |
365 | i2c_clk(I2C_CLOCK_HIGH); | |
366 | /* | |
367 | * Use PORT PB instead of I2C | |
368 | * for input. (I2C not working) | |
369 | */ | |
370 | i2c_clk(1); | |
371 | i2c_data(1); | |
372 | /* | |
373 | * switch off I2C | |
374 | */ | |
375 | i2c_data(1); | |
376 | i2c_disable(); | |
377 | i2c_dir_in(); | |
378 | /* | |
379 | * now wait for ack | |
380 | */ | |
381 | i2c_delay(CLOCK_HIGH_TIME/2); | |
382 | /* | |
383 | * check for ack | |
384 | */ | |
385 | if(i2c_getbit()) | |
386 | ack = 0; | |
387 | i2c_delay(CLOCK_HIGH_TIME/2); | |
388 | if(!ack){ | |
389 | if(!i2c_getbit()) /* receiver pulld SDA low */ | |
390 | ack = 1; | |
391 | i2c_delay(CLOCK_HIGH_TIME/2); | |
392 | } | |
393 | ||
394 | /* | |
395 | * our clock is high now, make sure data is low | |
396 | * before we enable our output. If we keep data high | |
397 | * and enable output, we would generate a stop condition. | |
398 | */ | |
399 | i2c_data(I2C_DATA_LOW); | |
400 | ||
401 | /* | |
402 | * end clock pulse | |
403 | */ | |
404 | i2c_enable(); | |
405 | i2c_dir_out(); | |
406 | i2c_clk(I2C_CLOCK_LOW); | |
407 | i2c_delay(CLOCK_HIGH_TIME/4); | |
408 | /* | |
409 | * enable output | |
410 | */ | |
411 | i2c_dir_out(); | |
412 | /* | |
413 | * remove ACK clock pulse | |
414 | */ | |
415 | i2c_data(I2C_DATA_HIGH); | |
416 | i2c_delay(CLOCK_LOW_TIME/2); | |
417 | return ack; | |
418 | } | |
419 | ||
420 | /*#--------------------------------------------------------------------------- | |
421 | *# | |
422 | *# FUNCTION NAME: I2C::sendAck | |
423 | *# | |
424 | *# DESCRIPTION : Send ACK on received data | |
425 | *# | |
426 | *#--------------------------------------------------------------------------*/ | |
427 | void | |
428 | i2c_sendack(void) | |
429 | { | |
430 | /* | |
431 | * enable output | |
432 | */ | |
433 | i2c_delay(CLOCK_LOW_TIME); | |
434 | i2c_dir_out(); | |
435 | /* | |
436 | * set ack pulse high | |
437 | */ | |
438 | i2c_data(I2C_DATA_LOW); | |
439 | /* | |
440 | * generate clock pulse | |
441 | */ | |
442 | i2c_delay(CLOCK_HIGH_TIME/6); | |
443 | i2c_clk(I2C_CLOCK_HIGH); | |
444 | i2c_delay(CLOCK_HIGH_TIME); | |
445 | i2c_clk(I2C_CLOCK_LOW); | |
446 | i2c_delay(CLOCK_LOW_TIME/6); | |
447 | /* | |
448 | * reset data out | |
449 | */ | |
450 | i2c_data(I2C_DATA_HIGH); | |
451 | i2c_delay(CLOCK_LOW_TIME); | |
452 | ||
453 | i2c_dir_in(); | |
454 | } | |
455 | ||
456 | /*#--------------------------------------------------------------------------- | |
457 | *# | |
458 | *# FUNCTION NAME: i2c_sendnack | |
459 | *# | |
460 | *# DESCRIPTION : Sends NACK on received data | |
461 | *# | |
462 | *#--------------------------------------------------------------------------*/ | |
463 | void | |
464 | i2c_sendnack(void) | |
465 | { | |
466 | /* | |
467 | * enable output | |
468 | */ | |
469 | i2c_delay(CLOCK_LOW_TIME); | |
470 | i2c_dir_out(); | |
471 | /* | |
472 | * set data high | |
473 | */ | |
474 | i2c_data(I2C_DATA_HIGH); | |
475 | /* | |
476 | * generate clock pulse | |
477 | */ | |
478 | i2c_delay(CLOCK_HIGH_TIME/6); | |
479 | i2c_clk(I2C_CLOCK_HIGH); | |
480 | i2c_delay(CLOCK_HIGH_TIME); | |
481 | i2c_clk(I2C_CLOCK_LOW); | |
482 | i2c_delay(CLOCK_LOW_TIME); | |
483 | ||
484 | i2c_dir_in(); | |
485 | } | |
486 | ||
487 | /*#--------------------------------------------------------------------------- | |
488 | *# | |
489 | *# FUNCTION NAME: i2c_writereg | |
490 | *# | |
491 | *# DESCRIPTION : Writes a value to an I2C device | |
492 | *# | |
493 | *#--------------------------------------------------------------------------*/ | |
494 | int | |
495 | i2c_writereg(unsigned char theSlave, unsigned char theReg, | |
496 | unsigned char theValue) | |
497 | { | |
498 | int error, cntr = 3; | |
499 | unsigned long flags; | |
500 | ||
7e920426 MS |
501 | spin_lock(&i2c_lock); |
502 | ||
1da177e4 LT |
503 | do { |
504 | error = 0; | |
505 | /* | |
506 | * we don't like to be interrupted | |
507 | */ | |
508 | local_irq_save(flags); | |
1da177e4 LT |
509 | |
510 | i2c_start(); | |
511 | /* | |
512 | * send slave address | |
513 | */ | |
514 | i2c_outbyte((theSlave & 0xfe)); | |
515 | /* | |
516 | * wait for ack | |
517 | */ | |
518 | if(!i2c_getack()) | |
519 | error = 1; | |
520 | /* | |
521 | * now select register | |
522 | */ | |
523 | i2c_dir_out(); | |
524 | i2c_outbyte(theReg); | |
525 | /* | |
526 | * now it's time to wait for ack | |
527 | */ | |
528 | if(!i2c_getack()) | |
529 | error |= 2; | |
530 | /* | |
531 | * send register register data | |
532 | */ | |
533 | i2c_outbyte(theValue); | |
534 | /* | |
535 | * now it's time to wait for ack | |
536 | */ | |
537 | if(!i2c_getack()) | |
538 | error |= 4; | |
539 | /* | |
540 | * end byte stream | |
541 | */ | |
542 | i2c_stop(); | |
543 | /* | |
544 | * enable interrupt again | |
545 | */ | |
546 | local_irq_restore(flags); | |
547 | ||
548 | } while(error && cntr--); | |
549 | ||
550 | i2c_delay(CLOCK_LOW_TIME); | |
551 | ||
7e920426 MS |
552 | spin_unlock(&i2c_lock); |
553 | ||
1da177e4 LT |
554 | return -error; |
555 | } | |
556 | ||
557 | /*#--------------------------------------------------------------------------- | |
558 | *# | |
559 | *# FUNCTION NAME: i2c_readreg | |
560 | *# | |
561 | *# DESCRIPTION : Reads a value from the decoder registers. | |
562 | *# | |
563 | *#--------------------------------------------------------------------------*/ | |
564 | unsigned char | |
565 | i2c_readreg(unsigned char theSlave, unsigned char theReg) | |
566 | { | |
567 | unsigned char b = 0; | |
568 | int error, cntr = 3; | |
569 | unsigned long flags; | |
570 | ||
7e920426 MS |
571 | spin_lock(&i2c_lock); |
572 | ||
1da177e4 LT |
573 | do { |
574 | error = 0; | |
575 | /* | |
576 | * we don't like to be interrupted | |
577 | */ | |
578 | local_irq_save(flags); | |
1da177e4 LT |
579 | /* |
580 | * generate start condition | |
581 | */ | |
582 | i2c_start(); | |
583 | ||
584 | /* | |
585 | * send slave address | |
586 | */ | |
587 | i2c_outbyte((theSlave & 0xfe)); | |
588 | /* | |
589 | * wait for ack | |
590 | */ | |
591 | if(!i2c_getack()) | |
592 | error = 1; | |
593 | /* | |
594 | * now select register | |
595 | */ | |
596 | i2c_dir_out(); | |
597 | i2c_outbyte(theReg); | |
598 | /* | |
599 | * now it's time to wait for ack | |
600 | */ | |
601 | if(!i2c_getack()) | |
602 | error = 1; | |
603 | /* | |
604 | * repeat start condition | |
605 | */ | |
606 | i2c_delay(CLOCK_LOW_TIME); | |
607 | i2c_start(); | |
608 | /* | |
609 | * send slave address | |
610 | */ | |
611 | i2c_outbyte(theSlave | 0x01); | |
612 | /* | |
613 | * wait for ack | |
614 | */ | |
615 | if(!i2c_getack()) | |
616 | error = 1; | |
617 | /* | |
618 | * fetch register | |
619 | */ | |
620 | b = i2c_inbyte(); | |
621 | /* | |
622 | * last received byte needs to be nacked | |
623 | * instead of acked | |
624 | */ | |
625 | i2c_sendack(); | |
626 | /* | |
627 | * end sequence | |
628 | */ | |
629 | i2c_stop(); | |
630 | /* | |
631 | * enable interrupt again | |
632 | */ | |
633 | local_irq_restore(flags); | |
634 | ||
635 | } while(error && cntr--); | |
636 | ||
7e920426 MS |
637 | spin_unlock(&i2c_lock); |
638 | ||
1da177e4 LT |
639 | return b; |
640 | } | |
641 | ||
642 | static int | |
643 | i2c_open(struct inode *inode, struct file *filp) | |
644 | { | |
645 | return 0; | |
646 | } | |
647 | ||
648 | static int | |
649 | i2c_release(struct inode *inode, struct file *filp) | |
650 | { | |
651 | return 0; | |
652 | } | |
653 | ||
654 | /* Main device API. ioctl's to write or read to/from i2c registers. | |
655 | */ | |
656 | ||
657 | static int | |
658 | i2c_ioctl(struct inode *inode, struct file *file, | |
659 | unsigned int cmd, unsigned long arg) | |
660 | { | |
661 | if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { | |
662 | return -EINVAL; | |
663 | } | |
664 | ||
665 | switch (_IOC_NR(cmd)) { | |
666 | case I2C_WRITEREG: | |
667 | /* write to an i2c slave */ | |
668 | D(printk("i2cw %d %d %d\n", | |
669 | I2C_ARGSLAVE(arg), | |
670 | I2C_ARGREG(arg), | |
671 | I2C_ARGVALUE(arg))); | |
672 | ||
673 | return i2c_writereg(I2C_ARGSLAVE(arg), | |
674 | I2C_ARGREG(arg), | |
675 | I2C_ARGVALUE(arg)); | |
676 | case I2C_READREG: | |
677 | { | |
678 | unsigned char val; | |
679 | /* read from an i2c slave */ | |
680 | D(printk("i2cr %d %d ", | |
681 | I2C_ARGSLAVE(arg), | |
682 | I2C_ARGREG(arg))); | |
683 | val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg)); | |
684 | D(printk("= %d\n", val)); | |
685 | return val; | |
686 | } | |
687 | default: | |
688 | return -EINVAL; | |
689 | ||
690 | } | |
691 | ||
692 | return 0; | |
693 | } | |
694 | ||
695 | static struct file_operations i2c_fops = { | |
696 | .owner = THIS_MODULE, | |
697 | .ioctl = i2c_ioctl, | |
698 | .open = i2c_open, | |
699 | .release = i2c_release, | |
700 | }; | |
701 | ||
702 | int __init | |
703 | i2c_init(void) | |
704 | { | |
7e920426 MS |
705 | static int res = 0; |
706 | static int first = 1; | |
707 | ||
708 | if (!first) { | |
709 | return res; | |
710 | } | |
711 | ||
1da177e4 LT |
712 | /* Setup and enable the Port B I2C interface */ |
713 | ||
714 | #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C | |
7e920426 MS |
715 | if ((res = cris_request_io_interface(if_i2c, "I2C"))) { |
716 | printk(KERN_CRIT "i2c_init: Failed to get IO interface\n"); | |
717 | return res; | |
718 | } | |
719 | ||
1da177e4 LT |
720 | *R_PORT_PB_I2C = port_pb_i2c_shadow |= |
721 | IO_STATE(R_PORT_PB_I2C, i2c_en, on) | | |
722 | IO_FIELD(R_PORT_PB_I2C, i2c_d, 1) | | |
723 | IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1) | | |
724 | IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable); | |
1da177e4 LT |
725 | |
726 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0); | |
727 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1); | |
728 | ||
729 | *R_PORT_PB_DIR = (port_pb_dir_shadow |= | |
730 | IO_STATE(R_PORT_PB_DIR, dir0, input) | | |
731 | IO_STATE(R_PORT_PB_DIR, dir1, output)); | |
7e920426 MS |
732 | #else |
733 | if ((res = cris_io_interface_allocate_pins(if_i2c, | |
734 | 'b', | |
735 | CONFIG_ETRAX_I2C_DATA_PORT, | |
736 | CONFIG_ETRAX_I2C_DATA_PORT))) { | |
737 | printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C data port\n"); | |
738 | return res; | |
739 | } else if ((res = cris_io_interface_allocate_pins(if_i2c, | |
740 | 'b', | |
741 | CONFIG_ETRAX_I2C_CLK_PORT, | |
742 | CONFIG_ETRAX_I2C_CLK_PORT))) { | |
743 | cris_io_interface_free_pins(if_i2c, | |
744 | 'b', | |
745 | CONFIG_ETRAX_I2C_DATA_PORT, | |
746 | CONFIG_ETRAX_I2C_DATA_PORT); | |
747 | printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C clk port\n"); | |
748 | } | |
749 | #endif | |
1da177e4 | 750 | |
7e920426 | 751 | return res; |
1da177e4 LT |
752 | } |
753 | ||
754 | static int __init | |
755 | i2c_register(void) | |
756 | { | |
757 | int res; | |
758 | ||
7e920426 MS |
759 | res = i2c_init(); |
760 | if (res < 0) | |
761 | return res; | |
1da177e4 LT |
762 | res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); |
763 | if(res < 0) { | |
764 | printk(KERN_ERR "i2c: couldn't get a major number.\n"); | |
765 | return res; | |
766 | } | |
767 | ||
7e920426 | 768 | printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n"); |
1da177e4 LT |
769 | |
770 | return 0; | |
771 | } | |
772 | ||
773 | /* this makes sure that i2c_register is called during boot */ | |
774 | ||
775 | module_init(i2c_register); | |
776 | ||
777 | /****************** END OF FILE i2c.c ********************************/ |