.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Regulators driver for Marvell 88PM8607 |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2009 Marvell International Ltd. |
---|
5 | 6 | * Haojian Zhuang <haojian.zhuang@marvell.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License version 2 as |
---|
9 | | - * published by the Free Software Foundation. |
---|
10 | 7 | */ |
---|
11 | 8 | #include <linux/kernel.h> |
---|
12 | 9 | #include <linux/init.h> |
---|
13 | 10 | #include <linux/err.h> |
---|
14 | | -#include <linux/i2c.h> |
---|
15 | 11 | #include <linux/of.h> |
---|
16 | 12 | #include <linux/regulator/of_regulator.h> |
---|
17 | 13 | #include <linux/platform_device.h> |
---|
.. | .. |
---|
22 | 18 | |
---|
23 | 19 | struct pm8607_regulator_info { |
---|
24 | 20 | struct regulator_desc desc; |
---|
25 | | - struct pm860x_chip *chip; |
---|
26 | | - struct regulator_dev *regulator; |
---|
27 | | - struct i2c_client *i2c; |
---|
28 | | - struct i2c_client *i2c_8606; |
---|
29 | 21 | |
---|
30 | | - unsigned int *vol_table; |
---|
31 | 22 | unsigned int *vol_suspend; |
---|
32 | 23 | |
---|
33 | 24 | int slope_double; |
---|
.. | .. |
---|
210 | 201 | static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) |
---|
211 | 202 | { |
---|
212 | 203 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
---|
213 | | - int ret = -EINVAL; |
---|
| 204 | + int ret; |
---|
214 | 205 | |
---|
215 | | - if (info->vol_table && (index < rdev->desc->n_voltages)) { |
---|
216 | | - ret = info->vol_table[index]; |
---|
217 | | - if (info->slope_double) |
---|
218 | | - ret <<= 1; |
---|
219 | | - } |
---|
| 206 | + ret = regulator_list_voltage_table(rdev, index); |
---|
| 207 | + if (ret < 0) |
---|
| 208 | + return ret; |
---|
| 209 | + |
---|
| 210 | + if (info->slope_double) |
---|
| 211 | + ret <<= 1; |
---|
| 212 | + |
---|
220 | 213 | return ret; |
---|
221 | 214 | } |
---|
222 | 215 | |
---|
.. | .. |
---|
239 | 232 | { \ |
---|
240 | 233 | .desc = { \ |
---|
241 | 234 | .name = "PREG", \ |
---|
| 235 | + .of_match = of_match_ptr("PREG"), \ |
---|
| 236 | + .regulators_node = of_match_ptr("regulators"), \ |
---|
242 | 237 | .ops = &pm8606_preg_ops, \ |
---|
243 | 238 | .type = REGULATOR_CURRENT, \ |
---|
244 | 239 | .id = PM8606_ID_PREG, \ |
---|
.. | .. |
---|
253 | 248 | { \ |
---|
254 | 249 | .desc = { \ |
---|
255 | 250 | .name = #vreg, \ |
---|
| 251 | + .of_match = of_match_ptr(#vreg), \ |
---|
| 252 | + .regulators_node = of_match_ptr("regulators"), \ |
---|
256 | 253 | .ops = &pm8607_regulator_ops, \ |
---|
257 | 254 | .type = REGULATOR_VOLTAGE, \ |
---|
258 | 255 | .id = PM8607_ID_##vreg, \ |
---|
259 | 256 | .owner = THIS_MODULE, \ |
---|
| 257 | + .volt_table = vreg##_table, \ |
---|
260 | 258 | .n_voltages = ARRAY_SIZE(vreg##_table), \ |
---|
261 | 259 | .vsel_reg = PM8607_##vreg, \ |
---|
262 | 260 | .vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \ |
---|
.. | .. |
---|
266 | 264 | .enable_mask = 1 << (ebit), \ |
---|
267 | 265 | }, \ |
---|
268 | 266 | .slope_double = (0), \ |
---|
269 | | - .vol_table = (unsigned int *)&vreg##_table, \ |
---|
270 | 267 | .vol_suspend = (unsigned int *)&vreg##_suspend_table, \ |
---|
271 | 268 | } |
---|
272 | 269 | |
---|
.. | .. |
---|
274 | 271 | { \ |
---|
275 | 272 | .desc = { \ |
---|
276 | 273 | .name = "LDO" #_id, \ |
---|
| 274 | + .of_match = of_match_ptr("LDO" #_id), \ |
---|
| 275 | + .regulators_node = of_match_ptr("regulators"), \ |
---|
277 | 276 | .ops = &pm8607_regulator_ops, \ |
---|
278 | 277 | .type = REGULATOR_VOLTAGE, \ |
---|
279 | 278 | .id = PM8607_ID_LDO##_id, \ |
---|
280 | 279 | .owner = THIS_MODULE, \ |
---|
| 280 | + .volt_table = LDO##_id##_table, \ |
---|
281 | 281 | .n_voltages = ARRAY_SIZE(LDO##_id##_table), \ |
---|
282 | 282 | .vsel_reg = PM8607_##vreg, \ |
---|
283 | 283 | .vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \ |
---|
.. | .. |
---|
285 | 285 | .enable_mask = 1 << (ebit), \ |
---|
286 | 286 | }, \ |
---|
287 | 287 | .slope_double = (0), \ |
---|
288 | | - .vol_table = (unsigned int *)&LDO##_id##_table, \ |
---|
289 | 288 | .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \ |
---|
290 | 289 | } |
---|
291 | 290 | |
---|
.. | .. |
---|
313 | 312 | PM8606_PREG(PREREGULATORB, 5), |
---|
314 | 313 | }; |
---|
315 | 314 | |
---|
316 | | -#ifdef CONFIG_OF |
---|
317 | | -static int pm8607_regulator_dt_init(struct platform_device *pdev, |
---|
318 | | - struct pm8607_regulator_info *info, |
---|
319 | | - struct regulator_config *config) |
---|
320 | | -{ |
---|
321 | | - struct device_node *nproot, *np; |
---|
322 | | - nproot = pdev->dev.parent->of_node; |
---|
323 | | - if (!nproot) |
---|
324 | | - return -ENODEV; |
---|
325 | | - nproot = of_get_child_by_name(nproot, "regulators"); |
---|
326 | | - if (!nproot) { |
---|
327 | | - dev_err(&pdev->dev, "failed to find regulators node\n"); |
---|
328 | | - return -ENODEV; |
---|
329 | | - } |
---|
330 | | - for_each_child_of_node(nproot, np) { |
---|
331 | | - if (!of_node_cmp(np->name, info->desc.name)) { |
---|
332 | | - config->init_data = |
---|
333 | | - of_get_regulator_init_data(&pdev->dev, np, |
---|
334 | | - &info->desc); |
---|
335 | | - config->of_node = np; |
---|
336 | | - break; |
---|
337 | | - } |
---|
338 | | - } |
---|
339 | | - of_node_put(nproot); |
---|
340 | | - return 0; |
---|
341 | | -} |
---|
342 | | -#else |
---|
343 | | -#define pm8607_regulator_dt_init(x, y, z) (-1) |
---|
344 | | -#endif |
---|
345 | | - |
---|
346 | 315 | static int pm8607_regulator_probe(struct platform_device *pdev) |
---|
347 | 316 | { |
---|
348 | 317 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
---|
349 | 318 | struct pm8607_regulator_info *info = NULL; |
---|
350 | 319 | struct regulator_init_data *pdata = dev_get_platdata(&pdev->dev); |
---|
351 | 320 | struct regulator_config config = { }; |
---|
| 321 | + struct regulator_dev *rdev; |
---|
352 | 322 | struct resource *res; |
---|
353 | 323 | int i; |
---|
354 | 324 | |
---|
.. | .. |
---|
371 | 341 | /* i is used to check regulator ID */ |
---|
372 | 342 | i = -1; |
---|
373 | 343 | } |
---|
374 | | - info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; |
---|
375 | | - info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : |
---|
376 | | - chip->client; |
---|
377 | | - info->chip = chip; |
---|
378 | 344 | |
---|
379 | 345 | /* check DVC ramp slope double */ |
---|
380 | | - if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double) |
---|
| 346 | + if ((i == PM8607_ID_BUCK3) && chip->buck3_double) |
---|
381 | 347 | info->slope_double = 1; |
---|
382 | 348 | |
---|
383 | | - config.dev = &pdev->dev; |
---|
| 349 | + config.dev = chip->dev; |
---|
384 | 350 | config.driver_data = info; |
---|
385 | 351 | |
---|
386 | | - if (pm8607_regulator_dt_init(pdev, info, &config)) |
---|
387 | | - if (pdata) |
---|
388 | | - config.init_data = pdata; |
---|
| 352 | + if (pdata) |
---|
| 353 | + config.init_data = pdata; |
---|
389 | 354 | |
---|
390 | 355 | if (chip->id == CHIP_PM8607) |
---|
391 | 356 | config.regmap = chip->regmap; |
---|
392 | 357 | else |
---|
393 | 358 | config.regmap = chip->regmap_companion; |
---|
394 | 359 | |
---|
395 | | - info->regulator = devm_regulator_register(&pdev->dev, &info->desc, |
---|
396 | | - &config); |
---|
397 | | - if (IS_ERR(info->regulator)) { |
---|
| 360 | + rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); |
---|
| 361 | + if (IS_ERR(rdev)) { |
---|
398 | 362 | dev_err(&pdev->dev, "failed to register regulator %s\n", |
---|
399 | 363 | info->desc.name); |
---|
400 | | - return PTR_ERR(info->regulator); |
---|
| 364 | + return PTR_ERR(rdev); |
---|
401 | 365 | } |
---|
402 | 366 | |
---|
403 | 367 | platform_set_drvdata(pdev, info); |
---|