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 */ 46static int i2c_id; 47 48static inline unsigned char 49iic_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 61static void 62iop3xx_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 70static void 71iop3xx_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_set_value(7, 0); 82 gpio_set_value(6, 0); 83 } else { 84 gpio_set_value(5, 0); 85 gpio_set_value(4, 0); 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 99static void 100iop3xx_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 */ 114static irqreturn_t 115iop3xx_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 */ 129static int 130iop3xx_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 143static inline u32 144iop3xx_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 */ 161typedef int (* compare_func)(unsigned test, unsigned mask); 162/* returns 1 on correct comparison */ 163 164static int 165iop3xx_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 */ 197static int 198all_bits_clear(unsigned test, unsigned mask) 199{ 200 return (test & mask) == 0; 201} 202 203static int 204any_bits_set(unsigned test, unsigned mask) 205{ 206 return (test & mask) != 0; 207} 208 209static int 210iop3xx_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 218static int 219iop3xx_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 227static int 228iop3xx_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 234static int 235iop3xx_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 260static int 261iop3xx_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 282static int 283iop3xx_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 307static int 308iop3xx_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 319static int 320iop3xx_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 */ 339static int 340iop3xx_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 */ 360static int 361iop3xx_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 385static u32 386iop3xx_i2c_func(struct i2c_adapter *adap) 387{ 388 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 389} 390 391static const struct i2c_algorithm iop3xx_i2c_algo = { 392 .master_xfer = iop3xx_i2c_master_xfer, 393 .functionality = iop3xx_i2c_func, 394}; 395 396static int 397iop3xx_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 return 0; 418} 419 420static int 421iop3xx_i2c_probe(struct platform_device *pdev) 422{ 423 struct resource *res; 424 int ret, irq; 425 struct i2c_adapter *new_adapter; 426 struct i2c_algo_iop3xx_data *adapter_data; 427 428 new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); 429 if (!new_adapter) { 430 ret = -ENOMEM; 431 goto out; 432 } 433 434 adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL); 435 if (!adapter_data) { 436 ret = -ENOMEM; 437 goto free_adapter; 438 } 439 440 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 441 if (!res) { 442 ret = -ENODEV; 443 goto free_both; 444 } 445 446 if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) { 447 ret = -EBUSY; 448 goto free_both; 449 } 450 451 /* set the adapter enumeration # */ 452 adapter_data->id = i2c_id++; 453 454 adapter_data->ioaddr = ioremap(res->start, IOP3XX_I2C_IO_SIZE); 455 if (!adapter_data->ioaddr) { 456 ret = -ENOMEM; 457 goto release_region; 458 } 459 460 irq = platform_get_irq(pdev, 0); 461 if (irq < 0) { 462 ret = -ENXIO; 463 goto unmap; 464 } 465 ret = request_irq(irq, iop3xx_i2c_irq_handler, 0, 466 pdev->name, adapter_data); 467 468 if (ret) { 469 ret = -EIO; 470 goto unmap; 471 } 472 473 memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); 474 new_adapter->owner = THIS_MODULE; 475 new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; 476 new_adapter->dev.parent = &pdev->dev; 477 new_adapter->nr = pdev->id; 478 479 /* 480 * Default values...should these come in from board code? 481 */ 482 new_adapter->timeout = HZ; 483 new_adapter->algo = &iop3xx_i2c_algo; 484 485 init_waitqueue_head(&adapter_data->waitq); 486 spin_lock_init(&adapter_data->lock); 487 488 iop3xx_i2c_reset(adapter_data); 489 iop3xx_i2c_enable(adapter_data); 490 491 platform_set_drvdata(pdev, new_adapter); 492 new_adapter->algo_data = adapter_data; 493 494 i2c_add_numbered_adapter(new_adapter); 495 496 return 0; 497 498unmap: 499 iounmap(adapter_data->ioaddr); 500 501release_region: 502 release_mem_region(res->start, IOP3XX_I2C_IO_SIZE); 503 504free_both: 505 kfree(adapter_data); 506 507free_adapter: 508 kfree(new_adapter); 509 510out: 511 return ret; 512} 513 514 515static struct platform_driver iop3xx_i2c_driver = { 516 .probe = iop3xx_i2c_probe, 517 .remove = iop3xx_i2c_remove, 518 .driver = { 519 .name = "IOP3xx-I2C", 520 }, 521}; 522 523module_platform_driver(iop3xx_i2c_driver); 524 525MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>"); 526MODULE_DESCRIPTION("IOP3xx iic algorithm and driver"); 527MODULE_LICENSE("GPL"); 528MODULE_ALIAS("platform:IOP3xx-I2C"); 529