linux/drivers/i2c/busses/i2c-kempld.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * I2C bus driver for Kontron COM modules
   4 *
   5 * Copyright (c) 2010-2013 Kontron Europe GmbH
   6 * Author: Michael Brunner <michael.brunner@kontron.com>
   7 *
   8 * The driver is based on the i2c-ocores driver by Peter Korsgaard.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <linux/i2c.h>
  14#include <linux/delay.h>
  15#include <linux/mfd/kempld.h>
  16
  17#define KEMPLD_I2C_PRELOW       0x0b
  18#define KEMPLD_I2C_PREHIGH      0x0c
  19#define KEMPLD_I2C_DATA         0x0e
  20
  21#define KEMPLD_I2C_CTRL         0x0d
  22#define I2C_CTRL_IEN            0x40
  23#define I2C_CTRL_EN             0x80
  24
  25#define KEMPLD_I2C_STAT         0x0f
  26#define I2C_STAT_IF             0x01
  27#define I2C_STAT_TIP            0x02
  28#define I2C_STAT_ARBLOST        0x20
  29#define I2C_STAT_BUSY           0x40
  30#define I2C_STAT_NACK           0x80
  31
  32#define KEMPLD_I2C_CMD          0x0f
  33#define I2C_CMD_START           0x91
  34#define I2C_CMD_STOP            0x41
  35#define I2C_CMD_READ            0x21
  36#define I2C_CMD_WRITE           0x11
  37#define I2C_CMD_READ_ACK        0x21
  38#define I2C_CMD_READ_NACK       0x29
  39#define I2C_CMD_IACK            0x01
  40
  41#define KEMPLD_I2C_FREQ_MAX     2700    /* 2.7 mHz */
  42#define KEMPLD_I2C_FREQ_STD     100     /* 100 kHz */
  43
  44enum {
  45        STATE_DONE = 0,
  46        STATE_INIT,
  47        STATE_ADDR,
  48        STATE_ADDR10,
  49        STATE_START,
  50        STATE_WRITE,
  51        STATE_READ,
  52        STATE_ERROR,
  53};
  54
  55struct kempld_i2c_data {
  56        struct device                   *dev;
  57        struct kempld_device_data       *pld;
  58        struct i2c_adapter              adap;
  59        struct i2c_msg                  *msg;
  60        int                             pos;
  61        int                             nmsgs;
  62        int                             state;
  63        bool                            was_active;
  64};
  65
  66static unsigned int bus_frequency = KEMPLD_I2C_FREQ_STD;
  67module_param(bus_frequency, uint, 0);
  68MODULE_PARM_DESC(bus_frequency, "Set I2C bus frequency in kHz (default="
  69                                __MODULE_STRING(KEMPLD_I2C_FREQ_STD)")");
  70
  71static int i2c_bus = -1;
  72module_param(i2c_bus, int, 0);
  73MODULE_PARM_DESC(i2c_bus, "Set I2C bus number (default=-1 for dynamic assignment)");
  74
  75static bool i2c_gpio_mux;
  76module_param(i2c_gpio_mux, bool, 0);
  77MODULE_PARM_DESC(i2c_gpio_mux, "Enable I2C port on GPIO out (default=false)");
  78
  79/*
  80 * kempld_get_mutex must be called prior to calling this function.
  81 */
  82static int kempld_i2c_process(struct kempld_i2c_data *i2c)
  83{
  84        struct kempld_device_data *pld = i2c->pld;
  85        u8 stat = kempld_read8(pld, KEMPLD_I2C_STAT);
  86        struct i2c_msg *msg = i2c->msg;
  87        u8 addr;
  88
  89        /* Ready? */
  90        if (stat & I2C_STAT_TIP)
  91                return -EBUSY;
  92
  93        if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) {
  94                /* Stop has been sent */
  95                kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
  96                if (i2c->state == STATE_ERROR)
  97                        return -EIO;
  98                return 0;
  99        }
 100
 101        /* Error? */
 102        if (stat & I2C_STAT_ARBLOST) {
 103                i2c->state = STATE_ERROR;
 104                kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
 105                return -EAGAIN;
 106        }
 107
 108        if (i2c->state == STATE_INIT) {
 109                if (stat & I2C_STAT_BUSY)
 110                        return -EBUSY;
 111
 112                i2c->state = STATE_ADDR;
 113        }
 114
 115        if (i2c->state == STATE_ADDR) {
 116                /* 10 bit address? */
 117                if (i2c->msg->flags & I2C_M_TEN) {
 118                        addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6);
 119                        /* Set read bit if necessary */
 120                        addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;
 121                        i2c->state = STATE_ADDR10;
 122                } else {
 123                        addr = i2c_8bit_addr_from_msg(i2c->msg);
 124                        i2c->state = STATE_START;
 125                }
 126
 127                kempld_write8(pld, KEMPLD_I2C_DATA, addr);
 128                kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_START);
 129
 130                return 0;
 131        }
 132
 133        /* Second part of 10 bit addressing */
 134        if (i2c->state == STATE_ADDR10) {
 135                kempld_write8(pld, KEMPLD_I2C_DATA, i2c->msg->addr & 0xff);
 136                kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
 137
 138                i2c->state = STATE_START;
 139                return 0;
 140        }
 141
 142        if (i2c->state == STATE_START || i2c->state == STATE_WRITE) {
 143                i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
 144
 145                if (stat & I2C_STAT_NACK) {
 146                        i2c->state = STATE_ERROR;
 147                        kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
 148                        return -ENXIO;
 149                }
 150        } else {
 151                msg->buf[i2c->pos++] = kempld_read8(pld, KEMPLD_I2C_DATA);
 152        }
 153
 154        if (i2c->pos >= msg->len) {
 155                i2c->nmsgs--;
 156                i2c->msg++;
 157                i2c->pos = 0;
 158                msg = i2c->msg;
 159
 160                if (i2c->nmsgs) {
 161                        if (!(msg->flags & I2C_M_NOSTART)) {
 162                                i2c->state = STATE_ADDR;
 163                                return 0;
 164                        } else {
 165                                i2c->state = (msg->flags & I2C_M_RD)
 166                                        ? STATE_READ : STATE_WRITE;
 167                        }
 168                } else {
 169                        i2c->state = STATE_DONE;
 170                        kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
 171                        return 0;
 172                }
 173        }
 174
 175        if (i2c->state == STATE_READ) {
 176                kempld_write8(pld, KEMPLD_I2C_CMD, i2c->pos == (msg->len - 1) ?
 177                              I2C_CMD_READ_NACK : I2C_CMD_READ_ACK);
 178        } else {
 179                kempld_write8(pld, KEMPLD_I2C_DATA, msg->buf[i2c->pos++]);
 180                kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
 181        }
 182
 183        return 0;
 184}
 185
 186static int kempld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 187                                int num)
 188{
 189        struct kempld_i2c_data *i2c = i2c_get_adapdata(adap);
 190        struct kempld_device_data *pld = i2c->pld;
 191        unsigned long timeout = jiffies + HZ;
 192        int ret;
 193
 194        i2c->msg = msgs;
 195        i2c->pos = 0;
 196        i2c->nmsgs = num;
 197        i2c->state = STATE_INIT;
 198
 199        /* Handle the transfer */
 200        while (time_before(jiffies, timeout)) {
 201                kempld_get_mutex(pld);
 202                ret = kempld_i2c_process(i2c);
 203                kempld_release_mutex(pld);
 204
 205                if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR)
 206                        return (i2c->state == STATE_DONE) ? num : ret;
 207
 208                if (ret == 0)
 209                        timeout = jiffies + HZ;
 210
 211                usleep_range(5, 15);
 212        }
 213
 214        i2c->state = STATE_ERROR;
 215
 216        return -ETIMEDOUT;
 217}
 218
 219/*
 220 * kempld_get_mutex must be called prior to calling this function.
 221 */
 222static void kempld_i2c_device_init(struct kempld_i2c_data *i2c)
 223{
 224        struct kempld_device_data *pld = i2c->pld;
 225        u16 prescale_corr;
 226        long prescale;
 227        u8 ctrl;
 228        u8 stat;
 229        u8 cfg;
 230
 231        /* Make sure the device is disabled */
 232        ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
 233        ctrl &= ~(I2C_CTRL_EN | I2C_CTRL_IEN);
 234        kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
 235
 236        if (bus_frequency > KEMPLD_I2C_FREQ_MAX)
 237                bus_frequency = KEMPLD_I2C_FREQ_MAX;
 238
 239        if (pld->info.spec_major == 1)
 240                prescale = pld->pld_clock / (bus_frequency * 5) - 1000;
 241        else
 242                prescale = pld->pld_clock / (bus_frequency * 4) - 3000;
 243
 244        if (prescale < 0)
 245                prescale = 0;
 246
 247        /* Round to the best matching value */
 248        prescale_corr = prescale / 1000;
 249        if (prescale % 1000 >= 500)
 250                prescale_corr++;
 251
 252        kempld_write8(pld, KEMPLD_I2C_PRELOW, prescale_corr & 0xff);
 253        kempld_write8(pld, KEMPLD_I2C_PREHIGH, prescale_corr >> 8);
 254
 255        /* Activate I2C bus output on GPIO pins */
 256        cfg = kempld_read8(pld, KEMPLD_CFG);
 257        if (i2c_gpio_mux)
 258                cfg |= KEMPLD_CFG_GPIO_I2C_MUX;
 259        else
 260                cfg &= ~KEMPLD_CFG_GPIO_I2C_MUX;
 261        kempld_write8(pld, KEMPLD_CFG, cfg);
 262
 263        /* Enable the device */
 264        kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
 265        ctrl |= I2C_CTRL_EN;
 266        kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
 267
 268        stat = kempld_read8(pld, KEMPLD_I2C_STAT);
 269        if (stat & I2C_STAT_BUSY)
 270                kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
 271}
 272
 273static u32 kempld_i2c_func(struct i2c_adapter *adap)
 274{
 275        return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
 276}
 277
 278static const struct i2c_algorithm kempld_i2c_algorithm = {
 279        .master_xfer    = kempld_i2c_xfer,
 280        .functionality  = kempld_i2c_func,
 281};
 282
 283static const struct i2c_adapter kempld_i2c_adapter = {
 284        .owner          = THIS_MODULE,
 285        .name           = "i2c-kempld",
 286        .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
 287        .algo           = &kempld_i2c_algorithm,
 288};
 289
 290static int kempld_i2c_probe(struct platform_device *pdev)
 291{
 292        struct kempld_device_data *pld = dev_get_drvdata(pdev->dev.parent);
 293        struct kempld_i2c_data *i2c;
 294        int ret;
 295        u8 ctrl;
 296
 297        i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
 298        if (!i2c)
 299                return -ENOMEM;
 300
 301        i2c->pld = pld;
 302        i2c->dev = &pdev->dev;
 303        i2c->adap = kempld_i2c_adapter;
 304        i2c->adap.dev.parent = i2c->dev;
 305        i2c_set_adapdata(&i2c->adap, i2c);
 306        platform_set_drvdata(pdev, i2c);
 307
 308        kempld_get_mutex(pld);
 309        ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
 310
 311        if (ctrl & I2C_CTRL_EN)
 312                i2c->was_active = true;
 313
 314        kempld_i2c_device_init(i2c);
 315        kempld_release_mutex(pld);
 316
 317        /* Add I2C adapter to I2C tree */
 318        if (i2c_bus >= -1)
 319                i2c->adap.nr = i2c_bus;
 320        ret = i2c_add_numbered_adapter(&i2c->adap);
 321        if (ret)
 322                return ret;
 323
 324        dev_info(i2c->dev, "I2C bus initialized at %dkHz\n",
 325                 bus_frequency);
 326
 327        return 0;
 328}
 329
 330static int kempld_i2c_remove(struct platform_device *pdev)
 331{
 332        struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
 333        struct kempld_device_data *pld = i2c->pld;
 334        u8 ctrl;
 335
 336        kempld_get_mutex(pld);
 337        /*
 338         * Disable I2C logic if it was not activated before the
 339         * driver loaded
 340         */
 341        if (!i2c->was_active) {
 342                ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
 343                ctrl &= ~I2C_CTRL_EN;
 344                kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
 345        }
 346        kempld_release_mutex(pld);
 347
 348        i2c_del_adapter(&i2c->adap);
 349
 350        return 0;
 351}
 352
 353#ifdef CONFIG_PM
 354static int kempld_i2c_suspend(struct platform_device *pdev, pm_message_t state)
 355{
 356        struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
 357        struct kempld_device_data *pld = i2c->pld;
 358        u8 ctrl;
 359
 360        kempld_get_mutex(pld);
 361        ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
 362        ctrl &= ~I2C_CTRL_EN;
 363        kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
 364        kempld_release_mutex(pld);
 365
 366        return 0;
 367}
 368
 369static int kempld_i2c_resume(struct platform_device *pdev)
 370{
 371        struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
 372        struct kempld_device_data *pld = i2c->pld;
 373
 374        kempld_get_mutex(pld);
 375        kempld_i2c_device_init(i2c);
 376        kempld_release_mutex(pld);
 377
 378        return 0;
 379}
 380#else
 381#define kempld_i2c_suspend      NULL
 382#define kempld_i2c_resume       NULL
 383#endif
 384
 385static struct platform_driver kempld_i2c_driver = {
 386        .driver = {
 387                .name = "kempld-i2c",
 388        },
 389        .probe          = kempld_i2c_probe,
 390        .remove         = kempld_i2c_remove,
 391        .suspend        = kempld_i2c_suspend,
 392        .resume         = kempld_i2c_resume,
 393};
 394
 395module_platform_driver(kempld_i2c_driver);
 396
 397MODULE_DESCRIPTION("KEM PLD I2C Driver");
 398MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
 399MODULE_LICENSE("GPL");
 400MODULE_ALIAS("platform:kempld_i2c");
 401