aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/palmas.c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2013-08-13 03:53:11 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-08-19 21:23:52 -0400
commitcc01b4639c94b1732995a9909a8973bfed67db2b (patch)
tree346a792fb5f78783e13a396ba95dd06f0460c684 /drivers/mfd/palmas.c
parenta0e08b8606f3c0722b235a09b537264e5b14f748 (diff)
mfd: palmas: Add support for external control configuration
Some of Palmas resources like clock, SMPSs, LDOs etc can be controlled by external pins ENABLE1, ENABLE2 or NSLEEP. Add support to configure these resources to externally controlled. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/palmas.c')
-rw-r--r--drivers/mfd/palmas.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index e4d1c706df8b..e71fa289eb01 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -25,6 +25,52 @@
25#include <linux/mfd/palmas.h> 25#include <linux/mfd/palmas.h>
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27 27
28#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 | \
29 PALMAS_EXT_CONTROL_ENABLE2 | \
30 PALMAS_EXT_CONTROL_NSLEEP)
31
32struct palmas_sleep_requestor_info {
33 int id;
34 int reg_offset;
35 int bit_pos;
36};
37
38#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \
39 [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \
40 .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \
41 .reg_offset = _offset, \
42 .bit_pos = _pos, \
43 }
44
45static struct palmas_sleep_requestor_info sleep_req_info[] = {
46 EXTERNAL_REQUESTOR(REGEN1, 0, 0),
47 EXTERNAL_REQUESTOR(REGEN2, 0, 1),
48 EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
49 EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
50 EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
51 EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
52 EXTERNAL_REQUESTOR(REGEN3, 0, 6),
53 EXTERNAL_REQUESTOR(SMPS12, 1, 0),
54 EXTERNAL_REQUESTOR(SMPS3, 1, 1),
55 EXTERNAL_REQUESTOR(SMPS45, 1, 2),
56 EXTERNAL_REQUESTOR(SMPS6, 1, 3),
57 EXTERNAL_REQUESTOR(SMPS7, 1, 4),
58 EXTERNAL_REQUESTOR(SMPS8, 1, 5),
59 EXTERNAL_REQUESTOR(SMPS9, 1, 6),
60 EXTERNAL_REQUESTOR(SMPS10, 1, 7),
61 EXTERNAL_REQUESTOR(LDO1, 2, 0),
62 EXTERNAL_REQUESTOR(LDO2, 2, 1),
63 EXTERNAL_REQUESTOR(LDO3, 2, 2),
64 EXTERNAL_REQUESTOR(LDO4, 2, 3),
65 EXTERNAL_REQUESTOR(LDO5, 2, 4),
66 EXTERNAL_REQUESTOR(LDO6, 2, 5),
67 EXTERNAL_REQUESTOR(LDO7, 2, 6),
68 EXTERNAL_REQUESTOR(LDO8, 2, 7),
69 EXTERNAL_REQUESTOR(LDO9, 3, 0),
70 EXTERNAL_REQUESTOR(LDOLN, 3, 1),
71 EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
72};
73
28static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { 74static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
29 { 75 {
30 .reg_bits = 8, 76 .reg_bits = 8,
@@ -186,6 +232,57 @@ static struct regmap_irq_chip palmas_irq_chip = {
186 PALMAS_INT1_MASK), 232 PALMAS_INT1_MASK),
187}; 233};
188 234
235int palmas_ext_control_req_config(struct palmas *palmas,
236 enum palmas_external_requestor_id id, int ext_ctrl, bool enable)
237{
238 int preq_mask_bit = 0;
239 int reg_add = 0;
240 int bit_pos;
241 int ret;
242
243 if (!(ext_ctrl & PALMAS_EXT_REQ))
244 return 0;
245
246 if (id >= PALMAS_EXTERNAL_REQSTR_ID_MAX)
247 return 0;
248
249 if (ext_ctrl & PALMAS_EXT_CONTROL_NSLEEP) {
250 reg_add = PALMAS_NSLEEP_RES_ASSIGN;
251 preq_mask_bit = 0;
252 } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE1) {
253 reg_add = PALMAS_ENABLE1_RES_ASSIGN;
254 preq_mask_bit = 1;
255 } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE2) {
256 reg_add = PALMAS_ENABLE2_RES_ASSIGN;
257 preq_mask_bit = 2;
258 }
259
260 bit_pos = sleep_req_info[id].bit_pos;
261 reg_add += sleep_req_info[id].reg_offset;
262 if (enable)
263 ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
264 reg_add, BIT(bit_pos), BIT(bit_pos));
265 else
266 ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
267 reg_add, BIT(bit_pos), 0);
268 if (ret < 0) {
269 dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n",
270 reg_add, ret);
271 return ret;
272 }
273
274 /* Unmask the PREQ */
275 ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
276 PALMAS_POWER_CTRL, BIT(preq_mask_bit), 0);
277 if (ret < 0) {
278 dev_err(palmas->dev, "POWER_CTRL register update failed %d\n",
279 ret);
280 return ret;
281 }
282 return ret;
283}
284EXPORT_SYMBOL_GPL(palmas_ext_control_req_config);
285
189static int palmas_set_pdata_irq_flag(struct i2c_client *i2c, 286static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
190 struct palmas_platform_data *pdata) 287 struct palmas_platform_data *pdata)
191{ 288{