Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/mfd/sec-core.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us