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