0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/moduleparam.h>
0008 #include <linux/init.h>
0009 #include <linux/err.h>
0010 #include <linux/slab.h>
0011 #include <linux/i2c.h>
0012 #include <linux/of.h>
0013 #include <linux/of_device.h>
0014 #include <linux/of_irq.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/mutex.h>
0018 #include <linux/mfd/core.h>
0019 #include <linux/mfd/samsung/core.h>
0020 #include <linux/mfd/samsung/irq.h>
0021 #include <linux/mfd/samsung/s2mpa01.h>
0022 #include <linux/mfd/samsung/s2mps11.h>
0023 #include <linux/mfd/samsung/s2mps13.h>
0024 #include <linux/mfd/samsung/s2mps14.h>
0025 #include <linux/mfd/samsung/s2mps15.h>
0026 #include <linux/mfd/samsung/s2mpu02.h>
0027 #include <linux/mfd/samsung/s5m8763.h>
0028 #include <linux/mfd/samsung/s5m8767.h>
0029 #include <linux/regmap.h>
0030
0031 static const struct mfd_cell s5m8751_devs[] = {
0032 { .name = "s5m8751-pmic", },
0033 { .name = "s5m-charger", },
0034 { .name = "s5m8751-codec", },
0035 };
0036
0037 static const struct mfd_cell s5m8763_devs[] = {
0038 { .name = "s5m8763-pmic", },
0039 { .name = "s5m-rtc", },
0040 { .name = "s5m-charger", },
0041 };
0042
0043 static const struct mfd_cell s5m8767_devs[] = {
0044 { .name = "s5m8767-pmic", },
0045 { .name = "s5m-rtc", },
0046 {
0047 .name = "s5m8767-clk",
0048 .of_compatible = "samsung,s5m8767-clk",
0049 },
0050 };
0051
0052 static const struct mfd_cell s2mps11_devs[] = {
0053 { .name = "s2mps11-regulator", },
0054 { .name = "s2mps14-rtc", },
0055 {
0056 .name = "s2mps11-clk",
0057 .of_compatible = "samsung,s2mps11-clk",
0058 },
0059 };
0060
0061 static const struct mfd_cell s2mps13_devs[] = {
0062 { .name = "s2mps13-regulator", },
0063 { .name = "s2mps13-rtc", },
0064 {
0065 .name = "s2mps13-clk",
0066 .of_compatible = "samsung,s2mps13-clk",
0067 },
0068 };
0069
0070 static const struct mfd_cell s2mps14_devs[] = {
0071 { .name = "s2mps14-regulator", },
0072 { .name = "s2mps14-rtc", },
0073 {
0074 .name = "s2mps14-clk",
0075 .of_compatible = "samsung,s2mps14-clk",
0076 },
0077 };
0078
0079 static const struct mfd_cell s2mps15_devs[] = {
0080 { .name = "s2mps15-regulator", },
0081 { .name = "s2mps15-rtc", },
0082 {
0083 .name = "s2mps13-clk",
0084 .of_compatible = "samsung,s2mps13-clk",
0085 },
0086 };
0087
0088 static const struct mfd_cell s2mpa01_devs[] = {
0089 { .name = "s2mpa01-pmic", },
0090 { .name = "s2mps14-rtc", },
0091 };
0092
0093 static const struct mfd_cell s2mpu02_devs[] = {
0094 { .name = "s2mpu02-regulator", },
0095 };
0096
0097 static const struct of_device_id sec_dt_match[] = {
0098 {
0099 .compatible = "samsung,s5m8767-pmic",
0100 .data = (void *)S5M8767X,
0101 }, {
0102 .compatible = "samsung,s2mps11-pmic",
0103 .data = (void *)S2MPS11X,
0104 }, {
0105 .compatible = "samsung,s2mps13-pmic",
0106 .data = (void *)S2MPS13X,
0107 }, {
0108 .compatible = "samsung,s2mps14-pmic",
0109 .data = (void *)S2MPS14X,
0110 }, {
0111 .compatible = "samsung,s2mps15-pmic",
0112 .data = (void *)S2MPS15X,
0113 }, {
0114 .compatible = "samsung,s2mpa01-pmic",
0115 .data = (void *)S2MPA01,
0116 }, {
0117 .compatible = "samsung,s2mpu02-pmic",
0118 .data = (void *)S2MPU02,
0119 }, {
0120
0121 },
0122 };
0123 MODULE_DEVICE_TABLE(of, sec_dt_match);
0124
0125 static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
0126 {
0127 switch (reg) {
0128 case S2MPA01_REG_INT1M:
0129 case S2MPA01_REG_INT2M:
0130 case S2MPA01_REG_INT3M:
0131 return false;
0132 default:
0133 return true;
0134 }
0135 }
0136
0137 static bool s2mps11_volatile(struct device *dev, unsigned int reg)
0138 {
0139 switch (reg) {
0140 case S2MPS11_REG_INT1M:
0141 case S2MPS11_REG_INT2M:
0142 case S2MPS11_REG_INT3M:
0143 return false;
0144 default:
0145 return true;
0146 }
0147 }
0148
0149 static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
0150 {
0151 switch (reg) {
0152 case S2MPU02_REG_INT1M:
0153 case S2MPU02_REG_INT2M:
0154 case S2MPU02_REG_INT3M:
0155 return false;
0156 default:
0157 return true;
0158 }
0159 }
0160
0161 static bool s5m8763_volatile(struct device *dev, unsigned int reg)
0162 {
0163 switch (reg) {
0164 case S5M8763_REG_IRQM1:
0165 case S5M8763_REG_IRQM2:
0166 case S5M8763_REG_IRQM3:
0167 case S5M8763_REG_IRQM4:
0168 return false;
0169 default:
0170 return true;
0171 }
0172 }
0173
0174 static const struct regmap_config sec_regmap_config = {
0175 .reg_bits = 8,
0176 .val_bits = 8,
0177 };
0178
0179 static const struct regmap_config s2mpa01_regmap_config = {
0180 .reg_bits = 8,
0181 .val_bits = 8,
0182
0183 .max_register = S2MPA01_REG_LDO_OVCB4,
0184 .volatile_reg = s2mpa01_volatile,
0185 .cache_type = REGCACHE_FLAT,
0186 };
0187
0188 static const struct regmap_config s2mps11_regmap_config = {
0189 .reg_bits = 8,
0190 .val_bits = 8,
0191
0192 .max_register = S2MPS11_REG_L38CTRL,
0193 .volatile_reg = s2mps11_volatile,
0194 .cache_type = REGCACHE_FLAT,
0195 };
0196
0197 static const struct regmap_config s2mps13_regmap_config = {
0198 .reg_bits = 8,
0199 .val_bits = 8,
0200
0201 .max_register = S2MPS13_REG_LDODSCH5,
0202 .volatile_reg = s2mps11_volatile,
0203 .cache_type = REGCACHE_FLAT,
0204 };
0205
0206 static const struct regmap_config s2mps14_regmap_config = {
0207 .reg_bits = 8,
0208 .val_bits = 8,
0209
0210 .max_register = S2MPS14_REG_LDODSCH3,
0211 .volatile_reg = s2mps11_volatile,
0212 .cache_type = REGCACHE_FLAT,
0213 };
0214
0215 static const struct regmap_config s2mps15_regmap_config = {
0216 .reg_bits = 8,
0217 .val_bits = 8,
0218
0219 .max_register = S2MPS15_REG_LDODSCH4,
0220 .volatile_reg = s2mps11_volatile,
0221 .cache_type = REGCACHE_FLAT,
0222 };
0223
0224 static const struct regmap_config s2mpu02_regmap_config = {
0225 .reg_bits = 8,
0226 .val_bits = 8,
0227
0228 .max_register = S2MPU02_REG_DVSDATA,
0229 .volatile_reg = s2mpu02_volatile,
0230 .cache_type = REGCACHE_FLAT,
0231 };
0232
0233 static const struct regmap_config s5m8763_regmap_config = {
0234 .reg_bits = 8,
0235 .val_bits = 8,
0236
0237 .max_register = S5M8763_REG_LBCNFG2,
0238 .volatile_reg = s5m8763_volatile,
0239 .cache_type = REGCACHE_FLAT,
0240 };
0241
0242 static const struct regmap_config s5m8767_regmap_config = {
0243 .reg_bits = 8,
0244 .val_bits = 8,
0245
0246 .max_register = S5M8767_REG_LDO28CTRL,
0247 .volatile_reg = s2mps11_volatile,
0248 .cache_type = REGCACHE_FLAT,
0249 };
0250
0251 static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
0252 {
0253 unsigned int val;
0254
0255
0256 if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
0257 dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
0258 }
0259
0260 static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
0261 {
0262 int err;
0263
0264 if (sec_pmic->device_type != S2MPS13X)
0265 return;
0266
0267 if (sec_pmic->pdata->disable_wrstbi) {
0268
0269
0270
0271
0272
0273 err = regmap_update_bits(sec_pmic->regmap_pmic,
0274 S2MPS13_REG_WRSTBI,
0275 S2MPS13_REG_WRSTBI_MASK, 0x0);
0276 if (err)
0277 dev_warn(sec_pmic->dev,
0278 "Cannot initialize WRSTBI config: %d\n",
0279 err);
0280 }
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 static struct sec_platform_data *
0293 sec_pmic_i2c_parse_dt_pdata(struct device *dev)
0294 {
0295 struct sec_platform_data *pd;
0296
0297 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
0298 if (!pd)
0299 return ERR_PTR(-ENOMEM);
0300
0301 pd->manual_poweroff = of_property_read_bool(dev->of_node,
0302 "samsung,s2mps11-acokb-ground");
0303 pd->disable_wrstbi = of_property_read_bool(dev->of_node,
0304 "samsung,s2mps11-wrstbi-ground");
0305 return pd;
0306 }
0307
0308 static int sec_pmic_probe(struct i2c_client *i2c,
0309 const struct i2c_device_id *id)
0310 {
0311 const struct regmap_config *regmap;
0312 struct sec_platform_data *pdata;
0313 const struct mfd_cell *sec_devs;
0314 struct sec_pmic_dev *sec_pmic;
0315 int ret, num_sec_devs;
0316
0317 sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev),
0318 GFP_KERNEL);
0319 if (sec_pmic == NULL)
0320 return -ENOMEM;
0321
0322 i2c_set_clientdata(i2c, sec_pmic);
0323 sec_pmic->dev = &i2c->dev;
0324 sec_pmic->i2c = i2c;
0325 sec_pmic->irq = i2c->irq;
0326
0327 pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
0328 if (IS_ERR(pdata)) {
0329 ret = PTR_ERR(pdata);
0330 return ret;
0331 }
0332
0333 sec_pmic->device_type = (unsigned long)of_device_get_match_data(sec_pmic->dev);
0334 sec_pmic->pdata = pdata;
0335
0336 switch (sec_pmic->device_type) {
0337 case S2MPA01:
0338 regmap = &s2mpa01_regmap_config;
0339 break;
0340 case S2MPS11X:
0341 regmap = &s2mps11_regmap_config;
0342 break;
0343 case S2MPS13X:
0344 regmap = &s2mps13_regmap_config;
0345 break;
0346 case S2MPS14X:
0347 regmap = &s2mps14_regmap_config;
0348 break;
0349 case S2MPS15X:
0350 regmap = &s2mps15_regmap_config;
0351 break;
0352 case S5M8763X:
0353 regmap = &s5m8763_regmap_config;
0354 break;
0355 case S5M8767X:
0356 regmap = &s5m8767_regmap_config;
0357 break;
0358 case S2MPU02:
0359 regmap = &s2mpu02_regmap_config;
0360 break;
0361 default:
0362 regmap = &sec_regmap_config;
0363 break;
0364 }
0365
0366 sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
0367 if (IS_ERR(sec_pmic->regmap_pmic)) {
0368 ret = PTR_ERR(sec_pmic->regmap_pmic);
0369 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
0370 ret);
0371 return ret;
0372 }
0373
0374 sec_irq_init(sec_pmic);
0375
0376 pm_runtime_set_active(sec_pmic->dev);
0377
0378 switch (sec_pmic->device_type) {
0379 case S5M8751X:
0380 sec_devs = s5m8751_devs;
0381 num_sec_devs = ARRAY_SIZE(s5m8751_devs);
0382 break;
0383 case S5M8763X:
0384 sec_devs = s5m8763_devs;
0385 num_sec_devs = ARRAY_SIZE(s5m8763_devs);
0386 break;
0387 case S5M8767X:
0388 sec_devs = s5m8767_devs;
0389 num_sec_devs = ARRAY_SIZE(s5m8767_devs);
0390 break;
0391 case S2MPA01:
0392 sec_devs = s2mpa01_devs;
0393 num_sec_devs = ARRAY_SIZE(s2mpa01_devs);
0394 break;
0395 case S2MPS11X:
0396 sec_devs = s2mps11_devs;
0397 num_sec_devs = ARRAY_SIZE(s2mps11_devs);
0398 break;
0399 case S2MPS13X:
0400 sec_devs = s2mps13_devs;
0401 num_sec_devs = ARRAY_SIZE(s2mps13_devs);
0402 break;
0403 case S2MPS14X:
0404 sec_devs = s2mps14_devs;
0405 num_sec_devs = ARRAY_SIZE(s2mps14_devs);
0406 break;
0407 case S2MPS15X:
0408 sec_devs = s2mps15_devs;
0409 num_sec_devs = ARRAY_SIZE(s2mps15_devs);
0410 break;
0411 case S2MPU02:
0412 sec_devs = s2mpu02_devs;
0413 num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
0414 break;
0415 default:
0416 dev_err(&i2c->dev, "Unsupported device type (%lu)\n",
0417 sec_pmic->device_type);
0418 return -ENODEV;
0419 }
0420 ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
0421 NULL, 0, NULL);
0422 if (ret)
0423 return ret;
0424
0425 sec_pmic_configure(sec_pmic);
0426 sec_pmic_dump_rev(sec_pmic);
0427
0428 return ret;
0429 }
0430
0431 static void sec_pmic_shutdown(struct i2c_client *i2c)
0432 {
0433 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
0434 unsigned int reg, mask;
0435
0436 if (!sec_pmic->pdata->manual_poweroff)
0437 return;
0438
0439 switch (sec_pmic->device_type) {
0440 case S2MPS11X:
0441 reg = S2MPS11_REG_CTRL1;
0442 mask = S2MPS11_CTRL1_PWRHOLD_MASK;
0443 break;
0444 default:
0445
0446
0447
0448
0449 dev_warn(sec_pmic->dev,
0450 "Unsupported device %lu for manual power off\n",
0451 sec_pmic->device_type);
0452 return;
0453 }
0454
0455 regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
0456 }
0457
0458 #ifdef CONFIG_PM_SLEEP
0459 static int sec_pmic_suspend(struct device *dev)
0460 {
0461 struct i2c_client *i2c = to_i2c_client(dev);
0462 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
0463
0464 if (device_may_wakeup(dev))
0465 enable_irq_wake(sec_pmic->irq);
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475 disable_irq(sec_pmic->irq);
0476
0477 return 0;
0478 }
0479
0480 static int sec_pmic_resume(struct device *dev)
0481 {
0482 struct i2c_client *i2c = to_i2c_client(dev);
0483 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
0484
0485 if (device_may_wakeup(dev))
0486 disable_irq_wake(sec_pmic->irq);
0487 enable_irq(sec_pmic->irq);
0488
0489 return 0;
0490 }
0491 #endif
0492
0493 static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
0494
0495 static struct i2c_driver sec_pmic_driver = {
0496 .driver = {
0497 .name = "sec_pmic",
0498 .pm = &sec_pmic_pm_ops,
0499 .of_match_table = sec_dt_match,
0500 },
0501 .probe = sec_pmic_probe,
0502 .shutdown = sec_pmic_shutdown,
0503 };
0504 module_i2c_driver(sec_pmic_driver);
0505
0506 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
0507 MODULE_DESCRIPTION("Core support for the S5M MFD");
0508 MODULE_LICENSE("GPL");