hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/regulator/arizona-ldo1.c
....@@ -1,15 +1,10 @@
1
-/*
2
- * arizona-ldo1.c -- LDO1 supply for Arizona devices
3
- *
4
- * Copyright 2012 Wolfson Microelectronics PLC.
5
- *
6
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License as published by the
10
- * Free Software Foundation; either version 2 of the License, or (at your
11
- * option) any later version.
12
- */
1
+// SPDX-License-Identifier: GPL-2.0+
2
+//
3
+// arizona-ldo1.c -- LDO1 supply for Arizona devices
4
+//
5
+// Copyright 2012 Wolfson Microelectronics PLC.
6
+//
7
+// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
138
149 #include <linux/module.h>
1510 #include <linux/moduleparam.h>
....@@ -30,6 +25,10 @@
3025 #include <linux/mfd/arizona/pdata.h>
3126 #include <linux/mfd/arizona/registers.h>
3227
28
+#include <linux/mfd/madera/core.h>
29
+#include <linux/mfd/madera/pdata.h>
30
+#include <linux/mfd/madera/registers.h>
31
+
3332 struct arizona_ldo1 {
3433 struct regulator_dev *regulator;
3534 struct regmap *regmap;
....@@ -40,35 +39,10 @@
4039 struct gpio_desc *ena_gpiod;
4140 };
4241
43
-static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev,
44
- unsigned int selector)
45
-{
46
- if (selector >= rdev->desc->n_voltages)
47
- return -EINVAL;
48
-
49
- if (selector == rdev->desc->n_voltages - 1)
50
- return 1800000;
51
- else
52
- return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
53
-}
54
-
55
-static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev,
56
- int min_uV, int max_uV)
57
-{
58
- int sel;
59
-
60
- sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
61
- if (sel >= rdev->desc->n_voltages)
62
- sel = rdev->desc->n_voltages - 1;
63
-
64
- return sel;
65
-}
66
-
6742 static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
6843 unsigned sel)
6944 {
70
- struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
71
- struct regmap *regmap = ldo->regmap;
45
+ struct regmap *regmap = rdev_get_regmap(rdev);
7246 unsigned int val;
7347 int ret;
7448
....@@ -85,16 +59,12 @@
8559 if (val)
8660 return 0;
8761
88
- val = sel << ARIZONA_LDO1_VSEL_SHIFT;
89
-
90
- return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1,
91
- ARIZONA_LDO1_VSEL_MASK, val);
62
+ return regulator_set_voltage_sel_regmap(rdev, sel);
9263 }
9364
9465 static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
9566 {
96
- struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
97
- struct regmap *regmap = ldo->regmap;
67
+ struct regmap *regmap = rdev_get_regmap(rdev);
9868 unsigned int val;
9969 int ret;
10070
....@@ -105,20 +75,21 @@
10575 if (val & ARIZONA_LDO1_HI_PWR)
10676 return rdev->desc->n_voltages - 1;
10777
108
- ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val);
109
- if (ret != 0)
110
- return ret;
111
-
112
- return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT;
78
+ return regulator_get_voltage_sel_regmap(rdev);
11379 }
11480
11581 static const struct regulator_ops arizona_ldo1_hc_ops = {
116
- .list_voltage = arizona_ldo1_hc_list_voltage,
117
- .map_voltage = arizona_ldo1_hc_map_voltage,
82
+ .list_voltage = regulator_list_voltage_linear_range,
83
+ .map_voltage = regulator_map_voltage_linear_range,
11884 .get_voltage_sel = arizona_ldo1_hc_get_voltage_sel,
11985 .set_voltage_sel = arizona_ldo1_hc_set_voltage_sel,
12086 .get_bypass = regulator_get_bypass_regmap,
12187 .set_bypass = regulator_set_bypass_regmap,
88
+};
89
+
90
+static const struct linear_range arizona_ldo1_hc_ranges[] = {
91
+ REGULATOR_LINEAR_RANGE(900000, 0, 0x6, 50000),
92
+ REGULATOR_LINEAR_RANGE(1800000, 0x7, 0x7, 0),
12293 };
12394
12495 static const struct regulator_desc arizona_ldo1_hc = {
....@@ -127,10 +98,12 @@
12798 .type = REGULATOR_VOLTAGE,
12899 .ops = &arizona_ldo1_hc_ops,
129100
101
+ .vsel_reg = ARIZONA_LDO1_CONTROL_1,
102
+ .vsel_mask = ARIZONA_LDO1_VSEL_MASK,
130103 .bypass_reg = ARIZONA_LDO1_CONTROL_1,
131104 .bypass_mask = ARIZONA_LDO1_BYPASS,
132
- .min_uV = 900000,
133
- .uV_step = 50000,
105
+ .linear_ranges = arizona_ldo1_hc_ranges,
106
+ .n_linear_ranges = ARRAY_SIZE(arizona_ldo1_hc_ranges),
134107 .n_voltages = 8,
135108 .enable_time = 1500,
136109 .ramp_delay = 24000,
....@@ -185,6 +158,31 @@
185158 .max_uV = 1200000,
186159 .valid_ops_mask = REGULATOR_CHANGE_STATUS |
187160 REGULATOR_CHANGE_VOLTAGE,
161
+ },
162
+ .num_consumer_supplies = 1,
163
+};
164
+
165
+static const struct regulator_desc madera_ldo1 = {
166
+ .name = "LDO1",
167
+ .supply_name = "LDOVDD",
168
+ .type = REGULATOR_VOLTAGE,
169
+ .ops = &arizona_ldo1_ops,
170
+
171
+ .vsel_reg = MADERA_LDO1_CONTROL_1,
172
+ .vsel_mask = MADERA_LDO1_VSEL_MASK,
173
+ .min_uV = 900000,
174
+ .uV_step = 25000,
175
+ .n_voltages = 13,
176
+ .enable_time = 3000,
177
+
178
+ .owner = THIS_MODULE,
179
+};
180
+
181
+static const struct regulator_init_data madera_ldo1_default = {
182
+ .constraints = {
183
+ .min_uV = 1200000,
184
+ .max_uV = 1200000,
185
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
188186 },
189187 .num_consumer_supplies = 1,
190188 };
....@@ -260,7 +258,7 @@
260258 * so clean up would happen at the wrong time
261259 */
262260 config.ena_gpiod = gpiod_get_optional(parent_dev, "wlf,ldoena",
263
- GPIOD_OUT_LOW);
261
+ GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
264262 if (IS_ERR(config.ena_gpiod))
265263 return PTR_ERR(config.ena_gpiod);
266264
....@@ -283,9 +281,6 @@
283281 of_node_put(config.of_node);
284282
285283 if (IS_ERR(ldo1->regulator)) {
286
- if (config.ena_gpiod)
287
- gpiod_put(config.ena_gpiod);
288
-
289284 ret = PTR_ERR(ldo1->regulator);
290285 dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n",
291286 ret);
....@@ -354,6 +349,32 @@
354349 return 0;
355350 }
356351
352
+static int madera_ldo1_probe(struct platform_device *pdev)
353
+{
354
+ struct madera *madera = dev_get_drvdata(pdev->dev.parent);
355
+ struct arizona_ldo1 *ldo1;
356
+ bool external_dcvdd;
357
+ int ret;
358
+
359
+ ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
360
+ if (!ldo1)
361
+ return -ENOMEM;
362
+
363
+ ldo1->regmap = madera->regmap;
364
+
365
+ ldo1->init_data = madera_ldo1_default;
366
+
367
+ ret = arizona_ldo1_common_init(pdev, ldo1, &madera_ldo1,
368
+ &madera->pdata.ldo1,
369
+ &external_dcvdd);
370
+ if (ret)
371
+ return ret;
372
+
373
+ madera->internal_dcvdd = !external_dcvdd;
374
+
375
+ return 0;
376
+}
377
+
357378 static struct platform_driver arizona_ldo1_driver = {
358379 .probe = arizona_ldo1_probe,
359380 .remove = arizona_ldo1_remove,
....@@ -362,10 +383,36 @@
362383 },
363384 };
364385
365
-module_platform_driver(arizona_ldo1_driver);
386
+static struct platform_driver madera_ldo1_driver = {
387
+ .probe = madera_ldo1_probe,
388
+ .remove = arizona_ldo1_remove,
389
+ .driver = {
390
+ .name = "madera-ldo1",
391
+ },
392
+};
393
+
394
+static struct platform_driver * const madera_ldo1_drivers[] = {
395
+ &arizona_ldo1_driver,
396
+ &madera_ldo1_driver,
397
+};
398
+
399
+static int __init arizona_ldo1_init(void)
400
+{
401
+ return platform_register_drivers(madera_ldo1_drivers,
402
+ ARRAY_SIZE(madera_ldo1_drivers));
403
+}
404
+module_init(arizona_ldo1_init);
405
+
406
+static void __exit madera_ldo1_exit(void)
407
+{
408
+ platform_unregister_drivers(madera_ldo1_drivers,
409
+ ARRAY_SIZE(madera_ldo1_drivers));
410
+}
411
+module_exit(madera_ldo1_exit);
366412
367413 /* Module information */
368414 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
369415 MODULE_DESCRIPTION("Arizona LDO1 driver");
370416 MODULE_LICENSE("GPL");
371417 MODULE_ALIAS("platform:arizona-ldo1");
418
+MODULE_ALIAS("platform:madera-ldo1");