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/irqdomain.h> 13 #include <linux/slab.h> 14 #include <linux/i2c.h> 15 #include <linux/mfd/core.h> 16 #include <linux/mfd/tc3589x.h> 17 18 #define TC3589x_CLKMODE_MODCTL_SLEEP 0x0 19 #define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0) 20 21 /** 22 * tc3589x_reg_read() - read a single TC3589x register 23 * @tc3589x: Device to read from 24 * @reg: Register to read 25 */ 26 int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg) 27 { 28 int ret; 29 30 ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg); 31 if (ret < 0) 32 dev_err(tc3589x->dev, "failed to read reg %#x: %d\n", 33 reg, ret); 34 35 return ret; 36 } 37 EXPORT_SYMBOL_GPL(tc3589x_reg_read); 38 39 /** 40 * tc3589x_reg_read() - write a single TC3589x register 41 * @tc3589x: Device to write to 42 * @reg: Register to read 43 * @data: Value to write 44 */ 45 int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data) 46 { 47 int ret; 48 49 ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data); 50 if (ret < 0) 51 dev_err(tc3589x->dev, "failed to write reg %#x: %d\n", 52 reg, ret); 53 54 return ret; 55 } 56 EXPORT_SYMBOL_GPL(tc3589x_reg_write); 57 58 /** 59 * tc3589x_block_read() - read multiple TC3589x registers 60 * @tc3589x: Device to read from 61 * @reg: First register 62 * @length: Number of registers 63 * @values: Buffer to write to 64 */ 65 int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values) 66 { 67 int ret; 68 69 ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values); 70 if (ret < 0) 71 dev_err(tc3589x->dev, "failed to read regs %#x: %d\n", 72 reg, ret); 73 74 return ret; 75 } 76 EXPORT_SYMBOL_GPL(tc3589x_block_read); 77 78 /** 79 * tc3589x_block_write() - write multiple TC3589x registers 80 * @tc3589x: Device to write to 81 * @reg: First register 82 * @length: Number of registers 83 * @values: Values to write 84 */ 85 int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length, 86 const u8 *values) 87 { 88 int ret; 89 90 ret = i2c_smbus_write_i2c_block_data(tc3589x->i2c, reg, length, 91 values); 92 if (ret < 0) 93 dev_err(tc3589x->dev, "failed to write regs %#x: %d\n", 94 reg, ret); 95 96 return ret; 97 } 98 EXPORT_SYMBOL_GPL(tc3589x_block_write); 99 100 /** 101 * tc3589x_set_bits() - set the value of a bitfield in a TC3589x register 102 * @tc3589x: Device to write to 103 * @reg: Register to write 104 * @mask: Mask of bits to set 105 * @values: Value to set 106 */ 107 int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val) 108 { 109 int ret; 110 111 mutex_lock(&tc3589x->lock); 112 113 ret = tc3589x_reg_read(tc3589x, reg); 114 if (ret < 0) 115 goto out; 116 117 ret &= ~mask; 118 ret |= val; 119 120 ret = tc3589x_reg_write(tc3589x, reg, ret); 121 122 out: 123 mutex_unlock(&tc3589x->lock); 124 return ret; 125 } 126 EXPORT_SYMBOL_GPL(tc3589x_set_bits); 127 128 static struct resource gpio_resources[] = { 129 { 130 .start = TC3589x_INT_GPIIRQ, 131 .end = TC3589x_INT_GPIIRQ, 132 .flags = IORESOURCE_IRQ, 133 }, 134 }; 135 136 static struct resource keypad_resources[] = { 137 { 138 .start = TC3589x_INT_KBDIRQ, 139 .end = TC3589x_INT_KBDIRQ, 140 .flags = IORESOURCE_IRQ, 141 }, 142 }; 143 144 static struct mfd_cell tc3589x_dev_gpio[] = { 145 { 146 .name = "tc3589x-gpio", 147 .num_resources = ARRAY_SIZE(gpio_resources), 148 .resources = &gpio_resources[0], 149 }, 150 }; 151 152 static struct mfd_cell tc3589x_dev_keypad[] = { 153 { 154 .name = "tc3589x-keypad", 155 .num_resources = ARRAY_SIZE(keypad_resources), 156 .resources = &keypad_resources[0], 157 }, 158 }; 159 160 static irqreturn_t tc3589x_irq(int irq, void *data) 161 { 162 struct tc3589x *tc3589x = data; 163 int status; 164 165 again: 166 status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); 167 if (status < 0) 168 return IRQ_NONE; 169 170 while (status) { 171 int bit = __ffs(status); 172 int virq = irq_create_mapping(tc3589x->domain, bit); 173 174 handle_nested_irq(virq); 175 status &= ~(1 << bit); 176 } 177 178 /* 179 * A dummy read or write (to any register) appears to be necessary to 180 * have the last interrupt clear (for example, GPIO IC write) take 181 * effect. In such a case, recheck for any interrupt which is still 182 * pending. 183 */ 184 status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); 185 if (status) 186 goto again; 187 188 return IRQ_HANDLED; 189 } 190 191 static int tc3589x_irq_map(struct irq_domain *d, unsigned int virq, 192 irq_hw_number_t hwirq) 193 { 194 struct tc3589x *tc3589x = d->host_data; 195 196 irq_set_chip_data(virq, tc3589x); 197 irq_set_chip_and_handler(virq, &dummy_irq_chip, 198 handle_edge_irq); 199 irq_set_nested_thread(virq, 1); 200 #ifdef CONFIG_ARM 201 set_irq_flags(virq, IRQF_VALID); 202 #else 203 irq_set_noprobe(virq); 204 #endif 205 206 return 0; 207 } 208 209 static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq) 210 { 211 #ifdef CONFIG_ARM 212 set_irq_flags(virq, 0); 213 #endif 214 irq_set_chip_and_handler(virq, NULL, NULL); 215 irq_set_chip_data(virq, NULL); 216 } 217 218 static struct irq_domain_ops tc3589x_irq_ops = { 219 .map = tc3589x_irq_map, 220 .unmap = tc3589x_irq_unmap, 221 .xlate = irq_domain_xlate_twocell, 222 }; 223 224 static int tc3589x_irq_init(struct tc3589x *tc3589x) 225 { 226 int base = tc3589x->irq_base; 227 228 if (base) { 229 tc3589x->domain = irq_domain_add_legacy( 230 NULL, TC3589x_NR_INTERNAL_IRQS, base, 231 0, &tc3589x_irq_ops, tc3589x); 232 } 233 else { 234 tc3589x->domain = irq_domain_add_linear( 235 NULL, TC3589x_NR_INTERNAL_IRQS, 236 &tc3589x_irq_ops, tc3589x); 237 } 238 239 if (!tc3589x->domain) { 240 dev_err(tc3589x->dev, "Failed to create irqdomain\n"); 241 return -ENOSYS; 242 } 243 244 return 0; 245 } 246 247 static int tc3589x_chip_init(struct tc3589x *tc3589x) 248 { 249 int manf, ver, ret; 250 251 manf = tc3589x_reg_read(tc3589x, TC3589x_MANFCODE); 252 if (manf < 0) 253 return manf; 254 255 ver = tc3589x_reg_read(tc3589x, TC3589x_VERSION); 256 if (ver < 0) 257 return ver; 258 259 if (manf != TC3589x_MANFCODE_MAGIC) { 260 dev_err(tc3589x->dev, "unknown manufacturer: %#x\n", manf); 261 return -EINVAL; 262 } 263 264 dev_info(tc3589x->dev, "manufacturer: %#x, version: %#x\n", manf, ver); 265 266 /* 267 * Put everything except the IRQ module into reset; 268 * also spare the GPIO module for any pin initialization 269 * done during pre-kernel boot 270 */ 271 ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL, 272 TC3589x_RSTCTRL_TIMRST 273 | TC3589x_RSTCTRL_ROTRST 274 | TC3589x_RSTCTRL_KBDRST); 275 if (ret < 0) 276 return ret; 277 278 /* Clear the reset interrupt. */ 279 return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1); 280 } 281 282 static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) 283 { 284 int ret = 0; 285 unsigned int blocks = tc3589x->pdata->block; 286 287 if (blocks & TC3589x_BLOCK_GPIO) { 288 ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, 289 ARRAY_SIZE(tc3589x_dev_gpio), NULL, 290 tc3589x->irq_base, tc3589x->domain); 291 if (ret) { 292 dev_err(tc3589x->dev, "failed to add gpio child\n"); 293 return ret; 294 } 295 dev_info(tc3589x->dev, "added gpio block\n"); 296 } 297 298 if (blocks & TC3589x_BLOCK_KEYPAD) { 299 ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, 300 ARRAY_SIZE(tc3589x_dev_keypad), NULL, 301 tc3589x->irq_base, tc3589x->domain); 302 if (ret) { 303 dev_err(tc3589x->dev, "failed to keypad child\n"); 304 return ret; 305 } 306 dev_info(tc3589x->dev, "added keypad block\n"); 307 } 308 309 return ret; 310 } 311 312 static int __devinit tc3589x_probe(struct i2c_client *i2c, 313 const struct i2c_device_id *id) 314 { 315 struct tc3589x_platform_data *pdata = i2c->dev.platform_data; 316 struct tc3589x *tc3589x; 317 int ret; 318 319 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA 320 | I2C_FUNC_SMBUS_I2C_BLOCK)) 321 return -EIO; 322 323 tc3589x = kzalloc(sizeof(struct tc3589x), GFP_KERNEL); 324 if (!tc3589x) 325 return -ENOMEM; 326 327 mutex_init(&tc3589x->lock); 328 329 tc3589x->dev = &i2c->dev; 330 tc3589x->i2c = i2c; 331 tc3589x->pdata = pdata; 332 tc3589x->irq_base = pdata->irq_base; 333 tc3589x->num_gpio = id->driver_data; 334 335 i2c_set_clientdata(i2c, tc3589x); 336 337 ret = tc3589x_chip_init(tc3589x); 338 if (ret) 339 goto out_free; 340 341 ret = tc3589x_irq_init(tc3589x); 342 if (ret) 343 goto out_free; 344 345 ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq, 346 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 347 "tc3589x", tc3589x); 348 if (ret) { 349 dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret); 350 goto out_free; 351 } 352 353 ret = tc3589x_device_init(tc3589x); 354 if (ret) { 355 dev_err(tc3589x->dev, "failed to add child devices\n"); 356 goto out_freeirq; 357 } 358 359 return 0; 360 361 out_freeirq: 362 free_irq(tc3589x->i2c->irq, tc3589x); 363 out_free: 364 kfree(tc3589x); 365 return ret; 366 } 367 368 static int __devexit tc3589x_remove(struct i2c_client *client) 369 { 370 struct tc3589x *tc3589x = i2c_get_clientdata(client); 371 372 mfd_remove_devices(tc3589x->dev); 373 374 free_irq(tc3589x->i2c->irq, tc3589x); 375 376 kfree(tc3589x); 377 378 return 0; 379 } 380 381 #ifdef CONFIG_PM_SLEEP 382 static int tc3589x_suspend(struct device *dev) 383 { 384 struct tc3589x *tc3589x = dev_get_drvdata(dev); 385 struct i2c_client *client = tc3589x->i2c; 386 int ret = 0; 387 388 /* put the system to sleep mode */ 389 if (!device_may_wakeup(&client->dev)) 390 ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, 391 TC3589x_CLKMODE_MODCTL_SLEEP); 392 393 return ret; 394 } 395 396 static int tc3589x_resume(struct device *dev) 397 { 398 struct tc3589x *tc3589x = dev_get_drvdata(dev); 399 struct i2c_client *client = tc3589x->i2c; 400 int ret = 0; 401 402 /* enable the system into operation */ 403 if (!device_may_wakeup(&client->dev)) 404 ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, 405 TC3589x_CLKMODE_MODCTL_OPERATION); 406 407 return ret; 408 } 409 #endif 410 411 static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume); 412 413 static const struct i2c_device_id tc3589x_id[] = { 414 { "tc3589x", 24 }, 415 { } 416 }; 417 MODULE_DEVICE_TABLE(i2c, tc3589x_id); 418 419 static struct i2c_driver tc3589x_driver = { 420 .driver.name = "tc3589x", 421 .driver.owner = THIS_MODULE, 422 .driver.pm = &tc3589x_dev_pm_ops, 423 .probe = tc3589x_probe, 424 .remove = __devexit_p(tc3589x_remove), 425 .id_table = tc3589x_id, 426 }; 427 428 static int __init tc3589x_init(void) 429 { 430 return i2c_add_driver(&tc3589x_driver); 431 } 432 subsys_initcall(tc3589x_init); 433 434 static void __exit tc3589x_exit(void) 435 { 436 i2c_del_driver(&tc3589x_driver); 437 } 438 module_exit(tc3589x_exit); 439 440 MODULE_LICENSE("GPL v2"); 441 MODULE_DESCRIPTION("TC3589x MFD core driver"); 442 MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); 443