1 /* ------------------------------------------------------------------------- */ 2 /* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */ 3 /* ------------------------------------------------------------------------- */ 4 /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd 5 * <Peter dot Milne at D hyphen TACQ dot com> 6 * 7 * With acknowledgements to i2c-algo-ibm_ocp.c by 8 * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com 9 * 10 * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: 11 * 12 * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund 13 * 14 * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, 15 * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> 16 * 17 * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005: 18 * 19 * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs 20 * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference 21 * - Make it work with IXP46x chips 22 * - Cleanup function names, coding style, etc 23 * 24 * This program is free software; you can redistribute it and/or modify 25 * it under the terms of the GNU General Public License as published by 26 * the Free Software Foundation, version 2. 27 */ 28 29 #include <linux/config.h> 30 #include <linux/interrupt.h> 31 #include <linux/kernel.h> 32 #include <linux/module.h> 33 #include <linux/delay.h> 34 #include <linux/slab.h> 35 #include <linux/init.h> 36 #include <linux/errno.h> 37 #include <linux/sched.h> 38 #include <linux/platform_device.h> 39 #include <linux/i2c.h> 40 41 #include <asm/io.h> 42 43 #include "i2c-iop3xx.h" 44 45 /* global unit counter */ 46 static int i2c_id; 47 48 static inline unsigned char 49 iic_cook_addr(struct i2c_msg *msg) 50 { 51 unsigned char addr; 52 53 addr = (msg->addr << 1); 54 55 if (msg->flags & I2C_M_RD) 56 addr |= 1; 57 58 /* 59 * Read or Write? 60 */ 61 if (msg->flags & I2C_M_REV_DIR_ADDR) 62 addr ^= 1; 63 64 return addr; 65 } 66 67 static void 68 iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) 69 { 70 /* Follows devman 9.3 */ 71 __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); 72 __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); 73 __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); 74 } 75 76 static void 77 iop3xx_i2c_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap) 78 { 79 __raw_writel(MYSAR, iop3xx_adap->ioaddr + SAR_OFFSET); 80 } 81 82 static void 83 iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) 84 { 85 u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; 86 87 /* 88 * Every time unit enable is asserted, GPOD needs to be cleared 89 * on IOP321 to avoid data corruption on the bus. 90 */ 91 #ifdef CONFIG_ARCH_IOP321 92 #define IOP321_GPOD_I2C0 0x00c0 /* clear these bits to enable ch0 */ 93 #define IOP321_GPOD_I2C1 0x0030 /* clear these bits to enable ch1 */ 94 95 *IOP321_GPOD &= (iop3xx_adap->id == 0) ? ~IOP321_GPOD_I2C0 : 96 ~IOP321_GPOD_I2C1; 97 #endif 98 /* NB SR bits not same position as CR IE bits :-( */ 99 iop3xx_adap->SR_enabled = 100 IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | 101 IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; 102 103 cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE | 104 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE; 105 106 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 107 } 108 109 static void 110 iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) 111 { 112 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 113 114 cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | 115 IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); 116 117 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 118 } 119 120 /* 121 * NB: the handler has to clear the source of the interrupt! 122 * Then it passes the SR flags of interest to BH via adap data 123 */ 124 static irqreturn_t 125 iop3xx_i2c_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs) 126 { 127 struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; 128 u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); 129 130 if ((sr &= iop3xx_adap->SR_enabled)) { 131 __raw_writel(sr, iop3xx_adap->ioaddr + SR_OFFSET); 132 iop3xx_adap->SR_received |= sr; 133 wake_up_interruptible(&iop3xx_adap->waitq); 134 } 135 return IRQ_HANDLED; 136 } 137 138 /* check all error conditions, clear them , report most important */ 139 static int 140 iop3xx_i2c_error(u32 sr) 141 { 142 int rc = 0; 143 144 if ((sr & IOP3XX_ISR_BERRD)) { 145 if ( !rc ) rc = -I2C_ERR_BERR; 146 } 147 if ((sr & IOP3XX_ISR_ALD)) { 148 if ( !rc ) rc = -I2C_ERR_ALD; 149 } 150 return rc; 151 } 152 153 static inline u32 154 iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) 155 { 156 unsigned long flags; 157 u32 sr; 158 159 spin_lock_irqsave(&iop3xx_adap->lock, flags); 160 sr = iop3xx_adap->SR_received; 161 iop3xx_adap->SR_received = 0; 162 spin_unlock_irqrestore(&iop3xx_adap->lock, flags); 163 164 return sr; 165 } 166 167 /* 168 * sleep until interrupted, then recover and analyse the SR 169 * saved by handler 170 */ 171 typedef int (* compare_func)(unsigned test, unsigned mask); 172 /* returns 1 on correct comparison */ 173 174 static int 175 iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 176 unsigned flags, unsigned* status, 177 compare_func compare) 178 { 179 unsigned sr = 0; 180 int interrupted; 181 int done; 182 int rc = 0; 183 184 do { 185 interrupted = wait_event_interruptible_timeout ( 186 iop3xx_adap->waitq, 187 (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )), 188 1 * HZ; 189 ); 190 if ((rc = iop3xx_i2c_error(sr)) < 0) { 191 *status = sr; 192 return rc; 193 } else if (!interrupted) { 194 *status = sr; 195 return -ETIMEDOUT; 196 } 197 } while(!done); 198 199 *status = sr; 200 201 return 0; 202 } 203 204 /* 205 * Concrete compare_funcs 206 */ 207 static int 208 all_bits_clear(unsigned test, unsigned mask) 209 { 210 return (test & mask) == 0; 211 } 212 213 static int 214 any_bits_set(unsigned test, unsigned mask) 215 { 216 return (test & mask) != 0; 217 } 218 219 static int 220 iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) 221 { 222 return iop3xx_i2c_wait_event( 223 iop3xx_adap, 224 IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, 225 status, any_bits_set); 226 } 227 228 static int 229 iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) 230 { 231 return iop3xx_i2c_wait_event( 232 iop3xx_adap, 233 IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, 234 status, any_bits_set); 235 } 236 237 static int 238 iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) 239 { 240 return iop3xx_i2c_wait_event( 241 iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); 242 } 243 244 static int 245 iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, 246 struct i2c_msg* msg) 247 { 248 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 249 int status; 250 int rc; 251 252 __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); 253 254 cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); 255 cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; 256 257 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 258 rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); 259 260 return rc; 261 } 262 263 static int 264 iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, 265 int stop) 266 { 267 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 268 int status; 269 int rc = 0; 270 271 __raw_writel(byte, iop3xx_adap->ioaddr + DBR_OFFSET); 272 cr &= ~IOP3XX_ICR_MSTART; 273 if (stop) { 274 cr |= IOP3XX_ICR_MSTOP; 275 } else { 276 cr &= ~IOP3XX_ICR_MSTOP; 277 } 278 cr |= IOP3XX_ICR_TBYTE; 279 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 280 rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); 281 282 return rc; 283 } 284 285 static int 286 iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, 287 int stop) 288 { 289 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 290 int status; 291 int rc = 0; 292 293 cr &= ~IOP3XX_ICR_MSTART; 294 295 if (stop) { 296 cr |= IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK; 297 } else { 298 cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); 299 } 300 cr |= IOP3XX_ICR_TBYTE; 301 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 302 303 rc = iop3xx_i2c_wait_rx_done(iop3xx_adap, &status); 304 305 *byte = __raw_readl(iop3xx_adap->ioaddr + DBR_OFFSET); 306 307 return rc; 308 } 309 310 static int 311 iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) 312 { 313 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 314 int ii; 315 int rc = 0; 316 317 for (ii = 0; rc == 0 && ii != count; ++ii) 318 rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); 319 return rc; 320 } 321 322 static int 323 iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) 324 { 325 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 326 int ii; 327 int rc = 0; 328 329 for (ii = 0; rc == 0 && ii != count; ++ii) 330 rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); 331 332 return rc; 333 } 334 335 /* 336 * Description: This function implements combined transactions. Combined 337 * transactions consist of combinations of reading and writing blocks of data. 338 * FROM THE SAME ADDRESS 339 * Each transfer (i.e. a read or a write) is separated by a repeated start 340 * condition. 341 */ 342 static int 343 iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 344 { 345 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 346 int rc; 347 348 rc = iop3xx_i2c_send_target_addr(iop3xx_adap, pmsg); 349 if (rc < 0) { 350 return rc; 351 } 352 353 if ((pmsg->flags&I2C_M_RD)) { 354 return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len); 355 } else { 356 return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len); 357 } 358 } 359 360 /* 361 * master_xfer() - main read/write entry 362 */ 363 static int 364 iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, 365 int num) 366 { 367 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 368 int im = 0; 369 int ret = 0; 370 int status; 371 372 iop3xx_i2c_wait_idle(iop3xx_adap, &status); 373 iop3xx_i2c_reset(iop3xx_adap); 374 iop3xx_i2c_enable(iop3xx_adap); 375 376 for (im = 0; ret == 0 && im != num; im++) { 377 ret = iop3xx_i2c_handle_msg(i2c_adap, &msgs[im]); 378 } 379 380 iop3xx_i2c_transaction_cleanup(iop3xx_adap); 381 382 if(ret) 383 return ret; 384 385 return im; 386 } 387 388 static int 389 iop3xx_i2c_algo_control(struct i2c_adapter *adapter, unsigned int cmd, 390 unsigned long arg) 391 { 392 return 0; 393 } 394 395 static u32 396 iop3xx_i2c_func(struct i2c_adapter *adap) 397 { 398 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 399 } 400 401 static struct i2c_algorithm iop3xx_i2c_algo = { 402 .master_xfer = iop3xx_i2c_master_xfer, 403 .algo_control = iop3xx_i2c_algo_control, 404 .functionality = iop3xx_i2c_func, 405 }; 406 407 static int 408 iop3xx_i2c_remove(struct platform_device *pdev) 409 { 410 struct i2c_adapter *padapter = platform_get_drvdata(pdev); 411 struct i2c_algo_iop3xx_data *adapter_data = 412 (struct i2c_algo_iop3xx_data *)padapter->algo_data; 413 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 414 unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); 415 416 /* 417 * Disable the actual HW unit 418 */ 419 cr &= ~(IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE | 420 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE); 421 __raw_writel(cr, adapter_data->ioaddr + CR_OFFSET); 422 423 iounmap((void __iomem*)adapter_data->ioaddr); 424 release_mem_region(res->start, IOP3XX_I2C_IO_SIZE); 425 kfree(adapter_data); 426 kfree(padapter); 427 428 platform_set_drvdata(pdev, NULL); 429 430 return 0; 431 } 432 433 static int 434 iop3xx_i2c_probe(struct platform_device *pdev) 435 { 436 struct resource *res; 437 int ret; 438 struct i2c_adapter *new_adapter; 439 struct i2c_algo_iop3xx_data *adapter_data; 440 441 new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); 442 if (!new_adapter) { 443 ret = -ENOMEM; 444 goto out; 445 } 446 447 adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL); 448 if (!adapter_data) { 449 ret = -ENOMEM; 450 goto free_adapter; 451 } 452 453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 454 if (!res) { 455 ret = -ENODEV; 456 goto free_both; 457 } 458 459 if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) { 460 ret = -EBUSY; 461 goto free_both; 462 } 463 464 /* set the adapter enumeration # */ 465 adapter_data->id = i2c_id++; 466 467 adapter_data->ioaddr = (u32)ioremap(res->start, IOP3XX_I2C_IO_SIZE); 468 if (!adapter_data->ioaddr) { 469 ret = -ENOMEM; 470 goto release_region; 471 } 472 473 ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0, 474 pdev->name, adapter_data); 475 476 if (ret) { 477 ret = -EIO; 478 goto unmap; 479 } 480 481 memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); 482 new_adapter->id = I2C_HW_IOP3XX; 483 new_adapter->owner = THIS_MODULE; 484 new_adapter->dev.parent = &pdev->dev; 485 486 /* 487 * Default values...should these come in from board code? 488 */ 489 new_adapter->timeout = 100; 490 new_adapter->retries = 3; 491 new_adapter->algo = &iop3xx_i2c_algo; 492 493 init_waitqueue_head(&adapter_data->waitq); 494 spin_lock_init(&adapter_data->lock); 495 496 iop3xx_i2c_reset(adapter_data); 497 iop3xx_i2c_set_slave_addr(adapter_data); 498 iop3xx_i2c_enable(adapter_data); 499 500 platform_set_drvdata(pdev, new_adapter); 501 new_adapter->algo_data = adapter_data; 502 503 i2c_add_adapter(new_adapter); 504 505 return 0; 506 507 unmap: 508 iounmap((void __iomem*)adapter_data->ioaddr); 509 510 release_region: 511 release_mem_region(res->start, IOP3XX_I2C_IO_SIZE); 512 513 free_both: 514 kfree(adapter_data); 515 516 free_adapter: 517 kfree(new_adapter); 518 519 out: 520 return ret; 521 } 522 523 524 static struct platform_driver iop3xx_i2c_driver = { 525 .probe = iop3xx_i2c_probe, 526 .remove = iop3xx_i2c_remove, 527 .driver = { 528 .owner = THIS_MODULE, 529 .name = "IOP3xx-I2C", 530 }, 531 }; 532 533 static int __init 534 i2c_iop3xx_init (void) 535 { 536 return platform_driver_register(&iop3xx_i2c_driver); 537 } 538 539 static void __exit 540 i2c_iop3xx_exit (void) 541 { 542 platform_driver_unregister(&iop3xx_i2c_driver); 543 return; 544 } 545 546 module_init (i2c_iop3xx_init); 547 module_exit (i2c_iop3xx_exit); 548 549 MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>"); 550 MODULE_DESCRIPTION("IOP3xx iic algorithm and driver"); 551 MODULE_LICENSE("GPL"); 552