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