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/s2mps13.h> 31 #include <linux/mfd/samsung/s2mps14.h> 32 #include <linux/mfd/samsung/s2mpu02.h> 33 #include <linux/mfd/samsung/s5m8763.h> 34 #include <linux/mfd/samsung/s5m8767.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 s2mps13_regmap_config = { 210 .reg_bits = 8, 211 .val_bits = 8, 212 213 .max_register = S2MPS13_REG_LDODSCH5, 214 .volatile_reg = s2mps11_volatile, 215 .cache_type = REGCACHE_FLAT, 216 }; 217 218 static const struct regmap_config s2mps14_regmap_config = { 219 .reg_bits = 8, 220 .val_bits = 8, 221 222 .max_register = S2MPS14_REG_LDODSCH3, 223 .volatile_reg = s2mps11_volatile, 224 .cache_type = REGCACHE_FLAT, 225 }; 226 227 static const struct regmap_config s2mpu02_regmap_config = { 228 .reg_bits = 8, 229 .val_bits = 8, 230 231 .max_register = S2MPU02_REG_DVSDATA, 232 .volatile_reg = s2mpu02_volatile, 233 .cache_type = REGCACHE_FLAT, 234 }; 235 236 static const struct regmap_config s5m8763_regmap_config = { 237 .reg_bits = 8, 238 .val_bits = 8, 239 240 .max_register = S5M8763_REG_LBCNFG2, 241 .volatile_reg = s5m8763_volatile, 242 .cache_type = REGCACHE_FLAT, 243 }; 244 245 static const struct regmap_config s5m8767_regmap_config = { 246 .reg_bits = 8, 247 .val_bits = 8, 248 249 .max_register = S5M8767_REG_LDO28CTRL, 250 .volatile_reg = s2mps11_volatile, 251 .cache_type = REGCACHE_FLAT, 252 }; 253 254 #ifdef CONFIG_OF 255 /* 256 * Only the common platform data elements for s5m8767 are parsed here from the 257 * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and 258 * others have to parse their own platform data elements from device tree. 259 * 260 * The s5m8767 platform data structure is instantiated here and the drivers for 261 * the sub-modules need not instantiate another instance while parsing their 262 * platform data. 263 */ 264 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( 265 struct device *dev) 266 { 267 struct sec_platform_data *pd; 268 269 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); 270 if (!pd) { 271 dev_err(dev, "could not allocate memory for pdata\n"); 272 return ERR_PTR(-ENOMEM); 273 } 274 275 /* 276 * ToDo: the 'wakeup' member in the platform data is more of a linux 277 * specfic information. Hence, there is no binding for that yet and 278 * not parsed here. 279 */ 280 281 return pd; 282 } 283 #else 284 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( 285 struct device *dev) 286 { 287 return NULL; 288 } 289 #endif 290 291 static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c, 292 const struct i2c_device_id *id) 293 { 294 #ifdef CONFIG_OF 295 if (i2c->dev.of_node) { 296 const struct of_device_id *match; 297 298 match = of_match_node(sec_dt_match, i2c->dev.of_node); 299 return (unsigned long)match->data; 300 } 301 #endif 302 return id->driver_data; 303 } 304 305 static int sec_pmic_probe(struct i2c_client *i2c, 306 const struct i2c_device_id *id) 307 { 308 struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); 309 const struct regmap_config *regmap; 310 const struct mfd_cell *sec_devs; 311 struct sec_pmic_dev *sec_pmic; 312 unsigned long device_type; 313 int ret, num_sec_devs; 314 315 sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), 316 GFP_KERNEL); 317 if (sec_pmic == NULL) 318 return -ENOMEM; 319 320 i2c_set_clientdata(i2c, sec_pmic); 321 sec_pmic->dev = &i2c->dev; 322 sec_pmic->i2c = i2c; 323 sec_pmic->irq = i2c->irq; 324 device_type = sec_i2c_get_driver_data(i2c, id); 325 326 if (sec_pmic->dev->of_node) { 327 pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); 328 if (IS_ERR(pdata)) { 329 ret = PTR_ERR(pdata); 330 return ret; 331 } 332 pdata->device_type = device_type; 333 } 334 if (pdata) { 335 sec_pmic->device_type = pdata->device_type; 336 sec_pmic->ono = pdata->ono; 337 sec_pmic->irq_base = pdata->irq_base; 338 sec_pmic->wakeup = pdata->wakeup; 339 sec_pmic->pdata = pdata; 340 } 341 342 switch (sec_pmic->device_type) { 343 case S2MPA01: 344 regmap = &s2mpa01_regmap_config; 345 break; 346 case S2MPS11X: 347 regmap = &s2mps11_regmap_config; 348 break; 349 case S2MPS13X: 350 regmap = &s2mps13_regmap_config; 351 break; 352 case S2MPS14X: 353 regmap = &s2mps14_regmap_config; 354 break; 355 case S5M8763X: 356 regmap = &s5m8763_regmap_config; 357 break; 358 case S5M8767X: 359 regmap = &s5m8767_regmap_config; 360 break; 361 case S2MPU02: 362 regmap = &s2mpu02_regmap_config; 363 break; 364 default: 365 regmap = &sec_regmap_config; 366 break; 367 } 368 369 sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap); 370 if (IS_ERR(sec_pmic->regmap_pmic)) { 371 ret = PTR_ERR(sec_pmic->regmap_pmic); 372 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 373 ret); 374 return ret; 375 } 376 377 if (pdata && pdata->cfg_pmic_irq) 378 pdata->cfg_pmic_irq(); 379 380 sec_irq_init(sec_pmic); 381 382 pm_runtime_set_active(sec_pmic->dev); 383 384 switch (sec_pmic->device_type) { 385 case S5M8751X: 386 sec_devs = s5m8751_devs; 387 num_sec_devs = ARRAY_SIZE(s5m8751_devs); 388 break; 389 case S5M8763X: 390 sec_devs = s5m8763_devs; 391 num_sec_devs = ARRAY_SIZE(s5m8763_devs); 392 break; 393 case S5M8767X: 394 sec_devs = s5m8767_devs; 395 num_sec_devs = ARRAY_SIZE(s5m8767_devs); 396 break; 397 case S2MPA01: 398 sec_devs = s2mpa01_devs; 399 num_sec_devs = ARRAY_SIZE(s2mpa01_devs); 400 break; 401 case S2MPS11X: 402 sec_devs = s2mps11_devs; 403 num_sec_devs = ARRAY_SIZE(s2mps11_devs); 404 break; 405 case S2MPS13X: 406 sec_devs = s2mps13_devs; 407 num_sec_devs = ARRAY_SIZE(s2mps13_devs); 408 break; 409 case S2MPS14X: 410 sec_devs = s2mps14_devs; 411 num_sec_devs = ARRAY_SIZE(s2mps14_devs); 412 break; 413 case S2MPU02: 414 sec_devs = s2mpu02_devs; 415 num_sec_devs = ARRAY_SIZE(s2mpu02_devs); 416 break; 417 default: 418 /* If this happens the probe function is problem */ 419 BUG(); 420 } 421 ret = mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL, 422 0, NULL); 423 if (ret) 424 goto err_mfd; 425 426 device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup); 427 428 return ret; 429 430 err_mfd: 431 sec_irq_exit(sec_pmic); 432 return ret; 433 } 434 435 static int sec_pmic_remove(struct i2c_client *i2c) 436 { 437 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); 438 439 mfd_remove_devices(sec_pmic->dev); 440 sec_irq_exit(sec_pmic); 441 return 0; 442 } 443 444 #ifdef CONFIG_PM_SLEEP 445 static int sec_pmic_suspend(struct device *dev) 446 { 447 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 448 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); 449 450 if (device_may_wakeup(dev)) 451 enable_irq_wake(sec_pmic->irq); 452 /* 453 * PMIC IRQ must be disabled during suspend for RTC alarm 454 * to work properly. 455 * When device is woken up from suspend, an 456 * interrupt occurs before resuming I2C bus controller. 457 * The interrupt is handled by regmap_irq_thread which tries 458 * to read RTC registers. This read fails (I2C is still 459 * suspended) and RTC Alarm interrupt is disabled. 460 */ 461 disable_irq(sec_pmic->irq); 462 463 return 0; 464 } 465 466 static int sec_pmic_resume(struct device *dev) 467 { 468 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 469 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); 470 471 if (device_may_wakeup(dev)) 472 disable_irq_wake(sec_pmic->irq); 473 enable_irq(sec_pmic->irq); 474 475 return 0; 476 } 477 #endif /* CONFIG_PM_SLEEP */ 478 479 static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); 480 481 static const struct i2c_device_id sec_pmic_id[] = { 482 { "sec_pmic", 0 }, 483 { } 484 }; 485 MODULE_DEVICE_TABLE(i2c, sec_pmic_id); 486 487 static struct i2c_driver sec_pmic_driver = { 488 .driver = { 489 .name = "sec_pmic", 490 .owner = THIS_MODULE, 491 .pm = &sec_pmic_pm_ops, 492 .of_match_table = of_match_ptr(sec_dt_match), 493 }, 494 .probe = sec_pmic_probe, 495 .remove = sec_pmic_remove, 496 .id_table = sec_pmic_id, 497 }; 498 499 static int __init sec_pmic_init(void) 500 { 501 return i2c_add_driver(&sec_pmic_driver); 502 } 503 504 subsys_initcall(sec_pmic_init); 505 506 static void __exit sec_pmic_exit(void) 507 { 508 i2c_del_driver(&sec_pmic_driver); 509 } 510 module_exit(sec_pmic_exit); 511 512 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 513 MODULE_DESCRIPTION("Core support for the S5M MFD"); 514 MODULE_LICENSE("GPL"); 515