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