1/* 2 i2c Support for Atmel's AT91 Two-Wire Interface (TWI) 3 4 Copyright (C) 2004 Rick Bronson 5 Converted to 2.6 by Andrew Victor <andrew@sanpeople.com> 6 7 Borrowed heavily from original work by: 8 Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> 9 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. 14*/ 15 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> 26#include <linux/io.h> 27 28#include <mach/at91_twi.h> 29#include <mach/board.h> 30#include <mach/cpu.h> 31 32#define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */ 33 34 35static struct clk *twi_clk; 36static void __iomem *twi_base; 37 38#define at91_twi_read(reg) __raw_readl(twi_base + (reg)) 39#define at91_twi_write(reg, val) __raw_writel((val), twi_base + (reg)) 40 41 42/* 43 * Initialize the TWI hardware registers. 44 */ 45static void __devinit at91_twi_hwinit(void) 46{ 47 unsigned long cdiv, ckdiv; 48 49 at91_twi_write(AT91_TWI_IDR, 0xffffffff); /* Disable all interrupts */ 50 at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST); /* Reset peripheral */ 51 at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN); /* Set Master mode */ 52 53 /* Calcuate clock dividers */ 54 cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3; 55 cdiv = cdiv + 1; /* round up */ 56 ckdiv = 0; 57 while (cdiv > 255) { 58 ckdiv++; 59 cdiv = cdiv >> 1; 60 } 61 62 if (cpu_is_at91rm9200()) { /* AT91RM9200 Errata #22 */ 63 if (ckdiv > 5) { 64 printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n"); 65 ckdiv = 5; 66 } 67 } 68 69 at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv); 70} 71 72/* 73 * Poll the i2c status register until the specified bit is set. 74 * Returns 0 if timed out (100 msec). 75 */ 76static short at91_poll_status(unsigned long bit) 77{ 78 int loop_cntr = 10000; 79 80 do { 81 udelay(10); 82 } while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0)); 83 84 return (loop_cntr > 0); 85} 86 87static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length) 88{ 89 /* Send Start */ 90 at91_twi_write(AT91_TWI_CR, AT91_TWI_START); 91 92 /* Read data */ 93 while (length--) { 94 if (!length) /* need to send Stop before reading last byte */ 95 at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP); 96 if (!at91_poll_status(AT91_TWI_RXRDY)) { 97 dev_dbg(&adap->dev, "RXRDY timeout\n"); 98 return -ETIMEDOUT; 99 } 100 *buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff); 101 } 102 103 return 0; 104} 105 106static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length) 107{ 108 /* Load first byte into transmitter */ 109 at91_twi_write(AT91_TWI_THR, *buf++); 110 111 /* Send Start */ 112 at91_twi_write(AT91_TWI_CR, AT91_TWI_START); 113 114 do { 115 if (!at91_poll_status(AT91_TWI_TXRDY)) { 116 dev_dbg(&adap->dev, "TXRDY timeout\n"); 117 return -ETIMEDOUT; 118 } 119 120 length--; /* byte was transmitted */ 121 122 if (length > 0) /* more data to send? */ 123 at91_twi_write(AT91_TWI_THR, *buf++); 124 } while (length); 125 126 /* Send Stop */ 127 at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP); 128 129 return 0; 130} 131 132/* 133 * Generic i2c master transfer entrypoint. 134 * 135 * Note: We do not use Atmel's feature of storing the "internal device address". 136 * Instead the "internal device address" has to be written using a separate 137 * i2c message. 138 * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html 139 */ 140static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num) 141{ 142 int i, ret; 143 144 dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); 145 146 for (i = 0; i < num; i++) { 147 dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i, 148 pmsg->flags & I2C_M_RD ? "read" : "writ", 149 pmsg->len, pmsg->len > 1 ? "s" : "", 150 pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr); 151 152 at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16) 153 | ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0)); 154 155 if (pmsg->len && pmsg->buf) { /* sanity check */ 156 if (pmsg->flags & I2C_M_RD) 157 ret = xfer_read(adap, pmsg->buf, pmsg->len); 158 else 159 ret = xfer_write(adap, pmsg->buf, pmsg->len); 160 161 if (ret) 162 return ret; 163 164 /* Wait until transfer is finished */ 165 if (!at91_poll_status(AT91_TWI_TXCOMP)) { 166 dev_dbg(&adap->dev, "TXCOMP timeout\n"); 167 return -ETIMEDOUT; 168 } 169 } 170 dev_dbg(&adap->dev, "transfer complete\n"); 171 pmsg++; /* next message */ 172 } 173 return i; 174} 175 176/* 177 * Return list of supported functionality. 178 */ 179static u32 at91_func(struct i2c_adapter *adapter) 180{ 181 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 182} 183 184static struct i2c_algorithm at91_algorithm = { 185 .master_xfer = at91_xfer, 186 .functionality = at91_func, 187}; 188 189/* 190 * Main initialization routine. 191 */ 192static int __devinit at91_i2c_probe(struct platform_device *pdev) 193{ 194 struct i2c_adapter *adapter; 195 struct resource *res; 196 int rc; 197 198 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 199 if (!res) 200 return -ENXIO; 201 202 if (!request_mem_region(res->start, resource_size(res), "at91_i2c")) 203 return -EBUSY; 204 205 twi_base = ioremap(res->start, resource_size(res)); 206 if (!twi_base) { 207 rc = -ENOMEM; 208 goto fail0; 209 } 210 211 twi_clk = clk_get(NULL, "twi_clk"); 212 if (IS_ERR(twi_clk)) { 213 dev_err(&pdev->dev, "no clock defined\n"); 214 rc = -ENODEV; 215 goto fail1; 216 } 217 218 adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); 219 if (adapter == NULL) { 220 dev_err(&pdev->dev, "can't allocate inteface!\n"); 221 rc = -ENOMEM; 222 goto fail2; 223 } 224 snprintf(adapter->name, sizeof(adapter->name), "AT91"); 225 adapter->algo = &at91_algorithm; 226 adapter->class = I2C_CLASS_HWMON; 227 adapter->dev.parent = &pdev->dev; 228 /* adapter->id == 0 ... only one TWI controller for now */ 229 230 platform_set_drvdata(pdev, adapter); 231 232 clk_enable(twi_clk); /* enable peripheral clock */ 233 at91_twi_hwinit(); /* initialize TWI controller */ 234 235 rc = i2c_add_numbered_adapter(adapter); 236 if (rc) { 237 dev_err(&pdev->dev, "Adapter %s registration failed\n", 238 adapter->name); 239 goto fail3; 240 } 241 242 dev_info(&pdev->dev, "AT91 i2c bus driver.\n"); 243 return 0; 244 245fail3: 246 platform_set_drvdata(pdev, NULL); 247 kfree(adapter); 248 clk_disable(twi_clk); 249fail2: 250 clk_put(twi_clk); 251fail1: 252 iounmap(twi_base); 253fail0: 254 release_mem_region(res->start, resource_size(res)); 255 256 return rc; 257} 258 259static int __devexit at91_i2c_remove(struct platform_device *pdev) 260{ 261 struct i2c_adapter *adapter = platform_get_drvdata(pdev); 262 struct resource *res; 263 int rc; 264 265 rc = i2c_del_adapter(adapter); 266 platform_set_drvdata(pdev, NULL); 267 268 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 269 iounmap(twi_base); 270 release_mem_region(res->start, resource_size(res)); 271 272 clk_disable(twi_clk); /* disable peripheral clock */ 273 clk_put(twi_clk); 274 275 return rc; 276} 277 278#ifdef CONFIG_PM 279 280/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */ 281 282static int at91_i2c_suspend(struct platform_device *pdev, pm_message_t mesg) 283{ 284 clk_disable(twi_clk); 285 return 0; 286} 287 288static int at91_i2c_resume(struct platform_device *pdev) 289{ 290 return clk_enable(twi_clk); 291} 292 293#else 294#define at91_i2c_suspend NULL 295#define at91_i2c_resume NULL 296#endif 297 298/* work with "modprobe at91_i2c" from hotplugging or coldplugging */ 299MODULE_ALIAS("platform:at91_i2c"); 300 301static struct platform_driver at91_i2c_driver = { 302 .probe = at91_i2c_probe, 303 .remove = __devexit_p(at91_i2c_remove), 304 .suspend = at91_i2c_suspend, 305 .resume = at91_i2c_resume, 306 .driver = { 307 .name = "at91_i2c", 308 .owner = THIS_MODULE, 309 }, 310}; 311 312static int __init at91_i2c_init(void) 313{ 314 return platform_driver_register(&at91_i2c_driver); 315} 316 317static void __exit at91_i2c_exit(void) 318{ 319 platform_driver_unregister(&at91_i2c_driver); 320} 321 322module_init(at91_i2c_init); 323module_exit(at91_i2c_exit); 324 325MODULE_AUTHOR("Rick Bronson"); 326MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91"); 327MODULE_LICENSE("GPL"); 328