aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/tps65217-regulator.c69
-rw-r--r--include/linux/mfd/tps65217.h1
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
50static const unsigned int LDO1_VSEL_table[] = { 52static 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
123static 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
136static 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 */
122static struct regulator_ops tps65217_pmic_ops = { 153static 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
143static const struct regulator_desc regulators[] = { 178static 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
178static int tps65217_regulator_probe(struct platform_device *pdev) 220static 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
262static inline struct tps65217 *dev_to_tps65217(struct device *dev) 263static inline struct tps65217 *dev_to_tps65217(struct device *dev)