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