aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/ab8500-ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/ab8500-ext.c')
-rw-r--r--drivers/regulator/ab8500-ext.c98
1 files changed, 71 insertions, 27 deletions
diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
index 95008dec5190..21b9bfb0fc5e 100644
--- a/drivers/regulator/ab8500-ext.c
+++ b/drivers/regulator/ab8500-ext.c
@@ -28,80 +28,121 @@
28 * @dev: device pointer 28 * @dev: device pointer
29 * @desc: regulator description 29 * @desc: regulator description
30 * @rdev: regulator device 30 * @rdev: regulator device
31 * @cfg: regulator configuration (extension of regulator FW configuration)
31 * @is_enabled: status of regulator (on/off) 32 * @is_enabled: status of regulator (on/off)
32 * @update_bank: bank to control on/off 33 * @update_bank: bank to control on/off
33 * @update_reg: register to control on/off 34 * @update_reg: register to control on/off
34 * @update_mask: mask to enable/disable and set mode of regulator 35 * @update_mask: mask to enable/disable and set mode of regulator
35 * @update_val: bits holding the regulator current mode 36 * @update_val: bits holding the regulator current mode
36 * @update_val_en: bits to set EN pin active (LPn pin deactive) 37 * @update_val_hp: bits to set EN pin active (LPn pin deactive)
37 * normally this means high power mode 38 * normally this means high power mode
38 * @update_val_en_lp: bits to set EN pin active and LPn pin active 39 * @update_val_lp: bits to set EN pin active and LPn pin active
39 * normally this means low power mode 40 * normally this means low power mode
40 * @delay: startup delay in ms 41 * @update_val_hw: bits to set regulator pins in HW control
42 * SysClkReq pins and logic will choose mode
41 */ 43 */
42struct ab8500_ext_regulator_info { 44struct ab8500_ext_regulator_info {
43 struct device *dev; 45 struct device *dev;
44 struct regulator_desc desc; 46 struct regulator_desc desc;
45 struct regulator_dev *rdev; 47 struct regulator_dev *rdev;
48 struct ab8500_ext_regulator_cfg *cfg;
46 bool is_enabled; 49 bool is_enabled;
47 u8 update_bank; 50 u8 update_bank;
48 u8 update_reg; 51 u8 update_reg;
49 u8 update_mask; 52 u8 update_mask;
50 u8 update_val; 53 u8 update_val;
51 u8 update_val_en; 54 u8 update_val_hp;
52 u8 update_val_en_lp; 55 u8 update_val_lp;
56 u8 update_val_hw;
53}; 57};
54 58
55static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) 59static int enable(struct ab8500_ext_regulator_info *info, u8 *regval)
56{ 60{
57 int ret; 61 int ret;
58 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
59 62
60 if (info == NULL) { 63 *regval = info->update_val;
61 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 64
62 return -EINVAL; 65 /*
63 } 66 * To satisfy both HW high power request and SW request, the regulator
67 * must be on in high power.
68 */
69 if (info->cfg && info->cfg->hwreq)
70 *regval = info->update_val_hp;
64 71
65 ret = abx500_mask_and_set_register_interruptible(info->dev, 72 ret = abx500_mask_and_set_register_interruptible(info->dev,
66 info->update_bank, info->update_reg, 73 info->update_bank, info->update_reg,
67 info->update_mask, info->update_val); 74 info->update_mask, *regval);
68 if (ret < 0) 75 if (ret < 0)
69 dev_err(rdev_get_dev(info->rdev), 76 dev_err(rdev_get_dev(info->rdev),
70 "couldn't set enable bits for regulator\n"); 77 "couldn't set enable bits for regulator\n");
71 78
72 info->is_enabled = true; 79 info->is_enabled = true;
73 80
74 dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):"
75 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
76 info->desc.name, info->update_bank, info->update_reg,
77 info->update_mask, info->update_val);
78
79 return ret; 81 return ret;
80} 82}
81 83
82static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) 84static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
83{ 85{
84 int ret; 86 int ret;
85 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); 87 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
88 u8 regval;
86 89
87 if (info == NULL) { 90 if (info == NULL) {
88 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 91 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
89 return -EINVAL; 92 return -EINVAL;
90 } 93 }
91 94
95 ret = enable(info, &regval);
96
97 dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):"
98 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
99 info->desc.name, info->update_bank, info->update_reg,
100 info->update_mask, regval);
101
102 return ret;
103}
104
105static int disable(struct ab8500_ext_regulator_info *info, u8 *regval)
106{
107 int ret;
108
109 *regval = 0x0;
110
111 /*
112 * Set the regulator in HW request mode if configured
113 */
114 if (info->cfg && info->cfg->hwreq)
115 *regval = info->update_val_hw;
116
92 ret = abx500_mask_and_set_register_interruptible(info->dev, 117 ret = abx500_mask_and_set_register_interruptible(info->dev,
93 info->update_bank, info->update_reg, 118 info->update_bank, info->update_reg,
94 info->update_mask, 0x0); 119 info->update_mask, *regval);
95 if (ret < 0) 120 if (ret < 0)
96 dev_err(rdev_get_dev(info->rdev), 121 dev_err(rdev_get_dev(info->rdev),
97 "couldn't set disable bits for regulator\n"); 122 "couldn't set disable bits for regulator\n");
98 123
99 info->is_enabled = false; 124 info->is_enabled = false;
100 125
126 return ret;
127}
128
129static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
130{
131 int ret;
132 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
133 u8 regval;
134
135 if (info == NULL) {
136 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
137 return -EINVAL;
138 }
139
140 ret = disable(info, &regval);
141
101 dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):" 142 dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):"
102 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 143 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
103 info->desc.name, info->update_bank, info->update_reg, 144 info->desc.name, info->update_bank, info->update_reg,
104 info->update_mask, 0x0); 145 info->update_mask, regval);
105 146
106 return ret; 147 return ret;
107} 148}
@@ -130,7 +171,8 @@ static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev)
130 info->desc.name, info->update_bank, info->update_reg, 171 info->desc.name, info->update_bank, info->update_reg,
131 info->update_mask, regval); 172 info->update_mask, regval);
132 173
133 if (regval & info->update_mask) 174 if (((regval & info->update_mask) == info->update_val_lp) ||
175 ((regval & info->update_mask) == info->update_val_hp))
134 info->is_enabled = true; 176 info->is_enabled = true;
135 else 177 else
136 info->is_enabled = false; 178 info->is_enabled = false;
@@ -241,7 +283,6 @@ static struct regulator_ops ab8500_ext_regulator_ops = {
241 .list_voltage = ab8500_ext_list_voltage, 283 .list_voltage = ab8500_ext_list_voltage,
242}; 284};
243 285
244
245static struct ab8500_ext_regulator_info 286static struct ab8500_ext_regulator_info
246 ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = { 287 ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = {
247 [AB8500_EXT_SUPPLY1] = { 288 [AB8500_EXT_SUPPLY1] = {
@@ -291,8 +332,9 @@ static struct ab8500_ext_regulator_info
291 .update_reg = 0x08, 332 .update_reg = 0x08,
292 .update_mask = 0x30, 333 .update_mask = 0x30,
293 .update_val = 0x10, 334 .update_val = 0x10,
294 .update_val_en = 0x10, 335 .update_val_hp = 0x10,
295 .update_val_en_lp = 0x30, 336 .update_val_lp = 0x30,
337 .update_val_hw = 0x20,
296 }, 338 },
297}; 339};
298 340
@@ -333,8 +375,8 @@ int ab8500_ext_regulator_init(struct platform_device *pdev)
333 /* VextSupply3LPn is inverted on AB8500 2.x */ 375 /* VextSupply3LPn is inverted on AB8500 2.x */
334 info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3]; 376 info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3];
335 info->update_val = 0x30; 377 info->update_val = 0x30;
336 info->update_val_en = 0x30; 378 info->update_val_hp = 0x30;
337 info->update_val_en_lp = 0x10; 379 info->update_val_lp = 0x10;
338 } 380 }
339 381
340 /* register all regulators */ 382 /* register all regulators */
@@ -344,6 +386,8 @@ int ab8500_ext_regulator_init(struct platform_device *pdev)
344 /* assign per-regulator data */ 386 /* assign per-regulator data */
345 info = &ab8500_ext_regulator_info[i]; 387 info = &ab8500_ext_regulator_info[i];
346 info->dev = &pdev->dev; 388 info->dev = &pdev->dev;
389 info->cfg = (struct ab8500_ext_regulator_cfg *)
390 pdata->ext_regulator[i].driver_data;
347 391
348 config.dev = &pdev->dev; 392 config.dev = &pdev->dev;
349 config.init_data = &pdata->ext_regulator[i]; 393 config.init_data = &pdata->ext_regulator[i];