Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * I2C bus driver for Kontron COM modules
0004  *
0005  * Copyright (c) 2010-2013 Kontron Europe GmbH
0006  * Author: Michael Brunner <michael.brunner@kontron.com>
0007  *
0008  * The driver is based on the i2c-ocores driver by Peter Korsgaard.
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/i2c.h>
0014 #include <linux/delay.h>
0015 #include <linux/mfd/kempld.h>
0016 
0017 #define KEMPLD_I2C_PRELOW   0x0b
0018 #define KEMPLD_I2C_PREHIGH  0x0c
0019 #define KEMPLD_I2C_DATA     0x0e
0020 
0021 #define KEMPLD_I2C_CTRL     0x0d
0022 #define I2C_CTRL_IEN        0x40
0023 #define I2C_CTRL_EN     0x80
0024 
0025 #define KEMPLD_I2C_STAT     0x0f
0026 #define I2C_STAT_IF     0x01
0027 #define I2C_STAT_TIP        0x02
0028 #define I2C_STAT_ARBLOST    0x20
0029 #define I2C_STAT_BUSY       0x40
0030 #define I2C_STAT_NACK       0x80
0031 
0032 #define KEMPLD_I2C_CMD      0x0f
0033 #define I2C_CMD_START       0x91
0034 #define I2C_CMD_STOP        0x41
0035 #define I2C_CMD_READ        0x21
0036 #define I2C_CMD_WRITE       0x11
0037 #define I2C_CMD_READ_ACK    0x21
0038 #define I2C_CMD_READ_NACK   0x29
0039 #define I2C_CMD_IACK        0x01
0040 
0041 #define KEMPLD_I2C_FREQ_MAX 2700    /* 2.7 mHz */
0042 #define KEMPLD_I2C_FREQ_STD 100 /* 100 kHz */
0043 
0044 enum {
0045     STATE_DONE = 0,
0046     STATE_INIT,
0047     STATE_ADDR,
0048     STATE_ADDR10,
0049     STATE_START,
0050     STATE_WRITE,
0051     STATE_READ,
0052     STATE_ERROR,
0053 };
0054 
0055 struct kempld_i2c_data {
0056     struct device           *dev;
0057     struct kempld_device_data   *pld;
0058     struct i2c_adapter      adap;
0059     struct i2c_msg          *msg;
0060     int             pos;
0061     int             nmsgs;
0062     int             state;
0063     bool                was_active;
0064 };
0065 
0066 static unsigned int bus_frequency = KEMPLD_I2C_FREQ_STD;
0067 module_param(bus_frequency, uint, 0);
0068 MODULE_PARM_DESC(bus_frequency, "Set I2C bus frequency in kHz (default="
0069                 __MODULE_STRING(KEMPLD_I2C_FREQ_STD)")");
0070 
0071 static int i2c_bus = -1;
0072 module_param(i2c_bus, int, 0);
0073 MODULE_PARM_DESC(i2c_bus, "Set I2C bus number (default=-1 for dynamic assignment)");
0074 
0075 static bool i2c_gpio_mux;
0076 module_param(i2c_gpio_mux, bool, 0);
0077 MODULE_PARM_DESC(i2c_gpio_mux, "Enable I2C port on GPIO out (default=false)");
0078 
0079 /*
0080  * kempld_get_mutex must be called prior to calling this function.
0081  */
0082 static int kempld_i2c_process(struct kempld_i2c_data *i2c)
0083 {
0084     struct kempld_device_data *pld = i2c->pld;
0085     u8 stat = kempld_read8(pld, KEMPLD_I2C_STAT);
0086     struct i2c_msg *msg = i2c->msg;
0087     u8 addr;
0088 
0089     /* Ready? */
0090     if (stat & I2C_STAT_TIP)
0091         return -EBUSY;
0092 
0093     if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) {
0094         /* Stop has been sent */
0095         kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
0096         if (i2c->state == STATE_ERROR)
0097             return -EIO;
0098         return 0;
0099     }
0100 
0101     /* Error? */
0102     if (stat & I2C_STAT_ARBLOST) {
0103         i2c->state = STATE_ERROR;
0104         kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
0105         return -EAGAIN;
0106     }
0107 
0108     if (i2c->state == STATE_INIT) {
0109         if (stat & I2C_STAT_BUSY)
0110             return -EBUSY;
0111 
0112         i2c->state = STATE_ADDR;
0113     }
0114 
0115     if (i2c->state == STATE_ADDR) {
0116         /* 10 bit address? */
0117         if (i2c->msg->flags & I2C_M_TEN) {
0118             addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6);
0119             /* Set read bit if necessary */
0120             addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;
0121             i2c->state = STATE_ADDR10;
0122         } else {
0123             addr = i2c_8bit_addr_from_msg(i2c->msg);
0124             i2c->state = STATE_START;
0125         }
0126 
0127         kempld_write8(pld, KEMPLD_I2C_DATA, addr);
0128         kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_START);
0129 
0130         return 0;
0131     }
0132 
0133     /* Second part of 10 bit addressing */
0134     if (i2c->state == STATE_ADDR10) {
0135         kempld_write8(pld, KEMPLD_I2C_DATA, i2c->msg->addr & 0xff);
0136         kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
0137 
0138         i2c->state = STATE_START;
0139         return 0;
0140     }
0141 
0142     if (i2c->state == STATE_START || i2c->state == STATE_WRITE) {
0143         i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
0144 
0145         if (stat & I2C_STAT_NACK) {
0146             i2c->state = STATE_ERROR;
0147             kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
0148             return -ENXIO;
0149         }
0150     } else {
0151         msg->buf[i2c->pos++] = kempld_read8(pld, KEMPLD_I2C_DATA);
0152     }
0153 
0154     if (i2c->pos >= msg->len) {
0155         i2c->nmsgs--;
0156         i2c->msg++;
0157         i2c->pos = 0;
0158         msg = i2c->msg;
0159 
0160         if (i2c->nmsgs) {
0161             if (!(msg->flags & I2C_M_NOSTART)) {
0162                 i2c->state = STATE_ADDR;
0163                 return 0;
0164             } else {
0165                 i2c->state = (msg->flags & I2C_M_RD)
0166                     ? STATE_READ : STATE_WRITE;
0167             }
0168         } else {
0169             i2c->state = STATE_DONE;
0170             kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
0171             return 0;
0172         }
0173     }
0174 
0175     if (i2c->state == STATE_READ) {
0176         kempld_write8(pld, KEMPLD_I2C_CMD, i2c->pos == (msg->len - 1) ?
0177                   I2C_CMD_READ_NACK : I2C_CMD_READ_ACK);
0178     } else {
0179         kempld_write8(pld, KEMPLD_I2C_DATA, msg->buf[i2c->pos++]);
0180         kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
0181     }
0182 
0183     return 0;
0184 }
0185 
0186 static int kempld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
0187                 int num)
0188 {
0189     struct kempld_i2c_data *i2c = i2c_get_adapdata(adap);
0190     struct kempld_device_data *pld = i2c->pld;
0191     unsigned long timeout = jiffies + HZ;
0192     int ret;
0193 
0194     i2c->msg = msgs;
0195     i2c->pos = 0;
0196     i2c->nmsgs = num;
0197     i2c->state = STATE_INIT;
0198 
0199     /* Handle the transfer */
0200     while (time_before(jiffies, timeout)) {
0201         kempld_get_mutex(pld);
0202         ret = kempld_i2c_process(i2c);
0203         kempld_release_mutex(pld);
0204 
0205         if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR)
0206             return (i2c->state == STATE_DONE) ? num : ret;
0207 
0208         if (ret == 0)
0209             timeout = jiffies + HZ;
0210 
0211         usleep_range(5, 15);
0212     }
0213 
0214     i2c->state = STATE_ERROR;
0215 
0216     return -ETIMEDOUT;
0217 }
0218 
0219 /*
0220  * kempld_get_mutex must be called prior to calling this function.
0221  */
0222 static void kempld_i2c_device_init(struct kempld_i2c_data *i2c)
0223 {
0224     struct kempld_device_data *pld = i2c->pld;
0225     u16 prescale_corr;
0226     long prescale;
0227     u8 ctrl;
0228     u8 stat;
0229     u8 cfg;
0230 
0231     /* Make sure the device is disabled */
0232     ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
0233     ctrl &= ~(I2C_CTRL_EN | I2C_CTRL_IEN);
0234     kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
0235 
0236     if (bus_frequency > KEMPLD_I2C_FREQ_MAX)
0237         bus_frequency = KEMPLD_I2C_FREQ_MAX;
0238 
0239     if (pld->info.spec_major == 1)
0240         prescale = pld->pld_clock / (bus_frequency * 5) - 1000;
0241     else
0242         prescale = pld->pld_clock / (bus_frequency * 4) - 3000;
0243 
0244     if (prescale < 0)
0245         prescale = 0;
0246 
0247     /* Round to the best matching value */
0248     prescale_corr = prescale / 1000;
0249     if (prescale % 1000 >= 500)
0250         prescale_corr++;
0251 
0252     kempld_write8(pld, KEMPLD_I2C_PRELOW, prescale_corr & 0xff);
0253     kempld_write8(pld, KEMPLD_I2C_PREHIGH, prescale_corr >> 8);
0254 
0255     /* Activate I2C bus output on GPIO pins */
0256     cfg = kempld_read8(pld, KEMPLD_CFG);
0257     if (i2c_gpio_mux)
0258         cfg |= KEMPLD_CFG_GPIO_I2C_MUX;
0259     else
0260         cfg &= ~KEMPLD_CFG_GPIO_I2C_MUX;
0261     kempld_write8(pld, KEMPLD_CFG, cfg);
0262 
0263     /* Enable the device */
0264     kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
0265     ctrl |= I2C_CTRL_EN;
0266     kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
0267 
0268     stat = kempld_read8(pld, KEMPLD_I2C_STAT);
0269     if (stat & I2C_STAT_BUSY)
0270         kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
0271 }
0272 
0273 static u32 kempld_i2c_func(struct i2c_adapter *adap)
0274 {
0275     return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
0276 }
0277 
0278 static const struct i2c_algorithm kempld_i2c_algorithm = {
0279     .master_xfer    = kempld_i2c_xfer,
0280     .functionality  = kempld_i2c_func,
0281 };
0282 
0283 static const struct i2c_adapter kempld_i2c_adapter = {
0284     .owner      = THIS_MODULE,
0285     .name       = "i2c-kempld",
0286     .class      = I2C_CLASS_HWMON | I2C_CLASS_SPD |
0287               I2C_CLASS_DEPRECATED,
0288     .algo       = &kempld_i2c_algorithm,
0289 };
0290 
0291 static int kempld_i2c_probe(struct platform_device *pdev)
0292 {
0293     struct kempld_device_data *pld = dev_get_drvdata(pdev->dev.parent);
0294     struct kempld_i2c_data *i2c;
0295     int ret;
0296     u8 ctrl;
0297 
0298     i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
0299     if (!i2c)
0300         return -ENOMEM;
0301 
0302     i2c->pld = pld;
0303     i2c->dev = &pdev->dev;
0304     i2c->adap = kempld_i2c_adapter;
0305     i2c->adap.dev.parent = i2c->dev;
0306     ACPI_COMPANION_SET(&i2c->adap.dev, ACPI_COMPANION(&pdev->dev));
0307     i2c_set_adapdata(&i2c->adap, i2c);
0308     platform_set_drvdata(pdev, i2c);
0309 
0310     kempld_get_mutex(pld);
0311     ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
0312 
0313     if (ctrl & I2C_CTRL_EN)
0314         i2c->was_active = true;
0315 
0316     kempld_i2c_device_init(i2c);
0317     kempld_release_mutex(pld);
0318 
0319     /* Add I2C adapter to I2C tree */
0320     if (i2c_bus >= -1)
0321         i2c->adap.nr = i2c_bus;
0322     ret = i2c_add_numbered_adapter(&i2c->adap);
0323     if (ret)
0324         return ret;
0325 
0326     dev_info(i2c->dev, "I2C bus initialized at %dkHz\n",
0327          bus_frequency);
0328 
0329     return 0;
0330 }
0331 
0332 static int kempld_i2c_remove(struct platform_device *pdev)
0333 {
0334     struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
0335     struct kempld_device_data *pld = i2c->pld;
0336     u8 ctrl;
0337 
0338     kempld_get_mutex(pld);
0339     /*
0340      * Disable I2C logic if it was not activated before the
0341      * driver loaded
0342      */
0343     if (!i2c->was_active) {
0344         ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
0345         ctrl &= ~I2C_CTRL_EN;
0346         kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
0347     }
0348     kempld_release_mutex(pld);
0349 
0350     i2c_del_adapter(&i2c->adap);
0351 
0352     return 0;
0353 }
0354 
0355 #ifdef CONFIG_PM
0356 static int kempld_i2c_suspend(struct platform_device *pdev, pm_message_t state)
0357 {
0358     struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
0359     struct kempld_device_data *pld = i2c->pld;
0360     u8 ctrl;
0361 
0362     kempld_get_mutex(pld);
0363     ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
0364     ctrl &= ~I2C_CTRL_EN;
0365     kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
0366     kempld_release_mutex(pld);
0367 
0368     return 0;
0369 }
0370 
0371 static int kempld_i2c_resume(struct platform_device *pdev)
0372 {
0373     struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
0374     struct kempld_device_data *pld = i2c->pld;
0375 
0376     kempld_get_mutex(pld);
0377     kempld_i2c_device_init(i2c);
0378     kempld_release_mutex(pld);
0379 
0380     return 0;
0381 }
0382 #else
0383 #define kempld_i2c_suspend  NULL
0384 #define kempld_i2c_resume   NULL
0385 #endif
0386 
0387 static struct platform_driver kempld_i2c_driver = {
0388     .driver = {
0389         .name = "kempld-i2c",
0390     },
0391     .probe      = kempld_i2c_probe,
0392     .remove     = kempld_i2c_remove,
0393     .suspend    = kempld_i2c_suspend,
0394     .resume     = kempld_i2c_resume,
0395 };
0396 
0397 module_platform_driver(kempld_i2c_driver);
0398 
0399 MODULE_DESCRIPTION("KEM PLD I2C Driver");
0400 MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
0401 MODULE_LICENSE("GPL");
0402 MODULE_ALIAS("platform:kempld_i2c");