1*f4e8afdcSSundar Iyer /* 2*f4e8afdcSSundar Iyer * Copyright (C) ST-Ericsson SA 2010 3*f4e8afdcSSundar Iyer * 4*f4e8afdcSSundar Iyer * License Terms: GNU General Public License, version 2 5*f4e8afdcSSundar Iyer * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson 6*f4e8afdcSSundar Iyer * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson 7*f4e8afdcSSundar Iyer */ 8*f4e8afdcSSundar Iyer 9*f4e8afdcSSundar Iyer #include <linux/module.h> 10*f4e8afdcSSundar Iyer #include <linux/interrupt.h> 11*f4e8afdcSSundar Iyer #include <linux/irq.h> 12*f4e8afdcSSundar Iyer #include <linux/slab.h> 13*f4e8afdcSSundar Iyer #include <linux/i2c.h> 14*f4e8afdcSSundar Iyer #include <linux/mfd/core.h> 15*f4e8afdcSSundar Iyer #include <linux/mfd/tc3589x.h> 16*f4e8afdcSSundar Iyer 17*f4e8afdcSSundar Iyer /** 18*f4e8afdcSSundar Iyer * tc35892_reg_read() - read a single TC35892 register 19*f4e8afdcSSundar Iyer * @tc35892: Device to read from 20*f4e8afdcSSundar Iyer * @reg: Register to read 21*f4e8afdcSSundar Iyer */ 22*f4e8afdcSSundar Iyer int tc35892_reg_read(struct tc35892 *tc35892, u8 reg) 23*f4e8afdcSSundar Iyer { 24*f4e8afdcSSundar Iyer int ret; 25*f4e8afdcSSundar Iyer 26*f4e8afdcSSundar Iyer ret = i2c_smbus_read_byte_data(tc35892->i2c, reg); 27*f4e8afdcSSundar Iyer if (ret < 0) 28*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "failed to read reg %#x: %d\n", 29*f4e8afdcSSundar Iyer reg, ret); 30*f4e8afdcSSundar Iyer 31*f4e8afdcSSundar Iyer return ret; 32*f4e8afdcSSundar Iyer } 33*f4e8afdcSSundar Iyer EXPORT_SYMBOL_GPL(tc35892_reg_read); 34*f4e8afdcSSundar Iyer 35*f4e8afdcSSundar Iyer /** 36*f4e8afdcSSundar Iyer * tc35892_reg_read() - write a single TC35892 register 37*f4e8afdcSSundar Iyer * @tc35892: Device to write to 38*f4e8afdcSSundar Iyer * @reg: Register to read 39*f4e8afdcSSundar Iyer * @data: Value to write 40*f4e8afdcSSundar Iyer */ 41*f4e8afdcSSundar Iyer int tc35892_reg_write(struct tc35892 *tc35892, u8 reg, u8 data) 42*f4e8afdcSSundar Iyer { 43*f4e8afdcSSundar Iyer int ret; 44*f4e8afdcSSundar Iyer 45*f4e8afdcSSundar Iyer ret = i2c_smbus_write_byte_data(tc35892->i2c, reg, data); 46*f4e8afdcSSundar Iyer if (ret < 0) 47*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "failed to write reg %#x: %d\n", 48*f4e8afdcSSundar Iyer reg, ret); 49*f4e8afdcSSundar Iyer 50*f4e8afdcSSundar Iyer return ret; 51*f4e8afdcSSundar Iyer } 52*f4e8afdcSSundar Iyer EXPORT_SYMBOL_GPL(tc35892_reg_write); 53*f4e8afdcSSundar Iyer 54*f4e8afdcSSundar Iyer /** 55*f4e8afdcSSundar Iyer * tc35892_block_read() - read multiple TC35892 registers 56*f4e8afdcSSundar Iyer * @tc35892: Device to read from 57*f4e8afdcSSundar Iyer * @reg: First register 58*f4e8afdcSSundar Iyer * @length: Number of registers 59*f4e8afdcSSundar Iyer * @values: Buffer to write to 60*f4e8afdcSSundar Iyer */ 61*f4e8afdcSSundar Iyer int tc35892_block_read(struct tc35892 *tc35892, u8 reg, u8 length, u8 *values) 62*f4e8afdcSSundar Iyer { 63*f4e8afdcSSundar Iyer int ret; 64*f4e8afdcSSundar Iyer 65*f4e8afdcSSundar Iyer ret = i2c_smbus_read_i2c_block_data(tc35892->i2c, reg, length, values); 66*f4e8afdcSSundar Iyer if (ret < 0) 67*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "failed to read regs %#x: %d\n", 68*f4e8afdcSSundar Iyer reg, ret); 69*f4e8afdcSSundar Iyer 70*f4e8afdcSSundar Iyer return ret; 71*f4e8afdcSSundar Iyer } 72*f4e8afdcSSundar Iyer EXPORT_SYMBOL_GPL(tc35892_block_read); 73*f4e8afdcSSundar Iyer 74*f4e8afdcSSundar Iyer /** 75*f4e8afdcSSundar Iyer * tc35892_block_write() - write multiple TC35892 registers 76*f4e8afdcSSundar Iyer * @tc35892: Device to write to 77*f4e8afdcSSundar Iyer * @reg: First register 78*f4e8afdcSSundar Iyer * @length: Number of registers 79*f4e8afdcSSundar Iyer * @values: Values to write 80*f4e8afdcSSundar Iyer */ 81*f4e8afdcSSundar Iyer int tc35892_block_write(struct tc35892 *tc35892, u8 reg, u8 length, 82*f4e8afdcSSundar Iyer const u8 *values) 83*f4e8afdcSSundar Iyer { 84*f4e8afdcSSundar Iyer int ret; 85*f4e8afdcSSundar Iyer 86*f4e8afdcSSundar Iyer ret = i2c_smbus_write_i2c_block_data(tc35892->i2c, reg, length, 87*f4e8afdcSSundar Iyer values); 88*f4e8afdcSSundar Iyer if (ret < 0) 89*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "failed to write regs %#x: %d\n", 90*f4e8afdcSSundar Iyer reg, ret); 91*f4e8afdcSSundar Iyer 92*f4e8afdcSSundar Iyer return ret; 93*f4e8afdcSSundar Iyer } 94*f4e8afdcSSundar Iyer EXPORT_SYMBOL_GPL(tc35892_block_write); 95*f4e8afdcSSundar Iyer 96*f4e8afdcSSundar Iyer /** 97*f4e8afdcSSundar Iyer * tc35892_set_bits() - set the value of a bitfield in a TC35892 register 98*f4e8afdcSSundar Iyer * @tc35892: Device to write to 99*f4e8afdcSSundar Iyer * @reg: Register to write 100*f4e8afdcSSundar Iyer * @mask: Mask of bits to set 101*f4e8afdcSSundar Iyer * @values: Value to set 102*f4e8afdcSSundar Iyer */ 103*f4e8afdcSSundar Iyer int tc35892_set_bits(struct tc35892 *tc35892, u8 reg, u8 mask, u8 val) 104*f4e8afdcSSundar Iyer { 105*f4e8afdcSSundar Iyer int ret; 106*f4e8afdcSSundar Iyer 107*f4e8afdcSSundar Iyer mutex_lock(&tc35892->lock); 108*f4e8afdcSSundar Iyer 109*f4e8afdcSSundar Iyer ret = tc35892_reg_read(tc35892, reg); 110*f4e8afdcSSundar Iyer if (ret < 0) 111*f4e8afdcSSundar Iyer goto out; 112*f4e8afdcSSundar Iyer 113*f4e8afdcSSundar Iyer ret &= ~mask; 114*f4e8afdcSSundar Iyer ret |= val; 115*f4e8afdcSSundar Iyer 116*f4e8afdcSSundar Iyer ret = tc35892_reg_write(tc35892, reg, ret); 117*f4e8afdcSSundar Iyer 118*f4e8afdcSSundar Iyer out: 119*f4e8afdcSSundar Iyer mutex_unlock(&tc35892->lock); 120*f4e8afdcSSundar Iyer return ret; 121*f4e8afdcSSundar Iyer } 122*f4e8afdcSSundar Iyer EXPORT_SYMBOL_GPL(tc35892_set_bits); 123*f4e8afdcSSundar Iyer 124*f4e8afdcSSundar Iyer static struct resource gpio_resources[] = { 125*f4e8afdcSSundar Iyer { 126*f4e8afdcSSundar Iyer .start = TC35892_INT_GPIIRQ, 127*f4e8afdcSSundar Iyer .end = TC35892_INT_GPIIRQ, 128*f4e8afdcSSundar Iyer .flags = IORESOURCE_IRQ, 129*f4e8afdcSSundar Iyer }, 130*f4e8afdcSSundar Iyer }; 131*f4e8afdcSSundar Iyer 132*f4e8afdcSSundar Iyer static struct mfd_cell tc35892_devs[] = { 133*f4e8afdcSSundar Iyer { 134*f4e8afdcSSundar Iyer .name = "tc35892-gpio", 135*f4e8afdcSSundar Iyer .num_resources = ARRAY_SIZE(gpio_resources), 136*f4e8afdcSSundar Iyer .resources = &gpio_resources[0], 137*f4e8afdcSSundar Iyer }, 138*f4e8afdcSSundar Iyer }; 139*f4e8afdcSSundar Iyer 140*f4e8afdcSSundar Iyer static irqreturn_t tc35892_irq(int irq, void *data) 141*f4e8afdcSSundar Iyer { 142*f4e8afdcSSundar Iyer struct tc35892 *tc35892 = data; 143*f4e8afdcSSundar Iyer int status; 144*f4e8afdcSSundar Iyer 145*f4e8afdcSSundar Iyer status = tc35892_reg_read(tc35892, TC35892_IRQST); 146*f4e8afdcSSundar Iyer if (status < 0) 147*f4e8afdcSSundar Iyer return IRQ_NONE; 148*f4e8afdcSSundar Iyer 149*f4e8afdcSSundar Iyer while (status) { 150*f4e8afdcSSundar Iyer int bit = __ffs(status); 151*f4e8afdcSSundar Iyer 152*f4e8afdcSSundar Iyer handle_nested_irq(tc35892->irq_base + bit); 153*f4e8afdcSSundar Iyer status &= ~(1 << bit); 154*f4e8afdcSSundar Iyer } 155*f4e8afdcSSundar Iyer 156*f4e8afdcSSundar Iyer /* 157*f4e8afdcSSundar Iyer * A dummy read or write (to any register) appears to be necessary to 158*f4e8afdcSSundar Iyer * have the last interrupt clear (for example, GPIO IC write) take 159*f4e8afdcSSundar Iyer * effect. 160*f4e8afdcSSundar Iyer */ 161*f4e8afdcSSundar Iyer tc35892_reg_read(tc35892, TC35892_IRQST); 162*f4e8afdcSSundar Iyer 163*f4e8afdcSSundar Iyer return IRQ_HANDLED; 164*f4e8afdcSSundar Iyer } 165*f4e8afdcSSundar Iyer 166*f4e8afdcSSundar Iyer static void tc35892_irq_dummy(unsigned int irq) 167*f4e8afdcSSundar Iyer { 168*f4e8afdcSSundar Iyer /* No mask/unmask at this level */ 169*f4e8afdcSSundar Iyer } 170*f4e8afdcSSundar Iyer 171*f4e8afdcSSundar Iyer static struct irq_chip tc35892_irq_chip = { 172*f4e8afdcSSundar Iyer .name = "tc35892", 173*f4e8afdcSSundar Iyer .mask = tc35892_irq_dummy, 174*f4e8afdcSSundar Iyer .unmask = tc35892_irq_dummy, 175*f4e8afdcSSundar Iyer }; 176*f4e8afdcSSundar Iyer 177*f4e8afdcSSundar Iyer static int tc35892_irq_init(struct tc35892 *tc35892) 178*f4e8afdcSSundar Iyer { 179*f4e8afdcSSundar Iyer int base = tc35892->irq_base; 180*f4e8afdcSSundar Iyer int irq; 181*f4e8afdcSSundar Iyer 182*f4e8afdcSSundar Iyer for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) { 183*f4e8afdcSSundar Iyer set_irq_chip_data(irq, tc35892); 184*f4e8afdcSSundar Iyer set_irq_chip_and_handler(irq, &tc35892_irq_chip, 185*f4e8afdcSSundar Iyer handle_edge_irq); 186*f4e8afdcSSundar Iyer set_irq_nested_thread(irq, 1); 187*f4e8afdcSSundar Iyer #ifdef CONFIG_ARM 188*f4e8afdcSSundar Iyer set_irq_flags(irq, IRQF_VALID); 189*f4e8afdcSSundar Iyer #else 190*f4e8afdcSSundar Iyer set_irq_noprobe(irq); 191*f4e8afdcSSundar Iyer #endif 192*f4e8afdcSSundar Iyer } 193*f4e8afdcSSundar Iyer 194*f4e8afdcSSundar Iyer return 0; 195*f4e8afdcSSundar Iyer } 196*f4e8afdcSSundar Iyer 197*f4e8afdcSSundar Iyer static void tc35892_irq_remove(struct tc35892 *tc35892) 198*f4e8afdcSSundar Iyer { 199*f4e8afdcSSundar Iyer int base = tc35892->irq_base; 200*f4e8afdcSSundar Iyer int irq; 201*f4e8afdcSSundar Iyer 202*f4e8afdcSSundar Iyer for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) { 203*f4e8afdcSSundar Iyer #ifdef CONFIG_ARM 204*f4e8afdcSSundar Iyer set_irq_flags(irq, 0); 205*f4e8afdcSSundar Iyer #endif 206*f4e8afdcSSundar Iyer set_irq_chip_and_handler(irq, NULL, NULL); 207*f4e8afdcSSundar Iyer set_irq_chip_data(irq, NULL); 208*f4e8afdcSSundar Iyer } 209*f4e8afdcSSundar Iyer } 210*f4e8afdcSSundar Iyer 211*f4e8afdcSSundar Iyer static int tc35892_chip_init(struct tc35892 *tc35892) 212*f4e8afdcSSundar Iyer { 213*f4e8afdcSSundar Iyer int manf, ver, ret; 214*f4e8afdcSSundar Iyer 215*f4e8afdcSSundar Iyer manf = tc35892_reg_read(tc35892, TC35892_MANFCODE); 216*f4e8afdcSSundar Iyer if (manf < 0) 217*f4e8afdcSSundar Iyer return manf; 218*f4e8afdcSSundar Iyer 219*f4e8afdcSSundar Iyer ver = tc35892_reg_read(tc35892, TC35892_VERSION); 220*f4e8afdcSSundar Iyer if (ver < 0) 221*f4e8afdcSSundar Iyer return ver; 222*f4e8afdcSSundar Iyer 223*f4e8afdcSSundar Iyer if (manf != TC35892_MANFCODE_MAGIC) { 224*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "unknown manufacturer: %#x\n", manf); 225*f4e8afdcSSundar Iyer return -EINVAL; 226*f4e8afdcSSundar Iyer } 227*f4e8afdcSSundar Iyer 228*f4e8afdcSSundar Iyer dev_info(tc35892->dev, "manufacturer: %#x, version: %#x\n", manf, ver); 229*f4e8afdcSSundar Iyer 230*f4e8afdcSSundar Iyer /* Put everything except the IRQ module into reset */ 231*f4e8afdcSSundar Iyer ret = tc35892_reg_write(tc35892, TC35892_RSTCTRL, 232*f4e8afdcSSundar Iyer TC35892_RSTCTRL_TIMRST 233*f4e8afdcSSundar Iyer | TC35892_RSTCTRL_ROTRST 234*f4e8afdcSSundar Iyer | TC35892_RSTCTRL_KBDRST 235*f4e8afdcSSundar Iyer | TC35892_RSTCTRL_GPIRST); 236*f4e8afdcSSundar Iyer if (ret < 0) 237*f4e8afdcSSundar Iyer return ret; 238*f4e8afdcSSundar Iyer 239*f4e8afdcSSundar Iyer /* Clear the reset interrupt. */ 240*f4e8afdcSSundar Iyer return tc35892_reg_write(tc35892, TC35892_RSTINTCLR, 0x1); 241*f4e8afdcSSundar Iyer } 242*f4e8afdcSSundar Iyer 243*f4e8afdcSSundar Iyer static int __devinit tc35892_probe(struct i2c_client *i2c, 244*f4e8afdcSSundar Iyer const struct i2c_device_id *id) 245*f4e8afdcSSundar Iyer { 246*f4e8afdcSSundar Iyer struct tc35892_platform_data *pdata = i2c->dev.platform_data; 247*f4e8afdcSSundar Iyer struct tc35892 *tc35892; 248*f4e8afdcSSundar Iyer int ret; 249*f4e8afdcSSundar Iyer 250*f4e8afdcSSundar Iyer if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA 251*f4e8afdcSSundar Iyer | I2C_FUNC_SMBUS_I2C_BLOCK)) 252*f4e8afdcSSundar Iyer return -EIO; 253*f4e8afdcSSundar Iyer 254*f4e8afdcSSundar Iyer tc35892 = kzalloc(sizeof(struct tc35892), GFP_KERNEL); 255*f4e8afdcSSundar Iyer if (!tc35892) 256*f4e8afdcSSundar Iyer return -ENOMEM; 257*f4e8afdcSSundar Iyer 258*f4e8afdcSSundar Iyer mutex_init(&tc35892->lock); 259*f4e8afdcSSundar Iyer 260*f4e8afdcSSundar Iyer tc35892->dev = &i2c->dev; 261*f4e8afdcSSundar Iyer tc35892->i2c = i2c; 262*f4e8afdcSSundar Iyer tc35892->pdata = pdata; 263*f4e8afdcSSundar Iyer tc35892->irq_base = pdata->irq_base; 264*f4e8afdcSSundar Iyer tc35892->num_gpio = id->driver_data; 265*f4e8afdcSSundar Iyer 266*f4e8afdcSSundar Iyer i2c_set_clientdata(i2c, tc35892); 267*f4e8afdcSSundar Iyer 268*f4e8afdcSSundar Iyer ret = tc35892_chip_init(tc35892); 269*f4e8afdcSSundar Iyer if (ret) 270*f4e8afdcSSundar Iyer goto out_free; 271*f4e8afdcSSundar Iyer 272*f4e8afdcSSundar Iyer ret = tc35892_irq_init(tc35892); 273*f4e8afdcSSundar Iyer if (ret) 274*f4e8afdcSSundar Iyer goto out_free; 275*f4e8afdcSSundar Iyer 276*f4e8afdcSSundar Iyer ret = request_threaded_irq(tc35892->i2c->irq, NULL, tc35892_irq, 277*f4e8afdcSSundar Iyer IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 278*f4e8afdcSSundar Iyer "tc35892", tc35892); 279*f4e8afdcSSundar Iyer if (ret) { 280*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "failed to request IRQ: %d\n", ret); 281*f4e8afdcSSundar Iyer goto out_removeirq; 282*f4e8afdcSSundar Iyer } 283*f4e8afdcSSundar Iyer 284*f4e8afdcSSundar Iyer ret = mfd_add_devices(tc35892->dev, -1, tc35892_devs, 285*f4e8afdcSSundar Iyer ARRAY_SIZE(tc35892_devs), NULL, 286*f4e8afdcSSundar Iyer tc35892->irq_base); 287*f4e8afdcSSundar Iyer if (ret) { 288*f4e8afdcSSundar Iyer dev_err(tc35892->dev, "failed to add children\n"); 289*f4e8afdcSSundar Iyer goto out_freeirq; 290*f4e8afdcSSundar Iyer } 291*f4e8afdcSSundar Iyer 292*f4e8afdcSSundar Iyer return 0; 293*f4e8afdcSSundar Iyer 294*f4e8afdcSSundar Iyer out_freeirq: 295*f4e8afdcSSundar Iyer free_irq(tc35892->i2c->irq, tc35892); 296*f4e8afdcSSundar Iyer out_removeirq: 297*f4e8afdcSSundar Iyer tc35892_irq_remove(tc35892); 298*f4e8afdcSSundar Iyer out_free: 299*f4e8afdcSSundar Iyer kfree(tc35892); 300*f4e8afdcSSundar Iyer return ret; 301*f4e8afdcSSundar Iyer } 302*f4e8afdcSSundar Iyer 303*f4e8afdcSSundar Iyer static int __devexit tc35892_remove(struct i2c_client *client) 304*f4e8afdcSSundar Iyer { 305*f4e8afdcSSundar Iyer struct tc35892 *tc35892 = i2c_get_clientdata(client); 306*f4e8afdcSSundar Iyer 307*f4e8afdcSSundar Iyer mfd_remove_devices(tc35892->dev); 308*f4e8afdcSSundar Iyer 309*f4e8afdcSSundar Iyer free_irq(tc35892->i2c->irq, tc35892); 310*f4e8afdcSSundar Iyer tc35892_irq_remove(tc35892); 311*f4e8afdcSSundar Iyer 312*f4e8afdcSSundar Iyer kfree(tc35892); 313*f4e8afdcSSundar Iyer 314*f4e8afdcSSundar Iyer return 0; 315*f4e8afdcSSundar Iyer } 316*f4e8afdcSSundar Iyer 317*f4e8afdcSSundar Iyer static const struct i2c_device_id tc35892_id[] = { 318*f4e8afdcSSundar Iyer { "tc35892", 24 }, 319*f4e8afdcSSundar Iyer { } 320*f4e8afdcSSundar Iyer }; 321*f4e8afdcSSundar Iyer MODULE_DEVICE_TABLE(i2c, tc35892_id); 322*f4e8afdcSSundar Iyer 323*f4e8afdcSSundar Iyer static struct i2c_driver tc35892_driver = { 324*f4e8afdcSSundar Iyer .driver.name = "tc35892", 325*f4e8afdcSSundar Iyer .driver.owner = THIS_MODULE, 326*f4e8afdcSSundar Iyer .probe = tc35892_probe, 327*f4e8afdcSSundar Iyer .remove = __devexit_p(tc35892_remove), 328*f4e8afdcSSundar Iyer .id_table = tc35892_id, 329*f4e8afdcSSundar Iyer }; 330*f4e8afdcSSundar Iyer 331*f4e8afdcSSundar Iyer static int __init tc35892_init(void) 332*f4e8afdcSSundar Iyer { 333*f4e8afdcSSundar Iyer return i2c_add_driver(&tc35892_driver); 334*f4e8afdcSSundar Iyer } 335*f4e8afdcSSundar Iyer subsys_initcall(tc35892_init); 336*f4e8afdcSSundar Iyer 337*f4e8afdcSSundar Iyer static void __exit tc35892_exit(void) 338*f4e8afdcSSundar Iyer { 339*f4e8afdcSSundar Iyer i2c_del_driver(&tc35892_driver); 340*f4e8afdcSSundar Iyer } 341*f4e8afdcSSundar Iyer module_exit(tc35892_exit); 342*f4e8afdcSSundar Iyer 343*f4e8afdcSSundar Iyer MODULE_LICENSE("GPL v2"); 344*f4e8afdcSSundar Iyer MODULE_DESCRIPTION("TC35892 MFD core driver"); 345*f4e8afdcSSundar Iyer MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); 346