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