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