2 i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
4 Copyright (C) 2004 Rick Bronson
5 Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
7 Borrowed heavily from original work by:
8 Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
16 #include <linux/module.h>
17 #include <linux/version.h>
18 #include <linux/kernel.h>
19 #include <linux/err.h>
20 #include <linux/slab.h>
21 #include <linux/types.h>
22 #include <linux/delay.h>
23 #include <linux/i2c.h>
24 #include <linux/init.h>
25 #include <linux/clk.h>
26 #include <linux/platform_device.h>
30 #include <asm/arch/at91_twi.h>
31 #include <asm/arch/board.h>
32 #include <asm/arch/cpu.h>
34 #define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */
37 static struct clk
*twi_clk
;
38 static void __iomem
*twi_base
;
40 #define at91_twi_read(reg) __raw_readl(twi_base + (reg))
41 #define at91_twi_write(reg, val) __raw_writel((val), twi_base + (reg))
45 * Initialize the TWI hardware registers.
47 static void __devinit
at91_twi_hwinit(void)
49 unsigned long cdiv
, ckdiv
;
51 at91_twi_write(AT91_TWI_IDR
, 0xffffffff); /* Disable all interrupts */
52 at91_twi_write(AT91_TWI_CR
, AT91_TWI_SWRST
); /* Reset peripheral */
53 at91_twi_write(AT91_TWI_CR
, AT91_TWI_MSEN
); /* Set Master mode */
55 /* Calcuate clock dividers */
56 cdiv
= (clk_get_rate(twi_clk
) / (2 * TWI_CLOCK
)) - 3;
57 cdiv
= cdiv
+ 1; /* round up */
64 if (cpu_is_at91rm9200()) { /* AT91RM9200 Errata #22 */
66 printk(KERN_ERR
"AT91 I2C: Invalid TWI_CLOCK value!\n");
71 at91_twi_write(AT91_TWI_CWGR
, (ckdiv
<< 16) | (cdiv
<< 8) | cdiv
);
75 * Poll the i2c status register until the specified bit is set.
76 * Returns 0 if timed out (100 msec).
78 static short at91_poll_status(unsigned long bit
)
80 int loop_cntr
= 10000;
84 } while (!(at91_twi_read(AT91_TWI_SR
) & bit
) && (--loop_cntr
> 0));
86 return (loop_cntr
> 0);
89 static int xfer_read(struct i2c_adapter
*adap
, unsigned char *buf
, int length
)
92 at91_twi_write(AT91_TWI_CR
, AT91_TWI_START
);
96 if (!length
) /* need to send Stop before reading last byte */
97 at91_twi_write(AT91_TWI_CR
, AT91_TWI_STOP
);
98 if (!at91_poll_status(AT91_TWI_RXRDY
)) {
99 dev_dbg(&adap
->dev
, "RXRDY timeout\n");
102 *buf
++ = (at91_twi_read(AT91_TWI_RHR
) & 0xff);
108 static int xfer_write(struct i2c_adapter
*adap
, unsigned char *buf
, int length
)
110 /* Load first byte into transmitter */
111 at91_twi_write(AT91_TWI_THR
, *buf
++);
114 at91_twi_write(AT91_TWI_CR
, AT91_TWI_START
);
117 if (!at91_poll_status(AT91_TWI_TXRDY
)) {
118 dev_dbg(&adap
->dev
, "TXRDY timeout\n");
122 length
--; /* byte was transmitted */
124 if (length
> 0) /* more data to send? */
125 at91_twi_write(AT91_TWI_THR
, *buf
++);
129 at91_twi_write(AT91_TWI_CR
, AT91_TWI_STOP
);
135 * Generic i2c master transfer entrypoint.
137 * Note: We do not use Atmel's feature of storing the "internal device address".
138 * Instead the "internal device address" has to be written using a separate
140 * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
142 static int at91_xfer(struct i2c_adapter
*adap
, struct i2c_msg
*pmsg
, int num
)
146 dev_dbg(&adap
->dev
, "at91_xfer: processing %d messages:\n", num
);
148 for (i
= 0; i
< num
; i
++) {
149 dev_dbg(&adap
->dev
, " #%d: %sing %d byte%s %s 0x%02x\n", i
,
150 pmsg
->flags
& I2C_M_RD
? "read" : "writ",
151 pmsg
->len
, pmsg
->len
> 1 ? "s" : "",
152 pmsg
->flags
& I2C_M_RD
? "from" : "to", pmsg
->addr
);
154 at91_twi_write(AT91_TWI_MMR
, (pmsg
->addr
<< 16)
155 | ((pmsg
->flags
& I2C_M_RD
) ? AT91_TWI_MREAD
: 0));
157 if (pmsg
->len
&& pmsg
->buf
) { /* sanity check */
158 if (pmsg
->flags
& I2C_M_RD
)
159 ret
= xfer_read(adap
, pmsg
->buf
, pmsg
->len
);
161 ret
= xfer_write(adap
, pmsg
->buf
, pmsg
->len
);
166 /* Wait until transfer is finished */
167 if (!at91_poll_status(AT91_TWI_TXCOMP
)) {
168 dev_dbg(&adap
->dev
, "TXCOMP timeout\n");
172 dev_dbg(&adap
->dev
, "transfer complete\n");
173 pmsg
++; /* next message */
179 * Return list of supported functionality.
181 static u32
at91_func(struct i2c_adapter
*adapter
)
183 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
186 static struct i2c_algorithm at91_algorithm
= {
187 .master_xfer
= at91_xfer
,
188 .functionality
= at91_func
,
192 * Main initialization routine.
194 static int __devinit
at91_i2c_probe(struct platform_device
*pdev
)
196 struct i2c_adapter
*adapter
;
197 struct resource
*res
;
200 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
204 if (!request_mem_region(res
->start
, res
->end
- res
->start
+ 1, "at91_i2c"))
207 twi_base
= ioremap(res
->start
, res
->end
- res
->start
+ 1);
213 twi_clk
= clk_get(NULL
, "twi_clk");
214 if (IS_ERR(twi_clk
)) {
215 dev_err(&pdev
->dev
, "no clock defined\n");
220 adapter
= kzalloc(sizeof(struct i2c_adapter
), GFP_KERNEL
);
221 if (adapter
== NULL
) {
222 dev_err(&pdev
->dev
, "can't allocate inteface!\n");
226 sprintf(adapter
->name
, "AT91");
227 adapter
->algo
= &at91_algorithm
;
228 adapter
->class = I2C_CLASS_HWMON
;
229 adapter
->dev
.parent
= &pdev
->dev
;
230 /* adapter->id == 0 ... only one TWI controller for now */
232 platform_set_drvdata(pdev
, adapter
);
234 clk_enable(twi_clk
); /* enable peripheral clock */
235 at91_twi_hwinit(); /* initialize TWI controller */
237 rc
= i2c_add_numbered_adapter(adapter
);
239 dev_err(&pdev
->dev
, "Adapter %s registration failed\n",
244 dev_info(&pdev
->dev
, "AT91 i2c bus driver.\n");
248 platform_set_drvdata(pdev
, NULL
);
250 clk_disable(twi_clk
);
256 release_mem_region(res
->start
, res
->end
- res
->start
+ 1);
261 static int __devexit
at91_i2c_remove(struct platform_device
*pdev
)
263 struct i2c_adapter
*adapter
= platform_get_drvdata(pdev
);
264 struct resource
*res
;
267 rc
= i2c_del_adapter(adapter
);
268 platform_set_drvdata(pdev
, NULL
);
270 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
272 release_mem_region(res
->start
, res
->end
- res
->start
+ 1);
274 clk_disable(twi_clk
); /* disable peripheral clock */
282 /* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
284 static int at91_i2c_suspend(struct platform_device
*pdev
, pm_message_t mesg
)
286 clk_disable(twi_clk
);
290 static int at91_i2c_resume(struct platform_device
*pdev
)
292 return clk_enable(twi_clk
);
296 #define at91_i2c_suspend NULL
297 #define at91_i2c_resume NULL
300 /* work with "modprobe at91_i2c" from hotplugging or coldplugging */
301 MODULE_ALIAS("platform:at91_i2c");
303 static struct platform_driver at91_i2c_driver
= {
304 .probe
= at91_i2c_probe
,
305 .remove
= __devexit_p(at91_i2c_remove
),
306 .suspend
= at91_i2c_suspend
,
307 .resume
= at91_i2c_resume
,
310 .owner
= THIS_MODULE
,
314 static int __init
at91_i2c_init(void)
316 return platform_driver_register(&at91_i2c_driver
);
319 static void __exit
at91_i2c_exit(void)
321 platform_driver_unregister(&at91_i2c_driver
);
324 module_init(at91_i2c_init
);
325 module_exit(at91_i2c_exit
);
327 MODULE_AUTHOR("Rick Bronson");
328 MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
329 MODULE_LICENSE("GPL");