at91: kernel v5.15: copy config and patches from 5.10
[openwrt/openwrt.git] / target / linux / at91 / patches-5.15 / 125-regulator-mcp16502-add-support-for-ramp-delay.patch
1 From 7f13433e11a3c88f1fd6417c4c5e5a6c98370b9a Mon Sep 17 00:00:00 2001
2 From: Claudiu Beznea <claudiu.beznea@microchip.com>
3 Date: Fri, 13 Nov 2020 17:21:09 +0200
4 Subject: [PATCH 125/247] regulator: mcp16502: add support for ramp delay
5
6 MCP16502 have configurable ramp delay support (via DVSR bits in
7 regulators' CFG register).
8
9 Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
10 Link: https://lore.kernel.org/r/1605280870-32432-6-git-send-email-claudiu.beznea@microchip.com
11 Signed-off-by: Mark Brown <broonie@kernel.org>
12 ---
13 drivers/regulator/mcp16502.c | 89 +++++++++++++++++++++++++++++++++++-
14 1 file changed, 87 insertions(+), 2 deletions(-)
15
16 --- a/drivers/regulator/mcp16502.c
17 +++ b/drivers/regulator/mcp16502.c
18 @@ -22,8 +22,9 @@
19 #define VDD_LOW_SEL 0x0D
20 #define VDD_HIGH_SEL 0x3F
21
22 -#define MCP16502_FLT BIT(7)
23 -#define MCP16502_ENS BIT(0)
24 +#define MCP16502_FLT BIT(7)
25 +#define MCP16502_DVSR GENMASK(3, 2)
26 +#define MCP16502_ENS BIT(0)
27
28 /*
29 * The PMIC has four sets of registers corresponding to four power modes:
30 @@ -88,6 +89,12 @@ enum mcp16502_reg {
31 MCP16502_REG_CFG,
32 };
33
34 +/* Ramp delay (uV/us) for buck1, ldo1, ldo2. */
35 +static const int mcp16502_ramp_b1l12[] = { 6250, 3125, 2083, 1563 };
36 +
37 +/* Ramp delay (uV/us) for buck2, buck3, buck4. */
38 +static const int mcp16502_ramp_b234[] = { 3125, 1563, 1042, 781 };
39 +
40 static unsigned int mcp16502_of_map_mode(unsigned int mode)
41 {
42 if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
43 @@ -271,6 +278,80 @@ static int mcp16502_get_status(struct re
44 return REGULATOR_STATUS_UNDEFINED;
45 }
46
47 +static int mcp16502_set_voltage_time_sel(struct regulator_dev *rdev,
48 + unsigned int old_sel,
49 + unsigned int new_sel)
50 +{
51 + static const u8 us_ramp[] = { 8, 16, 24, 32 };
52 + int id = rdev_get_id(rdev);
53 + unsigned int uV_delta, val;
54 + int ret;
55 +
56 + ret = regmap_read(rdev->regmap, MCP16502_REG_BASE(id, CFG), &val);
57 + if (ret)
58 + return ret;
59 +
60 + val = (val & MCP16502_DVSR) >> 2;
61 + uV_delta = abs(new_sel * rdev->desc->linear_ranges->step -
62 + old_sel * rdev->desc->linear_ranges->step);
63 + switch (id) {
64 + case BUCK1:
65 + case LDO1:
66 + case LDO2:
67 + ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
68 + mcp16502_ramp_b1l12[val]);
69 + break;
70 +
71 + case BUCK2:
72 + case BUCK3:
73 + case BUCK4:
74 + ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
75 + mcp16502_ramp_b234[val]);
76 + break;
77 +
78 + default:
79 + return -EINVAL;
80 + }
81 +
82 + return ret;
83 +}
84 +
85 +static int mcp16502_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
86 +{
87 + const int *ramp;
88 + int id = rdev_get_id(rdev);
89 + unsigned int i, size;
90 +
91 + switch (id) {
92 + case BUCK1:
93 + case LDO1:
94 + case LDO2:
95 + ramp = mcp16502_ramp_b1l12;
96 + size = ARRAY_SIZE(mcp16502_ramp_b1l12);
97 + break;
98 +
99 + case BUCK2:
100 + case BUCK3:
101 + case BUCK4:
102 + ramp = mcp16502_ramp_b234;
103 + size = ARRAY_SIZE(mcp16502_ramp_b234);
104 + break;
105 +
106 + default:
107 + return -EINVAL;
108 + }
109 +
110 + for (i = 0; i < size; i++) {
111 + if (ramp[i] == ramp_delay)
112 + break;
113 + }
114 + if (i == size)
115 + return -EINVAL;
116 +
117 + return regmap_update_bits(rdev->regmap, MCP16502_REG_BASE(id, CFG),
118 + MCP16502_DVSR, (i << 2));
119 +}
120 +
121 #ifdef CONFIG_SUSPEND
122 /*
123 * mcp16502_suspend_get_target_reg() - get the reg of the target suspend PMIC
124 @@ -365,6 +446,8 @@ static const struct regulator_ops mcp165
125 .disable = regulator_disable_regmap,
126 .is_enabled = regulator_is_enabled_regmap,
127 .get_status = mcp16502_get_status,
128 + .set_voltage_time_sel = mcp16502_set_voltage_time_sel,
129 + .set_ramp_delay = mcp16502_set_ramp_delay,
130
131 .set_mode = mcp16502_set_mode,
132 .get_mode = mcp16502_get_mode,
133 @@ -389,6 +472,8 @@ static const struct regulator_ops mcp165
134 .disable = regulator_disable_regmap,
135 .is_enabled = regulator_is_enabled_regmap,
136 .get_status = mcp16502_get_status,
137 + .set_voltage_time_sel = mcp16502_set_voltage_time_sel,
138 + .set_ramp_delay = mcp16502_set_ramp_delay,
139
140 #ifdef CONFIG_SUSPEND
141 .set_suspend_voltage = mcp16502_set_suspend_voltage,