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 * - writing to slave address causes latchup on iop331. 25 * fix: driver refuses to address self. 26 * 27 * This program is free software; you can redistribute it and/or modify 28 * it under the terms of the GNU General Public License as published by 29 * the Free Software Foundation, version 2. 30 */ 31 32 #include <linux/interrupt.h> 33 #include <linux/kernel.h> 34 #include <linux/module.h> 35 #include <linux/delay.h> 36 #include <linux/slab.h> 37 #include <linux/init.h> 38 #include <linux/errno.h> 39 #include <linux/platform_device.h> 40 #include <linux/i2c.h> 41 42 #include <asm/io.h> 43 44 #include "i2c-iop3xx.h" 45 46 /* global unit counter */ 47 static int i2c_id; 48 49 static inline unsigned char 50 iic_cook_addr(struct i2c_msg *msg) 51 { 52 unsigned char addr; 53 54 addr = (msg->addr << 1); 55 56 if (msg->flags & I2C_M_RD) 57 addr |= 1; 58 59 /* 60 * Read or Write? 61 */ 62 if (msg->flags & I2C_M_REV_DIR_ADDR) 63 addr ^= 1; 64 65 return addr; 66 } 67 68 static void 69 iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) 70 { 71 /* Follows devman 9.3 */ 72 __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); 73 __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); 74 __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); 75 } 76 77 static void 78 iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) 79 { 80 u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; 81 82 /* 83 * Every time unit enable is asserted, GPOD needs to be cleared 84 * on IOP3XX to avoid data corruption on the bus. 85 */ 86 #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) 87 if (iop3xx_adap->id == 0) { 88 gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW); 89 gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW); 90 } else { 91 gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW); 92 gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW); 93 } 94 #endif 95 /* NB SR bits not same position as CR IE bits :-( */ 96 iop3xx_adap->SR_enabled = 97 IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | 98 IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; 99 100 cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE | 101 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE; 102 103 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 104 } 105 106 static void 107 iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) 108 { 109 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 110 111 cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | 112 IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); 113 114 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 115 } 116 117 /* 118 * NB: the handler has to clear the source of the interrupt! 119 * Then it passes the SR flags of interest to BH via adap data 120 */ 121 static irqreturn_t 122 iop3xx_i2c_irq_handler(int this_irq, void *dev_id) 123 { 124 struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; 125 u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); 126 127 if ((sr &= iop3xx_adap->SR_enabled)) { 128 __raw_writel(sr, iop3xx_adap->ioaddr + SR_OFFSET); 129 iop3xx_adap->SR_received |= sr; 130 wake_up_interruptible(&iop3xx_adap->waitq); 131 } 132 return IRQ_HANDLED; 133 } 134 135 /* check all error conditions, clear them , report most important */ 136 static int 137 iop3xx_i2c_error(u32 sr) 138 { 139 int rc = 0; 140 141 if ((sr & IOP3XX_ISR_BERRD)) { 142 if ( !rc ) rc = -I2C_ERR_BERR; 143 } 144 if ((sr & IOP3XX_ISR_ALD)) { 145 if ( !rc ) rc = -I2C_ERR_ALD; 146 } 147 return rc; 148 } 149 150 static inline u32 151 iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) 152 { 153 unsigned long flags; 154 u32 sr; 155 156 spin_lock_irqsave(&iop3xx_adap->lock, flags); 157 sr = iop3xx_adap->SR_received; 158 iop3xx_adap->SR_received = 0; 159 spin_unlock_irqrestore(&iop3xx_adap->lock, flags); 160 161 return sr; 162 } 163 164 /* 165 * sleep until interrupted, then recover and analyse the SR 166 * saved by handler 167 */ 168 typedef int (* compare_func)(unsigned test, unsigned mask); 169 /* returns 1 on correct comparison */ 170 171 static int 172 iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 173 unsigned flags, unsigned* status, 174 compare_func compare) 175 { 176 unsigned sr = 0; 177 int interrupted; 178 int done; 179 int rc = 0; 180 181 do { 182 interrupted = wait_event_interruptible_timeout ( 183 iop3xx_adap->waitq, 184 (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )), 185 1 * HZ; 186 ); 187 if ((rc = iop3xx_i2c_error(sr)) < 0) { 188 *status = sr; 189 return rc; 190 } else if (!interrupted) { 191 *status = sr; 192 return -ETIMEDOUT; 193 } 194 } while(!done); 195 196 *status = sr; 197 198 return 0; 199 } 200 201 /* 202 * Concrete compare_funcs 203 */ 204 static int 205 all_bits_clear(unsigned test, unsigned mask) 206 { 207 return (test & mask) == 0; 208 } 209 210 static int 211 any_bits_set(unsigned test, unsigned mask) 212 { 213 return (test & mask) != 0; 214 } 215 216 static int 217 iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) 218 { 219 return iop3xx_i2c_wait_event( 220 iop3xx_adap, 221 IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, 222 status, any_bits_set); 223 } 224 225 static int 226 iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) 227 { 228 return iop3xx_i2c_wait_event( 229 iop3xx_adap, 230 IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, 231 status, any_bits_set); 232 } 233 234 static int 235 iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) 236 { 237 return iop3xx_i2c_wait_event( 238 iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); 239 } 240 241 static int 242 iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, 243 struct i2c_msg* msg) 244 { 245 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 246 int status; 247 int rc; 248 249 /* avoid writing to my slave address (hangs on 80331), 250 * forbidden in Intel developer manual 251 */ 252 if (msg->addr == MYSAR) { 253 return -EBUSY; 254 } 255 256 __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); 257 258 cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); 259 cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; 260 261 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 262 rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); 263 264 return rc; 265 } 266 267 static int 268 iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, 269 int stop) 270 { 271 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 272 int status; 273 int rc = 0; 274 275 __raw_writel(byte, iop3xx_adap->ioaddr + DBR_OFFSET); 276 cr &= ~IOP3XX_ICR_MSTART; 277 if (stop) { 278 cr |= IOP3XX_ICR_MSTOP; 279 } else { 280 cr &= ~IOP3XX_ICR_MSTOP; 281 } 282 cr |= IOP3XX_ICR_TBYTE; 283 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 284 rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); 285 286 return rc; 287 } 288 289 static int 290 iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, 291 int stop) 292 { 293 unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); 294 int status; 295 int rc = 0; 296 297 cr &= ~IOP3XX_ICR_MSTART; 298 299 if (stop) { 300 cr |= IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK; 301 } else { 302 cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); 303 } 304 cr |= IOP3XX_ICR_TBYTE; 305 __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); 306 307 rc = iop3xx_i2c_wait_rx_done(iop3xx_adap, &status); 308 309 *byte = __raw_readl(iop3xx_adap->ioaddr + DBR_OFFSET); 310 311 return rc; 312 } 313 314 static int 315 iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) 316 { 317 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 318 int ii; 319 int rc = 0; 320 321 for (ii = 0; rc == 0 && ii != count; ++ii) 322 rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); 323 return rc; 324 } 325 326 static int 327 iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) 328 { 329 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 330 int ii; 331 int rc = 0; 332 333 for (ii = 0; rc == 0 && ii != count; ++ii) 334 rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); 335 336 return rc; 337 } 338 339 /* 340 * Description: This function implements combined transactions. Combined 341 * transactions consist of combinations of reading and writing blocks of data. 342 * FROM THE SAME ADDRESS 343 * Each transfer (i.e. a read or a write) is separated by a repeated start 344 * condition. 345 */ 346 static int 347 iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 348 { 349 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 350 int rc; 351 352 rc = iop3xx_i2c_send_target_addr(iop3xx_adap, pmsg); 353 if (rc < 0) { 354 return rc; 355 } 356 357 if ((pmsg->flags&I2C_M_RD)) { 358 return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len); 359 } else { 360 return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len); 361 } 362 } 363 364 /* 365 * master_xfer() - main read/write entry 366 */ 367 static int 368 iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, 369 int num) 370 { 371 struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; 372 int im = 0; 373 int ret = 0; 374 int status; 375 376 iop3xx_i2c_wait_idle(iop3xx_adap, &status); 377 iop3xx_i2c_reset(iop3xx_adap); 378 iop3xx_i2c_enable(iop3xx_adap); 379 380 for (im = 0; ret == 0 && im != num; im++) { 381 ret = iop3xx_i2c_handle_msg(i2c_adap, &msgs[im]); 382 } 383 384 iop3xx_i2c_transaction_cleanup(iop3xx_adap); 385 386 if(ret) 387 return ret; 388 389 return im; 390 } 391 392 static u32 393 iop3xx_i2c_func(struct i2c_adapter *adap) 394 { 395 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 396 } 397 398 static const struct i2c_algorithm iop3xx_i2c_algo = { 399 .master_xfer = iop3xx_i2c_master_xfer, 400 .functionality = iop3xx_i2c_func, 401 }; 402 403 static int 404 iop3xx_i2c_remove(struct platform_device *pdev) 405 { 406 struct i2c_adapter *padapter = platform_get_drvdata(pdev); 407 struct i2c_algo_iop3xx_data *adapter_data = 408 (struct i2c_algo_iop3xx_data *)padapter->algo_data; 409 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 410 unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); 411 412 /* 413 * Disable the actual HW unit 414 */ 415 cr &= ~(IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE | 416 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE); 417 __raw_writel(cr, adapter_data->ioaddr + CR_OFFSET); 418 419 iounmap((void __iomem*)adapter_data->ioaddr); 420 release_mem_region(res->start, IOP3XX_I2C_IO_SIZE); 421 kfree(adapter_data); 422 kfree(padapter); 423 424 platform_set_drvdata(pdev, NULL); 425 426 return 0; 427 } 428 429 static int 430 iop3xx_i2c_probe(struct platform_device *pdev) 431 { 432 struct resource *res; 433 int ret, irq; 434 struct i2c_adapter *new_adapter; 435 struct i2c_algo_iop3xx_data *adapter_data; 436 437 new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); 438 if (!new_adapter) { 439 ret = -ENOMEM; 440 goto out; 441 } 442 443 adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL); 444 if (!adapter_data) { 445 ret = -ENOMEM; 446 goto free_adapter; 447 } 448 449 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 450 if (!res) { 451 ret = -ENODEV; 452 goto free_both; 453 } 454 455 if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) { 456 ret = -EBUSY; 457 goto free_both; 458 } 459 460 /* set the adapter enumeration # */ 461 adapter_data->id = i2c_id++; 462 463 adapter_data->ioaddr = (u32)ioremap(res->start, IOP3XX_I2C_IO_SIZE); 464 if (!adapter_data->ioaddr) { 465 ret = -ENOMEM; 466 goto release_region; 467 } 468 469 irq = platform_get_irq(pdev, 0); 470 if (irq < 0) { 471 ret = -ENXIO; 472 goto unmap; 473 } 474 ret = request_irq(irq, iop3xx_i2c_irq_handler, 0, 475 pdev->name, adapter_data); 476 477 if (ret) { 478 ret = -EIO; 479 goto unmap; 480 } 481 482 memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); 483 new_adapter->owner = THIS_MODULE; 484 new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; 485 new_adapter->dev.parent = &pdev->dev; 486 new_adapter->nr = pdev->id; 487 488 /* 489 * Default values...should these come in from board code? 490 */ 491 new_adapter->timeout = HZ; 492 new_adapter->algo = &iop3xx_i2c_algo; 493 494 init_waitqueue_head(&adapter_data->waitq); 495 spin_lock_init(&adapter_data->lock); 496 497 iop3xx_i2c_reset(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_numbered_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 MODULE_ALIAS("platform:IOP3xx-I2C"); 553