Loading Documentation/ABI/testing/sysfs-class-regulator +21 −0 Original line number Diff line number Diff line Loading @@ -349,3 +349,24 @@ Description: This will be one of the same strings reported by the "state" attribute. What: /sys/class/regulator/.../bypass Date: September 2012 KernelVersion: 3.7 Contact: Mark Brown <broonie@opensource.wolfsonmicro.com> Description: Some regulator directories will contain a field called bypass. This indicates if the device is in bypass mode. This will be one of the following strings: 'enabled' 'disabled' 'unknown' 'enabled' means the regulator is in bypass mode. 'disabled' means that the regulator is regulating. 'unknown' means software cannot determine the state, or the reported state is invalid. drivers/extcon/extcon-arizona.c +5 −0 Original line number Diff line number Diff line Loading @@ -434,6 +434,11 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev) regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, ARIZONA_JD1_ENA, ARIZONA_JD1_ENA); ret = regulator_allow_bypass(info->micvdd, true); if (ret != 0) dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n", ret); pm_runtime_put(&pdev->dev); return 0; Loading drivers/regulator/arizona-ldo1.c +4 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ static struct regulator_ops arizona_ldo1_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; static const struct regulator_desc arizona_ldo1 = { Loading @@ -49,6 +51,8 @@ static const struct regulator_desc arizona_ldo1 = { .vsel_reg = ARIZONA_LDO1_CONTROL_1, .vsel_mask = ARIZONA_LDO1_VSEL_MASK, .bypass_reg = ARIZONA_LDO1_CONTROL_1, .bypass_mask = ARIZONA_LDO1_BYPASS, .min_uV = 900000, .uV_step = 50000, .n_voltages = 7, Loading drivers/regulator/arizona-micsupp.c +5 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; static const struct regulator_desc arizona_micsupp = { Loading @@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = { .vsel_mask = ARIZONA_LDO2_VSEL_MASK, .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, .enable_mask = ARIZONA_CPMIC_ENA, .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, .bypass_mask = ARIZONA_CPMIC_BYPASS, .owner = THIS_MODULE, }; Loading drivers/regulator/core.c +126 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ struct regulator { struct device *dev; struct list_head list; unsigned int always_on:1; unsigned int bypass:1; int uA_load; int min_uV; int max_uV; Loading Loading @@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev, case REGULATOR_STATUS_STANDBY: label = "standby"; break; case REGULATOR_STATUS_BYPASS: label = "bypass"; break; case REGULATOR_STATUS_UNDEFINED: label = "undefined"; break; Loading Loading @@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev, static DEVICE_ATTR(suspend_standby_state, 0444, regulator_suspend_standby_state_show, NULL); static ssize_t regulator_bypass_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); const char *report; bool bypass; int ret; ret = rdev->desc->ops->get_bypass(rdev, &bypass); if (ret != 0) report = "unknown"; else if (bypass) report = "enabled"; else report = "disabled"; return sprintf(buf, "%s\n", report); } static DEVICE_ATTR(bypass, 0444, regulator_bypass_show, NULL); /* * These are the only attributes are present for all regulators. Loading Loading @@ -2673,6 +2698,100 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) } EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); /** * regulator_set_bypass_regmap - Default set_bypass() using regmap * * @rdev: device to operate on. * @enable: state to set. */ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) { unsigned int val; if (enable) val = rdev->desc->bypass_mask; else val = 0; return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, rdev->desc->bypass_mask, val); } EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); /** * regulator_get_bypass_regmap - Default get_bypass() using regmap * * @rdev: device to operate on. * @enable: current state. */ int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) { unsigned int val; int ret; ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); if (ret != 0) return ret; *enable = val & rdev->desc->bypass_mask; return 0; } EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); /** * regulator_allow_bypass - allow the regulator to go into bypass mode * * @regulator: Regulator to configure * @allow: enable or disable bypass mode * * Allow the regulator to go into bypass mode if all other consumers * for the regulator also enable bypass mode and the machine * constraints allow this. Bypass mode means that the regulator is * simply passing the input directly to the output with no regulation. */ int regulator_allow_bypass(struct regulator *regulator, bool enable) { struct regulator_dev *rdev = regulator->rdev; int ret = 0; if (!rdev->desc->ops->set_bypass) return 0; if (rdev->constraints && !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS)) return 0; mutex_lock(&rdev->mutex); if (enable && !regulator->bypass) { rdev->bypass_count++; if (rdev->bypass_count == rdev->open_count) { ret = rdev->desc->ops->set_bypass(rdev, enable); if (ret != 0) rdev->bypass_count--; } } else if (!enable && regulator->bypass) { rdev->bypass_count--; if (rdev->bypass_count != rdev->open_count) { ret = rdev->desc->ops->set_bypass(rdev, enable); if (ret != 0) rdev->bypass_count++; } } if (ret == 0) regulator->bypass = enable; mutex_unlock(&rdev->mutex); return ret; } EXPORT_SYMBOL_GPL(regulator_allow_bypass); /** * regulator_register_notifier - register regulator event notifier * @regulator: regulator source Loading Loading @@ -3036,6 +3155,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev) if (status < 0) return status; } if (ops->get_bypass) { status = device_create_file(dev, &dev_attr_bypass); if (status < 0) return status; } /* some attributes are type-specific */ if (rdev->desc->type == REGULATOR_CURRENT) { Loading Loading @@ -3124,6 +3248,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) &rdev->use_count); debugfs_create_u32("open_count", 0444, rdev->debugfs, &rdev->open_count); debugfs_create_u32("bypass_count", 0444, rdev->debugfs, &rdev->bypass_count); } /** Loading Loading
Documentation/ABI/testing/sysfs-class-regulator +21 −0 Original line number Diff line number Diff line Loading @@ -349,3 +349,24 @@ Description: This will be one of the same strings reported by the "state" attribute. What: /sys/class/regulator/.../bypass Date: September 2012 KernelVersion: 3.7 Contact: Mark Brown <broonie@opensource.wolfsonmicro.com> Description: Some regulator directories will contain a field called bypass. This indicates if the device is in bypass mode. This will be one of the following strings: 'enabled' 'disabled' 'unknown' 'enabled' means the regulator is in bypass mode. 'disabled' means that the regulator is regulating. 'unknown' means software cannot determine the state, or the reported state is invalid.
drivers/extcon/extcon-arizona.c +5 −0 Original line number Diff line number Diff line Loading @@ -434,6 +434,11 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev) regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, ARIZONA_JD1_ENA, ARIZONA_JD1_ENA); ret = regulator_allow_bypass(info->micvdd, true); if (ret != 0) dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n", ret); pm_runtime_put(&pdev->dev); return 0; Loading
drivers/regulator/arizona-ldo1.c +4 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ static struct regulator_ops arizona_ldo1_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; static const struct regulator_desc arizona_ldo1 = { Loading @@ -49,6 +51,8 @@ static const struct regulator_desc arizona_ldo1 = { .vsel_reg = ARIZONA_LDO1_CONTROL_1, .vsel_mask = ARIZONA_LDO1_VSEL_MASK, .bypass_reg = ARIZONA_LDO1_CONTROL_1, .bypass_mask = ARIZONA_LDO1_BYPASS, .min_uV = 900000, .uV_step = 50000, .n_voltages = 7, Loading
drivers/regulator/arizona-micsupp.c +5 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; static const struct regulator_desc arizona_micsupp = { Loading @@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = { .vsel_mask = ARIZONA_LDO2_VSEL_MASK, .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, .enable_mask = ARIZONA_CPMIC_ENA, .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, .bypass_mask = ARIZONA_CPMIC_BYPASS, .owner = THIS_MODULE, }; Loading
drivers/regulator/core.c +126 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ struct regulator { struct device *dev; struct list_head list; unsigned int always_on:1; unsigned int bypass:1; int uA_load; int min_uV; int max_uV; Loading Loading @@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev, case REGULATOR_STATUS_STANDBY: label = "standby"; break; case REGULATOR_STATUS_BYPASS: label = "bypass"; break; case REGULATOR_STATUS_UNDEFINED: label = "undefined"; break; Loading Loading @@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev, static DEVICE_ATTR(suspend_standby_state, 0444, regulator_suspend_standby_state_show, NULL); static ssize_t regulator_bypass_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); const char *report; bool bypass; int ret; ret = rdev->desc->ops->get_bypass(rdev, &bypass); if (ret != 0) report = "unknown"; else if (bypass) report = "enabled"; else report = "disabled"; return sprintf(buf, "%s\n", report); } static DEVICE_ATTR(bypass, 0444, regulator_bypass_show, NULL); /* * These are the only attributes are present for all regulators. Loading Loading @@ -2673,6 +2698,100 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) } EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); /** * regulator_set_bypass_regmap - Default set_bypass() using regmap * * @rdev: device to operate on. * @enable: state to set. */ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) { unsigned int val; if (enable) val = rdev->desc->bypass_mask; else val = 0; return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, rdev->desc->bypass_mask, val); } EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); /** * regulator_get_bypass_regmap - Default get_bypass() using regmap * * @rdev: device to operate on. * @enable: current state. */ int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) { unsigned int val; int ret; ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); if (ret != 0) return ret; *enable = val & rdev->desc->bypass_mask; return 0; } EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); /** * regulator_allow_bypass - allow the regulator to go into bypass mode * * @regulator: Regulator to configure * @allow: enable or disable bypass mode * * Allow the regulator to go into bypass mode if all other consumers * for the regulator also enable bypass mode and the machine * constraints allow this. Bypass mode means that the regulator is * simply passing the input directly to the output with no regulation. */ int regulator_allow_bypass(struct regulator *regulator, bool enable) { struct regulator_dev *rdev = regulator->rdev; int ret = 0; if (!rdev->desc->ops->set_bypass) return 0; if (rdev->constraints && !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS)) return 0; mutex_lock(&rdev->mutex); if (enable && !regulator->bypass) { rdev->bypass_count++; if (rdev->bypass_count == rdev->open_count) { ret = rdev->desc->ops->set_bypass(rdev, enable); if (ret != 0) rdev->bypass_count--; } } else if (!enable && regulator->bypass) { rdev->bypass_count--; if (rdev->bypass_count != rdev->open_count) { ret = rdev->desc->ops->set_bypass(rdev, enable); if (ret != 0) rdev->bypass_count++; } } if (ret == 0) regulator->bypass = enable; mutex_unlock(&rdev->mutex); return ret; } EXPORT_SYMBOL_GPL(regulator_allow_bypass); /** * regulator_register_notifier - register regulator event notifier * @regulator: regulator source Loading Loading @@ -3036,6 +3155,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev) if (status < 0) return status; } if (ops->get_bypass) { status = device_create_file(dev, &dev_attr_bypass); if (status < 0) return status; } /* some attributes are type-specific */ if (rdev->desc->type == REGULATOR_CURRENT) { Loading Loading @@ -3124,6 +3248,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) &rdev->use_count); debugfs_create_u32("open_count", 0444, rdev->debugfs, &rdev->open_count); debugfs_create_u32("bypass_count", 0444, rdev->debugfs, &rdev->bypass_count); } /** Loading