diff options
-rw-r--r-- | drivers/regulator/Kconfig | 8 | ||||
-rw-r--r-- | drivers/regulator/max77693.c | 125 |
2 files changed, 117 insertions, 16 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index bef3bde6971b..b1022c2fd877 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -407,13 +407,13 @@ config REGULATOR_MAX77686 | |||
407 | Exynos-4 chips to control VARM and VINT voltages. | 407 | Exynos-4 chips to control VARM and VINT voltages. |
408 | 408 | ||
409 | config REGULATOR_MAX77693 | 409 | config REGULATOR_MAX77693 |
410 | tristate "Maxim MAX77693 regulator" | 410 | tristate "Maxim 77693/77843 regulator" |
411 | depends on MFD_MAX77693 | 411 | depends on (MFD_MAX77693 || MFD_MAX77843) |
412 | help | 412 | help |
413 | This driver controls a Maxim 77693 regulator via I2C bus. | 413 | This driver controls a Maxim 77693/77843 regulators via I2C bus. |
414 | The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2' | 414 | The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2' |
415 | and one current regulator 'CHARGER'. This is suitable for | 415 | and one current regulator 'CHARGER'. This is suitable for |
416 | Exynos-4x12 chips. | 416 | Exynos-4x12 (MAX77693) or Exynos5433 (MAX77843) SoC chips. |
417 | 417 | ||
418 | config REGULATOR_MAX77802 | 418 | config REGULATOR_MAX77802 |
419 | tristate "Maxim 77802 regulator" | 419 | tristate "Maxim 77802 regulator" |
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index c6ab440a74b7..788379b87962 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * max77693.c - Regulator driver for the Maxim 77693 | 2 | * max77693.c - Regulator driver for the Maxim 77693 and 77843 |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Samsung Electronics | 4 | * Copyright (C) 2013-2015 Samsung Electronics |
5 | * Jonghwa Lee <jonghwa3.lee@samsung.com> | 5 | * Jonghwa Lee <jonghwa3.lee@samsung.com> |
6 | * Krzysztof Kozlowski <k.kozlowski.k@gmail.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -31,10 +32,23 @@ | |||
31 | #include <linux/mfd/max77693.h> | 32 | #include <linux/mfd/max77693.h> |
32 | #include <linux/mfd/max77693-common.h> | 33 | #include <linux/mfd/max77693-common.h> |
33 | #include <linux/mfd/max77693-private.h> | 34 | #include <linux/mfd/max77693-private.h> |
35 | #include <linux/mfd/max77843-private.h> | ||
34 | #include <linux/regulator/of_regulator.h> | 36 | #include <linux/regulator/of_regulator.h> |
35 | #include <linux/regmap.h> | 37 | #include <linux/regmap.h> |
36 | 38 | ||
37 | /* Charger regulator differences between MAX77693 and MAX77843 */ | 39 | /* |
40 | * ID for MAX77843 regulators. | ||
41 | * There is no need for such for MAX77693. | ||
42 | */ | ||
43 | enum max77843_regulator_type { | ||
44 | MAX77843_SAFEOUT1 = 0, | ||
45 | MAX77843_SAFEOUT2, | ||
46 | MAX77843_CHARGER, | ||
47 | |||
48 | MAX77843_NUM, | ||
49 | }; | ||
50 | |||
51 | /* Register differences between chargers: MAX77693 and MAX77843 */ | ||
38 | struct chg_reg_data { | 52 | struct chg_reg_data { |
39 | unsigned int linear_reg; | 53 | unsigned int linear_reg; |
40 | unsigned int linear_mask; | 54 | unsigned int linear_mask; |
@@ -43,9 +57,14 @@ struct chg_reg_data { | |||
43 | }; | 57 | }; |
44 | 58 | ||
45 | /* | 59 | /* |
46 | * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA | 60 | * MAX77693 CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA |
47 | * 0x00, 0x01, 0x2, 0x03 = 60 mA | 61 | * 0x00, 0x01, 0x2, 0x03 = 60 mA |
48 | * 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA | 62 | * 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA |
63 | * Actually for MAX77693 the driver manipulates the maximum input current, | ||
64 | * not the fast charge current (output). This should be fixed. | ||
65 | * | ||
66 | * On MAX77843 the calculation formula is the same (except values). | ||
67 | * Fortunately it properly manipulates the fast charge current. | ||
49 | */ | 68 | */ |
50 | static int max77693_chg_get_current_limit(struct regulator_dev *rdev) | 69 | static int max77693_chg_get_current_limit(struct regulator_dev *rdev) |
51 | { | 70 | { |
@@ -95,6 +114,26 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev, | |||
95 | } | 114 | } |
96 | /* end of CHARGER regulator ops */ | 115 | /* end of CHARGER regulator ops */ |
97 | 116 | ||
117 | /* Returns regmap suitable for given regulator on chosen device */ | ||
118 | static struct regmap *max77693_get_regmap(enum max77693_types type, | ||
119 | struct max77693_dev *max77693, | ||
120 | int reg_id) | ||
121 | { | ||
122 | if (type == TYPE_MAX77693) | ||
123 | return max77693->regmap; | ||
124 | |||
125 | /* Else: TYPE_MAX77843 */ | ||
126 | switch (reg_id) { | ||
127 | case MAX77843_SAFEOUT1: | ||
128 | case MAX77843_SAFEOUT2: | ||
129 | return max77693->regmap; | ||
130 | case MAX77843_CHARGER: | ||
131 | return max77693->regmap_chg; | ||
132 | default: | ||
133 | return max77693->regmap; | ||
134 | } | ||
135 | } | ||
136 | |||
98 | static const unsigned int max77693_safeout_table[] = { | 137 | static const unsigned int max77693_safeout_table[] = { |
99 | 4850000, | 138 | 4850000, |
100 | 4900000, | 139 | 4900000, |
@@ -119,7 +158,7 @@ static struct regulator_ops max77693_charger_ops = { | |||
119 | .set_current_limit = max77693_chg_set_current_limit, | 158 | .set_current_limit = max77693_chg_set_current_limit, |
120 | }; | 159 | }; |
121 | 160 | ||
122 | #define regulator_desc_esafeout(_num) { \ | 161 | #define max77693_regulator_desc_esafeout(_num) { \ |
123 | .name = "ESAFEOUT"#_num, \ | 162 | .name = "ESAFEOUT"#_num, \ |
124 | .id = MAX77693_ESAFEOUT##_num, \ | 163 | .id = MAX77693_ESAFEOUT##_num, \ |
125 | .of_match = of_match_ptr("ESAFEOUT"#_num), \ | 164 | .of_match = of_match_ptr("ESAFEOUT"#_num), \ |
@@ -135,9 +174,9 @@ static struct regulator_ops max77693_charger_ops = { | |||
135 | .enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \ | 174 | .enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \ |
136 | } | 175 | } |
137 | 176 | ||
138 | static const struct regulator_desc regulators[] = { | 177 | static const struct regulator_desc max77693_supported_regulators[] = { |
139 | regulator_desc_esafeout(1), | 178 | max77693_regulator_desc_esafeout(1), |
140 | regulator_desc_esafeout(2), | 179 | max77693_regulator_desc_esafeout(2), |
141 | { | 180 | { |
142 | .name = "CHARGER", | 181 | .name = "CHARGER", |
143 | .id = MAX77693_CHARGER, | 182 | .id = MAX77693_CHARGER, |
@@ -160,19 +199,79 @@ static const struct chg_reg_data max77693_chg_reg_data = { | |||
160 | .min_sel = 3, | 199 | .min_sel = 3, |
161 | }; | 200 | }; |
162 | 201 | ||
202 | #define max77843_regulator_desc_esafeout(num) { \ | ||
203 | .name = "SAFEOUT" # num, \ | ||
204 | .id = MAX77843_SAFEOUT ## num, \ | ||
205 | .ops = &max77693_safeout_ops, \ | ||
206 | .of_match = of_match_ptr("SAFEOUT" # num), \ | ||
207 | .regulators_node = of_match_ptr("regulators"), \ | ||
208 | .type = REGULATOR_VOLTAGE, \ | ||
209 | .owner = THIS_MODULE, \ | ||
210 | .n_voltages = ARRAY_SIZE(max77693_safeout_table), \ | ||
211 | .volt_table = max77693_safeout_table, \ | ||
212 | .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \ | ||
213 | .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num, \ | ||
214 | .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \ | ||
215 | .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \ | ||
216 | } | ||
217 | |||
218 | static const struct regulator_desc max77843_supported_regulators[] = { | ||
219 | [MAX77843_SAFEOUT1] = max77843_regulator_desc_esafeout(1), | ||
220 | [MAX77843_SAFEOUT2] = max77843_regulator_desc_esafeout(2), | ||
221 | [MAX77843_CHARGER] = { | ||
222 | .name = "CHARGER", | ||
223 | .id = MAX77843_CHARGER, | ||
224 | .ops = &max77693_charger_ops, | ||
225 | .of_match = of_match_ptr("CHARGER"), | ||
226 | .regulators_node = of_match_ptr("regulators"), | ||
227 | .type = REGULATOR_CURRENT, | ||
228 | .owner = THIS_MODULE, | ||
229 | .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00, | ||
230 | .enable_mask = MAX77843_CHG_MASK, | ||
231 | .enable_val = MAX77843_CHG_MASK, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | static const struct chg_reg_data max77843_chg_reg_data = { | ||
236 | .linear_reg = MAX77843_CHG_REG_CHG_CNFG_02, | ||
237 | .linear_mask = MAX77843_CHG_FAST_CHG_CURRENT_MASK, | ||
238 | .uA_step = MAX77843_CHG_FAST_CHG_CURRENT_STEP, | ||
239 | .min_sel = 2, | ||
240 | }; | ||
241 | |||
163 | static int max77693_pmic_probe(struct platform_device *pdev) | 242 | static int max77693_pmic_probe(struct platform_device *pdev) |
164 | { | 243 | { |
244 | enum max77693_types type = platform_get_device_id(pdev)->driver_data; | ||
165 | struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 245 | struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
246 | const struct regulator_desc *regulators; | ||
247 | unsigned int regulators_size; | ||
166 | int i; | 248 | int i; |
167 | struct regulator_config config = { }; | 249 | struct regulator_config config = { }; |
168 | 250 | ||
169 | config.dev = iodev->dev; | 251 | config.dev = iodev->dev; |
170 | config.regmap = iodev->regmap; | ||
171 | config.driver_data = (void *)&max77693_chg_reg_data; | ||
172 | 252 | ||
173 | for (i = 0; i < ARRAY_SIZE(regulators); i++) { | 253 | switch (type) { |
254 | case TYPE_MAX77693: | ||
255 | regulators = max77693_supported_regulators; | ||
256 | regulators_size = ARRAY_SIZE(max77693_supported_regulators); | ||
257 | config.driver_data = (void *)&max77693_chg_reg_data; | ||
258 | break; | ||
259 | case TYPE_MAX77843: | ||
260 | regulators = max77843_supported_regulators; | ||
261 | regulators_size = ARRAY_SIZE(max77843_supported_regulators); | ||
262 | config.driver_data = (void *)&max77843_chg_reg_data; | ||
263 | break; | ||
264 | default: | ||
265 | dev_err(&pdev->dev, "Unsupported device type: %u\n", type); | ||
266 | return -ENODEV; | ||
267 | } | ||
268 | |||
269 | for (i = 0; i < regulators_size; i++) { | ||
174 | struct regulator_dev *rdev; | 270 | struct regulator_dev *rdev; |
175 | 271 | ||
272 | config.regmap = max77693_get_regmap(type, iodev, | ||
273 | regulators[i].id); | ||
274 | |||
176 | rdev = devm_regulator_register(&pdev->dev, | 275 | rdev = devm_regulator_register(&pdev->dev, |
177 | ®ulators[i], &config); | 276 | ®ulators[i], &config); |
178 | if (IS_ERR(rdev)) { | 277 | if (IS_ERR(rdev)) { |
@@ -187,6 +286,7 @@ static int max77693_pmic_probe(struct platform_device *pdev) | |||
187 | 286 | ||
188 | static const struct platform_device_id max77693_pmic_id[] = { | 287 | static const struct platform_device_id max77693_pmic_id[] = { |
189 | { "max77693-pmic", TYPE_MAX77693 }, | 288 | { "max77693-pmic", TYPE_MAX77693 }, |
289 | { "max77843-regulator", TYPE_MAX77843 }, | ||
190 | {}, | 290 | {}, |
191 | }; | 291 | }; |
192 | 292 | ||
@@ -202,6 +302,7 @@ static struct platform_driver max77693_pmic_driver = { | |||
202 | 302 | ||
203 | module_platform_driver(max77693_pmic_driver); | 303 | module_platform_driver(max77693_pmic_driver); |
204 | 304 | ||
205 | MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver"); | 305 | MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver"); |
206 | MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); | 306 | MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); |
307 | MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski.k@gmail.com>"); | ||
207 | MODULE_LICENSE("GPL"); | 308 | MODULE_LICENSE("GPL"); |