• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/cris/arch-v10/drivers/
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*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
10*!
11*!***************************************************************************/
12
13/****************** INCLUDE FILES SECTION ***********************************/
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 <asm/system.h>
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/****************** I2C DEFINITION SECTION *************************/
34
35#define D(x)
36
37#define I2C_MAJOR 123  /* LOCAL/EXPERIMENTAL */
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/* Use PB and not PB_I2C */
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/* enable or disable output-enable, to select output or input on the i2c bus */
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/* control the i2c clock and data signals */
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/* read a bit from the i2c interface */
80
81#define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)
82
83#else
84/* enable or disable the i2c interface */
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/* enable or disable output-enable, to select output or input on the i2c bus */
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/* control the i2c clock and data signals */
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/* read a bit from the i2c interface */
111
112#define i2c_getbit() (*R_PORT_PB_READ & 0x1)
113#endif
114
115/* use the kernels delay routine */
116
117#define i2c_delay(usecs) udelay(usecs)
118
119static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
120
121/****************** FUNCTION DEFINITION SECTION *************************/
122
123
124/* generate i2c start condition */
125
126void
127i2c_start(void)
128{
129	/*
130	 * SCL=1 SDA=1
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	 * SCL=1 SDA=0
139	 */
140	i2c_data(I2C_DATA_LOW);
141	i2c_delay(START_CONDITION_HOLD_TIME);
142	/*
143	 * SCL=0 SDA=0
144	 */
145	i2c_clk(I2C_CLOCK_LOW);
146	i2c_delay(CLOCK_LOW_TIME);
147}
148
149/* generate i2c stop condition */
150
151void
152i2c_stop(void)
153{
154	i2c_dir_out();
155
156	/*
157	 * SCL=0 SDA=0
158	 */
159	i2c_clk(I2C_CLOCK_LOW);
160	i2c_data(I2C_DATA_LOW);
161	i2c_delay(CLOCK_LOW_TIME*2);
162	/*
163	 * SCL=1 SDA=0
164	 */
165	i2c_clk(I2C_CLOCK_HIGH);
166	i2c_delay(CLOCK_HIGH_TIME*2);
167	/*
168	 * SCL=1 SDA=1
169	 */
170	i2c_data(I2C_DATA_HIGH);
171	i2c_delay(STOP_CONDITION_HOLD_TIME);
172
173	i2c_dir_in();
174}
175
176/* write a byte to the i2c interface */
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	 * enable input
204	 */
205	i2c_dir_in();
206}
207
208/* read a byte from the i2c interface */
209
210unsigned char
211i2c_inbyte(void)
212{
213	unsigned char aBitByte = 0;
214	int i;
215
216	/* Switch off I2C to get bit */
217	i2c_disable();
218	i2c_dir_in();
219	i2c_delay(CLOCK_HIGH_TIME/2);
220
221	/* Get bit */
222	aBitByte |= i2c_getbit();
223
224	/* Enable I2C */
225	i2c_enable();
226	i2c_delay(CLOCK_LOW_TIME/2);
227
228	for (i = 1; i < 8; i++) {
229		aBitByte <<= 1;
230		/* Clock pulse */
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		/* Switch off I2C to get bit */
237		i2c_disable();
238		i2c_dir_in();
239		i2c_delay(CLOCK_HIGH_TIME/2);
240
241		/* Get bit */
242		aBitByte |= i2c_getbit();
243
244		/* Enable I2C */
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	 * we leave the clock low, getbyte is usually followed
253	 * by sendack/nack, they assume the clock to be low
254	 */
255        i2c_clk(I2C_CLOCK_LOW);
256	return aBitByte;
257}
258
259/*#---------------------------------------------------------------------------
260*#
261*# FUNCTION NAME: i2c_getack
262*#
263*# DESCRIPTION  : checks if ack was received from ic2
264*#
265*#--------------------------------------------------------------------------*/
266
267int
268i2c_getack(void)
269{
270	int ack = 1;
271	/*
272	 * enable output
273	 */
274	i2c_dir_out();
275	/*
276	 * Release data bus by setting
277	 * data high
278	 */
279	i2c_data(I2C_DATA_HIGH);
280	/*
281	 * enable input
282	 */
283	i2c_dir_in();
284	i2c_delay(CLOCK_HIGH_TIME/4);
285	/*
286	 * generate ACK clock pulse
287	 */
288	i2c_clk(I2C_CLOCK_HIGH);
289	/*
290	 * Use PORT PB instead of I2C
291	 * for input. (I2C not working)
292	 */
293	i2c_clk(1);
294	i2c_data(1);
295	/*
296	 * switch off I2C
297	 */
298	i2c_data(1);
299	i2c_disable();
300	i2c_dir_in();
301	/*
302	 * now wait for ack
303	 */
304	i2c_delay(CLOCK_HIGH_TIME/2);
305	/*
306	 * check for ack
307	 */
308	if(i2c_getbit())
309		ack = 0;
310	i2c_delay(CLOCK_HIGH_TIME/2);
311	if(!ack){
312		if(!i2c_getbit()) /* receiver pulld SDA low */
313			ack = 1;
314		i2c_delay(CLOCK_HIGH_TIME/2);
315	}
316
317	/*
318	 * our clock is high now, make sure data is low
319	 * before we enable our output. If we keep data high
320	 * and enable output, we would generate a stop condition.
321	 */
322	i2c_data(I2C_DATA_LOW);
323
324	/*
325	 * end clock pulse
326	 */
327	i2c_enable();
328	i2c_dir_out();
329	i2c_clk(I2C_CLOCK_LOW);
330	i2c_delay(CLOCK_HIGH_TIME/4);
331	/*
332	 * enable output
333	 */
334	i2c_dir_out();
335	/*
336	 * remove ACK clock pulse
337	 */
338	i2c_data(I2C_DATA_HIGH);
339	i2c_delay(CLOCK_LOW_TIME/2);
340	return ack;
341}
342
343/*#---------------------------------------------------------------------------
344*#
345*# FUNCTION NAME: I2C::sendAck
346*#
347*# DESCRIPTION  : Send ACK on received data
348*#
349*#--------------------------------------------------------------------------*/
350void
351i2c_sendack(void)
352{
353	/*
354	 * enable output
355	 */
356	i2c_delay(CLOCK_LOW_TIME);
357	i2c_dir_out();
358	/*
359	 * set ack pulse high
360	 */
361	i2c_data(I2C_DATA_LOW);
362	/*
363	 * generate clock pulse
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	 * reset data out
372	 */
373	i2c_data(I2C_DATA_HIGH);
374	i2c_delay(CLOCK_LOW_TIME);
375
376	i2c_dir_in();
377}
378
379/*#---------------------------------------------------------------------------
380*#
381*# FUNCTION NAME: i2c_sendnack
382*#
383*# DESCRIPTION  : Sends NACK on received data
384*#
385*#--------------------------------------------------------------------------*/
386void
387i2c_sendnack(void)
388{
389	/*
390	 * enable output
391	 */
392	i2c_delay(CLOCK_LOW_TIME);
393	i2c_dir_out();
394	/*
395	 * set data high
396	 */
397	i2c_data(I2C_DATA_HIGH);
398	/*
399	 * generate clock pulse
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*# FUNCTION NAME: i2c_writereg
413*#
414*# DESCRIPTION  : Writes a value to an I2C device
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		 * we don't like to be interrupted
430		 */
431		local_irq_save(flags);
432
433		i2c_start();
434		/*
435		 * send slave address
436		 */
437		i2c_outbyte((theSlave & 0xfe));
438		/*
439		 * wait for ack
440		 */
441		if(!i2c_getack())
442			error = 1;
443		/*
444		 * now select register
445		 */
446		i2c_dir_out();
447		i2c_outbyte(theReg);
448		/*
449		 * now it's time to wait for ack
450		 */
451		if(!i2c_getack())
452			error |= 2;
453		/*
454		 * send register register data
455		 */
456		i2c_outbyte(theValue);
457		/*
458		 * now it's time to wait for ack
459		 */
460		if(!i2c_getack())
461			error |= 4;
462		/*
463		 * end byte stream
464		 */
465		i2c_stop();
466		/*
467		 * enable interrupt again
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*# FUNCTION NAME: i2c_readreg
483*#
484*# DESCRIPTION  : Reads a value from the decoder registers.
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		 * we don't like to be interrupted
500		 */
501		local_irq_save(flags);
502		/*
503		 * generate start condition
504		 */
505		i2c_start();
506
507		/*
508		 * send slave address
509		 */
510		i2c_outbyte((theSlave & 0xfe));
511		/*
512		 * wait for ack
513		 */
514		if(!i2c_getack())
515			error = 1;
516		/*
517		 * now select register
518		 */
519		i2c_dir_out();
520		i2c_outbyte(theReg);
521		/*
522		 * now it's time to wait for ack
523		 */
524		if(!i2c_getack())
525			error = 1;
526		/*
527		 * repeat start condition
528		 */
529		i2c_delay(CLOCK_LOW_TIME);
530		i2c_start();
531		/*
532		 * send slave address
533		 */
534		i2c_outbyte(theSlave | 0x01);
535		/*
536		 * wait for ack
537		 */
538		if(!i2c_getack())
539			error = 1;
540		/*
541		 * fetch register
542		 */
543		b = i2c_inbyte();
544		/*
545		 * last received byte needs to be nacked
546		 * instead of acked
547		 */
548		i2c_sendnack();
549		/*
550		 * end sequence
551		 */
552		i2c_stop();
553		/*
554		 * enable interrupt again
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/* Main device API. ioctl's to write or read to/from i2c registers.
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			/* write to an i2c slave */
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			/* read from an i2c slave */
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};
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	/* Setup and enable the Port B I2C interface */
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/* this makes sure that i2c_register is called during boot */
695
696module_init(i2c_register);
697
698/****************** END OF FILE i2c.c ********************************/
699