aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-19 07:43:08 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-19 07:43:08 -0500
commit178a097d5e6ae57d67310ff18bef0afb5589f2dd (patch)
treef64a80af7069b46bea3f55c5f2d90e9881565a36 /drivers/mfd
parent728088871c867f912f8a33ea049b7c4135c95637 (diff)
parente81d7bc89c9623ea000890fb4cdf7e731dc21f71 (diff)
Merge remote-tracking branch 'regulator/topic/s5m8767' into regulator-next
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/sec-core.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index 49d361a618d0..77ee26ef5941 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -17,6 +17,7 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/of_irq.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
@@ -60,6 +61,15 @@ static struct mfd_cell s2mps11_devs[] = {
60 }, 61 },
61}; 62};
62 63
64#ifdef CONFIG_OF
65static struct of_device_id sec_dt_match[] = {
66 { .compatible = "samsung,s5m8767-pmic",
67 .data = (void *)S5M8767X,
68 },
69 {},
70};
71#endif
72
63int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest) 73int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest)
64{ 74{
65 return regmap_read(sec_pmic->regmap, reg, dest); 75 return regmap_read(sec_pmic->regmap, reg, dest);
@@ -95,6 +105,57 @@ static struct regmap_config sec_regmap_config = {
95 .val_bits = 8, 105 .val_bits = 8,
96}; 106};
97 107
108
109#ifdef CONFIG_OF
110/*
111 * Only the common platform data elements for s5m8767 are parsed here from the
112 * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
113 * others have to parse their own platform data elements from device tree.
114 *
115 * The s5m8767 platform data structure is instantiated here and the drivers for
116 * the sub-modules need not instantiate another instance while parsing their
117 * platform data.
118 */
119static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
120 struct device *dev)
121{
122 struct sec_platform_data *pd;
123
124 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
125 if (!pd) {
126 dev_err(dev, "could not allocate memory for pdata\n");
127 return ERR_PTR(-ENOMEM);
128 }
129
130 /*
131 * ToDo: the 'wakeup' member in the platform data is more of a linux
132 * specfic information. Hence, there is no binding for that yet and
133 * not parsed here.
134 */
135
136 return pd;
137}
138#else
139static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
140 struct device *dev)
141{
142 return 0;
143}
144#endif
145
146static inline int sec_i2c_get_driver_data(struct i2c_client *i2c,
147 const struct i2c_device_id *id)
148{
149#ifdef CONFIG_OF
150 if (i2c->dev.of_node) {
151 const struct of_device_id *match;
152 match = of_match_node(sec_dt_match, i2c->dev.of_node);
153 return (int)match->data;
154 }
155#endif
156 return (int)id->driver_data;
157}
158
98static int sec_pmic_probe(struct i2c_client *i2c, 159static int sec_pmic_probe(struct i2c_client *i2c,
99 const struct i2c_device_id *id) 160 const struct i2c_device_id *id)
100{ 161{
@@ -111,13 +172,22 @@ static int sec_pmic_probe(struct i2c_client *i2c,
111 sec_pmic->dev = &i2c->dev; 172 sec_pmic->dev = &i2c->dev;
112 sec_pmic->i2c = i2c; 173 sec_pmic->i2c = i2c;
113 sec_pmic->irq = i2c->irq; 174 sec_pmic->irq = i2c->irq;
114 sec_pmic->type = id->driver_data; 175 sec_pmic->type = sec_i2c_get_driver_data(i2c, id);
115 176
177 if (sec_pmic->dev->of_node) {
178 pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
179 if (IS_ERR(pdata)) {
180 ret = PTR_ERR(pdata);
181 return ret;
182 }
183 pdata->device_type = sec_pmic->type;
184 }
116 if (pdata) { 185 if (pdata) {
117 sec_pmic->device_type = pdata->device_type; 186 sec_pmic->device_type = pdata->device_type;
118 sec_pmic->ono = pdata->ono; 187 sec_pmic->ono = pdata->ono;
119 sec_pmic->irq_base = pdata->irq_base; 188 sec_pmic->irq_base = pdata->irq_base;
120 sec_pmic->wakeup = pdata->wakeup; 189 sec_pmic->wakeup = pdata->wakeup;
190 sec_pmic->pdata = pdata;
121 } 191 }
122 192
123 sec_pmic->regmap = devm_regmap_init_i2c(i2c, &sec_regmap_config); 193 sec_pmic->regmap = devm_regmap_init_i2c(i2c, &sec_regmap_config);
@@ -192,6 +262,7 @@ static struct i2c_driver sec_pmic_driver = {
192 .driver = { 262 .driver = {
193 .name = "sec_pmic", 263 .name = "sec_pmic",
194 .owner = THIS_MODULE, 264 .owner = THIS_MODULE,
265 .of_match_table = of_match_ptr(sec_dt_match),
195 }, 266 },
196 .probe = sec_pmic_probe, 267 .probe = sec_pmic_probe,
197 .remove = sec_pmic_remove, 268 .remove = sec_pmic_remove,