aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/sec-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/sec-core.c')
-rw-r--r--drivers/mfd/sec-core.c176
1 files changed, 156 insertions, 20 deletions
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index 1d158d5ba8b8..281a82747275 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -26,12 +26,14 @@
26#include <linux/mfd/samsung/core.h> 26#include <linux/mfd/samsung/core.h>
27#include <linux/mfd/samsung/irq.h> 27#include <linux/mfd/samsung/irq.h>
28#include <linux/mfd/samsung/rtc.h> 28#include <linux/mfd/samsung/rtc.h>
29#include <linux/mfd/samsung/s2mpa01.h>
29#include <linux/mfd/samsung/s2mps11.h> 30#include <linux/mfd/samsung/s2mps11.h>
31#include <linux/mfd/samsung/s2mps14.h>
30#include <linux/mfd/samsung/s5m8763.h> 32#include <linux/mfd/samsung/s5m8763.h>
31#include <linux/mfd/samsung/s5m8767.h> 33#include <linux/mfd/samsung/s5m8767.h>
32#include <linux/regmap.h> 34#include <linux/regmap.h>
33 35
34static struct mfd_cell s5m8751_devs[] = { 36static const struct mfd_cell s5m8751_devs[] = {
35 { 37 {
36 .name = "s5m8751-pmic", 38 .name = "s5m8751-pmic",
37 }, { 39 }, {
@@ -41,7 +43,7 @@ static struct mfd_cell s5m8751_devs[] = {
41 }, 43 },
42}; 44};
43 45
44static struct mfd_cell s5m8763_devs[] = { 46static const struct mfd_cell s5m8763_devs[] = {
45 { 47 {
46 .name = "s5m8763-pmic", 48 .name = "s5m8763-pmic",
47 }, { 49 }, {
@@ -51,15 +53,17 @@ static struct mfd_cell s5m8763_devs[] = {
51 }, 53 },
52}; 54};
53 55
54static struct mfd_cell s5m8767_devs[] = { 56static const struct mfd_cell s5m8767_devs[] = {
55 { 57 {
56 .name = "s5m8767-pmic", 58 .name = "s5m8767-pmic",
57 }, { 59 }, {
58 .name = "s5m-rtc", 60 .name = "s5m-rtc",
59 }, 61 }, {
62 .name = "s5m8767-clk",
63 }
60}; 64};
61 65
62static struct mfd_cell s2mps11_devs[] = { 66static const struct mfd_cell s2mps11_devs[] = {
63 { 67 {
64 .name = "s2mps11-pmic", 68 .name = "s2mps11-pmic",
65 }, { 69 }, {
@@ -67,18 +71,53 @@ static struct mfd_cell s2mps11_devs[] = {
67 } 71 }
68}; 72};
69 73
74static const struct mfd_cell s2mps14_devs[] = {
75 {
76 .name = "s2mps14-pmic",
77 }, {
78 .name = "s2mps14-rtc",
79 }, {
80 .name = "s2mps14-clk",
81 }
82};
83
84static const struct mfd_cell s2mpa01_devs[] = {
85 {
86 .name = "s2mpa01-pmic",
87 },
88};
89
70#ifdef CONFIG_OF 90#ifdef CONFIG_OF
71static struct of_device_id sec_dt_match[] = { 91static struct of_device_id sec_dt_match[] = {
72 { .compatible = "samsung,s5m8767-pmic", 92 { .compatible = "samsung,s5m8767-pmic",
73 .data = (void *)S5M8767X, 93 .data = (void *)S5M8767X,
74 }, 94 }, {
75 { .compatible = "samsung,s2mps11-pmic", 95 .compatible = "samsung,s2mps11-pmic",
76 .data = (void *)S2MPS11X, 96 .data = (void *)S2MPS11X,
97 }, {
98 .compatible = "samsung,s2mps14-pmic",
99 .data = (void *)S2MPS14X,
100 }, {
101 .compatible = "samsung,s2mpa01-pmic",
102 .data = (void *)S2MPA01,
103 }, {
104 /* Sentinel */
77 }, 105 },
78 {},
79}; 106};
80#endif 107#endif
81 108
109static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
110{
111 switch (reg) {
112 case S2MPA01_REG_INT1M:
113 case S2MPA01_REG_INT2M:
114 case S2MPA01_REG_INT3M:
115 return false;
116 default:
117 return true;
118 }
119}
120
82static bool s2mps11_volatile(struct device *dev, unsigned int reg) 121static bool s2mps11_volatile(struct device *dev, unsigned int reg)
83{ 122{
84 switch (reg) { 123 switch (reg) {
@@ -104,12 +143,21 @@ static bool s5m8763_volatile(struct device *dev, unsigned int reg)
104 } 143 }
105} 144}
106 145
107static struct regmap_config sec_regmap_config = { 146static const struct regmap_config sec_regmap_config = {
108 .reg_bits = 8, 147 .reg_bits = 8,
109 .val_bits = 8, 148 .val_bits = 8,
110}; 149};
111 150
112static struct regmap_config s2mps11_regmap_config = { 151static const struct regmap_config s2mpa01_regmap_config = {
152 .reg_bits = 8,
153 .val_bits = 8,
154
155 .max_register = S2MPA01_REG_LDO_OVCB4,
156 .volatile_reg = s2mpa01_volatile,
157 .cache_type = REGCACHE_FLAT,
158};
159
160static const struct regmap_config s2mps11_regmap_config = {
113 .reg_bits = 8, 161 .reg_bits = 8,
114 .val_bits = 8, 162 .val_bits = 8,
115 163
@@ -118,7 +166,16 @@ static struct regmap_config s2mps11_regmap_config = {
118 .cache_type = REGCACHE_FLAT, 166 .cache_type = REGCACHE_FLAT,
119}; 167};
120 168
121static struct regmap_config s5m8763_regmap_config = { 169static const struct regmap_config s2mps14_regmap_config = {
170 .reg_bits = 8,
171 .val_bits = 8,
172
173 .max_register = S2MPS14_REG_LDODSCH3,
174 .volatile_reg = s2mps11_volatile,
175 .cache_type = REGCACHE_FLAT,
176};
177
178static const struct regmap_config s5m8763_regmap_config = {
122 .reg_bits = 8, 179 .reg_bits = 8,
123 .val_bits = 8, 180 .val_bits = 8,
124 181
@@ -127,7 +184,7 @@ static struct regmap_config s5m8763_regmap_config = {
127 .cache_type = REGCACHE_FLAT, 184 .cache_type = REGCACHE_FLAT,
128}; 185};
129 186
130static struct regmap_config s5m8767_regmap_config = { 187static const struct regmap_config s5m8767_regmap_config = {
131 .reg_bits = 8, 188 .reg_bits = 8,
132 .val_bits = 8, 189 .val_bits = 8,
133 190
@@ -136,9 +193,18 @@ static struct regmap_config s5m8767_regmap_config = {
136 .cache_type = REGCACHE_FLAT, 193 .cache_type = REGCACHE_FLAT,
137}; 194};
138 195
139static const struct regmap_config sec_rtc_regmap_config = { 196static const struct regmap_config s5m_rtc_regmap_config = {
140 .reg_bits = 8, 197 .reg_bits = 8,
141 .val_bits = 8, 198 .val_bits = 8,
199
200 .max_register = SEC_RTC_REG_MAX,
201};
202
203static const struct regmap_config s2mps14_rtc_regmap_config = {
204 .reg_bits = 8,
205 .val_bits = 8,
206
207 .max_register = S2MPS_RTC_REG_MAX,
142}; 208};
143 209
144#ifdef CONFIG_OF 210#ifdef CONFIG_OF
@@ -174,28 +240,28 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
174static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( 240static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
175 struct device *dev) 241 struct device *dev)
176{ 242{
177 return 0; 243 return NULL;
178} 244}
179#endif 245#endif
180 246
181static inline int sec_i2c_get_driver_data(struct i2c_client *i2c, 247static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c,
182 const struct i2c_device_id *id) 248 const struct i2c_device_id *id)
183{ 249{
184#ifdef CONFIG_OF 250#ifdef CONFIG_OF
185 if (i2c->dev.of_node) { 251 if (i2c->dev.of_node) {
186 const struct of_device_id *match; 252 const struct of_device_id *match;
187 match = of_match_node(sec_dt_match, i2c->dev.of_node); 253 match = of_match_node(sec_dt_match, i2c->dev.of_node);
188 return (int)match->data; 254 return (unsigned long)match->data;
189 } 255 }
190#endif 256#endif
191 return (int)id->driver_data; 257 return id->driver_data;
192} 258}
193 259
194static int sec_pmic_probe(struct i2c_client *i2c, 260static int sec_pmic_probe(struct i2c_client *i2c,
195 const struct i2c_device_id *id) 261 const struct i2c_device_id *id)
196{ 262{
197 struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); 263 struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
198 const struct regmap_config *regmap; 264 const struct regmap_config *regmap, *regmap_rtc;
199 struct sec_pmic_dev *sec_pmic; 265 struct sec_pmic_dev *sec_pmic;
200 int ret; 266 int ret;
201 267
@@ -227,17 +293,34 @@ static int sec_pmic_probe(struct i2c_client *i2c,
227 } 293 }
228 294
229 switch (sec_pmic->device_type) { 295 switch (sec_pmic->device_type) {
296 case S2MPA01:
297 regmap = &s2mpa01_regmap_config;
298 break;
230 case S2MPS11X: 299 case S2MPS11X:
231 regmap = &s2mps11_regmap_config; 300 regmap = &s2mps11_regmap_config;
301 /*
302 * The rtc-s5m driver does not support S2MPS11 and there
303 * is no mfd_cell for S2MPS11 RTC device.
304 * However we must pass something to devm_regmap_init_i2c()
305 * so use S5M-like regmap config even though it wouldn't work.
306 */
307 regmap_rtc = &s5m_rtc_regmap_config;
308 break;
309 case S2MPS14X:
310 regmap = &s2mps14_regmap_config;
311 regmap_rtc = &s2mps14_rtc_regmap_config;
232 break; 312 break;
233 case S5M8763X: 313 case S5M8763X:
234 regmap = &s5m8763_regmap_config; 314 regmap = &s5m8763_regmap_config;
315 regmap_rtc = &s5m_rtc_regmap_config;
235 break; 316 break;
236 case S5M8767X: 317 case S5M8767X:
237 regmap = &s5m8767_regmap_config; 318 regmap = &s5m8767_regmap_config;
319 regmap_rtc = &s5m_rtc_regmap_config;
238 break; 320 break;
239 default: 321 default:
240 regmap = &sec_regmap_config; 322 regmap = &sec_regmap_config;
323 regmap_rtc = &s5m_rtc_regmap_config;
241 break; 324 break;
242 } 325 }
243 326
@@ -250,10 +333,13 @@ static int sec_pmic_probe(struct i2c_client *i2c,
250 } 333 }
251 334
252 sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); 335 sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
336 if (!sec_pmic->rtc) {
337 dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n");
338 return -ENODEV;
339 }
253 i2c_set_clientdata(sec_pmic->rtc, sec_pmic); 340 i2c_set_clientdata(sec_pmic->rtc, sec_pmic);
254 341
255 sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, 342 sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, regmap_rtc);
256 &sec_rtc_regmap_config);
257 if (IS_ERR(sec_pmic->regmap_rtc)) { 343 if (IS_ERR(sec_pmic->regmap_rtc)) {
258 ret = PTR_ERR(sec_pmic->regmap_rtc); 344 ret = PTR_ERR(sec_pmic->regmap_rtc);
259 dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n", 345 dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
@@ -281,10 +367,18 @@ static int sec_pmic_probe(struct i2c_client *i2c,
281 ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, 367 ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs,
282 ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); 368 ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL);
283 break; 369 break;
370 case S2MPA01:
371 ret = mfd_add_devices(sec_pmic->dev, -1, s2mpa01_devs,
372 ARRAY_SIZE(s2mpa01_devs), NULL, 0, NULL);
373 break;
284 case S2MPS11X: 374 case S2MPS11X:
285 ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, 375 ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs,
286 ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); 376 ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);
287 break; 377 break;
378 case S2MPS14X:
379 ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs,
380 ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL);
381 break;
288 default: 382 default:
289 /* If this happens the probe function is problem */ 383 /* If this happens the probe function is problem */
290 BUG(); 384 BUG();
@@ -293,6 +387,8 @@ static int sec_pmic_probe(struct i2c_client *i2c,
293 if (ret) 387 if (ret)
294 goto err; 388 goto err;
295 389
390 device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
391
296 return ret; 392 return ret;
297 393
298err: 394err:
@@ -311,6 +407,45 @@ static int sec_pmic_remove(struct i2c_client *i2c)
311 return 0; 407 return 0;
312} 408}
313 409
410#ifdef CONFIG_PM_SLEEP
411static int sec_pmic_suspend(struct device *dev)
412{
413 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
414 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
415
416 if (device_may_wakeup(dev)) {
417 enable_irq_wake(sec_pmic->irq);
418 /*
419 * PMIC IRQ must be disabled during suspend for RTC alarm
420 * to work properly.
421 * When device is woken up from suspend by RTC Alarm, an
422 * interrupt occurs before resuming I2C bus controller.
423 * The interrupt is handled by regmap_irq_thread which tries
424 * to read RTC registers. This read fails (I2C is still
425 * suspended) and RTC Alarm interrupt is disabled.
426 */
427 disable_irq(sec_pmic->irq);
428 }
429
430 return 0;
431}
432
433static int sec_pmic_resume(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 disable_irq_wake(sec_pmic->irq);
440 enable_irq(sec_pmic->irq);
441 }
442
443 return 0;
444}
445#endif /* CONFIG_PM_SLEEP */
446
447static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
448
314static const struct i2c_device_id sec_pmic_id[] = { 449static const struct i2c_device_id sec_pmic_id[] = {
315 { "sec_pmic", 0 }, 450 { "sec_pmic", 0 },
316 { } 451 { }
@@ -321,6 +456,7 @@ static struct i2c_driver sec_pmic_driver = {
321 .driver = { 456 .driver = {
322 .name = "sec_pmic", 457 .name = "sec_pmic",
323 .owner = THIS_MODULE, 458 .owner = THIS_MODULE,
459 .pm = &sec_pmic_pm_ops,
324 .of_match_table = of_match_ptr(sec_dt_match), 460 .of_match_table = of_match_ptr(sec_dt_match),
325 }, 461 },
326 .probe = sec_pmic_probe, 462 .probe = sec_pmic_probe,