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/kernel.h>
18 #include <linux/err.h>
19 #include <linux/slab.h>
20 #include <linux/types.h>
21 #include <linux/delay.h>
22 #include <linux/i2c.h>
23 #include <linux/init.h>
24 #include <linux/clk.h>
25 #include <linux/platform_device.h>
29 #include <mach/at91_twi.h>
30 #include <mach/board.h>
33 #define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */
36 static struct clk
*twi_clk
;
37 static void __iomem
*twi_base
;
39 #define at91_twi_read(reg) __raw_readl(twi_base + (reg))
40 #define at91_twi_write(reg, val) __raw_writel((val), twi_base + (reg))
44 * Initialize the TWI hardware registers.
46 static void __devinit
at91_twi_hwinit(void)
48 unsigned long cdiv
, ckdiv
;
50 at91_twi_write(AT91_TWI_IDR
, 0xffffffff); /* Disable all interrupts */
51 at91_twi_write(AT91_TWI_CR
, AT91_TWI_SWRST
); /* Reset peripheral */
52 at91_twi_write(AT91_TWI_CR
, AT91_TWI_MSEN
); /* Set Master mode */
54 /* Calcuate clock dividers */
55 cdiv
= (clk_get_rate(twi_clk
) / (2 * TWI_CLOCK
)) - 3;
56 cdiv
= cdiv
+ 1; /* round up */
63 if (cpu_is_at91rm9200()) { /* AT91RM9200 Errata #22 */
65 printk(KERN_ERR
"AT91 I2C: Invalid TWI_CLOCK value!\n");
70 at91_twi_write(AT91_TWI_CWGR
, (ckdiv
<< 16) | (cdiv
<< 8) | cdiv
);
74 * Poll the i2c status register until the specified bit is set.
75 * Returns 0 if timed out (100 msec).
77 static short at91_poll_status(unsigned long bit
)
79 int loop_cntr
= 10000;
83 } while (!(at91_twi_read(AT91_TWI_SR
) & bit
) && (--loop_cntr
> 0));
85 return (loop_cntr
> 0);
88 static int xfer_read(struct i2c_adapter
*adap
, unsigned char *buf
, int length
)
91 at91_twi_write(AT91_TWI_CR
, AT91_TWI_START
);
95 if (!length
) /* need to send Stop before reading last byte */
96 at91_twi_write(AT91_TWI_CR
, AT91_TWI_STOP
);
97 if (!at91_poll_status(AT91_TWI_RXRDY
)) {
98 dev_dbg(&adap
->dev
, "RXRDY timeout\n");
101 *buf
++ = (at91_twi_read(AT91_TWI_RHR
) & 0xff);
107 static int xfer_write(struct i2c_adapter
*adap
, unsigned char *buf
, int length
)
109 /* Load first byte into transmitter */
110 at91_twi_write(AT91_TWI_THR
, *buf
++);
113 at91_twi_write(AT91_TWI_CR
, AT91_TWI_START
);
116 if (!at91_poll_status(AT91_TWI_TXRDY
)) {
117 dev_dbg(&adap
->dev
, "TXRDY timeout\n");
121 length
--; /* byte was transmitted */
123 if (length
> 0) /* more data to send? */
124 at91_twi_write(AT91_TWI_THR
, *buf
++);
128 at91_twi_write(AT91_TWI_CR
, AT91_TWI_STOP
);
134 * Generic i2c master transfer entrypoint.
136 * Note: We do not use Atmel's feature of storing the "internal device address".
137 * Instead the "internal device address" has to be written using a separate
139 * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
141 static int at91_xfer(struct i2c_adapter
*adap
, struct i2c_msg
*pmsg
, int num
)
145 dev_dbg(&adap
->dev
, "at91_xfer: processing %d messages:\n", num
);
147 for (i
= 0; i
< num
; i
++) {
148 dev_dbg(&adap
->dev
, " #%d: %sing %d byte%s %s 0x%02x\n", i
,
149 pmsg
->flags
& I2C_M_RD
? "read" : "writ",
150 pmsg
->len
, pmsg
->len
> 1 ? "s" : "",
151 pmsg
->flags
& I2C_M_RD
? "from" : "to", pmsg
->addr
);
153 at91_twi_write(AT91_TWI_MMR
, (pmsg
->addr
<< 16)
154 | ((pmsg
->flags
& I2C_M_RD
) ? AT91_TWI_MREAD
: 0));
156 if (pmsg
->len
&& pmsg
->buf
) { /* sanity check */
157 if (pmsg
->flags
& I2C_M_RD
)
158 ret
= xfer_read(adap
, pmsg
->buf
, pmsg
->len
);
160 ret
= xfer_write(adap
, pmsg
->buf
, pmsg
->len
);
165 /* Wait until transfer is finished */
166 if (!at91_poll_status(AT91_TWI_TXCOMP
)) {
167 dev_dbg(&adap
->dev
, "TXCOMP timeout\n");
171 dev_dbg(&adap
->dev
, "transfer complete\n");
172 pmsg
++; /* next message */
178 * Return list of supported functionality.
180 static u32
at91_func(struct i2c_adapter
*adapter
)
182 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
185 static struct i2c_algorithm at91_algorithm
= {
186 .master_xfer
= at91_xfer
,
187 .functionality
= at91_func
,
191 * Main initialization routine.
193 static int __devinit
at91_i2c_probe(struct platform_device
*pdev
)
195 struct i2c_adapter
*adapter
;
196 struct resource
*res
;
199 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
203 if (!request_mem_region(res
->start
, resource_size(res
), "at91_i2c"))
206 twi_base
= ioremap(res
->start
, resource_size(res
));
212 twi_clk
= clk_get(NULL
, "twi_clk");
213 if (IS_ERR(twi_clk
)) {
214 dev_err(&pdev
->dev
, "no clock defined\n");
219 adapter
= kzalloc(sizeof(struct i2c_adapter
), GFP_KERNEL
);
220 if (adapter
== NULL
) {
221 dev_err(&pdev
->dev
, "can't allocate inteface!\n");
225 snprintf(adapter
->name
, sizeof(adapter
->name
), "AT91");
226 adapter
->algo
= &at91_algorithm
;
227 adapter
->class = I2C_CLASS_HWMON
;
228 adapter
->dev
.parent
= &pdev
->dev
;
229 /* adapter->id == 0 ... only one TWI controller for now */
231 platform_set_drvdata(pdev
, adapter
);
233 clk_enable(twi_clk
); /* enable peripheral clock */
234 at91_twi_hwinit(); /* initialize TWI controller */
236 rc
= i2c_add_numbered_adapter(adapter
);
238 dev_err(&pdev
->dev
, "Adapter %s registration failed\n",
243 dev_info(&pdev
->dev
, "AT91 i2c bus driver.\n");
247 platform_set_drvdata(pdev
, NULL
);
249 clk_disable(twi_clk
);
255 release_mem_region(res
->start
, resource_size(res
));
260 static int __devexit
at91_i2c_remove(struct platform_device
*pdev
)
262 struct i2c_adapter
*adapter
= platform_get_drvdata(pdev
);
263 struct resource
*res
;
266 rc
= i2c_del_adapter(adapter
);
267 platform_set_drvdata(pdev
, NULL
);
269 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
271 release_mem_region(res
->start
, resource_size(res
));
273 clk_disable(twi_clk
); /* disable peripheral clock */
281 /* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
283 static int at91_i2c_suspend(struct platform_device
*pdev
, pm_message_t mesg
)
285 clk_disable(twi_clk
);
289 static int at91_i2c_resume(struct platform_device
*pdev
)
291 return clk_enable(twi_clk
);
295 #define at91_i2c_suspend NULL
296 #define at91_i2c_resume NULL
299 /* work with "modprobe at91_i2c" from hotplugging or coldplugging */
300 MODULE_ALIAS("platform:at91_i2c");
302 static struct platform_driver at91_i2c_driver
= {
303 .probe
= at91_i2c_probe
,
304 .remove
= __devexit_p(at91_i2c_remove
),
305 .suspend
= at91_i2c_suspend
,
306 .resume
= at91_i2c_resume
,
309 .owner
= THIS_MODULE
,
313 static int __init
at91_i2c_init(void)
315 return platform_driver_register(&at91_i2c_driver
);
318 static void __exit
at91_i2c_exit(void)
320 platform_driver_unregister(&at91_i2c_driver
);
323 module_init(at91_i2c_init
);
324 module_exit(at91_i2c_exit
);
326 MODULE_AUTHOR("Rick Bronson");
327 MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
328 MODULE_LICENSE("GPL");