Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753045AbbK1VOw (ORCPT ); Sat, 28 Nov 2015 16:14:52 -0500 Received: from proxima.lp0.eu ([81.2.80.65]:51033 "EHLO proxima.lp0.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752768AbbK1VOu (ORCPT ); Sat, 28 Nov 2015 16:14:50 -0500 Subject: [PATCH 2/2] regulator: fixed: Add support for regmap To: devicetree@vger.kernel.org, Liam Girdwood , Mark Brown References: <565A18DD.60108@simon.arlott.org.uk> Cc: Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , linux-kernel@vger.kernel.org, Florian Fainelli , Jonas Gorski From: Simon Arlott Message-ID: <565A1945.1040800@simon.arlott.org.uk> Date: Sat, 28 Nov 2015 21:14:45 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <565A18DD.60108@simon.arlott.org.uk> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4551 Lines: 127 Use the device tree properties for regmap: * Lookup the regmap phandle * Use the enable offset and enable mask * Reuse enable-active-high value Use an alternative set of regulator_ops when the regmap is set, specifying the regmap helper functions. As syscon_regmap_lookup_by_phandle() can only return -ENODEV or -ENOSYS as errors and -EPROBE_DEFER doesn't make sense for a register, the specific error is never propagated. This is required for Broadcom BCM63xx SoCs that enable power to individual peripherals by clearing a bit in the miscIddqCtrl register. Signed-off-by: Simon Arlott --- drivers/regulator/fixed.c | 30 +++++++++++++++++++++++++++++- include/linux/regulator/fixed.h | 9 ++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index ff62d69..5a3fa44 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -30,6 +30,7 @@ #include #include #include +#include struct fixed_voltage_data { struct regulator_desc desc; @@ -92,6 +93,19 @@ of_get_fixed_voltage_config(struct device *dev, if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER)) return ERR_PTR(-EPROBE_DEFER); + config->regmap = syscon_regmap_lookup_by_phandle(np, "regmap"); + if (!IS_ERR(config->regmap)) { + u32 val; + + if (of_property_read_u32(np, "regmap-offset", &val)) + return ERR_PTR(-EINVAL); + config->enable_reg = val; + + if (of_property_read_u32(np, "regmap-mask", &val)) + return ERR_PTR(-EINVAL); + config->enable_mask = val; + } + of_property_read_u32(np, "startup-delay-us", &config->startup_delay); config->enable_high = of_property_read_bool(np, "enable-active-high"); @@ -107,6 +121,12 @@ of_get_fixed_voltage_config(struct device *dev, static struct regulator_ops fixed_voltage_ops = { }; +static struct regulator_ops fixed_voltage_regmap_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + static int reg_fixed_voltage_probe(struct platform_device *pdev) { struct fixed_voltage_config *config; @@ -140,7 +160,15 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) } drvdata->desc.type = REGULATOR_VOLTAGE; drvdata->desc.owner = THIS_MODULE; - drvdata->desc.ops = &fixed_voltage_ops; + if (!IS_ERR_OR_NULL(config->regmap)) { + drvdata->desc.ops = &fixed_voltage_regmap_ops; + cfg.regmap = config->regmap; + drvdata->desc.enable_reg = config->enable_reg; + drvdata->desc.enable_mask = config->enable_mask; + drvdata->desc.enable_is_inverted = !config->enable_high; + } else { + drvdata->desc.ops = &fixed_voltage_ops; + } drvdata->desc.enable_time = config->startup_delay; diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h index 48918be..7cec0d1 100644 --- a/include/linux/regulator/fixed.h +++ b/include/linux/regulator/fixed.h @@ -26,6 +26,10 @@ struct regulator_init_data; * @microvolts: Output voltage of regulator * @gpio: GPIO to use for enable control * set to -EINVAL if not used + * @regmap: Regmap to use for enable control + * set to -ENODEV if not used + * @enable_reg: Register for control when using regmap + * @enable_mask: Mask for control when using regmap * @startup_delay: Start-up time in microseconds * @gpio_is_open_drain: Gpio pin is open drain or normal type. * If it is open drain type then HIGH will be set @@ -33,7 +37,7 @@ struct regulator_init_data; * and low will be set as gpio-output with driven * to low. For non-open-drain case, the gpio will * will be in output and drive to low/high accordingly. - * @enable_high: Polarity of enable GPIO + * @enable_high: Polarity of enable GPIO/regmap * 1 = Active high, 0 = Active low * @enabled_at_boot: Whether regulator has been enabled at * boot or not. 1 = Yes, 0 = No @@ -50,6 +54,9 @@ struct fixed_voltage_config { const char *input_supply; int microvolts; int gpio; + struct regmap *regmap; + unsigned int enable_reg; + unsigned int enable_mask; unsigned startup_delay; unsigned gpio_is_open_drain:1; unsigned enable_high:1; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/