linux/drivers/i2c/busses/i2c-au1550.c
<<
>>
Prefs
   1/*
   2 * i2c-au1550.c: SMBus (i2c) adapter for Alchemy PSC interface
   3 * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com>
   4 *
   5 * 2.6 port by Matt Porter <mporter@kernel.crashing.org>
   6 *
   7 * The documentation describes this as an SMBus controller, but it doesn't
   8 * understand any of the SMBus protocol in hardware.  It's really an I2C
   9 * controller that could emulate most of the SMBus in software.
  10 *
  11 * This is just a skeleton adapter to use with the Au1550 PSC
  12 * algorithm.  It was developed for the Pb1550, but will work with
  13 * any Au1550 board that has a similar PSC configuration.
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License
  17 * as published by the Free Software Foundation; either version 2
  18 * of the License, or (at your option) any later version.
  19 *
  20 * This program is distributed in the hope that it will be useful,
  21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 * GNU General Public License for more details.
  24 *
  25 * You should have received a copy of the GNU General Public License
  26 * along with this program; if not, write to the Free Software
  27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  28 */
  29
  30#include <linux/delay.h>
  31#include <linux/kernel.h>
  32#include <linux/module.h>
  33#include <linux/platform_device.h>
  34#include <linux/init.h>
  35#include <linux/errno.h>
  36#include <linux/i2c.h>
  37#include <linux/slab.h>
  38
  39#include <asm/mach-au1x00/au1xxx.h>
  40#include <asm/mach-au1x00/au1xxx_psc.h>
  41
  42struct i2c_au1550_data {
  43        u32     psc_base;
  44        int     xfer_timeout;
  45        int     ack_timeout;
  46        struct i2c_adapter adap;
  47        struct resource *ioarea;
  48};
  49
  50static int
  51wait_xfer_done(struct i2c_au1550_data *adap)
  52{
  53        u32     stat;
  54        int     i;
  55        volatile psc_smb_t      *sp;
  56
  57        sp = (volatile psc_smb_t *)(adap->psc_base);
  58
  59        /* Wait for Tx Buffer Empty
  60        */
  61        for (i = 0; i < adap->xfer_timeout; i++) {
  62                stat = sp->psc_smbstat;
  63                au_sync();
  64                if ((stat & PSC_SMBSTAT_TE) != 0)
  65                        return 0;
  66
  67                udelay(1);
  68        }
  69
  70        return -ETIMEDOUT;
  71}
  72
  73static int
  74wait_ack(struct i2c_au1550_data *adap)
  75{
  76        u32     stat;
  77        volatile psc_smb_t      *sp;
  78
  79        if (wait_xfer_done(adap))
  80                return -ETIMEDOUT;
  81
  82        sp = (volatile psc_smb_t *)(adap->psc_base);
  83
  84        stat = sp->psc_smbevnt;
  85        au_sync();
  86
  87        if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0)
  88                return -ETIMEDOUT;
  89
  90        return 0;
  91}
  92
  93static int
  94wait_master_done(struct i2c_au1550_data *adap)
  95{
  96        u32     stat;
  97        int     i;
  98        volatile psc_smb_t      *sp;
  99
 100        sp = (volatile psc_smb_t *)(adap->psc_base);
 101
 102        /* Wait for Master Done.
 103        */
 104        for (i = 0; i < adap->xfer_timeout; i++) {
 105                stat = sp->psc_smbevnt;
 106                au_sync();
 107                if ((stat & PSC_SMBEVNT_MD) != 0)
 108                        return 0;
 109                udelay(1);
 110        }
 111
 112        return -ETIMEDOUT;
 113}
 114
 115static int
 116do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q)
 117{
 118        volatile psc_smb_t      *sp;
 119        u32                     stat;
 120
 121        sp = (volatile psc_smb_t *)(adap->psc_base);
 122
 123        /* Reset the FIFOs, clear events.
 124        */
 125        stat = sp->psc_smbstat;
 126        sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR;
 127        au_sync();
 128
 129        if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) {
 130                sp->psc_smbpcr = PSC_SMBPCR_DC;
 131                au_sync();
 132                do {
 133                        stat = sp->psc_smbpcr;
 134                        au_sync();
 135                } while ((stat & PSC_SMBPCR_DC) != 0);
 136                udelay(50);
 137        }
 138
 139        /* Write out the i2c chip address and specify operation
 140        */
 141        addr <<= 1;
 142        if (rd)
 143                addr |= 1;
 144
 145        /* zero-byte xfers stop immediately */
 146        if (q)
 147                addr |= PSC_SMBTXRX_STP;
 148
 149        /* Put byte into fifo, start up master.
 150        */
 151        sp->psc_smbtxrx = addr;
 152        au_sync();
 153        sp->psc_smbpcr = PSC_SMBPCR_MS;
 154        au_sync();
 155        if (wait_ack(adap))
 156                return -EIO;
 157        return (q) ? wait_master_done(adap) : 0;
 158}
 159
 160static u32
 161wait_for_rx_byte(struct i2c_au1550_data *adap, u32 *ret_data)
 162{
 163        int     j;
 164        u32     data, stat;
 165        volatile psc_smb_t      *sp;
 166
 167        if (wait_xfer_done(adap))
 168                return -EIO;
 169
 170        sp = (volatile psc_smb_t *)(adap->psc_base);
 171
 172        j =  adap->xfer_timeout * 100;
 173        do {
 174                j--;
 175                if (j <= 0)
 176                        return -EIO;
 177
 178                stat = sp->psc_smbstat;
 179                au_sync();
 180                if ((stat & PSC_SMBSTAT_RE) == 0)
 181                        j = 0;
 182                else
 183                        udelay(1);
 184        } while (j > 0);
 185        data = sp->psc_smbtxrx;
 186        au_sync();
 187        *ret_data = data;
 188
 189        return 0;
 190}
 191
 192static int
 193i2c_read(struct i2c_au1550_data *adap, unsigned char *buf,
 194                    unsigned int len)
 195{
 196        int     i;
 197        u32     data;
 198        volatile psc_smb_t      *sp;
 199
 200        if (len == 0)
 201                return 0;
 202
 203        /* A read is performed by stuffing the transmit fifo with
 204         * zero bytes for timing, waiting for bytes to appear in the
 205         * receive fifo, then reading the bytes.
 206         */
 207
 208        sp = (volatile psc_smb_t *)(adap->psc_base);
 209
 210        i = 0;
 211        while (i < (len-1)) {
 212                sp->psc_smbtxrx = 0;
 213                au_sync();
 214                if (wait_for_rx_byte(adap, &data))
 215                        return -EIO;
 216
 217                buf[i] = data;
 218                i++;
 219        }
 220
 221        /* The last byte has to indicate transfer done.
 222        */
 223        sp->psc_smbtxrx = PSC_SMBTXRX_STP;
 224        au_sync();
 225        if (wait_master_done(adap))
 226                return -EIO;
 227
 228        data = sp->psc_smbtxrx;
 229        au_sync();
 230        buf[i] = data;
 231        return 0;
 232}
 233
 234static int
 235i2c_write(struct i2c_au1550_data *adap, unsigned char *buf,
 236                     unsigned int len)
 237{
 238        int     i;
 239        u32     data;
 240        volatile psc_smb_t      *sp;
 241
 242        if (len == 0)
 243                return 0;
 244
 245        sp = (volatile psc_smb_t *)(adap->psc_base);
 246
 247        i = 0;
 248        while (i < (len-1)) {
 249                data = buf[i];
 250                sp->psc_smbtxrx = data;
 251                au_sync();
 252                if (wait_ack(adap))
 253                        return -EIO;
 254                i++;
 255        }
 256
 257        /* The last byte has to indicate transfer done.
 258        */
 259        data = buf[i];
 260        data |= PSC_SMBTXRX_STP;
 261        sp->psc_smbtxrx = data;
 262        au_sync();
 263        if (wait_master_done(adap))
 264                return -EIO;
 265        return 0;
 266}
 267
 268static int
 269au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
 270{
 271        struct i2c_au1550_data *adap = i2c_adap->algo_data;
 272        volatile psc_smb_t *sp = (volatile psc_smb_t *)adap->psc_base;
 273        struct i2c_msg *p;
 274        int i, err = 0;
 275
 276        sp->psc_ctrl = PSC_CTRL_ENABLE;
 277        au_sync();
 278
 279        for (i = 0; !err && i < num; i++) {
 280                p = &msgs[i];
 281                err = do_address(adap, p->addr, p->flags & I2C_M_RD,
 282                                 (p->len == 0));
 283                if (err || !p->len)
 284                        continue;
 285                if (p->flags & I2C_M_RD)
 286                        err = i2c_read(adap, p->buf, p->len);
 287                else
 288                        err = i2c_write(adap, p->buf, p->len);
 289        }
 290
 291        /* Return the number of messages processed, or the error code.
 292        */
 293        if (err == 0)
 294                err = num;
 295
 296        sp->psc_ctrl = PSC_CTRL_SUSPEND;
 297        au_sync();
 298
 299        return err;
 300}
 301
 302static u32
 303au1550_func(struct i2c_adapter *adap)
 304{
 305        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 306}
 307
 308static const struct i2c_algorithm au1550_algo = {
 309        .master_xfer    = au1550_xfer,
 310        .functionality  = au1550_func,
 311};
 312
 313static void i2c_au1550_setup(struct i2c_au1550_data *priv)
 314{
 315        volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 316        u32 stat;
 317
 318        sp->psc_ctrl = PSC_CTRL_DISABLE;
 319        au_sync();
 320        sp->psc_sel = PSC_SEL_PS_SMBUSMODE;
 321        sp->psc_smbcfg = 0;
 322        au_sync();
 323        sp->psc_ctrl = PSC_CTRL_ENABLE;
 324        au_sync();
 325        do {
 326                stat = sp->psc_smbstat;
 327                au_sync();
 328        } while ((stat & PSC_SMBSTAT_SR) == 0);
 329
 330        sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 |
 331                                PSC_SMBCFG_DD_DISABLE);
 332
 333        /* Divide by 8 to get a 6.25 MHz clock.  The later protocol
 334         * timings are based on this clock.
 335         */
 336        sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
 337        sp->psc_smbmsk = PSC_SMBMSK_ALLMASK;
 338        au_sync();
 339
 340        /* Set the protocol timer values.  See Table 71 in the
 341         * Au1550 Data Book for standard timing values.
 342         */
 343        sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \
 344                PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \
 345                PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \
 346                PSC_SMBTMR_SET_CH(15);
 347        au_sync();
 348
 349        sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE;
 350        do {
 351                stat = sp->psc_smbstat;
 352                au_sync();
 353        } while ((stat & PSC_SMBSTAT_SR) == 0);
 354
 355        sp->psc_ctrl = PSC_CTRL_SUSPEND;
 356        au_sync();
 357}
 358
 359static void i2c_au1550_disable(struct i2c_au1550_data *priv)
 360{
 361        volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 362
 363        sp->psc_smbcfg = 0;
 364        sp->psc_ctrl = PSC_CTRL_DISABLE;
 365        au_sync();
 366}
 367
 368/*
 369 * registering functions to load algorithms at runtime
 370 * Prior to calling us, the 50MHz clock frequency and routing
 371 * must have been set up for the PSC indicated by the adapter.
 372 */
 373static int __devinit
 374i2c_au1550_probe(struct platform_device *pdev)
 375{
 376        struct i2c_au1550_data *priv;
 377        struct resource *r;
 378        int ret;
 379
 380        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 381        if (!r) {
 382                ret = -ENODEV;
 383                goto out;
 384        }
 385
 386        priv = kzalloc(sizeof(struct i2c_au1550_data), GFP_KERNEL);
 387        if (!priv) {
 388                ret = -ENOMEM;
 389                goto out;
 390        }
 391
 392        priv->ioarea = request_mem_region(r->start, r->end - r->start + 1,
 393                                          pdev->name);
 394        if (!priv->ioarea) {
 395                ret = -EBUSY;
 396                goto out_mem;
 397        }
 398
 399        priv->psc_base = CKSEG1ADDR(r->start);
 400        priv->xfer_timeout = 200;
 401        priv->ack_timeout = 200;
 402
 403        priv->adap.id = I2C_HW_AU1550_PSC;
 404        priv->adap.nr = pdev->id;
 405        priv->adap.algo = &au1550_algo;
 406        priv->adap.algo_data = priv;
 407        priv->adap.dev.parent = &pdev->dev;
 408        strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));
 409
 410        /* Now, set up the PSC for SMBus PIO mode.
 411        */
 412        i2c_au1550_setup(priv);
 413
 414        ret = i2c_add_numbered_adapter(&priv->adap);
 415        if (ret == 0) {
 416                platform_set_drvdata(pdev, priv);
 417                return 0;
 418        }
 419
 420        i2c_au1550_disable(priv);
 421
 422        release_resource(priv->ioarea);
 423        kfree(priv->ioarea);
 424out_mem:
 425        kfree(priv);
 426out:
 427        return ret;
 428}
 429
 430static int __devexit
 431i2c_au1550_remove(struct platform_device *pdev)
 432{
 433        struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
 434
 435        platform_set_drvdata(pdev, NULL);
 436        i2c_del_adapter(&priv->adap);
 437        i2c_au1550_disable(priv);
 438        release_resource(priv->ioarea);
 439        kfree(priv->ioarea);
 440        kfree(priv);
 441        return 0;
 442}
 443
 444#ifdef CONFIG_PM
 445static int
 446i2c_au1550_suspend(struct platform_device *pdev, pm_message_t state)
 447{
 448        struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
 449
 450        i2c_au1550_disable(priv);
 451
 452        return 0;
 453}
 454
 455static int
 456i2c_au1550_resume(struct platform_device *pdev)
 457{
 458        struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
 459
 460        i2c_au1550_setup(priv);
 461
 462        return 0;
 463}
 464#else
 465#define i2c_au1550_suspend      NULL
 466#define i2c_au1550_resume       NULL
 467#endif
 468
 469static struct platform_driver au1xpsc_smbus_driver = {
 470        .driver = {
 471                .name   = "au1xpsc_smbus",
 472                .owner  = THIS_MODULE,
 473        },
 474        .probe          = i2c_au1550_probe,
 475        .remove         = __devexit_p(i2c_au1550_remove),
 476        .suspend        = i2c_au1550_suspend,
 477        .resume         = i2c_au1550_resume,
 478};
 479
 480static int __init
 481i2c_au1550_init(void)
 482{
 483        return platform_driver_register(&au1xpsc_smbus_driver);
 484}
 485
 486static void __exit
 487i2c_au1550_exit(void)
 488{
 489        platform_driver_unregister(&au1xpsc_smbus_driver);
 490}
 491
 492MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
 493MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
 494MODULE_LICENSE("GPL");
 495MODULE_ALIAS("platform:au1xpsc_smbus");
 496
 497module_init (i2c_au1550_init);
 498module_exit (i2c_au1550_exit);
 499
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.