From 1b5b42216469b05ef4b5916cb40b127dfab1da88 Mon Sep 17 00:00:00 2001 From: Axel Haslam Date: Thu, 3 Nov 2016 12:11:42 +0100 Subject: regulator: core: Add new API to poll for error conditions Regulator consumers can receive event notifications when errors are reported to the driver, but currently, there is no way for a regulator consumer to know when the error is over. To allow a regulator consumer to poll for error conditions add a new API: regulator_get_error_flags. Signed-off-by: Axel Haslam Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 26 ++++++++++++++++++++++++++ include/linux/regulator/driver.h | 4 ++++ 2 files changed, 30 insertions(+) (limited to 'include/linux') diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 692108222271..528eb1f5273e 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -120,6 +120,25 @@ struct regmap; #define REGULATOR_EVENT_PRE_DISABLE 0x400 #define REGULATOR_EVENT_ABORT_DISABLE 0x800 +/* + * Regulator errors that can be queried using regulator_get_error_flags + * + * UNDER_VOLTAGE Regulator output is under voltage. + * OVER_CURRENT Regulator output current is too high. + * REGULATION_OUT Regulator output is out of regulation. + * FAIL Regulator output has failed. + * OVER_TEMP Regulator over temp. + * + * NOTE: These errors can be OR'ed together. + */ + +#define REGULATOR_ERROR_UNDER_VOLTAGE BIT(1) +#define REGULATOR_ERROR_OVER_CURRENT BIT(2) +#define REGULATOR_ERROR_REGULATION_OUT BIT(3) +#define REGULATOR_ERROR_FAIL BIT(4) +#define REGULATOR_ERROR_OVER_TEMP BIT(5) + + /** * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event * @@ -237,6 +256,8 @@ int regulator_get_current_limit(struct regulator *regulator); int regulator_set_mode(struct regulator *regulator, unsigned int mode); unsigned int regulator_get_mode(struct regulator *regulator); +int regulator_get_error_flags(struct regulator *regulator, + unsigned int *flags); int regulator_set_load(struct regulator *regulator, int load_uA); int regulator_allow_bypass(struct regulator *regulator, bool allow); @@ -477,6 +498,11 @@ static inline unsigned int regulator_get_mode(struct regulator *regulator) return REGULATOR_MODE_NORMAL; } +static inline int regulator_get_error_flags(struct regulator *regulator) +{ + return -EINVAL; +} + static inline int regulator_set_load(struct regulator *regulator, int load_uA) { return REGULATOR_MODE_NORMAL; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 37b532410528..dac8e7b16bc6 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -100,6 +100,7 @@ struct regulator_linear_range { * * @set_mode: Set the configured operating mode for the regulator. * @get_mode: Get the configured operating mode for the regulator. + * @get_error_flags: Get the current error(s) for the regulator. * @get_status: Return actual (not as-configured) status of regulator, as a * REGULATOR_STATUS value (or negative errno) * @get_optimum_mode: Get the most efficient operating mode for the regulator @@ -169,6 +170,9 @@ struct regulator_ops { int (*set_mode) (struct regulator_dev *, unsigned int mode); unsigned int (*get_mode) (struct regulator_dev *); + /* retrieve current error flags on the regulator */ + int (*get_error_flags)(struct regulator_dev *, unsigned int *flags); + /* Time taken to enable or set voltage on the regulator */ int (*enable_time) (struct regulator_dev *); int (*set_ramp_delay) (struct regulator_dev *, int ramp_delay); -- cgit v1.2.3 From 383d0fca7035a12f1201277d33e8fc87c9d60c9a Mon Sep 17 00:00:00 2001 From: Venkat Reddy Talla Date: Thu, 17 Nov 2016 23:24:35 +0530 Subject: regulator: max77620: add support to configure MPOK Adding support to configure regulator POK mapping bit to control nRST_IO and GPIO1 POK function. In tegra based platform which uses MAX20024 pmic, when some of regulators are configured FPS_NONE(flexible power sequencer) causes PMIC GPIO1 to go low which lead to various other rails turning off, to avoid this MPOK bit of those regulators need to be set to 0 so that PMIC GPIO1 will not go low. Signed-off-by: Venkat Reddy Talla Acked-by: Lee Jones Signed-off-by: Mark Brown --- drivers/regulator/max77620-regulator.c | 46 ++++++++++++++++++++++++++++++++++ include/linux/mfd/max77620.h | 2 ++ 2 files changed, 48 insertions(+) (limited to 'include/linux') diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index c39a56b41901..d088a7c79e60 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -80,6 +80,7 @@ struct max77620_regulator_pdata { int suspend_fps_pd_slot; int suspend_fps_pu_slot; int current_mode; + int power_ok; int ramp_rate_setting; }; @@ -350,11 +351,48 @@ static int max77620_set_slew_rate(struct max77620_regulator *pmic, int id, return 0; } +static int max77620_config_power_ok(struct max77620_regulator *pmic, int id) +{ + struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id]; + struct max77620_regulator_info *rinfo = pmic->rinfo[id]; + struct max77620_chip *chip = dev_get_drvdata(pmic->dev->parent); + u8 val, mask; + int ret; + + switch (chip->chip_id) { + case MAX20024: + if (rpdata->power_ok >= 0) { + if (rinfo->type == MAX77620_REGULATOR_TYPE_SD) + mask = MAX20024_SD_CFG1_MPOK_MASK; + else + mask = MAX20024_LDO_CFG2_MPOK_MASK; + + val = rpdata->power_ok ? mask : 0; + + ret = regmap_update_bits(pmic->rmap, rinfo->cfg_addr, + mask, val); + if (ret < 0) { + dev_err(pmic->dev, "Reg 0x%02x update failed %d\n", + rinfo->cfg_addr, ret); + return ret; + } + } + break; + + default: + break; + } + + return 0; +} + static int max77620_init_pmic(struct max77620_regulator *pmic, int id) { struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id]; int ret; + max77620_config_power_ok(pmic, id); + /* Update power mode */ ret = max77620_regulator_get_power_mode(pmic, id); if (ret < 0) @@ -594,6 +632,12 @@ static int max77620_of_parse_cb(struct device_node *np, np, "maxim,suspend-fps-power-down-slot", &pval); rpdata->suspend_fps_pd_slot = (!ret) ? pval : -1; + ret = of_property_read_u32(np, "maxim,power-ok-control", &pval); + if (!ret) + rpdata->power_ok = pval; + else + rpdata->power_ok = -1; + ret = of_property_read_u32(np, "maxim,ramp-rate-setting", &pval); rpdata->ramp_rate_setting = (!ret) ? pval : 0; @@ -806,6 +850,8 @@ static int max77620_regulator_resume(struct device *dev) for (id = 0; id < MAX77620_NUM_REGS; id++) { reg_pdata = &pmic->reg_pdata[id]; + max77620_config_power_ok(pmic, id); + max77620_regulator_set_fps_slots(pmic, id, false); if (reg_pdata->active_fps_src < 0) continue; diff --git a/include/linux/mfd/max77620.h b/include/linux/mfd/max77620.h index 3ca0af07fc78..ad2a9a852aea 100644 --- a/include/linux/mfd/max77620.h +++ b/include/linux/mfd/max77620.h @@ -180,6 +180,7 @@ #define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2) #define MAX77620_SD_CFG1_FPWM_SD_SKIP 0 #define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2) +#define MAX20024_SD_CFG1_MPOK_MASK BIT(1) #define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0) #define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0 #define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0) @@ -187,6 +188,7 @@ /* LDO_CNFG2 */ #define MAX77620_LDO_POWER_MODE_MASK 0xC0 #define MAX77620_LDO_POWER_MODE_SHIFT 6 +#define MAX20024_LDO_CFG2_MPOK_MASK BIT(2) #define MAX77620_LDO_CFG2_ADE_MASK BIT(1) #define MAX77620_LDO_CFG2_ADE_DISABLE 0 #define MAX77620_LDO_CFG2_ADE_ENABLE BIT(1) -- cgit v1.2.3 From 30103b5b6432a51c3822a26dc340e35d91237f39 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sun, 4 Dec 2016 16:52:31 -0600 Subject: regulator: Fix regulator_get_error_flags() signature mismatch The function signature of does not match regulator_get_error_flags() when CONFIG_REGULATOR is not defined vs. when it is not defined. This makes both declarations match to prevent compiler errors. Signed-off-by: David Lechner Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 528eb1f5273e..ea0fffa5faeb 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -498,7 +498,8 @@ static inline unsigned int regulator_get_mode(struct regulator *regulator) return REGULATOR_MODE_NORMAL; } -static inline int regulator_get_error_flags(struct regulator *regulator) +static inline int regulator_get_error_flags(struct regulator *regulator, + unsigned int *flags) { return -EINVAL; } -- cgit v1.2.3