aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/max1586.c71
-rw-r--r--include/linux/regulator/max1586.h11
2 files changed, 63 insertions, 19 deletions
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index bbbb55fcfe8c..92799f40c864 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -29,7 +29,6 @@
29 29
30#define MAX1586_V3_MIN_UV 700000 30#define MAX1586_V3_MIN_UV 700000
31#define MAX1586_V3_MAX_UV 1475000 31#define MAX1586_V3_MAX_UV 1475000
32#define MAX1586_V3_STEP_UV 25000
33 32
34#define MAX1586_V6_MIN_UV 0 33#define MAX1586_V6_MIN_UV 0
35#define MAX1586_V6_MAX_UV 3000000 34#define MAX1586_V6_MAX_UV 3000000
@@ -37,33 +36,52 @@
37#define I2C_V3_SELECT (0 << 5) 36#define I2C_V3_SELECT (0 << 5)
38#define I2C_V6_SELECT (1 << 5) 37#define I2C_V6_SELECT (1 << 5)
39 38
39struct max1586_data {
40 struct i2c_client *client;
41
42 /* min/max V3 voltage */
43 int min_uV;
44 int max_uV;
45
46 struct regulator_dev *rdev[0];
47};
48
40/* 49/*
41 * V3 voltage 50 * V3 voltage
42 * On I2C bus, sending a "x" byte to the max1586 means : 51 * On I2C bus, sending a "x" byte to the max1586 means :
43 * set V3 to 0.700V + (x & 0x1f) * 0.025V 52 * set V3 to 0.700V + (x & 0x1f) * 0.025V
53 * This voltage can be increased by external resistors
54 * R24 and R25=100kOhm as described in the data sheet.
55 * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm
44 */ 56 */
45static int max1586_v3_calc_voltage(unsigned selector) 57static int max1586_v3_calc_voltage(struct max1586_data *max1586,
58 unsigned selector)
46{ 59{
47 return MAX1586_V3_MIN_UV + (MAX1586_V3_STEP_UV * selector); 60 unsigned range_uV = max1586->max_uV - max1586->min_uV;
61
62 return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL);
48} 63}
49 64
50static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV) 65static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
51{ 66{
52 struct i2c_client *client = rdev_get_drvdata(rdev); 67 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
68 struct i2c_client *client = max1586->client;
69 unsigned range_uV = max1586->max_uV - max1586->min_uV;
53 unsigned selector; 70 unsigned selector;
54 u8 v3_prog; 71 u8 v3_prog;
55 72
56 if (min_uV < MAX1586_V3_MIN_UV || min_uV > MAX1586_V3_MAX_UV) 73 if (min_uV > max1586->max_uV || max_uV < max1586->min_uV)
57 return -EINVAL;
58 if (max_uV < MAX1586_V3_MIN_UV || max_uV > MAX1586_V3_MAX_UV)
59 return -EINVAL; 74 return -EINVAL;
75 if (min_uV < max1586->min_uV)
76 min_uV = max1586->min_uV;
60 77
61 selector = (min_uV - MAX1586_V3_MIN_UV) / MAX1586_V3_STEP_UV; 78 selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL +
62 if (max1586_v3_calc_voltage(selector) > max_uV) 79 range_uV - 1) / range_uV;
80 if (max1586_v3_calc_voltage(max1586, selector) > max_uV)
63 return -EINVAL; 81 return -EINVAL;
64 82
65 dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", 83 dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
66 max1586_v3_calc_voltage(selector) / 1000); 84 max1586_v3_calc_voltage(max1586, selector) / 1000);
67 85
68 v3_prog = I2C_V3_SELECT | (u8) selector; 86 v3_prog = I2C_V3_SELECT | (u8) selector;
69 return i2c_smbus_write_byte(client, v3_prog); 87 return i2c_smbus_write_byte(client, v3_prog);
@@ -71,9 +89,11 @@ static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
71 89
72static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector) 90static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector)
73{ 91{
92 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
93
74 if (selector > MAX1586_V3_MAX_VSEL) 94 if (selector > MAX1586_V3_MAX_VSEL)
75 return -EINVAL; 95 return -EINVAL;
76 return max1586_v3_calc_voltage(selector); 96 return max1586_v3_calc_voltage(max1586, selector);
77} 97}
78 98
79/* 99/*
@@ -164,14 +184,25 @@ static int max1586_pmic_probe(struct i2c_client *client,
164{ 184{
165 struct regulator_dev **rdev; 185 struct regulator_dev **rdev;
166 struct max1586_platform_data *pdata = client->dev.platform_data; 186 struct max1586_platform_data *pdata = client->dev.platform_data;
167 int i, id, ret = 0; 187 struct max1586_data *max1586;
188 int i, id, ret = -ENOMEM;
189
190 max1586 = kzalloc(sizeof(struct max1586_data) +
191 sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
192 GFP_KERNEL);
193 if (!max1586)
194 goto out;
168 195
169 rdev = kzalloc(sizeof(struct regulator_dev *) * (MAX1586_V6 + 1), 196 max1586->client = client;
170 GFP_KERNEL);
171 if (!rdev)
172 return -ENOMEM;
173 197
174 ret = -EINVAL; 198 if (!pdata->v3_gain) {
199 ret = -EINVAL;
200 goto out_unmap;
201 }
202 max1586->min_uV = MAX1586_V3_MIN_UV * pdata->v3_gain / 1000000;
203 max1586->max_uV = MAX1586_V3_MAX_UV * pdata->v3_gain / 1000000;
204
205 rdev = max1586->rdev;
175 for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { 206 for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
176 id = pdata->subdevs[i].id; 207 id = pdata->subdevs[i].id;
177 if (!pdata->subdevs[i].platform_data) 208 if (!pdata->subdevs[i].platform_data)
@@ -182,7 +213,7 @@ static int max1586_pmic_probe(struct i2c_client *client,
182 } 213 }
183 rdev[i] = regulator_register(&max1586_reg[id], &client->dev, 214 rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
184 pdata->subdevs[i].platform_data, 215 pdata->subdevs[i].platform_data,
185 client); 216 max1586);
186 if (IS_ERR(rdev[i])) { 217 if (IS_ERR(rdev[i])) {
187 ret = PTR_ERR(rdev[i]); 218 ret = PTR_ERR(rdev[i]);
188 dev_err(&client->dev, "failed to register %s\n", 219 dev_err(&client->dev, "failed to register %s\n",
@@ -198,7 +229,9 @@ static int max1586_pmic_probe(struct i2c_client *client,
198err: 229err:
199 while (--i >= 0) 230 while (--i >= 0)
200 regulator_unregister(rdev[i]); 231 regulator_unregister(rdev[i]);
201 kfree(rdev); 232out_unmap:
233 kfree(max1586);
234out:
202 return ret; 235 return ret;
203} 236}
204 237
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h
index 2056973396b6..44563192bf16 100644
--- a/include/linux/regulator/max1586.h
+++ b/include/linux/regulator/max1586.h
@@ -26,6 +26,12 @@
26#define MAX1586_V3 0 26#define MAX1586_V3 0
27#define MAX1586_V6 1 27#define MAX1586_V6 1
28 28
29/* precalculated values for v3_gain */
30#define MAX1586_GAIN_NO_R24 1000000 /* 700000 .. 1475000 mV */
31#define MAX1586_GAIN_R24_3k32 1051098 /* 735768 .. 1550369 mV */
32#define MAX1586_GAIN_R24_5k11 1078648 /* 755053 .. 1591005 mV */
33#define MAX1586_GAIN_R24_7k5 1115432 /* 780802 .. 1645262 mV */
34
29/** 35/**
30 * max1586_subdev_data - regulator data 36 * max1586_subdev_data - regulator data
31 * @id: regulator Id (either MAX1586_V3 or MAX1586_V6) 37 * @id: regulator Id (either MAX1586_V3 or MAX1586_V6)
@@ -43,10 +49,15 @@ struct max1586_subdev_data {
43 * @num_subdevs: number of regultors used (may be 1 or 2) 49 * @num_subdevs: number of regultors used (may be 1 or 2)
44 * @subdevs: regulator used 50 * @subdevs: regulator used
45 * At most, there will be a regulator for V3 and one for V6 voltages. 51 * At most, there will be a regulator for V3 and one for V6 voltages.
52 * @v3_gain: gain on the V3 voltage output multiplied by 1e6.
53 * This can be calculated as ((1 + R24/R25 + R24/185.5kOhm) * 1e6)
54 * for an external resistor configuration as described in the
55 * data sheet (R25=100kOhm).
46 */ 56 */
47struct max1586_platform_data { 57struct max1586_platform_data {
48 int num_subdevs; 58 int num_subdevs;
49 struct max1586_subdev_data *subdevs; 59 struct max1586_subdev_data *subdevs;
60 int v3_gain;
50}; 61};
51 62
52#endif 63#endif