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