.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Regulator driver for LP87565 PMIC |
---|
3 | 4 | * |
---|
4 | | - * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms of the GNU General Public License as published by the |
---|
8 | | - * Free Software Foundation version 2. |
---|
| 5 | + * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
14 | 11 | |
---|
15 | 12 | #include <linux/mfd/lp87565.h> |
---|
16 | 13 | |
---|
17 | | -#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, _er, _em, \ |
---|
18 | | - _delay, _lr, _cr) \ |
---|
| 14 | +#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, \ |
---|
| 15 | + _er, _em, _ev, _delay, _lr, _cr) \ |
---|
19 | 16 | [_id] = { \ |
---|
20 | 17 | .desc = { \ |
---|
21 | 18 | .name = _name, \ |
---|
.. | .. |
---|
31 | 28 | .vsel_mask = _vm, \ |
---|
32 | 29 | .enable_reg = _er, \ |
---|
33 | 30 | .enable_mask = _em, \ |
---|
| 31 | + .enable_val = _ev, \ |
---|
34 | 32 | .ramp_delay = _delay, \ |
---|
35 | 33 | .linear_ranges = _lr, \ |
---|
36 | 34 | .n_linear_ranges = ARRAY_SIZE(_lr), \ |
---|
| 35 | + .curr_table = lp87565_buck_uA, \ |
---|
| 36 | + .n_current_limits = ARRAY_SIZE(lp87565_buck_uA),\ |
---|
| 37 | + .csel_reg = (_cr), \ |
---|
| 38 | + .csel_mask = LP87565_BUCK_CTRL_2_ILIM, \ |
---|
37 | 39 | }, \ |
---|
38 | 40 | .ctrl2_reg = _cr, \ |
---|
39 | 41 | } |
---|
.. | .. |
---|
45 | 47 | |
---|
46 | 48 | static const struct lp87565_regulator regulators[]; |
---|
47 | 49 | |
---|
48 | | -static const struct regulator_linear_range buck0_1_2_3_ranges[] = { |
---|
| 50 | +static const struct linear_range buck0_1_2_3_ranges[] = { |
---|
49 | 51 | REGULATOR_LINEAR_RANGE(600000, 0xA, 0x17, 10000), |
---|
50 | 52 | REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000), |
---|
51 | 53 | REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), |
---|
52 | 54 | }; |
---|
53 | 55 | |
---|
54 | | -static unsigned int lp87565_buck_ramp_delay[] = { |
---|
| 56 | +static const unsigned int lp87565_buck_ramp_delay[] = { |
---|
55 | 57 | 30000, 15000, 10000, 7500, 3800, 1900, 940, 470 |
---|
56 | 58 | }; |
---|
57 | 59 | |
---|
.. | .. |
---|
64 | 66 | int ramp_delay) |
---|
65 | 67 | { |
---|
66 | 68 | int id = rdev_get_id(rdev); |
---|
67 | | - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); |
---|
68 | 69 | unsigned int reg; |
---|
69 | 70 | int ret; |
---|
70 | 71 | |
---|
.. | .. |
---|
85 | 86 | else |
---|
86 | 87 | reg = 0; |
---|
87 | 88 | |
---|
88 | | - ret = regmap_update_bits(lp87565->regmap, regulators[id].ctrl2_reg, |
---|
| 89 | + ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg, |
---|
89 | 90 | LP87565_BUCK_CTRL_2_SLEW_RATE, |
---|
90 | 91 | reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE)); |
---|
91 | 92 | if (ret) { |
---|
92 | | - dev_err(lp87565->dev, "SLEW RATE write failed: %d\n", ret); |
---|
| 93 | + dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret); |
---|
93 | 94 | return ret; |
---|
94 | 95 | } |
---|
95 | 96 | |
---|
.. | .. |
---|
102 | 103 | return 0; |
---|
103 | 104 | } |
---|
104 | 105 | |
---|
105 | | -static int lp87565_buck_set_current_limit(struct regulator_dev *rdev, |
---|
106 | | - int min_uA, int max_uA) |
---|
107 | | -{ |
---|
108 | | - int id = rdev_get_id(rdev); |
---|
109 | | - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); |
---|
110 | | - int i; |
---|
111 | | - |
---|
112 | | - for (i = ARRAY_SIZE(lp87565_buck_uA) - 1; i >= 0; i--) { |
---|
113 | | - if (lp87565_buck_uA[i] >= min_uA && |
---|
114 | | - lp87565_buck_uA[i] <= max_uA) |
---|
115 | | - return regmap_update_bits(lp87565->regmap, |
---|
116 | | - regulators[id].ctrl2_reg, |
---|
117 | | - LP87565_BUCK_CTRL_2_ILIM, |
---|
118 | | - i << __ffs(LP87565_BUCK_CTRL_2_ILIM)); |
---|
119 | | - } |
---|
120 | | - |
---|
121 | | - return -EINVAL; |
---|
122 | | -} |
---|
123 | | - |
---|
124 | | -static int lp87565_buck_get_current_limit(struct regulator_dev *rdev) |
---|
125 | | -{ |
---|
126 | | - int id = rdev_get_id(rdev); |
---|
127 | | - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); |
---|
128 | | - int ret; |
---|
129 | | - unsigned int val; |
---|
130 | | - |
---|
131 | | - ret = regmap_read(lp87565->regmap, regulators[id].ctrl2_reg, &val); |
---|
132 | | - if (ret) |
---|
133 | | - return ret; |
---|
134 | | - |
---|
135 | | - val = (val & LP87565_BUCK_CTRL_2_ILIM) >> |
---|
136 | | - __ffs(LP87565_BUCK_CTRL_2_ILIM); |
---|
137 | | - |
---|
138 | | - return (val < ARRAY_SIZE(lp87565_buck_uA)) ? |
---|
139 | | - lp87565_buck_uA[val] : -EINVAL; |
---|
140 | | -} |
---|
141 | | - |
---|
142 | | -/* Operations permitted on BUCK0, BUCK1 */ |
---|
143 | | -static struct regulator_ops lp87565_buck_ops = { |
---|
| 106 | +/* Operations permitted on BUCKs */ |
---|
| 107 | +static const struct regulator_ops lp87565_buck_ops = { |
---|
144 | 108 | .is_enabled = regulator_is_enabled_regmap, |
---|
145 | 109 | .enable = regulator_enable_regmap, |
---|
146 | 110 | .disable = regulator_disable_regmap, |
---|
.. | .. |
---|
150 | 114 | .map_voltage = regulator_map_voltage_linear_range, |
---|
151 | 115 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
---|
152 | 116 | .set_ramp_delay = lp87565_buck_set_ramp_delay, |
---|
153 | | - .set_current_limit = lp87565_buck_set_current_limit, |
---|
154 | | - .get_current_limit = lp87565_buck_get_current_limit, |
---|
| 117 | + .set_current_limit = regulator_set_current_limit_regmap, |
---|
| 118 | + .get_current_limit = regulator_get_current_limit_regmap, |
---|
155 | 119 | }; |
---|
156 | 120 | |
---|
157 | 121 | static const struct lp87565_regulator regulators[] = { |
---|
158 | 122 | LP87565_REGULATOR("BUCK0", LP87565_BUCK_0, "buck0", lp87565_buck_ops, |
---|
159 | 123 | 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, |
---|
160 | 124 | LP87565_REG_BUCK0_CTRL_1, |
---|
| 125 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 126 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
---|
161 | 127 | LP87565_BUCK_CTRL_1_EN, 3230, |
---|
162 | 128 | buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), |
---|
163 | 129 | LP87565_REGULATOR("BUCK1", LP87565_BUCK_1, "buck1", lp87565_buck_ops, |
---|
164 | 130 | 256, LP87565_REG_BUCK1_VOUT, LP87565_BUCK_VSET, |
---|
165 | 131 | LP87565_REG_BUCK1_CTRL_1, |
---|
| 132 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 133 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
---|
166 | 134 | LP87565_BUCK_CTRL_1_EN, 3230, |
---|
167 | 135 | buck0_1_2_3_ranges, LP87565_REG_BUCK1_CTRL_2), |
---|
168 | 136 | LP87565_REGULATOR("BUCK2", LP87565_BUCK_2, "buck2", lp87565_buck_ops, |
---|
169 | 137 | 256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET, |
---|
170 | 138 | LP87565_REG_BUCK2_CTRL_1, |
---|
| 139 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 140 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
---|
171 | 141 | LP87565_BUCK_CTRL_1_EN, 3230, |
---|
172 | 142 | buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2), |
---|
173 | 143 | LP87565_REGULATOR("BUCK3", LP87565_BUCK_3, "buck3", lp87565_buck_ops, |
---|
174 | 144 | 256, LP87565_REG_BUCK3_VOUT, LP87565_BUCK_VSET, |
---|
175 | 145 | LP87565_REG_BUCK3_CTRL_1, |
---|
| 146 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 147 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
---|
176 | 148 | LP87565_BUCK_CTRL_1_EN, 3230, |
---|
177 | 149 | buck0_1_2_3_ranges, LP87565_REG_BUCK3_CTRL_2), |
---|
178 | 150 | LP87565_REGULATOR("BUCK10", LP87565_BUCK_10, "buck10", lp87565_buck_ops, |
---|
179 | 151 | 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, |
---|
180 | 152 | LP87565_REG_BUCK0_CTRL_1, |
---|
181 | 153 | LP87565_BUCK_CTRL_1_EN | |
---|
| 154 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL | |
---|
| 155 | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, |
---|
| 156 | + LP87565_BUCK_CTRL_1_EN | |
---|
182 | 157 | LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230, |
---|
183 | 158 | buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), |
---|
184 | 159 | LP87565_REGULATOR("BUCK23", LP87565_BUCK_23, "buck23", lp87565_buck_ops, |
---|
185 | 160 | 256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET, |
---|
186 | 161 | LP87565_REG_BUCK2_CTRL_1, |
---|
| 162 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 163 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, |
---|
187 | 164 | LP87565_BUCK_CTRL_1_EN, 3230, |
---|
188 | 165 | buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2), |
---|
| 166 | + LP87565_REGULATOR("BUCK3210", LP87565_BUCK_3210, "buck3210", |
---|
| 167 | + lp87565_buck_ops, 256, LP87565_REG_BUCK0_VOUT, |
---|
| 168 | + LP87565_BUCK_VSET, LP87565_REG_BUCK0_CTRL_1, |
---|
| 169 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 170 | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL | |
---|
| 171 | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, |
---|
| 172 | + LP87565_BUCK_CTRL_1_EN | |
---|
| 173 | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230, |
---|
| 174 | + buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), |
---|
189 | 175 | }; |
---|
190 | 176 | |
---|
191 | 177 | static int lp87565_regulator_probe(struct platform_device *pdev) |
---|
.. | .. |
---|
193 | 179 | struct lp87565 *lp87565 = dev_get_drvdata(pdev->dev.parent); |
---|
194 | 180 | struct regulator_config config = { }; |
---|
195 | 181 | struct regulator_dev *rdev; |
---|
196 | | - int i, min_idx = LP87565_BUCK_0, max_idx = LP87565_BUCK_3; |
---|
| 182 | + int i, min_idx, max_idx; |
---|
197 | 183 | |
---|
198 | 184 | platform_set_drvdata(pdev, lp87565); |
---|
199 | 185 | |
---|
.. | .. |
---|
202 | 188 | config.driver_data = lp87565; |
---|
203 | 189 | config.regmap = lp87565->regmap; |
---|
204 | 190 | |
---|
205 | | - if (lp87565->dev_type == LP87565_DEVICE_TYPE_LP87565_Q1) { |
---|
| 191 | + switch (lp87565->dev_type) { |
---|
| 192 | + case LP87565_DEVICE_TYPE_LP87565_Q1: |
---|
206 | 193 | min_idx = LP87565_BUCK_10; |
---|
207 | 194 | max_idx = LP87565_BUCK_23; |
---|
| 195 | + break; |
---|
| 196 | + case LP87565_DEVICE_TYPE_LP87561_Q1: |
---|
| 197 | + min_idx = LP87565_BUCK_3210; |
---|
| 198 | + max_idx = LP87565_BUCK_3210; |
---|
| 199 | + break; |
---|
| 200 | + default: |
---|
| 201 | + min_idx = LP87565_BUCK_0; |
---|
| 202 | + max_idx = LP87565_BUCK_3; |
---|
| 203 | + break; |
---|
208 | 204 | } |
---|
209 | 205 | |
---|
210 | 206 | for (i = min_idx; i <= max_idx; i++) { |
---|