1 /* 2 * sec-core.c 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd 5 * http://www.samsung.com 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 */ 13 14 #include <linux/module.h> 15 #include <linux/moduleparam.h> 16 #include <linux/init.h> 17 #include <linux/err.h> 18 #include <linux/slab.h> 19 #include <linux/i2c.h> 20 #include <linux/of.h> 21 #include <linux/of_irq.h> 22 #include <linux/interrupt.h> 23 #include <linux/pm_runtime.h> 24 #include <linux/mutex.h> 25 #include <linux/mfd/core.h> 26 #include <linux/mfd/samsung/core.h> 27 #include <linux/mfd/samsung/irq.h> 28 #include <linux/mfd/samsung/s2mpa01.h> 29 #include <linux/mfd/samsung/s2mps11.h> 30 #include <linux/mfd/samsung/s2mps14.h> 31 #include <linux/mfd/samsung/s2mpu02.h> 32 #include <linux/mfd/samsung/s5m8763.h> 33 #include <linux/mfd/samsung/s5m8767.h> 34 #include <linux/regulator/machine.h> 35 #include <linux/regmap.h> 36 37 static const struct mfd_cell s5m8751_devs[] = { 38 { 39 .name = "s5m8751-pmic", 40 }, { 41 .name = "s5m-charger", 42 }, { 43 .name = "s5m8751-codec", 44 }, 45 }; 46 47 static const struct mfd_cell s5m8763_devs[] = { 48 { 49 .name = "s5m8763-pmic", 50 }, { 51 .name = "s5m-rtc", 52 }, { 53 .name = "s5m-charger", 54 }, 55 }; 56 57 static const struct mfd_cell s5m8767_devs[] = { 58 { 59 .name = "s5m8767-pmic", 60 }, { 61 .name = "s5m-rtc", 62 }, { 63 .name = "s5m8767-clk", 64 .of_compatible = "samsung,s5m8767-clk", 65 } 66 }; 67 68 static const struct mfd_cell s2mps11_devs[] = { 69 { 70 .name = "s2mps11-pmic", 71 }, { 72 .name = "s2mps11-clk", 73 .of_compatible = "samsung,s2mps11-clk", 74 } 75 }; 76 77 static const struct mfd_cell s2mps13_devs[] = { 78 { .name = "s2mps13-pmic", }, 79 { .name = "s2mps13-rtc", }, 80 { 81 .name = "s2mps13-clk", 82 .of_compatible = "samsung,s2mps13-clk", 83 }, 84 }; 85 86 static const struct mfd_cell s2mps14_devs[] = { 87 { 88 .name = "s2mps14-pmic", 89 }, { 90 .name = "s2mps14-rtc", 91 }, { 92 .name = "s2mps14-clk", 93 .of_compatible = "samsung,s2mps14-clk", 94 } 95 }; 96 97 static const struct mfd_cell s2mpa01_devs[] = { 98 { 99 .name = "s2mpa01-pmic", 100 }, 101 }; 102 103 static const struct mfd_cell s2mpu02_devs[] = { 104 { .name = "s2mpu02-pmic", }, 105 { .name = "s2mpu02-rtc", }, 106 { 107 .name = "s2mpu02-clk", 108 .of_compatible = "samsung,s2mpu02-clk", 109 } 110 }; 111 112 #ifdef CONFIG_OF 113 static const struct of_device_id sec_dt_match[] = { 114 { .compatible = "samsung,s5m8767-pmic", 115 .data = (void *)S5M8767X, 116 }, { 117 .compatible = "samsung,s2mps11-pmic", 118 .data = (void *)S2MPS11X, 119 }, { 120 .compatible = "samsung,s2mps13-pmic", 121 .data = (void *)S2MPS13X, 122 }, { 123 .compatible = "samsung,s2mps14-pmic", 124 .data = (void *)S2MPS14X, 125 }, { 126 .compatible = "samsung,s2mpa01-pmic", 127 .data = (void *)S2MPA01, 128 }, { 129 .compatible = "samsung,s2mpu02-pmic", 130 .data = (void *)S2MPU02, 131 }, { 132 /* Sentinel */ 133 }, 134 }; 135 #endif 136 137 static bool s2mpa01_volatile(struct device *dev, unsigned int reg) 138 { 139 switch (reg) { 140 case S2MPA01_REG_INT1M: 141 case S2MPA01_REG_INT2M: 142 case S2MPA01_REG_INT3M: 143 return false; 144 default: 145 return true; 146 } 147 } 148 149 static bool s2mps11_volatile(struct device *dev, unsigned int reg) 150 { 151 switch (reg) { 152 case S2MPS11_REG_INT1M: 153 case S2MPS11_REG_INT2M: 154 case S2MPS11_REG_INT3M: 155 return false; 156 default: 157 return true; 158 } 159 } 160 161 static bool s2mpu02_volatile(struct device *dev, unsigned int reg) 162 { 163 switch (reg) { 164 case S2MPU02_REG_INT1M: 165 case S2MPU02_REG_INT2M: 166 case S2MPU02_REG_INT3M: 167 return false; 168 default: 169 return true; 170 } 171 } 172 173 static bool s5m8763_volatile(struct device *dev, unsigned int reg) 174 { 175 switch (reg) { 176 case S5M8763_REG_IRQM1: 177 case S5M8763_REG_IRQM2: 178 case S5M8763_REG_IRQM3: 179 case S5M8763_REG_IRQM4: 180 return false; 181 default: 182 return true; 183 } 184 } 185 186 static const struct regmap_config sec_regmap_config = { 187 .reg_bits = 8, 188 .val_bits = 8, 189 }; 190 191 static const struct regmap_config s2mpa01_regmap_config = { 192 .reg_bits = 8, 193 .val_bits = 8, 194 195 .max_register = S2MPA01_REG_LDO_OVCB4, 196 .volatile_reg = s2mpa01_volatile, 197 .cache_type = REGCACHE_FLAT, 198 }; 199 200 static const struct regmap_config s2mps11_regmap_config = { 201 .reg_bits = 8, 202 .val_bits = 8, 203 204 .max_register = S2MPS11_REG_L38CTRL, 205 .volatile_reg = s2mps11_volatile, 206 .cache_type = REGCACHE_FLAT, 207 }; 208 209 static const struct regmap_config s2mps14_regmap_config = { 210 .reg_bits = 8, 211 .val_bits = 8, 212 213 .max_register = S2MPS14_REG_LDODSCH3, 214 .volatile_reg = s2mps11_volatile, 215 .cache_type = REGCACHE_FLAT, 216 }; 217 218 static const struct regmap_config s2mpu02_regmap_config = { 219 .reg_bits = 8, 220 .val_bits = 8, 221 222 .max_register = S2MPU02_REG_DVSDATA, 223 .volatile_reg = s2mpu02_volatile, 224 .cache_type = REGCACHE_FLAT, 225 }; 226 227 static const struct regmap_config s5m8763_regmap_config = { 228 .reg_bits = 8, 229 .val_bits = 8, 230 231 .max_register = S5M8763_REG_LBCNFG2, 232 .volatile_reg = s5m8763_volatile, 233 .cache_type = REGCACHE_FLAT, 234 }; 235 236 static const struct regmap_config s5m8767_regmap_config = { 237 .reg_bits = 8, 238 .val_bits = 8, 239 240 .max_register = S5M8767_REG_LDO28CTRL, 241 .volatile_reg = s2mps11_volatile, 242 .cache_type = REGCACHE_FLAT, 243 }; 244 245 #ifdef CONFIG_OF 246 /* 247 * Only the common platform data elements for s5m8767 are parsed here from the 248 * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and 249 * others have to parse their own platform data elements from device tree. 250 * 251 * The s5m8767 platform data structure is instantiated here and the drivers for 252 * the sub-modules need not instantiate another instance while parsing their 253 * platform data. 254 */ 255 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( 256 struct device *dev) 257 { 258 struct sec_platform_data *pd; 259 260 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); 261 if (!pd) { 262 dev_err(dev, "could not allocate memory for pdata\n"); 263 return ERR_PTR(-ENOMEM); 264 } 265 266 /* 267 * ToDo: the 'wakeup' member in the platform data is more of a linux 268 * specfic information. Hence, there is no binding for that yet and 269 * not parsed here. 270 */ 271 272 return pd; 273 } 274 #else 275 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( 276 struct device *dev) 277 { 278 return NULL; 279 } 280 #endif 281 282 static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c, 283 const struct i2c_device_id *id) 284 { 285 #ifdef CONFIG_OF 286 if (i2c->dev.of_node) { 287 const struct of_device_id *match; 288 289 match = of_match_node(sec_dt_match, i2c->dev.of_node); 290 return (unsigned long)match->data; 291 } 292 #endif 293 return id->driver_data; 294 } 295 296 static int sec_pmic_probe(struct i2c_client *i2c, 297 const struct i2c_device_id *id) 298 { 299 struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); 300 const struct regmap_config *regmap; 301 const struct mfd_cell *sec_devs; 302 struct sec_pmic_dev *sec_pmic; 303 unsigned long device_type; 304 int ret, num_sec_devs; 305 306 sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), 307 GFP_KERNEL); 308 if (sec_pmic == NULL) 309 return -ENOMEM; 310 311 i2c_set_clientdata(i2c, sec_pmic); 312 sec_pmic->dev = &i2c->dev; 313 sec_pmic->i2c = i2c; 314 sec_pmic->irq = i2c->irq; 315 device_type = sec_i2c_get_driver_data(i2c, id); 316 317 if (sec_pmic->dev->of_node) { 318 pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); 319 if (IS_ERR(pdata)) { 320 ret = PTR_ERR(pdata); 321 return ret; 322 } 323 pdata->device_type = device_type; 324 } 325 if (pdata) { 326 sec_pmic->device_type = pdata->device_type; 327 sec_pmic->ono = pdata->ono; 328 sec_pmic->irq_base = pdata->irq_base; 329 sec_pmic->wakeup = pdata->wakeup; 330 sec_pmic->pdata = pdata; 331 } 332 333 switch (sec_pmic->device_type) { 334 case S2MPA01: 335 regmap = &s2mpa01_regmap_config; 336 break; 337 case S2MPS11X: 338 regmap = &s2mps11_regmap_config; 339 break; 340 case S2MPS14X: 341 regmap = &s2mps14_regmap_config; 342 break; 343 case S5M8763X: 344 regmap = &s5m8763_regmap_config; 345 break; 346 case S5M8767X: 347 regmap = &s5m8767_regmap_config; 348 break; 349 case S2MPU02: 350 regmap = &s2mpu02_regmap_config; 351 break; 352 default: 353 regmap = &sec_regmap_config; 354 break; 355 } 356 357 sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap); 358 if (IS_ERR(sec_pmic->regmap_pmic)) { 359 ret = PTR_ERR(sec_pmic->regmap_pmic); 360 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 361 ret); 362 return ret; 363 } 364 365 if (pdata && pdata->cfg_pmic_irq) 366 pdata->cfg_pmic_irq(); 367 368 sec_irq_init(sec_pmic); 369 370 pm_runtime_set_active(sec_pmic->dev); 371 372 switch (sec_pmic->device_type) { 373 case S5M8751X: 374 sec_devs = s5m8751_devs; 375 num_sec_devs = ARRAY_SIZE(s5m8751_devs); 376 break; 377 case S5M8763X: 378 sec_devs = s5m8763_devs; 379 num_sec_devs = ARRAY_SIZE(s5m8763_devs); 380 break; 381 case S5M8767X: 382 sec_devs = s5m8767_devs; 383 num_sec_devs = ARRAY_SIZE(s5m8767_devs); 384 break; 385 case S2MPA01: 386 sec_devs = s2mpa01_devs; 387 num_sec_devs = ARRAY_SIZE(s2mpa01_devs); 388 break; 389 case S2MPS11X: 390 sec_devs = s2mps11_devs; 391 num_sec_devs = ARRAY_SIZE(s2mps11_devs); 392 break; 393 case S2MPS13X: 394 sec_devs = s2mps13_devs; 395 num_sec_devs = ARRAY_SIZE(s2mps13_devs); 396 break; 397 case S2MPS14X: 398 sec_devs = s2mps14_devs; 399 num_sec_devs = ARRAY_SIZE(s2mps14_devs); 400 break; 401 case S2MPU02: 402 sec_devs = s2mpu02_devs; 403 num_sec_devs = ARRAY_SIZE(s2mpu02_devs); 404 break; 405 default: 406 /* If this happens the probe function is problem */ 407 BUG(); 408 } 409 ret = mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL, 410 0, NULL); 411 if (ret) 412 goto err_mfd; 413 414 device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup); 415 416 return ret; 417 418 err_mfd: 419 sec_irq_exit(sec_pmic); 420 return ret; 421 } 422 423 static int sec_pmic_remove(struct i2c_client *i2c) 424 { 425 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); 426 427 mfd_remove_devices(sec_pmic->dev); 428 sec_irq_exit(sec_pmic); 429 return 0; 430 } 431 432 #ifdef CONFIG_PM_SLEEP 433 static int sec_pmic_suspend(struct device *dev) 434 { 435 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 436 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); 437 438 if (device_may_wakeup(dev)) 439 enable_irq_wake(sec_pmic->irq); 440 /* 441 * PMIC IRQ must be disabled during suspend for RTC alarm 442 * to work properly. 443 * When device is woken up from suspend, an 444 * interrupt occurs before resuming I2C bus controller. 445 * The interrupt is handled by regmap_irq_thread which tries 446 * to read RTC registers. This read fails (I2C is still 447 * suspended) and RTC Alarm interrupt is disabled. 448 */ 449 disable_irq(sec_pmic->irq); 450 451 switch (sec_pmic->device_type) { 452 case S2MPS14X: 453 case S2MPU02: 454 regulator_suspend_prepare(PM_SUSPEND_MEM); 455 break; 456 default: 457 break; 458 } 459 460 return 0; 461 } 462 463 static int sec_pmic_resume(struct device *dev) 464 { 465 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 466 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); 467 468 if (device_may_wakeup(dev)) 469 disable_irq_wake(sec_pmic->irq); 470 enable_irq(sec_pmic->irq); 471 472 return 0; 473 } 474 #endif /* CONFIG_PM_SLEEP */ 475 476 static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); 477 478 static const struct i2c_device_id sec_pmic_id[] = { 479 { "sec_pmic", 0 }, 480 { } 481 }; 482 MODULE_DEVICE_TABLE(i2c, sec_pmic_id); 483 484 static struct i2c_driver sec_pmic_driver = { 485 .driver = { 486 .name = "sec_pmic", 487 .owner = THIS_MODULE, 488 .pm = &sec_pmic_pm_ops, 489 .of_match_table = of_match_ptr(sec_dt_match), 490 }, 491 .probe = sec_pmic_probe, 492 .remove = sec_pmic_remove, 493 .id_table = sec_pmic_id, 494 }; 495 496 static int __init sec_pmic_init(void) 497 { 498 return i2c_add_driver(&sec_pmic_driver); 499 } 500 501 subsys_initcall(sec_pmic_init); 502 503 static void __exit sec_pmic_exit(void) 504 { 505 i2c_del_driver(&sec_pmic_driver); 506 } 507 module_exit(sec_pmic_exit); 508 509 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 510 MODULE_DESCRIPTION("Core support for the S5M MFD"); 511 MODULE_LICENSE("GPL"); 512