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