aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/tps65090-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/tps65090-regulator.c')
-rw-r--r--drivers/regulator/tps65090-regulator.c106
1 files changed, 101 insertions, 5 deletions
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c
index 41c391789c97..c8e70451df38 100644
--- a/drivers/regulator/tps65090-regulator.c
+++ b/drivers/regulator/tps65090-regulator.c
@@ -19,11 +19,13 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22#include <linux/of_gpio.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <linux/err.h> 24#include <linux/err.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/regulator/driver.h> 26#include <linux/regulator/driver.h>
26#include <linux/regulator/machine.h> 27#include <linux/regulator/machine.h>
28#include <linux/regulator/of_regulator.h>
27#include <linux/mfd/tps65090.h> 29#include <linux/mfd/tps65090.h>
28 30
29struct tps65090_regulator { 31struct tps65090_regulator {
@@ -67,8 +69,8 @@ static struct regulator_desc tps65090_regulator_desc[] = {
67 tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), 69 tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops),
68 tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), 70 tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops),
69 tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), 71 tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops),
70 tps65090_REG_DESC(LDO1, "vsys_l1", 0, tps65090_ldo_ops), 72 tps65090_REG_DESC(LDO1, "vsys-l1", 0, tps65090_ldo_ops),
71 tps65090_REG_DESC(LDO2, "vsys_l2", 0, tps65090_ldo_ops), 73 tps65090_REG_DESC(LDO2, "vsys-l2", 0, tps65090_ldo_ops),
72}; 74};
73 75
74static inline bool is_dcdc(int id) 76static inline bool is_dcdc(int id)
@@ -138,6 +140,92 @@ static void tps65090_configure_regulator_config(
138 } 140 }
139} 141}
140 142
143#ifdef CONFIG_OF
144static struct of_regulator_match tps65090_matches[] = {
145 { .name = "dcdc1", },
146 { .name = "dcdc2", },
147 { .name = "dcdc3", },
148 { .name = "fet1", },
149 { .name = "fet2", },
150 { .name = "fet3", },
151 { .name = "fet4", },
152 { .name = "fet5", },
153 { .name = "fet6", },
154 { .name = "fet7", },
155 { .name = "ldo1", },
156 { .name = "ldo2", },
157};
158
159static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
160 struct platform_device *pdev,
161 struct of_regulator_match **tps65090_reg_matches)
162{
163 struct tps65090_platform_data *tps65090_pdata;
164 struct device_node *np = pdev->dev.parent->of_node;
165 struct device_node *regulators;
166 int idx = 0, ret;
167 struct tps65090_regulator_plat_data *reg_pdata;
168
169 tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata),
170 GFP_KERNEL);
171 if (!tps65090_pdata) {
172 dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n");
173 return ERR_PTR(-ENOMEM);
174 }
175
176 reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX *
177 sizeof(*reg_pdata), GFP_KERNEL);
178 if (!reg_pdata) {
179 dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n");
180 return ERR_PTR(-ENOMEM);
181 }
182
183 regulators = of_find_node_by_name(np, "regulators");
184 if (!regulators) {
185 dev_err(&pdev->dev, "regulator node not found\n");
186 return ERR_PTR(-ENODEV);
187 }
188
189 ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches,
190 ARRAY_SIZE(tps65090_matches));
191 if (ret < 0) {
192 dev_err(&pdev->dev,
193 "Error parsing regulator init data: %d\n", ret);
194 return ERR_PTR(ret);
195 }
196
197 *tps65090_reg_matches = tps65090_matches;
198 for (idx = 0; idx < ARRAY_SIZE(tps65090_matches); idx++) {
199 struct regulator_init_data *ri_data;
200 struct tps65090_regulator_plat_data *rpdata;
201
202 rpdata = &reg_pdata[idx];
203 ri_data = tps65090_matches[idx].init_data;
204 if (!ri_data || !tps65090_matches[idx].of_node)
205 continue;
206
207 rpdata->reg_init_data = ri_data;
208 rpdata->enable_ext_control = of_property_read_bool(
209 tps65090_matches[idx].of_node,
210 "ti,enable-ext-control");
211 if (rpdata->enable_ext_control)
212 rpdata->gpio = of_get_named_gpio(np,
213 "dcdc-ext-control-gpios", 0);
214
215 tps65090_pdata->reg_pdata[idx] = rpdata;
216 }
217 return tps65090_pdata;
218}
219#else
220static inline struct tps65090_platform_data *tps65090_parse_dt_reg_data(
221 struct platform_device *pdev,
222 struct of_regulator_match **tps65090_reg_matches)
223{
224 *tps65090_reg_matches = NULL;
225 return NULL;
226}
227#endif
228
141static int tps65090_regulator_probe(struct platform_device *pdev) 229static int tps65090_regulator_probe(struct platform_device *pdev)
142{ 230{
143 struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); 231 struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
@@ -147,15 +235,19 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
147 struct tps65090_regulator_plat_data *tps_pdata; 235 struct tps65090_regulator_plat_data *tps_pdata;
148 struct tps65090_regulator *pmic; 236 struct tps65090_regulator *pmic;
149 struct tps65090_platform_data *tps65090_pdata; 237 struct tps65090_platform_data *tps65090_pdata;
238 struct of_regulator_match *tps65090_reg_matches = NULL;
150 int num; 239 int num;
151 int ret; 240 int ret;
152 241
153 dev_dbg(&pdev->dev, "Probing regulator\n"); 242 dev_dbg(&pdev->dev, "Probing regulator\n");
154 243
155 tps65090_pdata = dev_get_platdata(pdev->dev.parent); 244 tps65090_pdata = dev_get_platdata(pdev->dev.parent);
156 if (!tps65090_pdata) { 245 if (!tps65090_pdata && tps65090_mfd->dev->of_node)
246 tps65090_pdata = tps65090_parse_dt_reg_data(pdev,
247 &tps65090_reg_matches);
248 if (IS_ERR_OR_NULL(tps65090_pdata)) {
157 dev_err(&pdev->dev, "Platform data missing\n"); 249 dev_err(&pdev->dev, "Platform data missing\n");
158 return -EINVAL; 250 return tps65090_pdata ? PTR_ERR(tps65090_pdata) : -EINVAL;
159 } 251 }
160 252
161 pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), 253 pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic),
@@ -192,13 +284,17 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
192 } 284 }
193 } 285 }
194 286
195 config.dev = &pdev->dev; 287 config.dev = pdev->dev.parent;
196 config.driver_data = ri; 288 config.driver_data = ri;
197 config.regmap = tps65090_mfd->rmap; 289 config.regmap = tps65090_mfd->rmap;
198 if (tps_pdata) 290 if (tps_pdata)
199 config.init_data = tps_pdata->reg_init_data; 291 config.init_data = tps_pdata->reg_init_data;
200 else 292 else
201 config.init_data = NULL; 293 config.init_data = NULL;
294 if (tps65090_reg_matches)
295 config.of_node = tps65090_reg_matches[num].of_node;
296 else
297 config.of_node = NULL;
202 298
203 rdev = regulator_register(ri->desc, &config); 299 rdev = regulator_register(ri->desc, &config);
204 if (IS_ERR(rdev)) { 300 if (IS_ERR(rdev)) {