1 /* 2 * TI Palmas MFD Driver 3 * 4 * Copyright 2011-2012 Texas Instruments Inc. 5 * 6 * Author: Graeme Gregory <gg@slimlogic.co.uk> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 15 #include <linux/module.h> 16 #include <linux/moduleparam.h> 17 #include <linux/init.h> 18 #include <linux/slab.h> 19 #include <linux/i2c.h> 20 #include <linux/interrupt.h> 21 #include <linux/irq.h> 22 #include <linux/regmap.h> 23 #include <linux/err.h> 24 #include <linux/mfd/core.h> 25 #include <linux/mfd/palmas.h> 26 #include <linux/of_platform.h> 27 28 enum palmas_ids { 29 PALMAS_PMIC_ID, 30 PALMAS_GPIO_ID, 31 PALMAS_LEDS_ID, 32 PALMAS_WDT_ID, 33 PALMAS_RTC_ID, 34 PALMAS_PWRBUTTON_ID, 35 PALMAS_GPADC_ID, 36 PALMAS_RESOURCE_ID, 37 PALMAS_CLK_ID, 38 PALMAS_PWM_ID, 39 PALMAS_USB_ID, 40 }; 41 42 static const struct mfd_cell palmas_children[] = { 43 { 44 .name = "palmas-pmic", 45 .id = PALMAS_PMIC_ID, 46 }, 47 { 48 .name = "palmas-gpio", 49 .id = PALMAS_GPIO_ID, 50 }, 51 { 52 .name = "palmas-leds", 53 .id = PALMAS_LEDS_ID, 54 }, 55 { 56 .name = "palmas-wdt", 57 .id = PALMAS_WDT_ID, 58 }, 59 { 60 .name = "palmas-rtc", 61 .id = PALMAS_RTC_ID, 62 }, 63 { 64 .name = "palmas-pwrbutton", 65 .id = PALMAS_PWRBUTTON_ID, 66 }, 67 { 68 .name = "palmas-gpadc", 69 .id = PALMAS_GPADC_ID, 70 }, 71 { 72 .name = "palmas-resource", 73 .id = PALMAS_RESOURCE_ID, 74 }, 75 { 76 .name = "palmas-clk", 77 .id = PALMAS_CLK_ID, 78 }, 79 { 80 .name = "palmas-pwm", 81 .id = PALMAS_PWM_ID, 82 }, 83 { 84 .name = "palmas-usb", 85 .id = PALMAS_USB_ID, 86 } 87 }; 88 89 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { 90 { 91 .reg_bits = 8, 92 .val_bits = 8, 93 .max_register = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, 94 PALMAS_PRIMARY_SECONDARY_PAD3), 95 }, 96 { 97 .reg_bits = 8, 98 .val_bits = 8, 99 .max_register = PALMAS_BASE_TO_REG(PALMAS_GPADC_BASE, 100 PALMAS_GPADC_SMPS_VSEL_MONITORING), 101 }, 102 { 103 .reg_bits = 8, 104 .val_bits = 8, 105 .max_register = PALMAS_BASE_TO_REG(PALMAS_TRIM_GPADC_BASE, 106 PALMAS_GPADC_TRIM16), 107 }, 108 }; 109 110 static const struct regmap_irq palmas_irqs[] = { 111 /* INT1 IRQs */ 112 [PALMAS_CHARG_DET_N_VBUS_OVV_IRQ] = { 113 .mask = PALMAS_INT1_STATUS_CHARG_DET_N_VBUS_OVV, 114 }, 115 [PALMAS_PWRON_IRQ] = { 116 .mask = PALMAS_INT1_STATUS_PWRON, 117 }, 118 [PALMAS_LONG_PRESS_KEY_IRQ] = { 119 .mask = PALMAS_INT1_STATUS_LONG_PRESS_KEY, 120 }, 121 [PALMAS_RPWRON_IRQ] = { 122 .mask = PALMAS_INT1_STATUS_RPWRON, 123 }, 124 [PALMAS_PWRDOWN_IRQ] = { 125 .mask = PALMAS_INT1_STATUS_PWRDOWN, 126 }, 127 [PALMAS_HOTDIE_IRQ] = { 128 .mask = PALMAS_INT1_STATUS_HOTDIE, 129 }, 130 [PALMAS_VSYS_MON_IRQ] = { 131 .mask = PALMAS_INT1_STATUS_VSYS_MON, 132 }, 133 [PALMAS_VBAT_MON_IRQ] = { 134 .mask = PALMAS_INT1_STATUS_VBAT_MON, 135 }, 136 /* INT2 IRQs*/ 137 [PALMAS_RTC_ALARM_IRQ] = { 138 .mask = PALMAS_INT2_STATUS_RTC_ALARM, 139 .reg_offset = 1, 140 }, 141 [PALMAS_RTC_TIMER_IRQ] = { 142 .mask = PALMAS_INT2_STATUS_RTC_TIMER, 143 .reg_offset = 1, 144 }, 145 [PALMAS_WDT_IRQ] = { 146 .mask = PALMAS_INT2_STATUS_WDT, 147 .reg_offset = 1, 148 }, 149 [PALMAS_BATREMOVAL_IRQ] = { 150 .mask = PALMAS_INT2_STATUS_BATREMOVAL, 151 .reg_offset = 1, 152 }, 153 [PALMAS_RESET_IN_IRQ] = { 154 .mask = PALMAS_INT2_STATUS_RESET_IN, 155 .reg_offset = 1, 156 }, 157 [PALMAS_FBI_BB_IRQ] = { 158 .mask = PALMAS_INT2_STATUS_FBI_BB, 159 .reg_offset = 1, 160 }, 161 [PALMAS_SHORT_IRQ] = { 162 .mask = PALMAS_INT2_STATUS_SHORT, 163 .reg_offset = 1, 164 }, 165 [PALMAS_VAC_ACOK_IRQ] = { 166 .mask = PALMAS_INT2_STATUS_VAC_ACOK, 167 .reg_offset = 1, 168 }, 169 /* INT3 IRQs */ 170 [PALMAS_GPADC_AUTO_0_IRQ] = { 171 .mask = PALMAS_INT3_STATUS_GPADC_AUTO_0, 172 .reg_offset = 2, 173 }, 174 [PALMAS_GPADC_AUTO_1_IRQ] = { 175 .mask = PALMAS_INT3_STATUS_GPADC_AUTO_1, 176 .reg_offset = 2, 177 }, 178 [PALMAS_GPADC_EOC_SW_IRQ] = { 179 .mask = PALMAS_INT3_STATUS_GPADC_EOC_SW, 180 .reg_offset = 2, 181 }, 182 [PALMAS_GPADC_EOC_RT_IRQ] = { 183 .mask = PALMAS_INT3_STATUS_GPADC_EOC_RT, 184 .reg_offset = 2, 185 }, 186 [PALMAS_ID_OTG_IRQ] = { 187 .mask = PALMAS_INT3_STATUS_ID_OTG, 188 .reg_offset = 2, 189 }, 190 [PALMAS_ID_IRQ] = { 191 .mask = PALMAS_INT3_STATUS_ID, 192 .reg_offset = 2, 193 }, 194 [PALMAS_VBUS_OTG_IRQ] = { 195 .mask = PALMAS_INT3_STATUS_VBUS_OTG, 196 .reg_offset = 2, 197 }, 198 [PALMAS_VBUS_IRQ] = { 199 .mask = PALMAS_INT3_STATUS_VBUS, 200 .reg_offset = 2, 201 }, 202 /* INT4 IRQs */ 203 [PALMAS_GPIO_0_IRQ] = { 204 .mask = PALMAS_INT4_STATUS_GPIO_0, 205 .reg_offset = 3, 206 }, 207 [PALMAS_GPIO_1_IRQ] = { 208 .mask = PALMAS_INT4_STATUS_GPIO_1, 209 .reg_offset = 3, 210 }, 211 [PALMAS_GPIO_2_IRQ] = { 212 .mask = PALMAS_INT4_STATUS_GPIO_2, 213 .reg_offset = 3, 214 }, 215 [PALMAS_GPIO_3_IRQ] = { 216 .mask = PALMAS_INT4_STATUS_GPIO_3, 217 .reg_offset = 3, 218 }, 219 [PALMAS_GPIO_4_IRQ] = { 220 .mask = PALMAS_INT4_STATUS_GPIO_4, 221 .reg_offset = 3, 222 }, 223 [PALMAS_GPIO_5_IRQ] = { 224 .mask = PALMAS_INT4_STATUS_GPIO_5, 225 .reg_offset = 3, 226 }, 227 [PALMAS_GPIO_6_IRQ] = { 228 .mask = PALMAS_INT4_STATUS_GPIO_6, 229 .reg_offset = 3, 230 }, 231 [PALMAS_GPIO_7_IRQ] = { 232 .mask = PALMAS_INT4_STATUS_GPIO_7, 233 .reg_offset = 3, 234 }, 235 }; 236 237 static struct regmap_irq_chip palmas_irq_chip = { 238 .name = "palmas", 239 .irqs = palmas_irqs, 240 .num_irqs = ARRAY_SIZE(palmas_irqs), 241 242 .num_regs = 4, 243 .irq_reg_stride = 5, 244 .status_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, 245 PALMAS_INT1_STATUS), 246 .mask_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, 247 PALMAS_INT1_MASK), 248 }; 249 250 static void palmas_dt_to_pdata(struct device_node *node, 251 struct palmas_platform_data *pdata) 252 { 253 int ret; 254 u32 prop; 255 256 ret = of_property_read_u32(node, "ti,mux_pad1", &prop); 257 if (!ret) { 258 pdata->mux_from_pdata = 1; 259 pdata->pad1 = prop; 260 } 261 262 ret = of_property_read_u32(node, "ti,mux_pad2", &prop); 263 if (!ret) { 264 pdata->mux_from_pdata = 1; 265 pdata->pad2 = prop; 266 } 267 268 /* The default for this register is all masked */ 269 ret = of_property_read_u32(node, "ti,power_ctrl", &prop); 270 if (!ret) 271 pdata->power_ctrl = prop; 272 else 273 pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK | 274 PALMAS_POWER_CTRL_ENABLE1_MASK | 275 PALMAS_POWER_CTRL_ENABLE2_MASK; 276 } 277 278 static int palmas_i2c_probe(struct i2c_client *i2c, 279 const struct i2c_device_id *id) 280 { 281 struct palmas *palmas; 282 struct palmas_platform_data *pdata; 283 struct device_node *node = i2c->dev.of_node; 284 int ret = 0, i; 285 unsigned int reg, addr; 286 int slave; 287 struct mfd_cell *children; 288 289 pdata = dev_get_platdata(&i2c->dev); 290 291 if (node && !pdata) { 292 pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); 293 294 if (!pdata) 295 return -ENOMEM; 296 297 palmas_dt_to_pdata(node, pdata); 298 } 299 300 if (!pdata) 301 return -EINVAL; 302 303 palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL); 304 if (palmas == NULL) 305 return -ENOMEM; 306 307 i2c_set_clientdata(i2c, palmas); 308 palmas->dev = &i2c->dev; 309 palmas->id = id->driver_data; 310 palmas->irq = i2c->irq; 311 312 for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { 313 if (i == 0) 314 palmas->i2c_clients[i] = i2c; 315 else { 316 palmas->i2c_clients[i] = 317 i2c_new_dummy(i2c->adapter, 318 i2c->addr + i); 319 if (!palmas->i2c_clients[i]) { 320 dev_err(palmas->dev, 321 "can't attach client %d\n", i); 322 ret = -ENOMEM; 323 goto err; 324 } 325 } 326 palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i], 327 &palmas_regmap_config[i]); 328 if (IS_ERR(palmas->regmap[i])) { 329 ret = PTR_ERR(palmas->regmap[i]); 330 dev_err(palmas->dev, 331 "Failed to allocate regmap %d, err: %d\n", 332 i, ret); 333 goto err; 334 } 335 } 336 337 /* Change IRQ into clear on read mode for efficiency */ 338 slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); 339 addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); 340 reg = PALMAS_INT_CTRL_INT_CLEAR; 341 342 regmap_write(palmas->regmap[slave], addr, reg); 343 344 ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, 345 IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip, 346 &palmas->irq_data); 347 if (ret < 0) 348 goto err; 349 350 slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); 351 addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, 352 PALMAS_PRIMARY_SECONDARY_PAD1); 353 354 if (pdata->mux_from_pdata) { 355 reg = pdata->pad1; 356 ret = regmap_write(palmas->regmap[slave], addr, reg); 357 if (ret) 358 goto err_irq; 359 } else { 360 ret = regmap_read(palmas->regmap[slave], addr, ®); 361 if (ret) 362 goto err_irq; 363 } 364 365 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) 366 palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; 367 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) 368 palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; 369 else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == 370 (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) 371 palmas->led_muxed |= PALMAS_LED1_MUXED; 372 else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == 373 (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) 374 palmas->pwm_muxed |= PALMAS_PWM1_MUXED; 375 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) 376 palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; 377 else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == 378 (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) 379 palmas->led_muxed |= PALMAS_LED2_MUXED; 380 else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == 381 (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) 382 palmas->pwm_muxed |= PALMAS_PWM2_MUXED; 383 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) 384 palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; 385 386 addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, 387 PALMAS_PRIMARY_SECONDARY_PAD2); 388 389 if (pdata->mux_from_pdata) { 390 reg = pdata->pad2; 391 ret = regmap_write(palmas->regmap[slave], addr, reg); 392 if (ret) 393 goto err_irq; 394 } else { 395 ret = regmap_read(palmas->regmap[slave], addr, ®); 396 if (ret) 397 goto err_irq; 398 } 399 400 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) 401 palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; 402 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) 403 palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; 404 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6)) 405 palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; 406 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) 407 palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; 408 409 dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", 410 palmas->gpio_muxed, palmas->pwm_muxed, 411 palmas->led_muxed); 412 413 reg = pdata->power_ctrl; 414 415 slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); 416 addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); 417 418 ret = regmap_write(palmas->regmap[slave], addr, reg); 419 if (ret) 420 goto err_irq; 421 422 /* 423 * If we are probing with DT do this the DT way and return here 424 * otherwise continue and add devices using mfd helpers. 425 */ 426 if (node) { 427 ret = of_platform_populate(node, NULL, NULL, &i2c->dev); 428 if (ret < 0) 429 goto err_irq; 430 else 431 return ret; 432 } 433 434 children = kmemdup(palmas_children, sizeof(palmas_children), 435 GFP_KERNEL); 436 if (!children) { 437 ret = -ENOMEM; 438 goto err_irq; 439 } 440 441 children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; 442 children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); 443 444 children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata; 445 children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata); 446 447 children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata; 448 children[PALMAS_RESOURCE_ID].pdata_size = 449 sizeof(*pdata->resource_pdata); 450 451 children[PALMAS_USB_ID].platform_data = pdata->usb_pdata; 452 children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata); 453 454 children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata; 455 children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata); 456 457 ret = mfd_add_devices(palmas->dev, -1, 458 children, ARRAY_SIZE(palmas_children), 459 NULL, regmap_irq_chip_get_base(palmas->irq_data), 460 NULL); 461 kfree(children); 462 463 if (ret < 0) 464 goto err_devices; 465 466 return ret; 467 468 err_devices: 469 mfd_remove_devices(palmas->dev); 470 err_irq: 471 regmap_del_irq_chip(palmas->irq, palmas->irq_data); 472 err: 473 return ret; 474 } 475 476 static int palmas_i2c_remove(struct i2c_client *i2c) 477 { 478 struct palmas *palmas = i2c_get_clientdata(i2c); 479 480 mfd_remove_devices(palmas->dev); 481 regmap_del_irq_chip(palmas->irq, palmas->irq_data); 482 483 return 0; 484 } 485 486 static const struct i2c_device_id palmas_i2c_id[] = { 487 { "palmas", }, 488 { "twl6035", }, 489 { "twl6037", }, 490 { "tps65913", }, 491 { /* end */ } 492 }; 493 MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); 494 495 static struct of_device_id of_palmas_match_tbl[] = { 496 { .compatible = "ti,palmas", }, 497 { /* end */ } 498 }; 499 500 static struct i2c_driver palmas_i2c_driver = { 501 .driver = { 502 .name = "palmas", 503 .of_match_table = of_palmas_match_tbl, 504 .owner = THIS_MODULE, 505 }, 506 .probe = palmas_i2c_probe, 507 .remove = palmas_i2c_remove, 508 .id_table = palmas_i2c_id, 509 }; 510 511 static int __init palmas_i2c_init(void) 512 { 513 return i2c_add_driver(&palmas_i2c_driver); 514 } 515 /* init early so consumer devices can complete system boot */ 516 subsys_initcall(palmas_i2c_init); 517 518 static void __exit palmas_i2c_exit(void) 519 { 520 i2c_del_driver(&palmas_i2c_driver); 521 } 522 module_exit(palmas_i2c_exit); 523 524 MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); 525 MODULE_DESCRIPTION("Palmas chip family multi-function driver"); 526 MODULE_LICENSE("GPL"); 527