diff options
Diffstat (limited to 'drivers/regulator/arizona-ldo1.c')
-rw-r--r-- | drivers/regulator/arizona-ldo1.c | 130 |
1 files changed, 127 insertions, 3 deletions
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index d184aa35abcb..739faf99b9e2 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
@@ -34,6 +34,108 @@ struct arizona_ldo1 { | |||
34 | struct regulator_init_data init_data; | 34 | struct regulator_init_data init_data; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev, | ||
38 | unsigned int selector) | ||
39 | { | ||
40 | if (selector >= rdev->desc->n_voltages) | ||
41 | return -EINVAL; | ||
42 | |||
43 | if (selector == rdev->desc->n_voltages - 1) | ||
44 | return 1800000; | ||
45 | else | ||
46 | return rdev->desc->min_uV + (rdev->desc->uV_step * selector); | ||
47 | } | ||
48 | |||
49 | static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev, | ||
50 | int min_uV, int max_uV) | ||
51 | { | ||
52 | int sel; | ||
53 | |||
54 | sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); | ||
55 | if (sel >= rdev->desc->n_voltages) | ||
56 | sel = rdev->desc->n_voltages - 1; | ||
57 | |||
58 | return sel; | ||
59 | } | ||
60 | |||
61 | static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, | ||
62 | unsigned sel) | ||
63 | { | ||
64 | struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); | ||
65 | struct regmap *regmap = ldo->arizona->regmap; | ||
66 | unsigned int val; | ||
67 | int ret; | ||
68 | |||
69 | if (sel == rdev->desc->n_voltages - 1) | ||
70 | val = ARIZONA_LDO1_HI_PWR; | ||
71 | else | ||
72 | val = 0; | ||
73 | |||
74 | ret = regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_2, | ||
75 | ARIZONA_LDO1_HI_PWR, val); | ||
76 | if (ret != 0) | ||
77 | return ret; | ||
78 | |||
79 | ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1, | ||
80 | ARIZONA_SUBSYS_MAX_FREQ, val); | ||
81 | if (ret != 0) | ||
82 | return ret; | ||
83 | |||
84 | if (val) | ||
85 | return 0; | ||
86 | |||
87 | val = sel << ARIZONA_LDO1_VSEL_SHIFT; | ||
88 | |||
89 | return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1, | ||
90 | ARIZONA_LDO1_VSEL_MASK, val); | ||
91 | } | ||
92 | |||
93 | static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) | ||
94 | { | ||
95 | struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); | ||
96 | struct regmap *regmap = ldo->arizona->regmap; | ||
97 | unsigned int val; | ||
98 | int ret; | ||
99 | |||
100 | ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_2, &val); | ||
101 | if (ret != 0) | ||
102 | return ret; | ||
103 | |||
104 | if (val & ARIZONA_LDO1_HI_PWR) | ||
105 | return rdev->desc->n_voltages - 1; | ||
106 | |||
107 | ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val); | ||
108 | if (ret != 0) | ||
109 | return ret; | ||
110 | |||
111 | return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT; | ||
112 | } | ||
113 | |||
114 | static struct regulator_ops arizona_ldo1_hc_ops = { | ||
115 | .list_voltage = arizona_ldo1_hc_list_voltage, | ||
116 | .map_voltage = arizona_ldo1_hc_map_voltage, | ||
117 | .get_voltage_sel = arizona_ldo1_hc_get_voltage_sel, | ||
118 | .set_voltage_sel = arizona_ldo1_hc_set_voltage_sel, | ||
119 | .get_bypass = regulator_get_bypass_regmap, | ||
120 | .set_bypass = regulator_set_bypass_regmap, | ||
121 | }; | ||
122 | |||
123 | static const struct regulator_desc arizona_ldo1_hc = { | ||
124 | .name = "LDO1", | ||
125 | .supply_name = "LDOVDD", | ||
126 | .type = REGULATOR_VOLTAGE, | ||
127 | .ops = &arizona_ldo1_hc_ops, | ||
128 | |||
129 | .bypass_reg = ARIZONA_LDO1_CONTROL_1, | ||
130 | .bypass_mask = ARIZONA_LDO1_BYPASS, | ||
131 | .min_uV = 900000, | ||
132 | .uV_step = 50000, | ||
133 | .n_voltages = 8, | ||
134 | .enable_time = 500, | ||
135 | |||
136 | .owner = THIS_MODULE, | ||
137 | }; | ||
138 | |||
37 | static struct regulator_ops arizona_ldo1_ops = { | 139 | static struct regulator_ops arizona_ldo1_ops = { |
38 | .list_voltage = regulator_list_voltage_linear, | 140 | .list_voltage = regulator_list_voltage_linear, |
39 | .map_voltage = regulator_map_voltage_linear, | 141 | .map_voltage = regulator_map_voltage_linear, |
@@ -55,11 +157,22 @@ static const struct regulator_desc arizona_ldo1 = { | |||
55 | .bypass_mask = ARIZONA_LDO1_BYPASS, | 157 | .bypass_mask = ARIZONA_LDO1_BYPASS, |
56 | .min_uV = 900000, | 158 | .min_uV = 900000, |
57 | .uV_step = 50000, | 159 | .uV_step = 50000, |
58 | .n_voltages = 6, | 160 | .n_voltages = 7, |
161 | .enable_time = 500, | ||
59 | 162 | ||
60 | .owner = THIS_MODULE, | 163 | .owner = THIS_MODULE, |
61 | }; | 164 | }; |
62 | 165 | ||
166 | static const struct regulator_init_data arizona_ldo1_dvfs = { | ||
167 | .constraints = { | ||
168 | .min_uV = 1200000, | ||
169 | .max_uV = 1800000, | ||
170 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | | ||
171 | REGULATOR_CHANGE_VOLTAGE, | ||
172 | }, | ||
173 | .num_consumer_supplies = 1, | ||
174 | }; | ||
175 | |||
63 | static const struct regulator_init_data arizona_ldo1_default = { | 176 | static const struct regulator_init_data arizona_ldo1_default = { |
64 | .constraints = { | 177 | .constraints = { |
65 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 178 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
@@ -70,6 +183,7 @@ static const struct regulator_init_data arizona_ldo1_default = { | |||
70 | static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | 183 | static __devinit int arizona_ldo1_probe(struct platform_device *pdev) |
71 | { | 184 | { |
72 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | 185 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); |
186 | const struct regulator_desc *desc; | ||
73 | struct regulator_config config = { }; | 187 | struct regulator_config config = { }; |
74 | struct arizona_ldo1 *ldo1; | 188 | struct arizona_ldo1 *ldo1; |
75 | int ret; | 189 | int ret; |
@@ -87,7 +201,17 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | |||
87 | * default init_data for it. This will be overridden with | 201 | * default init_data for it. This will be overridden with |
88 | * platform data if provided. | 202 | * platform data if provided. |
89 | */ | 203 | */ |
90 | ldo1->init_data = arizona_ldo1_default; | 204 | switch (arizona->type) { |
205 | case WM5102: | ||
206 | desc = &arizona_ldo1_hc; | ||
207 | ldo1->init_data = arizona_ldo1_dvfs; | ||
208 | break; | ||
209 | default: | ||
210 | desc = &arizona_ldo1; | ||
211 | ldo1->init_data = arizona_ldo1_default; | ||
212 | break; | ||
213 | } | ||
214 | |||
91 | ldo1->init_data.consumer_supplies = &ldo1->supply; | 215 | ldo1->init_data.consumer_supplies = &ldo1->supply; |
92 | ldo1->supply.supply = "DCVDD"; | 216 | ldo1->supply.supply = "DCVDD"; |
93 | ldo1->supply.dev_name = dev_name(arizona->dev); | 217 | ldo1->supply.dev_name = dev_name(arizona->dev); |
@@ -102,7 +226,7 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | |||
102 | else | 226 | else |
103 | config.init_data = &ldo1->init_data; | 227 | config.init_data = &ldo1->init_data; |
104 | 228 | ||
105 | ldo1->regulator = regulator_register(&arizona_ldo1, &config); | 229 | ldo1->regulator = regulator_register(desc, &config); |
106 | if (IS_ERR(ldo1->regulator)) { | 230 | if (IS_ERR(ldo1->regulator)) { |
107 | ret = PTR_ERR(ldo1->regulator); | 231 | ret = PTR_ERR(ldo1->regulator); |
108 | dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", | 232 | dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", |