diff options
-rw-r--r-- | drivers/regulator/tps65217-regulator.c | 69 | ||||
-rw-r--r-- | include/linux/mfd/tps65217.h | 1 |
2 files changed, 61 insertions, 9 deletions
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index adbe4fc5cf07..2d12b9af3540 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/mfd/tps65217.h> | 28 | #include <linux/mfd/tps65217.h> |
29 | 29 | ||
30 | #define TPS65217_REGULATOR(_name, _id, _of_match, _ops, _n, _vr, _vm, _em, \ | 30 | #define TPS65217_REGULATOR(_name, _id, _of_match, _ops, _n, _vr, _vm, _em, \ |
31 | _t, _lr, _nlr) \ | 31 | _t, _lr, _nlr, _sr, _sm) \ |
32 | { \ | 32 | { \ |
33 | .name = _name, \ | 33 | .name = _name, \ |
34 | .id = _id, \ | 34 | .id = _id, \ |
@@ -45,6 +45,8 @@ | |||
45 | .volt_table = _t, \ | 45 | .volt_table = _t, \ |
46 | .linear_ranges = _lr, \ | 46 | .linear_ranges = _lr, \ |
47 | .n_linear_ranges = _nlr, \ | 47 | .n_linear_ranges = _nlr, \ |
48 | .bypass_reg = _sr, \ | ||
49 | .bypass_mask = _sm, \ | ||
48 | } \ | 50 | } \ |
49 | 51 | ||
50 | static const unsigned int LDO1_VSEL_table[] = { | 52 | static const unsigned int LDO1_VSEL_table[] = { |
@@ -118,6 +120,35 @@ static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, | |||
118 | return ret; | 120 | return ret; |
119 | } | 121 | } |
120 | 122 | ||
123 | static int tps65217_pmic_set_suspend_enable(struct regulator_dev *dev) | ||
124 | { | ||
125 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
126 | unsigned int rid = rdev_get_id(dev); | ||
127 | |||
128 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
129 | return -EINVAL; | ||
130 | |||
131 | return tps65217_clear_bits(tps, dev->desc->bypass_reg, | ||
132 | dev->desc->bypass_mask, | ||
133 | TPS65217_PROTECT_L1); | ||
134 | } | ||
135 | |||
136 | static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev) | ||
137 | { | ||
138 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
139 | unsigned int rid = rdev_get_id(dev); | ||
140 | |||
141 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
142 | return -EINVAL; | ||
143 | |||
144 | if (!tps->strobes[rid]) | ||
145 | return -EINVAL; | ||
146 | |||
147 | return tps65217_set_bits(tps, dev->desc->bypass_reg, | ||
148 | dev->desc->bypass_mask, | ||
149 | tps->strobes[rid], TPS65217_PROTECT_L1); | ||
150 | } | ||
151 | |||
121 | /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ | 152 | /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ |
122 | static struct regulator_ops tps65217_pmic_ops = { | 153 | static struct regulator_ops tps65217_pmic_ops = { |
123 | .is_enabled = regulator_is_enabled_regmap, | 154 | .is_enabled = regulator_is_enabled_regmap, |
@@ -127,6 +158,8 @@ static struct regulator_ops tps65217_pmic_ops = { | |||
127 | .set_voltage_sel = tps65217_pmic_set_voltage_sel, | 158 | .set_voltage_sel = tps65217_pmic_set_voltage_sel, |
128 | .list_voltage = regulator_list_voltage_linear_range, | 159 | .list_voltage = regulator_list_voltage_linear_range, |
129 | .map_voltage = regulator_map_voltage_linear_range, | 160 | .map_voltage = regulator_map_voltage_linear_range, |
161 | .set_suspend_enable = tps65217_pmic_set_suspend_enable, | ||
162 | .set_suspend_disable = tps65217_pmic_set_suspend_disable, | ||
130 | }; | 163 | }; |
131 | 164 | ||
132 | /* Operations permitted on LDO1 */ | 165 | /* Operations permitted on LDO1 */ |
@@ -138,41 +171,50 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { | |||
138 | .set_voltage_sel = tps65217_pmic_set_voltage_sel, | 171 | .set_voltage_sel = tps65217_pmic_set_voltage_sel, |
139 | .list_voltage = regulator_list_voltage_table, | 172 | .list_voltage = regulator_list_voltage_table, |
140 | .map_voltage = regulator_map_voltage_ascend, | 173 | .map_voltage = regulator_map_voltage_ascend, |
174 | .set_suspend_enable = tps65217_pmic_set_suspend_enable, | ||
175 | .set_suspend_disable = tps65217_pmic_set_suspend_disable, | ||
141 | }; | 176 | }; |
142 | 177 | ||
143 | static const struct regulator_desc regulators[] = { | 178 | static const struct regulator_desc regulators[] = { |
144 | TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, "dcdc1", | 179 | TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, "dcdc1", |
145 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC1, | 180 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC1, |
146 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC1_EN, | 181 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC1_EN, |
147 | NULL, tps65217_uv1_ranges, 2), | 182 | NULL, tps65217_uv1_ranges, 2, TPS65217_REG_SEQ1, |
183 | TPS65217_SEQ1_DC1_SEQ_MASK), | ||
148 | TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, "dcdc2", | 184 | TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, "dcdc2", |
149 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC2, | 185 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC2, |
150 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC2_EN, | 186 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC2_EN, |
151 | NULL, tps65217_uv1_ranges, | 187 | NULL, tps65217_uv1_ranges, |
152 | ARRAY_SIZE(tps65217_uv1_ranges)), | 188 | ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ1, |
189 | TPS65217_SEQ1_DC2_SEQ_MASK), | ||
153 | TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, "dcdc3", | 190 | TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, "dcdc3", |
154 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC3, | 191 | tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC3, |
155 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC3_EN, | 192 | TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC3_EN, |
156 | NULL, tps65217_uv1_ranges, 1), | 193 | NULL, tps65217_uv1_ranges, 1, TPS65217_REG_SEQ2, |
194 | TPS65217_SEQ2_DC3_SEQ_MASK), | ||
157 | TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, "ldo1", | 195 | TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, "ldo1", |
158 | tps65217_pmic_ldo1_ops, 16, TPS65217_REG_DEFLDO1, | 196 | tps65217_pmic_ldo1_ops, 16, TPS65217_REG_DEFLDO1, |
159 | TPS65217_DEFLDO1_LDO1_MASK, TPS65217_ENABLE_LDO1_EN, | 197 | TPS65217_DEFLDO1_LDO1_MASK, TPS65217_ENABLE_LDO1_EN, |
160 | LDO1_VSEL_table, NULL, 0), | 198 | LDO1_VSEL_table, NULL, 0, TPS65217_REG_SEQ2, |
199 | TPS65217_SEQ2_LDO1_SEQ_MASK), | ||
161 | TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, "ldo2", tps65217_pmic_ops, | 200 | TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, "ldo2", tps65217_pmic_ops, |
162 | 64, TPS65217_REG_DEFLDO2, | 201 | 64, TPS65217_REG_DEFLDO2, |
163 | TPS65217_DEFLDO2_LDO2_MASK, TPS65217_ENABLE_LDO2_EN, | 202 | TPS65217_DEFLDO2_LDO2_MASK, TPS65217_ENABLE_LDO2_EN, |
164 | NULL, tps65217_uv1_ranges, | 203 | NULL, tps65217_uv1_ranges, |
165 | ARRAY_SIZE(tps65217_uv1_ranges)), | 204 | ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ3, |
205 | TPS65217_SEQ3_LDO2_SEQ_MASK), | ||
166 | TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, "ldo3", tps65217_pmic_ops, | 206 | TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, "ldo3", tps65217_pmic_ops, |
167 | 32, TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, | 207 | 32, TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, |
168 | TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, | 208 | TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, |
169 | NULL, tps65217_uv2_ranges, | 209 | NULL, tps65217_uv2_ranges, |
170 | ARRAY_SIZE(tps65217_uv2_ranges)), | 210 | ARRAY_SIZE(tps65217_uv2_ranges), TPS65217_REG_SEQ3, |
211 | TPS65217_SEQ3_LDO3_SEQ_MASK), | ||
171 | TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, "ldo4", tps65217_pmic_ops, | 212 | TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, "ldo4", tps65217_pmic_ops, |
172 | 32, TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, | 213 | 32, TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, |
173 | TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, | 214 | TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, |
174 | NULL, tps65217_uv2_ranges, | 215 | NULL, tps65217_uv2_ranges, |
175 | ARRAY_SIZE(tps65217_uv2_ranges)), | 216 | ARRAY_SIZE(tps65217_uv2_ranges), TPS65217_REG_SEQ4, |
217 | TPS65217_SEQ4_LDO4_SEQ_MASK), | ||
176 | }; | 218 | }; |
177 | 219 | ||
178 | static int tps65217_regulator_probe(struct platform_device *pdev) | 220 | static int tps65217_regulator_probe(struct platform_device *pdev) |
@@ -181,13 +223,18 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
181 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | 223 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); |
182 | struct regulator_dev *rdev; | 224 | struct regulator_dev *rdev; |
183 | struct regulator_config config = { }; | 225 | struct regulator_config config = { }; |
184 | int i; | 226 | int i, ret; |
227 | unsigned int val; | ||
185 | 228 | ||
186 | if (tps65217_chip_id(tps) != TPS65217) { | 229 | if (tps65217_chip_id(tps) != TPS65217) { |
187 | dev_err(&pdev->dev, "Invalid tps chip version\n"); | 230 | dev_err(&pdev->dev, "Invalid tps chip version\n"); |
188 | return -ENODEV; | 231 | return -ENODEV; |
189 | } | 232 | } |
190 | 233 | ||
234 | /* Allocate memory for strobes */ | ||
235 | tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) * | ||
236 | TPS65217_NUM_REGULATOR, GFP_KERNEL); | ||
237 | |||
191 | platform_set_drvdata(pdev, tps); | 238 | platform_set_drvdata(pdev, tps); |
192 | 239 | ||
193 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | 240 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { |
@@ -205,6 +252,10 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
205 | pdev->name); | 252 | pdev->name); |
206 | return PTR_ERR(rdev); | 253 | return PTR_ERR(rdev); |
207 | } | 254 | } |
255 | |||
256 | /* Store default strobe info */ | ||
257 | ret = tps65217_reg_read(tps, regulators[i].bypass_reg, &val); | ||
258 | tps->strobes[i] = val & regulators[i].bypass_mask; | ||
208 | } | 259 | } |
209 | 260 | ||
210 | return 0; | 261 | return 0; |
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index ac7fba44d7e4..1c88231496d3 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h | |||
@@ -257,6 +257,7 @@ struct tps65217 { | |||
257 | unsigned long id; | 257 | unsigned long id; |
258 | struct regulator_desc desc[TPS65217_NUM_REGULATOR]; | 258 | struct regulator_desc desc[TPS65217_NUM_REGULATOR]; |
259 | struct regmap *regmap; | 259 | struct regmap *regmap; |
260 | u8 *strobes; | ||
260 | }; | 261 | }; |
261 | 262 | ||
262 | static inline struct tps65217 *dev_to_tps65217(struct device *dev) | 263 | static inline struct tps65217 *dev_to_tps65217(struct device *dev) |