aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2012-11-29 00:19:43 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-09 22:23:56 -0500
commit4efd9dfecbf19a7a28f29b1142c07ba8327f2c8a (patch)
treebf1a4b7e00a98a0d98abe3a76a4955b19bf20f8c
parent9489e9dcae718d5fde988e4a684a0f55b5f94d17 (diff)
regulator: max1586: Implement get_voltage_sel callback
This is required since commit f7df20ec32 "regulator: core: Use list_voltage() to read single voltage regulators", otherwise _regulator_get_voltage returns rdev->desc->ops->list_voltage(rdev, 0). The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back the set up value. Thus this patch caches the setting when setting new voltage. Signed-off-by: Axel Lin <axel.lin@ingics.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--drivers/regulator/max1586.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index f67af3c1b963..ed2d3912efde 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -44,6 +44,9 @@ struct max1586_data {
44 unsigned int min_uV; 44 unsigned int min_uV;
45 unsigned int max_uV; 45 unsigned int max_uV;
46 46
47 unsigned int v3_curr_sel;
48 unsigned int v6_curr_sel;
49
47 struct regulator_dev *rdev[0]; 50 struct regulator_dev *rdev[0];
48}; 51};
49 52
@@ -63,31 +66,60 @@ static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 };
63 * R24 and R25=100kOhm as described in the data sheet. 66 * R24 and R25=100kOhm as described in the data sheet.
64 * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm 67 * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm
65 */ 68 */
69static int max1586_v3_get_voltage_sel(struct regulator_dev *rdev)
70{
71 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
72
73 return max1586->v3_curr_sel;
74}
75
66static int max1586_v3_set_voltage_sel(struct regulator_dev *rdev, 76static int max1586_v3_set_voltage_sel(struct regulator_dev *rdev,
67 unsigned selector) 77 unsigned selector)
68{ 78{
69 struct max1586_data *max1586 = rdev_get_drvdata(rdev); 79 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
70 struct i2c_client *client = max1586->client; 80 struct i2c_client *client = max1586->client;
81 int ret;
71 u8 v3_prog; 82 u8 v3_prog;
72 83
73 dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", 84 dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
74 regulator_list_voltage_linear(rdev, selector) / 1000); 85 regulator_list_voltage_linear(rdev, selector) / 1000);
75 86
76 v3_prog = I2C_V3_SELECT | (u8) selector; 87 v3_prog = I2C_V3_SELECT | (u8) selector;
77 return i2c_smbus_write_byte(client, v3_prog); 88 ret = i2c_smbus_write_byte(client, v3_prog);
89 if (ret)
90 return ret;
91
92 max1586->v3_curr_sel = selector;
93
94 return 0;
95}
96
97static int max1586_v6_get_voltage_sel(struct regulator_dev *rdev)
98{
99 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
100
101 return max1586->v6_curr_sel;
78} 102}
79 103
80static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, 104static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev,
81 unsigned int selector) 105 unsigned int selector)
82{ 106{
83 struct i2c_client *client = rdev_get_drvdata(rdev); 107 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
108 struct i2c_client *client = max1586->client;
84 u8 v6_prog; 109 u8 v6_prog;
110 int ret;
85 111
86 dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", 112 dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
87 rdev->desc->volt_table[selector] / 1000); 113 rdev->desc->volt_table[selector] / 1000);
88 114
89 v6_prog = I2C_V6_SELECT | (u8) selector; 115 v6_prog = I2C_V6_SELECT | (u8) selector;
90 return i2c_smbus_write_byte(client, v6_prog); 116 ret = i2c_smbus_write_byte(client, v6_prog);
117 if (ret)
118 return ret;
119
120 max1586->v6_curr_sel = selector;
121
122 return 0;
91} 123}
92 124
93/* 125/*
@@ -95,12 +127,14 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev,
95 * the set up value. 127 * the set up value.
96 */ 128 */
97static struct regulator_ops max1586_v3_ops = { 129static struct regulator_ops max1586_v3_ops = {
130 .get_voltage_sel = max1586_v3_get_voltage_sel,
98 .set_voltage_sel = max1586_v3_set_voltage_sel, 131 .set_voltage_sel = max1586_v3_set_voltage_sel,
99 .list_voltage = regulator_list_voltage_linear, 132 .list_voltage = regulator_list_voltage_linear,
100 .map_voltage = regulator_map_voltage_linear, 133 .map_voltage = regulator_map_voltage_linear,
101}; 134};
102 135
103static struct regulator_ops max1586_v6_ops = { 136static struct regulator_ops max1586_v6_ops = {
137 .get_voltage_sel = max1586_v6_get_voltage_sel,
104 .set_voltage_sel = max1586_v6_set_voltage_sel, 138 .set_voltage_sel = max1586_v6_set_voltage_sel,
105 .list_voltage = regulator_list_voltage_table, 139 .list_voltage = regulator_list_voltage_table,
106}; 140};
@@ -148,6 +182,10 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
148 max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000; 182 max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
149 max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000; 183 max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
150 184
185 /* Set curr_sel to default voltage on power-up */
186 max1586->v3_curr_sel = 24; /* 1.3V */
187 max1586->v6_curr_sel = 0;
188
151 rdev = max1586->rdev; 189 rdev = max1586->rdev;
152 for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { 190 for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
153 id = pdata->subdevs[i].id; 191 id = pdata->subdevs[i].id;