Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Laxman Dewangan and committed by
Samuel Ortiz
cc01b463 a0e08b86

+146
+97
drivers/mfd/palmas.c
··· 25 25 #include <linux/mfd/palmas.h> 26 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 + 32 + struct 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 + 45 + static 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 + 28 74 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { 29 75 { 30 76 .reg_bits = 8, ··· 231 185 .mask_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, 232 186 PALMAS_INT1_MASK), 233 187 }; 188 + 189 + int palmas_ext_control_req_config(struct palmas *palmas, 190 + enum palmas_external_requestor_id id, int ext_ctrl, bool enable) 191 + { 192 + int preq_mask_bit = 0; 193 + int reg_add = 0; 194 + int bit_pos; 195 + int ret; 196 + 197 + if (!(ext_ctrl & PALMAS_EXT_REQ)) 198 + return 0; 199 + 200 + if (id >= PALMAS_EXTERNAL_REQSTR_ID_MAX) 201 + return 0; 202 + 203 + if (ext_ctrl & PALMAS_EXT_CONTROL_NSLEEP) { 204 + reg_add = PALMAS_NSLEEP_RES_ASSIGN; 205 + preq_mask_bit = 0; 206 + } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE1) { 207 + reg_add = PALMAS_ENABLE1_RES_ASSIGN; 208 + preq_mask_bit = 1; 209 + } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE2) { 210 + reg_add = PALMAS_ENABLE2_RES_ASSIGN; 211 + preq_mask_bit = 2; 212 + } 213 + 214 + bit_pos = sleep_req_info[id].bit_pos; 215 + reg_add += sleep_req_info[id].reg_offset; 216 + if (enable) 217 + ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, 218 + reg_add, BIT(bit_pos), BIT(bit_pos)); 219 + else 220 + ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, 221 + reg_add, BIT(bit_pos), 0); 222 + if (ret < 0) { 223 + dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n", 224 + reg_add, ret); 225 + return ret; 226 + } 227 + 228 + /* Unmask the PREQ */ 229 + ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE, 230 + PALMAS_POWER_CTRL, BIT(preq_mask_bit), 0); 231 + if (ret < 0) { 232 + dev_err(palmas->dev, "POWER_CTRL register update failed %d\n", 233 + ret); 234 + return ret; 235 + } 236 + return ret; 237 + } 238 + EXPORT_SYMBOL_GPL(palmas_ext_control_req_config); 234 239 235 240 static int palmas_set_pdata_irq_flag(struct i2c_client *i2c, 236 241 struct palmas_platform_data *pdata)
+49
include/linux/mfd/palmas.h
··· 183 183 PALMAS_NUM_REGS, 184 184 }; 185 185 186 + /* External controll signal name */ 187 + enum { 188 + PALMAS_EXT_CONTROL_ENABLE1 = 0x1, 189 + PALMAS_EXT_CONTROL_ENABLE2 = 0x2, 190 + PALMAS_EXT_CONTROL_NSLEEP = 0x4, 191 + }; 192 + 193 + /* 194 + * Palmas device resources can be controlled externally for 195 + * enabling/disabling it rather than register write through i2c. 196 + * Add the external controlled requestor ID for different resources. 197 + */ 198 + enum palmas_external_requestor_id { 199 + PALMAS_EXTERNAL_REQSTR_ID_REGEN1, 200 + PALMAS_EXTERNAL_REQSTR_ID_REGEN2, 201 + PALMAS_EXTERNAL_REQSTR_ID_SYSEN1, 202 + PALMAS_EXTERNAL_REQSTR_ID_SYSEN2, 203 + PALMAS_EXTERNAL_REQSTR_ID_CLK32KG, 204 + PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO, 205 + PALMAS_EXTERNAL_REQSTR_ID_REGEN3, 206 + PALMAS_EXTERNAL_REQSTR_ID_SMPS12, 207 + PALMAS_EXTERNAL_REQSTR_ID_SMPS3, 208 + PALMAS_EXTERNAL_REQSTR_ID_SMPS45, 209 + PALMAS_EXTERNAL_REQSTR_ID_SMPS6, 210 + PALMAS_EXTERNAL_REQSTR_ID_SMPS7, 211 + PALMAS_EXTERNAL_REQSTR_ID_SMPS8, 212 + PALMAS_EXTERNAL_REQSTR_ID_SMPS9, 213 + PALMAS_EXTERNAL_REQSTR_ID_SMPS10, 214 + PALMAS_EXTERNAL_REQSTR_ID_LDO1, 215 + PALMAS_EXTERNAL_REQSTR_ID_LDO2, 216 + PALMAS_EXTERNAL_REQSTR_ID_LDO3, 217 + PALMAS_EXTERNAL_REQSTR_ID_LDO4, 218 + PALMAS_EXTERNAL_REQSTR_ID_LDO5, 219 + PALMAS_EXTERNAL_REQSTR_ID_LDO6, 220 + PALMAS_EXTERNAL_REQSTR_ID_LDO7, 221 + PALMAS_EXTERNAL_REQSTR_ID_LDO8, 222 + PALMAS_EXTERNAL_REQSTR_ID_LDO9, 223 + PALMAS_EXTERNAL_REQSTR_ID_LDOLN, 224 + PALMAS_EXTERNAL_REQSTR_ID_LDOUSB, 225 + 226 + /* Last entry */ 227 + PALMAS_EXTERNAL_REQSTR_ID_MAX, 228 + }; 229 + 186 230 struct palmas_pmic_platform_data { 187 231 /* An array of pointers to regulator init data indexed by regulator 188 232 * ID ··· 2909 2865 { 2910 2866 return regmap_irq_get_virq(palmas->irq_data, irq); 2911 2867 } 2868 + 2869 + 2870 + int palmas_ext_control_req_config(struct palmas *palmas, 2871 + enum palmas_external_requestor_id ext_control_req_id, 2872 + int ext_ctrl, bool enable); 2912 2873 2913 2874 #endif /* __LINUX_MFD_PALMAS_H */