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