1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/module.h>
17#include <linux/sched.h>
18#include <linux/errno.h>
19#include <linux/kernel.h>
20#include <linux/fs.h>
21#include <linux/string.h>
22#include <linux/init.h>
23
24#include <asm/etraxi2c.h>
25
26#include <arch/svinto.h>
27#include <asm/io.h>
28#include <asm/delay.h>
29#include <arch/io_interface_mux.h>
30
31#include "i2c.h"
32
33
34
35#define D(x)
36
37#define I2C_MAJOR 123
38static const char i2c_name[] = "i2c";
39
40#define CLOCK_LOW_TIME 8
41#define CLOCK_HIGH_TIME 8
42#define START_CONDITION_HOLD_TIME 8
43#define STOP_CONDITION_HOLD_TIME 8
44#define ENABLE_OUTPUT 0x01
45#define ENABLE_INPUT 0x00
46#define I2C_CLOCK_HIGH 1
47#define I2C_CLOCK_LOW 0
48#define I2C_DATA_HIGH 1
49#define I2C_DATA_LOW 0
50
51#ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
52
53#ifndef CONFIG_ETRAX_I2C_DATA_PORT
54#define CONFIG_ETRAX_I2C_DATA_PORT 0
55#endif
56#ifndef CONFIG_ETRAX_I2C_CLK_PORT
57#define CONFIG_ETRAX_I2C_CLK_PORT 1
58#endif
59
60#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT
61#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT
62#define i2c_enable()
63#define i2c_disable()
64
65
66
67#define i2c_dir_out() \
68 REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 1)
69#define i2c_dir_in() \
70 REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 0)
71
72
73
74#define i2c_clk(x) \
75 REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SCLBIT, x)
76#define i2c_data(x) \
77 REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SDABIT, x)
78
79
80
81#define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)
82
83#else
84
85
86#define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en))
87#define i2c_disable() *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_en))
88
89
90
91#define i2c_dir_out() \
92 *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \
93 REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1);
94#define i2c_dir_in() \
95 *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \
96 REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0);
97
98
99
100#define i2c_clk(x) \
101 *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \
102 ~IO_MASK(R_PORT_PB_I2C, i2c_clk)) | IO_FIELD(R_PORT_PB_I2C, i2c_clk, (x))); \
103 REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 1, x);
104
105#define i2c_data(x) \
106 *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \
107 ~IO_MASK(R_PORT_PB_I2C, i2c_d)) | IO_FIELD(R_PORT_PB_I2C, i2c_d, (x))); \
108 REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 0, x);
109
110
111
112#define i2c_getbit() (*R_PORT_PB_READ & 0x1)
113#endif
114
115
116
117#define i2c_delay(usecs) udelay(usecs)
118
119static DEFINE_SPINLOCK(i2c_lock);
120
121
122
123
124
125
126void
127i2c_start(void)
128{
129
130
131
132 i2c_dir_out();
133 i2c_delay(CLOCK_HIGH_TIME/6);
134 i2c_data(I2C_DATA_HIGH);
135 i2c_clk(I2C_CLOCK_HIGH);
136 i2c_delay(CLOCK_HIGH_TIME);
137
138
139
140 i2c_data(I2C_DATA_LOW);
141 i2c_delay(START_CONDITION_HOLD_TIME);
142
143
144
145 i2c_clk(I2C_CLOCK_LOW);
146 i2c_delay(CLOCK_LOW_TIME);
147}
148
149
150
151void
152i2c_stop(void)
153{
154 i2c_dir_out();
155
156
157
158
159 i2c_clk(I2C_CLOCK_LOW);
160 i2c_data(I2C_DATA_LOW);
161 i2c_delay(CLOCK_LOW_TIME*2);
162
163
164
165 i2c_clk(I2C_CLOCK_HIGH);
166 i2c_delay(CLOCK_HIGH_TIME*2);
167
168
169
170 i2c_data(I2C_DATA_HIGH);
171 i2c_delay(STOP_CONDITION_HOLD_TIME);
172
173 i2c_dir_in();
174}
175
176
177
178void
179i2c_outbyte(unsigned char x)
180{
181 int i;
182
183 i2c_dir_out();
184
185 for (i = 0; i < 8; i++) {
186 if (x & 0x80) {
187 i2c_data(I2C_DATA_HIGH);
188 } else {
189 i2c_data(I2C_DATA_LOW);
190 }
191
192 i2c_delay(CLOCK_LOW_TIME/2);
193 i2c_clk(I2C_CLOCK_HIGH);
194 i2c_delay(CLOCK_HIGH_TIME);
195 i2c_clk(I2C_CLOCK_LOW);
196 i2c_delay(CLOCK_LOW_TIME/2);
197 x <<= 1;
198 }
199 i2c_data(I2C_DATA_LOW);
200 i2c_delay(CLOCK_LOW_TIME/2);
201
202
203
204
205 i2c_dir_in();
206}
207
208
209
210unsigned char
211i2c_inbyte(void)
212{
213 unsigned char aBitByte = 0;
214 int i;
215
216
217 i2c_disable();
218 i2c_dir_in();
219 i2c_delay(CLOCK_HIGH_TIME/2);
220
221
222 aBitByte |= i2c_getbit();
223
224
225 i2c_enable();
226 i2c_delay(CLOCK_LOW_TIME/2);
227
228 for (i = 1; i < 8; i++) {
229 aBitByte <<= 1;
230
231 i2c_clk(I2C_CLOCK_HIGH);
232 i2c_delay(CLOCK_HIGH_TIME);
233 i2c_clk(I2C_CLOCK_LOW);
234 i2c_delay(CLOCK_LOW_TIME);
235
236
237 i2c_disable();
238 i2c_dir_in();
239 i2c_delay(CLOCK_HIGH_TIME/2);
240
241
242 aBitByte |= i2c_getbit();
243
244
245 i2c_enable();
246 i2c_delay(CLOCK_LOW_TIME/2);
247 }
248 i2c_clk(I2C_CLOCK_HIGH);
249 i2c_delay(CLOCK_HIGH_TIME);
250
251
252
253
254
255 i2c_clk(I2C_CLOCK_LOW);
256 return aBitByte;
257}
258
259
260
261
262
263
264
265
266
267int
268i2c_getack(void)
269{
270 int ack = 1;
271
272
273
274 i2c_dir_out();
275
276
277
278
279 i2c_data(I2C_DATA_HIGH);
280
281
282
283 i2c_dir_in();
284 i2c_delay(CLOCK_HIGH_TIME/4);
285
286
287
288 i2c_clk(I2C_CLOCK_HIGH);
289
290
291
292
293 i2c_clk(1);
294 i2c_data(1);
295
296
297
298 i2c_data(1);
299 i2c_disable();
300 i2c_dir_in();
301
302
303
304 i2c_delay(CLOCK_HIGH_TIME/2);
305
306
307
308 if(i2c_getbit())
309 ack = 0;
310 i2c_delay(CLOCK_HIGH_TIME/2);
311 if(!ack){
312 if(!i2c_getbit())
313 ack = 1;
314 i2c_delay(CLOCK_HIGH_TIME/2);
315 }
316
317
318
319
320
321
322 i2c_data(I2C_DATA_LOW);
323
324
325
326
327 i2c_enable();
328 i2c_dir_out();
329 i2c_clk(I2C_CLOCK_LOW);
330 i2c_delay(CLOCK_HIGH_TIME/4);
331
332
333
334 i2c_dir_out();
335
336
337
338 i2c_data(I2C_DATA_HIGH);
339 i2c_delay(CLOCK_LOW_TIME/2);
340 return ack;
341}
342
343
344
345
346
347
348
349
350void
351i2c_sendack(void)
352{
353
354
355
356 i2c_delay(CLOCK_LOW_TIME);
357 i2c_dir_out();
358
359
360
361 i2c_data(I2C_DATA_LOW);
362
363
364
365 i2c_delay(CLOCK_HIGH_TIME/6);
366 i2c_clk(I2C_CLOCK_HIGH);
367 i2c_delay(CLOCK_HIGH_TIME);
368 i2c_clk(I2C_CLOCK_LOW);
369 i2c_delay(CLOCK_LOW_TIME/6);
370
371
372
373 i2c_data(I2C_DATA_HIGH);
374 i2c_delay(CLOCK_LOW_TIME);
375
376 i2c_dir_in();
377}
378
379
380
381
382
383
384
385
386void
387i2c_sendnack(void)
388{
389
390
391
392 i2c_delay(CLOCK_LOW_TIME);
393 i2c_dir_out();
394
395
396
397 i2c_data(I2C_DATA_HIGH);
398
399
400
401 i2c_delay(CLOCK_HIGH_TIME/6);
402 i2c_clk(I2C_CLOCK_HIGH);
403 i2c_delay(CLOCK_HIGH_TIME);
404 i2c_clk(I2C_CLOCK_LOW);
405 i2c_delay(CLOCK_LOW_TIME);
406
407 i2c_dir_in();
408}
409
410
411
412
413
414
415
416
417int
418i2c_writereg(unsigned char theSlave, unsigned char theReg,
419 unsigned char theValue)
420{
421 int error, cntr = 3;
422 unsigned long flags;
423
424 spin_lock(&i2c_lock);
425
426 do {
427 error = 0;
428
429
430
431 local_irq_save(flags);
432
433 i2c_start();
434
435
436
437 i2c_outbyte((theSlave & 0xfe));
438
439
440
441 if(!i2c_getack())
442 error = 1;
443
444
445
446 i2c_dir_out();
447 i2c_outbyte(theReg);
448
449
450
451 if(!i2c_getack())
452 error |= 2;
453
454
455
456 i2c_outbyte(theValue);
457
458
459
460 if(!i2c_getack())
461 error |= 4;
462
463
464
465 i2c_stop();
466
467
468
469 local_irq_restore(flags);
470
471 } while(error && cntr--);
472
473 i2c_delay(CLOCK_LOW_TIME);
474
475 spin_unlock(&i2c_lock);
476
477 return -error;
478}
479
480
481
482
483
484
485
486
487unsigned char
488i2c_readreg(unsigned char theSlave, unsigned char theReg)
489{
490 unsigned char b = 0;
491 int error, cntr = 3;
492 unsigned long flags;
493
494 spin_lock(&i2c_lock);
495
496 do {
497 error = 0;
498
499
500
501 local_irq_save(flags);
502
503
504
505 i2c_start();
506
507
508
509
510 i2c_outbyte((theSlave & 0xfe));
511
512
513
514 if(!i2c_getack())
515 error = 1;
516
517
518
519 i2c_dir_out();
520 i2c_outbyte(theReg);
521
522
523
524 if(!i2c_getack())
525 error = 1;
526
527
528
529 i2c_delay(CLOCK_LOW_TIME);
530 i2c_start();
531
532
533
534 i2c_outbyte(theSlave | 0x01);
535
536
537
538 if(!i2c_getack())
539 error = 1;
540
541
542
543 b = i2c_inbyte();
544
545
546
547
548 i2c_sendnack();
549
550
551
552 i2c_stop();
553
554
555
556 local_irq_restore(flags);
557
558 } while(error && cntr--);
559
560 spin_unlock(&i2c_lock);
561
562 return b;
563}
564
565static int
566i2c_open(struct inode *inode, struct file *filp)
567{
568 return 0;
569}
570
571static int
572i2c_release(struct inode *inode, struct file *filp)
573{
574 return 0;
575}
576
577
578
579
580static long i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
581{
582 if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
583 return -EINVAL;
584 }
585
586 switch (_IOC_NR(cmd)) {
587 case I2C_WRITEREG:
588
589 D(printk(KERN_DEBUG "i2cw %d %d %d\n",
590 I2C_ARGSLAVE(arg),
591 I2C_ARGREG(arg),
592 I2C_ARGVALUE(arg)));
593
594 return i2c_writereg(I2C_ARGSLAVE(arg),
595 I2C_ARGREG(arg),
596 I2C_ARGVALUE(arg));
597 case I2C_READREG:
598 {
599 unsigned char val;
600
601 D(printk(KERN_DEBUG "i2cr %d %d ",
602 I2C_ARGSLAVE(arg),
603 I2C_ARGREG(arg)));
604 val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
605 D(printk(KERN_DEBUG "= %d\n", val));
606 return val;
607 }
608 default:
609 return -EINVAL;
610
611 }
612 return 0;
613}
614
615static const struct file_operations i2c_fops = {
616 .owner = THIS_MODULE,
617 .unlocked_ioctl = i2c_ioctl,
618 .open = i2c_open,
619 .release = i2c_release,
620 .llseek = noop_llseek,
621};
622
623int __init
624i2c_init(void)
625{
626 static int res = 0;
627 static int first = 1;
628
629 if (!first) {
630 return res;
631 }
632 first = 0;
633
634
635
636#ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
637 if ((res = cris_request_io_interface(if_i2c, "I2C"))) {
638 printk(KERN_CRIT "i2c_init: Failed to get IO interface\n");
639 return res;
640 }
641
642 *R_PORT_PB_I2C = port_pb_i2c_shadow |=
643 IO_STATE(R_PORT_PB_I2C, i2c_en, on) |
644 IO_FIELD(R_PORT_PB_I2C, i2c_d, 1) |
645 IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1) |
646 IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable);
647
648 port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0);
649 port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1);
650
651 *R_PORT_PB_DIR = (port_pb_dir_shadow |=
652 IO_STATE(R_PORT_PB_DIR, dir0, input) |
653 IO_STATE(R_PORT_PB_DIR, dir1, output));
654#else
655 if ((res = cris_io_interface_allocate_pins(if_i2c,
656 'b',
657 CONFIG_ETRAX_I2C_DATA_PORT,
658 CONFIG_ETRAX_I2C_DATA_PORT))) {
659 printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C data port\n");
660 return res;
661 } else if ((res = cris_io_interface_allocate_pins(if_i2c,
662 'b',
663 CONFIG_ETRAX_I2C_CLK_PORT,
664 CONFIG_ETRAX_I2C_CLK_PORT))) {
665 cris_io_interface_free_pins(if_i2c,
666 'b',
667 CONFIG_ETRAX_I2C_DATA_PORT,
668 CONFIG_ETRAX_I2C_DATA_PORT);
669 printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C clk port\n");
670 }
671#endif
672
673 return res;
674}
675
676static int __init
677i2c_register(void)
678{
679 int res;
680
681 res = i2c_init();
682 if (res < 0)
683 return res;
684 res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
685 if(res < 0) {
686 printk(KERN_ERR "i2c: couldn't get a major number.\n");
687 return res;
688 }
689
690 printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n");
691
692 return 0;
693}
694
695
696
697module_init(i2c_register);
698
699
700