diff options
-rw-r--r-- | Documentation/devicetree/bindings/regulator/da9211.txt | 63 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 9 | ||||
-rw-r--r-- | drivers/regulator/as3711-regulator.c | 61 | ||||
-rw-r--r-- | drivers/regulator/axp20x-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/bcm590xx-regulator.c | 8 | ||||
-rw-r--r-- | drivers/regulator/da9211-regulator.c | 172 | ||||
-rw-r--r-- | drivers/regulator/da9211-regulator.h | 7 | ||||
-rw-r--r-- | include/linux/regulator/da9211.h | 9 |
8 files changed, 260 insertions, 71 deletions
diff --git a/Documentation/devicetree/bindings/regulator/da9211.txt b/Documentation/devicetree/bindings/regulator/da9211.txt new file mode 100644 index 000000000000..240019a82f9a --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/da9211.txt | |||
@@ -0,0 +1,63 @@ | |||
1 | * Dialog Semiconductor DA9211/DA9213 Voltage Regulator | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "dlg,da9211" or "dlg,da9213". | ||
5 | - reg: I2C slave address, usually 0x68. | ||
6 | - interrupts: the interrupt outputs of the controller | ||
7 | - regulators: A node that houses a sub-node for each regulator within the | ||
8 | device. Each sub-node is identified using the node's name, with valid | ||
9 | values listed below. The content of each sub-node is defined by the | ||
10 | standard binding for regulators; see regulator.txt. | ||
11 | BUCKA and BUCKB. | ||
12 | |||
13 | Optional properties: | ||
14 | - Any optional property defined in regulator.txt | ||
15 | |||
16 | Example 1) DA9211 | ||
17 | |||
18 | pmic: da9211@68 { | ||
19 | compatible = "dlg,da9211"; | ||
20 | reg = <0x68>; | ||
21 | interrupts = <3 27>; | ||
22 | |||
23 | regulators { | ||
24 | BUCKA { | ||
25 | regulator-name = "VBUCKA"; | ||
26 | regulator-min-microvolt = < 300000>; | ||
27 | regulator-max-microvolt = <1570000>; | ||
28 | regulator-min-microamp = <2000000>; | ||
29 | regulator-max-microamp = <5000000>; | ||
30 | }; | ||
31 | BUCKB { | ||
32 | regulator-name = "VBUCKB"; | ||
33 | regulator-min-microvolt = < 300000>; | ||
34 | regulator-max-microvolt = <1570000>; | ||
35 | regulator-min-microamp = <2000000>; | ||
36 | regulator-max-microamp = <5000000>; | ||
37 | }; | ||
38 | }; | ||
39 | }; | ||
40 | |||
41 | Example 2) DA92113 | ||
42 | pmic: da9213@68 { | ||
43 | compatible = "dlg,da9213"; | ||
44 | reg = <0x68>; | ||
45 | interrupts = <3 27>; | ||
46 | |||
47 | regulators { | ||
48 | BUCKA { | ||
49 | regulator-name = "VBUCKA"; | ||
50 | regulator-min-microvolt = < 300000>; | ||
51 | regulator-max-microvolt = <1570000>; | ||
52 | regulator-min-microamp = <3000000>; | ||
53 | regulator-max-microamp = <6000000>; | ||
54 | }; | ||
55 | BUCKB { | ||
56 | regulator-name = "VBUCKB"; | ||
57 | regulator-min-microvolt = < 300000>; | ||
58 | regulator-max-microvolt = <1570000>; | ||
59 | regulator-min-microamp = <3000000>; | ||
60 | regulator-max-microamp = <6000000>; | ||
61 | }; | ||
62 | }; | ||
63 | }; | ||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..1344aa83b438 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -199,13 +199,14 @@ config REGULATOR_DA9210 | |||
199 | interface. | 199 | interface. |
200 | 200 | ||
201 | config REGULATOR_DA9211 | 201 | config REGULATOR_DA9211 |
202 | tristate "Dialog Semiconductor DA9211/DA9212 regulator" | 202 | tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214 regulator" |
203 | depends on I2C | 203 | depends on I2C |
204 | select REGMAP_I2C | 204 | select REGMAP_I2C |
205 | help | 205 | help |
206 | Say y here to support for the Dialog Semiconductor DA9211/DA9212. | 206 | Say y here to support for the Dialog Semiconductor DA9211/DA9212 |
207 | The DA9211/DA9212 is a multi-phase synchronous step down | 207 | /DA9213/DA9214. |
208 | converter 12A DC-DC Buck controlled through an I2C | 208 | The DA9211/DA9212/DA9213/DA9214 is a multi-phase synchronous |
209 | step down converter 12A or 16A DC-DC Buck controlled through an I2C | ||
209 | interface. | 210 | interface. |
210 | 211 | ||
211 | config REGULATOR_DBX500_PRCMU | 212 | config REGULATOR_DBX500_PRCMU |
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index b47283f91e2d..8459b0b648cd 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c | |||
@@ -22,12 +22,10 @@ | |||
22 | 22 | ||
23 | struct as3711_regulator_info { | 23 | struct as3711_regulator_info { |
24 | struct regulator_desc desc; | 24 | struct regulator_desc desc; |
25 | unsigned int max_uV; | ||
26 | }; | 25 | }; |
27 | 26 | ||
28 | struct as3711_regulator { | 27 | struct as3711_regulator { |
29 | struct as3711_regulator_info *reg_info; | 28 | struct as3711_regulator_info *reg_info; |
30 | struct regulator_dev *rdev; | ||
31 | }; | 29 | }; |
32 | 30 | ||
33 | /* | 31 | /* |
@@ -132,39 +130,37 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = { | |||
132 | REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000), | 130 | REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000), |
133 | }; | 131 | }; |
134 | 132 | ||
135 | #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _vshift, _min_uV, _max_uV, _sfx) \ | 133 | #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _sfx) \ |
136 | [AS3711_REGULATOR_ ## _id] = { \ | 134 | [AS3711_REGULATOR_ ## _id] = { \ |
137 | .desc = { \ | 135 | .desc = { \ |
138 | .name = "as3711-regulator-" # _id, \ | 136 | .name = "as3711-regulator-" # _id, \ |
139 | .id = AS3711_REGULATOR_ ## _id, \ | 137 | .id = AS3711_REGULATOR_ ## _id, \ |
140 | .n_voltages = (_vmask + 1), \ | 138 | .n_voltages = (_vmask + 1), \ |
141 | .ops = &as3711_ ## _sfx ## _ops, \ | 139 | .ops = &as3711_ ## _sfx ## _ops, \ |
142 | .type = REGULATOR_VOLTAGE, \ | 140 | .type = REGULATOR_VOLTAGE, \ |
143 | .owner = THIS_MODULE, \ | 141 | .owner = THIS_MODULE, \ |
144 | .vsel_reg = AS3711_ ## _id ## _VOLTAGE, \ | 142 | .vsel_reg = AS3711_ ## _id ## _VOLTAGE, \ |
145 | .vsel_mask = _vmask << _vshift, \ | 143 | .vsel_mask = _vmask, \ |
146 | .enable_reg = AS3711_ ## _en_reg, \ | 144 | .enable_reg = AS3711_ ## _en_reg, \ |
147 | .enable_mask = BIT(_en_bit), \ | 145 | .enable_mask = BIT(_en_bit), \ |
148 | .min_uV = _min_uV, \ | 146 | .linear_ranges = as3711_ ## _sfx ## _ranges, \ |
149 | .linear_ranges = as3711_ ## _sfx ## _ranges, \ | 147 | .n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \ |
150 | .n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \ | 148 | }, \ |
151 | }, \ | ||
152 | .max_uV = _max_uV, \ | ||
153 | } | 149 | } |
154 | 150 | ||
155 | static struct as3711_regulator_info as3711_reg_info[] = { | 151 | static struct as3711_regulator_info as3711_reg_info[] = { |
156 | AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, 0, 612500, 3350000, sd), | 152 | AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, sd), |
157 | AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, 0, 612500, 3350000, sd), | 153 | AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, sd), |
158 | AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, 0, 612500, 3350000, sd), | 154 | AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, sd), |
159 | AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, 0, 612500, 3350000, sd), | 155 | AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, sd), |
160 | AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), | 156 | AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, aldo), |
161 | AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), | 157 | AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, aldo), |
162 | AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 158 | AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, dldo), |
163 | AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 159 | AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, dldo), |
164 | AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 160 | AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, dldo), |
165 | AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 161 | AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, dldo), |
166 | AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 162 | AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, dldo), |
167 | AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), | 163 | AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, dldo), |
168 | /* StepUp output voltage depends on supplying regulator */ | 164 | /* StepUp output voltage depends on supplying regulator */ |
169 | }; | 165 | }; |
170 | 166 | ||
@@ -263,7 +259,6 @@ static int as3711_regulator_probe(struct platform_device *pdev) | |||
263 | ri->desc.name); | 259 | ri->desc.name); |
264 | return PTR_ERR(rdev); | 260 | return PTR_ERR(rdev); |
265 | } | 261 | } |
266 | reg->rdev = rdev; | ||
267 | } | 262 | } |
268 | platform_set_drvdata(pdev, regs); | 263 | platform_set_drvdata(pdev, regs); |
269 | return 0; | 264 | return 0; |
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 004aadb7bcc1..2e1010a34ddc 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c | |||
@@ -245,7 +245,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
245 | for (i = 0; i < AXP20X_REG_ID_MAX; i++) { | 245 | for (i = 0; i < AXP20X_REG_ID_MAX; i++) { |
246 | init_data = axp20x_matches[i].init_data; | 246 | init_data = axp20x_matches[i].init_data; |
247 | 247 | ||
248 | config.dev = &pdev->dev; | 248 | config.dev = pdev->dev.parent; |
249 | config.init_data = init_data; | 249 | config.init_data = init_data; |
250 | config.regmap = axp20x->regmap; | 250 | config.regmap = axp20x->regmap; |
251 | config.of_node = axp20x_matches[i].of_node; | 251 | config.of_node = axp20x_matches[i].of_node; |
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 5d1fd6f3d10a..fe6ac69549a6 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c | |||
@@ -202,7 +202,6 @@ static struct bcm590xx_info bcm590xx_regs[] = { | |||
202 | struct bcm590xx_reg { | 202 | struct bcm590xx_reg { |
203 | struct regulator_desc *desc; | 203 | struct regulator_desc *desc; |
204 | struct bcm590xx *mfd; | 204 | struct bcm590xx *mfd; |
205 | struct bcm590xx_info **info; | ||
206 | }; | 205 | }; |
207 | 206 | ||
208 | static int bcm590xx_get_vsel_register(int id) | 207 | static int bcm590xx_get_vsel_register(int id) |
@@ -389,11 +388,6 @@ static int bcm590xx_probe(struct platform_device *pdev) | |||
389 | if (!pmu->desc) | 388 | if (!pmu->desc) |
390 | return -ENOMEM; | 389 | return -ENOMEM; |
391 | 390 | ||
392 | pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * | ||
393 | sizeof(struct bcm590xx_info *), GFP_KERNEL); | ||
394 | if (!pmu->info) | ||
395 | return -ENOMEM; | ||
396 | |||
397 | info = bcm590xx_regs; | 391 | info = bcm590xx_regs; |
398 | 392 | ||
399 | for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { | 393 | for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { |
@@ -403,8 +397,6 @@ static int bcm590xx_probe(struct platform_device *pdev) | |||
403 | reg_data = NULL; | 397 | reg_data = NULL; |
404 | 398 | ||
405 | /* Register the regulators */ | 399 | /* Register the regulators */ |
406 | pmu->info[i] = info; | ||
407 | |||
408 | pmu->desc[i].name = info->name; | 400 | pmu->desc[i].name = info->name; |
409 | pmu->desc[i].supply_name = info->vin_name; | 401 | pmu->desc[i].supply_name = info->vin_name; |
410 | pmu->desc[i].id = i; | 402 | pmu->desc[i].id = i; |
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 05f879a5d24e..c78d2106d6cb 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * da9211-regulator.c - Regulator device driver for DA9211 | 2 | * da9211-regulator.c - Regulator device driver for DA9211/DA9213 |
3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. | 3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
@@ -24,9 +24,14 @@ | |||
24 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/regulator/of_regulator.h> | ||
27 | #include <linux/regulator/da9211.h> | 28 | #include <linux/regulator/da9211.h> |
28 | #include "da9211-regulator.h" | 29 | #include "da9211-regulator.h" |
29 | 30 | ||
31 | /* DEVICE IDs */ | ||
32 | #define DA9211_DEVICE_ID 0x22 | ||
33 | #define DA9213_DEVICE_ID 0x23 | ||
34 | |||
30 | #define DA9211_BUCK_MODE_SLEEP 1 | 35 | #define DA9211_BUCK_MODE_SLEEP 1 |
31 | #define DA9211_BUCK_MODE_SYNC 2 | 36 | #define DA9211_BUCK_MODE_SYNC 2 |
32 | #define DA9211_BUCK_MODE_AUTO 3 | 37 | #define DA9211_BUCK_MODE_AUTO 3 |
@@ -42,6 +47,7 @@ struct da9211 { | |||
42 | struct regulator_dev *rdev[DA9211_MAX_REGULATORS]; | 47 | struct regulator_dev *rdev[DA9211_MAX_REGULATORS]; |
43 | int num_regulator; | 48 | int num_regulator; |
44 | int chip_irq; | 49 | int chip_irq; |
50 | int chip_id; | ||
45 | }; | 51 | }; |
46 | 52 | ||
47 | static const struct regmap_range_cfg da9211_regmap_range[] = { | 53 | static const struct regmap_range_cfg da9211_regmap_range[] = { |
@@ -52,14 +58,14 @@ static const struct regmap_range_cfg da9211_regmap_range[] = { | |||
52 | .window_start = 0, | 58 | .window_start = 0, |
53 | .window_len = 256, | 59 | .window_len = 256, |
54 | .range_min = 0, | 60 | .range_min = 0, |
55 | .range_max = 2*256, | 61 | .range_max = 5*128, |
56 | }, | 62 | }, |
57 | }; | 63 | }; |
58 | 64 | ||
59 | static const struct regmap_config da9211_regmap_config = { | 65 | static const struct regmap_config da9211_regmap_config = { |
60 | .reg_bits = 8, | 66 | .reg_bits = 8, |
61 | .val_bits = 8, | 67 | .val_bits = 8, |
62 | .max_register = 2 * 256, | 68 | .max_register = 5 * 128, |
63 | .ranges = da9211_regmap_range, | 69 | .ranges = da9211_regmap_range, |
64 | .num_ranges = ARRAY_SIZE(da9211_regmap_range), | 70 | .num_ranges = ARRAY_SIZE(da9211_regmap_range), |
65 | }; | 71 | }; |
@@ -69,11 +75,20 @@ static const struct regmap_config da9211_regmap_config = { | |||
69 | #define DA9211_MAX_MV 1570 | 75 | #define DA9211_MAX_MV 1570 |
70 | #define DA9211_STEP_MV 10 | 76 | #define DA9211_STEP_MV 10 |
71 | 77 | ||
72 | /* Current limits for buck (uA) indices corresponds with register values */ | 78 | /* Current limits for DA9211 buck (uA) indices |
79 | * corresponds with register values | ||
80 | */ | ||
73 | static const int da9211_current_limits[] = { | 81 | static const int da9211_current_limits[] = { |
74 | 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, | 82 | 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, |
75 | 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000 | 83 | 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000 |
76 | }; | 84 | }; |
85 | /* Current limits for DA9213 buck (uA) indices | ||
86 | * corresponds with register values | ||
87 | */ | ||
88 | static const int da9213_current_limits[] = { | ||
89 | 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, | ||
90 | 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 | ||
91 | }; | ||
77 | 92 | ||
78 | static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) | 93 | static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) |
79 | { | 94 | { |
@@ -129,12 +144,26 @@ static int da9211_set_current_limit(struct regulator_dev *rdev, int min, | |||
129 | { | 144 | { |
130 | int id = rdev_get_id(rdev); | 145 | int id = rdev_get_id(rdev); |
131 | struct da9211 *chip = rdev_get_drvdata(rdev); | 146 | struct da9211 *chip = rdev_get_drvdata(rdev); |
132 | int i; | 147 | int i, max_size; |
148 | const int *current_limits; | ||
149 | |||
150 | switch (chip->chip_id) { | ||
151 | case DA9211: | ||
152 | current_limits = da9211_current_limits; | ||
153 | max_size = ARRAY_SIZE(da9211_current_limits)-1; | ||
154 | break; | ||
155 | case DA9213: | ||
156 | current_limits = da9213_current_limits; | ||
157 | max_size = ARRAY_SIZE(da9213_current_limits)-1; | ||
158 | break; | ||
159 | default: | ||
160 | return -EINVAL; | ||
161 | } | ||
133 | 162 | ||
134 | /* search for closest to maximum */ | 163 | /* search for closest to maximum */ |
135 | for (i = ARRAY_SIZE(da9211_current_limits)-1; i >= 0; i--) { | 164 | for (i = max_size; i >= 0; i--) { |
136 | if (min <= da9211_current_limits[i] && | 165 | if (min <= current_limits[i] && |
137 | max >= da9211_current_limits[i]) { | 166 | max >= current_limits[i]) { |
138 | return regmap_update_bits(chip->regmap, | 167 | return regmap_update_bits(chip->regmap, |
139 | DA9211_REG_BUCK_ILIM, | 168 | DA9211_REG_BUCK_ILIM, |
140 | (0x0F << id*4), (i << id*4)); | 169 | (0x0F << id*4), (i << id*4)); |
@@ -150,14 +179,28 @@ static int da9211_get_current_limit(struct regulator_dev *rdev) | |||
150 | struct da9211 *chip = rdev_get_drvdata(rdev); | 179 | struct da9211 *chip = rdev_get_drvdata(rdev); |
151 | unsigned int data; | 180 | unsigned int data; |
152 | int ret; | 181 | int ret; |
182 | const int *current_limits; | ||
183 | |||
184 | switch (chip->chip_id) { | ||
185 | case DA9211: | ||
186 | current_limits = da9211_current_limits; | ||
187 | break; | ||
188 | case DA9213: | ||
189 | current_limits = da9213_current_limits; | ||
190 | break; | ||
191 | default: | ||
192 | return -EINVAL; | ||
193 | } | ||
153 | 194 | ||
154 | ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); | 195 | ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); |
155 | if (ret < 0) | 196 | if (ret < 0) |
156 | return ret; | 197 | return ret; |
157 | 198 | ||
158 | /* select one of 16 values: 0000 (2000mA) to 1111 (5000mA) */ | 199 | /* select one of 16 values: 0000 (2000mA or 3000mA) |
200 | * to 1111 (5000mA or 6000mA). | ||
201 | */ | ||
159 | data = (data >> id*4) & 0x0F; | 202 | data = (data >> id*4) & 0x0F; |
160 | return da9211_current_limits[data]; | 203 | return current_limits[data]; |
161 | } | 204 | } |
162 | 205 | ||
163 | static struct regulator_ops da9211_buck_ops = { | 206 | static struct regulator_ops da9211_buck_ops = { |
@@ -194,6 +237,59 @@ static struct regulator_desc da9211_regulators[] = { | |||
194 | DA9211_BUCK(BUCKB), | 237 | DA9211_BUCK(BUCKB), |
195 | }; | 238 | }; |
196 | 239 | ||
240 | #ifdef CONFIG_OF | ||
241 | static struct of_regulator_match da9211_matches[] = { | ||
242 | [DA9211_ID_BUCKA] = { .name = "BUCKA" }, | ||
243 | [DA9211_ID_BUCKB] = { .name = "BUCKB" }, | ||
244 | }; | ||
245 | |||
246 | static struct da9211_pdata *da9211_parse_regulators_dt( | ||
247 | struct device *dev) | ||
248 | { | ||
249 | struct da9211_pdata *pdata; | ||
250 | struct device_node *node; | ||
251 | int i, num, n; | ||
252 | |||
253 | node = of_get_child_by_name(dev->of_node, "regulators"); | ||
254 | if (!node) { | ||
255 | dev_err(dev, "regulators node not found\n"); | ||
256 | return ERR_PTR(-ENODEV); | ||
257 | } | ||
258 | |||
259 | num = of_regulator_match(dev, node, da9211_matches, | ||
260 | ARRAY_SIZE(da9211_matches)); | ||
261 | of_node_put(node); | ||
262 | if (num < 0) { | ||
263 | dev_err(dev, "Failed to match regulators\n"); | ||
264 | return ERR_PTR(-EINVAL); | ||
265 | } | ||
266 | |||
267 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
268 | if (!pdata) | ||
269 | return ERR_PTR(-ENOMEM); | ||
270 | |||
271 | pdata->num_buck = num; | ||
272 | |||
273 | n = 0; | ||
274 | for (i = 0; i < ARRAY_SIZE(da9211_matches); i++) { | ||
275 | if (!da9211_matches[i].init_data) | ||
276 | continue; | ||
277 | |||
278 | pdata->init_data[n] = da9211_matches[i].init_data; | ||
279 | |||
280 | n++; | ||
281 | } | ||
282 | |||
283 | return pdata; | ||
284 | } | ||
285 | #else | ||
286 | static struct da9211_pdata *da9211_parse_regulators_dt( | ||
287 | struct device *dev) | ||
288 | { | ||
289 | return ERR_PTR(-ENODEV); | ||
290 | } | ||
291 | #endif | ||
292 | |||
197 | static irqreturn_t da9211_irq_handler(int irq, void *data) | 293 | static irqreturn_t da9211_irq_handler(int irq, void *data) |
198 | { | 294 | { |
199 | struct da9211 *chip = data; | 295 | struct da9211 *chip = data; |
@@ -264,13 +360,11 @@ static int da9211_regulator_init(struct da9211 *chip) | |||
264 | } | 360 | } |
265 | 361 | ||
266 | for (i = 0; i < chip->num_regulator; i++) { | 362 | for (i = 0; i < chip->num_regulator; i++) { |
267 | if (chip->pdata) | 363 | config.init_data = chip->pdata->init_data[i]; |
268 | config.init_data = | ||
269 | &(chip->pdata->init_data[i]); | ||
270 | |||
271 | config.dev = chip->dev; | 364 | config.dev = chip->dev; |
272 | config.driver_data = chip; | 365 | config.driver_data = chip; |
273 | config.regmap = chip->regmap; | 366 | config.regmap = chip->regmap; |
367 | config.of_node = chip->dev->of_node; | ||
274 | 368 | ||
275 | chip->rdev[i] = devm_regulator_register(chip->dev, | 369 | chip->rdev[i] = devm_regulator_register(chip->dev, |
276 | &da9211_regulators[i], &config); | 370 | &da9211_regulators[i], &config); |
@@ -293,6 +387,7 @@ static int da9211_regulator_init(struct da9211 *chip) | |||
293 | 387 | ||
294 | return 0; | 388 | return 0; |
295 | } | 389 | } |
390 | |||
296 | /* | 391 | /* |
297 | * I2C driver interface functions | 392 | * I2C driver interface functions |
298 | */ | 393 | */ |
@@ -301,14 +396,17 @@ static int da9211_i2c_probe(struct i2c_client *i2c, | |||
301 | { | 396 | { |
302 | struct da9211 *chip; | 397 | struct da9211 *chip; |
303 | int error, ret; | 398 | int error, ret; |
399 | unsigned int data; | ||
304 | 400 | ||
305 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); | 401 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); |
402 | if (!chip) | ||
403 | return -ENOMEM; | ||
306 | 404 | ||
307 | chip->dev = &i2c->dev; | 405 | chip->dev = &i2c->dev; |
308 | chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); | 406 | chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); |
309 | if (IS_ERR(chip->regmap)) { | 407 | if (IS_ERR(chip->regmap)) { |
310 | error = PTR_ERR(chip->regmap); | 408 | error = PTR_ERR(chip->regmap); |
311 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 409 | dev_err(chip->dev, "Failed to allocate register map: %d\n", |
312 | error); | 410 | error); |
313 | return error; | 411 | return error; |
314 | } | 412 | } |
@@ -316,11 +414,33 @@ static int da9211_i2c_probe(struct i2c_client *i2c, | |||
316 | i2c_set_clientdata(i2c, chip); | 414 | i2c_set_clientdata(i2c, chip); |
317 | 415 | ||
318 | chip->pdata = i2c->dev.platform_data; | 416 | chip->pdata = i2c->dev.platform_data; |
319 | if (!chip->pdata) { | 417 | |
320 | dev_err(&i2c->dev, "No platform init data supplied\n"); | 418 | ret = regmap_read(chip->regmap, DA9211_REG_DEVICE_ID, &data); |
419 | if (ret < 0) { | ||
420 | dev_err(chip->dev, "Failed to read DEVICE_ID reg: %d\n", ret); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | switch (data) { | ||
425 | case DA9211_DEVICE_ID: | ||
426 | chip->chip_id = DA9211; | ||
427 | break; | ||
428 | case DA9213_DEVICE_ID: | ||
429 | chip->chip_id = DA9213; | ||
430 | break; | ||
431 | default: | ||
432 | dev_err(chip->dev, "Unsupported device id = 0x%x.\n", data); | ||
321 | return -ENODEV; | 433 | return -ENODEV; |
322 | } | 434 | } |
323 | 435 | ||
436 | if (!chip->pdata) | ||
437 | chip->pdata = da9211_parse_regulators_dt(chip->dev); | ||
438 | |||
439 | if (IS_ERR(chip->pdata)) { | ||
440 | dev_err(chip->dev, "No regulators defined for the platform\n"); | ||
441 | return PTR_ERR(chip->pdata); | ||
442 | } | ||
443 | |||
324 | chip->chip_irq = i2c->irq; | 444 | chip->chip_irq = i2c->irq; |
325 | 445 | ||
326 | if (chip->chip_irq != 0) { | 446 | if (chip->chip_irq != 0) { |
@@ -340,22 +460,32 @@ static int da9211_i2c_probe(struct i2c_client *i2c, | |||
340 | ret = da9211_regulator_init(chip); | 460 | ret = da9211_regulator_init(chip); |
341 | 461 | ||
342 | if (ret < 0) | 462 | if (ret < 0) |
343 | dev_err(&i2c->dev, "Failed to initialize regulator: %d\n", ret); | 463 | dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); |
344 | 464 | ||
345 | return ret; | 465 | return ret; |
346 | } | 466 | } |
347 | 467 | ||
348 | static const struct i2c_device_id da9211_i2c_id[] = { | 468 | static const struct i2c_device_id da9211_i2c_id[] = { |
349 | {"da9211", 0}, | 469 | {"da9211", DA9211}, |
470 | {"da9213", DA9213}, | ||
350 | {}, | 471 | {}, |
351 | }; | 472 | }; |
352 | |||
353 | MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); | 473 | MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); |
354 | 474 | ||
475 | #ifdef CONFIG_OF | ||
476 | static const struct of_device_id da9211_dt_ids[] = { | ||
477 | { .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] }, | ||
478 | { .compatible = "dlg,da9213", .data = &da9211_i2c_id[1] }, | ||
479 | {}, | ||
480 | }; | ||
481 | MODULE_DEVICE_TABLE(of, da9211_dt_ids); | ||
482 | #endif | ||
483 | |||
355 | static struct i2c_driver da9211_regulator_driver = { | 484 | static struct i2c_driver da9211_regulator_driver = { |
356 | .driver = { | 485 | .driver = { |
357 | .name = "da9211", | 486 | .name = "da9211", |
358 | .owner = THIS_MODULE, | 487 | .owner = THIS_MODULE, |
488 | .of_match_table = of_match_ptr(da9211_dt_ids), | ||
359 | }, | 489 | }, |
360 | .probe = da9211_i2c_probe, | 490 | .probe = da9211_i2c_probe, |
361 | .id_table = da9211_i2c_id, | 491 | .id_table = da9211_i2c_id, |
@@ -364,5 +494,5 @@ static struct i2c_driver da9211_regulator_driver = { | |||
364 | module_i2c_driver(da9211_regulator_driver); | 494 | module_i2c_driver(da9211_regulator_driver); |
365 | 495 | ||
366 | MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); | 496 | MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); |
367 | MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211"); | 497 | MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213"); |
368 | MODULE_LICENSE("GPL v2"); | 498 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h index 88b1769e8058..93fa9df2721c 100644 --- a/drivers/regulator/da9211-regulator.h +++ b/drivers/regulator/da9211-regulator.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * da9211-regulator.h - Regulator definitions for DA9211 | 2 | * da9211-regulator.h - Regulator definitions for DA9211/DA9213 |
3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. | 3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
@@ -53,12 +53,15 @@ | |||
53 | /* BUCK Phase Selection*/ | 53 | /* BUCK Phase Selection*/ |
54 | #define DA9211_REG_CONFIG_E 0x147 | 54 | #define DA9211_REG_CONFIG_E 0x147 |
55 | 55 | ||
56 | /* Device ID */ | ||
57 | #define DA9211_REG_DEVICE_ID 0x201 | ||
58 | |||
56 | /* | 59 | /* |
57 | * Registers bits | 60 | * Registers bits |
58 | */ | 61 | */ |
59 | /* DA9211_REG_PAGE_CON (addr=0x00) */ | 62 | /* DA9211_REG_PAGE_CON (addr=0x00) */ |
60 | #define DA9211_REG_PAGE_SHIFT 1 | 63 | #define DA9211_REG_PAGE_SHIFT 1 |
61 | #define DA9211_REG_PAGE_MASK 0x02 | 64 | #define DA9211_REG_PAGE_MASK 0x06 |
62 | /* On I2C registers 0x00 - 0xFF */ | 65 | /* On I2C registers 0x00 - 0xFF */ |
63 | #define DA9211_REG_PAGE0 0 | 66 | #define DA9211_REG_PAGE0 0 |
64 | /* On I2C registers 0x100 - 0x1FF */ | 67 | /* On I2C registers 0x100 - 0x1FF */ |
diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h index 0981ce0e72cc..5479394fefce 100644 --- a/include/linux/regulator/da9211.h +++ b/include/linux/regulator/da9211.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * da9211.h - Regulator device driver for DA9211 | 2 | * da9211.h - Regulator device driver for DA9211/DA9213 |
3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. | 3 | * Copyright (C) 2014 Dialog Semiconductor Ltd. |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
@@ -20,6 +20,11 @@ | |||
20 | 20 | ||
21 | #define DA9211_MAX_REGULATORS 2 | 21 | #define DA9211_MAX_REGULATORS 2 |
22 | 22 | ||
23 | enum da9211_chip_id { | ||
24 | DA9211, | ||
25 | DA9213, | ||
26 | }; | ||
27 | |||
23 | struct da9211_pdata { | 28 | struct da9211_pdata { |
24 | /* | 29 | /* |
25 | * Number of buck | 30 | * Number of buck |
@@ -27,6 +32,6 @@ struct da9211_pdata { | |||
27 | * 2 : 2 phase 2 buck | 32 | * 2 : 2 phase 2 buck |
28 | */ | 33 | */ |
29 | int num_buck; | 34 | int num_buck; |
30 | struct regulator_init_data *init_data; | 35 | struct regulator_init_data *init_data[DA9211_MAX_REGULATORS]; |
31 | }; | 36 | }; |
32 | #endif | 37 | #endif |