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