From patchwork Sun Sep 28 02:28:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Zhong X-Patchwork-Id: 4990781 Return-Path: X-Original-To: patchwork-linux-rockchip@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id AD707BEEA6 for ; Sun, 28 Sep 2014 02:29:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 77C48202A1 for ; Sun, 28 Sep 2014 02:29:41 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3A88420274 for ; Sun, 28 Sep 2014 02:29:40 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XY4F1-0005ds-Vy; Sun, 28 Sep 2014 02:29:39 +0000 Received: from mail-pd0-f173.google.com ([209.85.192.173]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XY4Ez-0005ZE-Ur for linux-rockchip@lists.infradead.org; Sun, 28 Sep 2014 02:29:38 +0000 Received: by mail-pd0-f173.google.com with SMTP id w10so5437722pde.18 for ; Sat, 27 Sep 2014 19:29:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5oU8/zNE0w45YzG9MG/A/MLxPSzzsHeGjxfIYcoo83o=; b=dDjq4FOvnK/RU4CZrTgLypuJtOGkXTOZ0N12oroA3acj0dgJXabbXzzJjcMopsD947 9mx/1s+Fm68dLmJ2opDNjn7tYc/GEKKsJxHX28+2WClJ9Unha7RYNd5EvOpXMO1Wm3yC jkhQjW/RBXqTqgrepMtmhdZsPUTTvvUcp6Debj2wS24WBv6ELZa31fY4aKIRHn2j7VwP b2ubawsmOvcq28g9M+bJzytCnc46cEuoONf4+iPqYwcT0wIEfAViJHoYRo3sJT2yVDCE guiwsjfcZWaAV9MzcretZGLolBYkY7Y95As/PWh5/xOwmNlwYDKyNBascMGNxI+Xg/M+ Eq7g== X-Received: by 10.70.127.209 with SMTP id ni17mr9650477pdb.31.1411871355586; Sat, 27 Sep 2014 19:29:15 -0700 (PDT) Received: from localhost.localdomain (119.81.172.66-static.reverse.softlayer.com. [119.81.172.66]) by mx.google.com with ESMTPSA id p1sm8646815pdr.15.2014.09.27.19.29.10 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 27 Sep 2014 19:29:14 -0700 (PDT) From: Chris Zhong To: dianders@chromium.org, heiko@sntech.de Subject: [PATCH v7 1/2] regulator: pwm-regulator: get voltage and duty table from dts Date: Sun, 28 Sep 2014 10:28:53 +0800 Message-Id: <1411871334-17692-2-git-send-email-zyw@rock-chips.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1411871334-17692-1-git-send-email-zyw@rock-chips.com> References: <1411871334-17692-1-git-send-email-zyw@rock-chips.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140927_192938_043157_A0F610E4 X-CRM114-Status: GOOD ( 20.36 ) X-Spam-Score: -0.7 (/) Cc: devicetree@vger.kernel.org, Liam Girdwood , Rob Herring , linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, broonie@kernel.org, Chris Zhong , lee.jones@linaro.org, Grant Likely X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,LOTS_OF_MONEY, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, T_MONEY_PERCENT, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP rename st-pwm to pwm-regulator. And support getting voltage & duty table from device tree, other platforms can also use this driver without any modify. Signed-off-by: Chris Zhong Reviewed-by: Doug Anderson Tested-by: Doug Anderson --- Changes in v7: Adviced by Mark Brown - re-edit changelog Changes in v6: None Changes in v4: Adviced by Doug Anderson - improve kconfig - add const for desc structure Changes in v3: Adviced by Doug Anderson - Make Kconfig & Makefile alphabetical - remove pwm_reg_period from pwm_regulator_data - modify the calculation in pwm_regulator_set_voltage_sel - add length validity check Changes in v2: Adviced by Lee Jones - rename the file - remove all the prefix st_ - add depend on PWM in Kconfig drivers/regulator/Kconfig | 13 +- drivers/regulator/Makefile | 2 +- drivers/regulator/{st-pwm.c => pwm-regulator.c} | 147 ++++++++++++----------- 3 files changed, 85 insertions(+), 77 deletions(-) rename drivers/regulator/{st-pwm.c => pwm-regulator.c} (44%) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index fb32bab..b927cab 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -449,6 +449,13 @@ config REGULATOR_PFUZE100 Say y here to support the regulators found on the Freescale PFUZE100/PFUZE200 PMIC. +config REGULATOR_PWM + tristate "PWM voltage regulator" + depends on PWM + help + This driver supports PWM controlled voltage regulators. PWM + duty cycle can increase or decrease the voltage. + config REGULATOR_RC5T583 tristate "RICOH RC5T583 Power regulators" depends on MFD_RC5T583 @@ -493,12 +500,6 @@ config REGULATOR_S5M8767 via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and supports DVS mode with 8bits of output voltage control. -config REGULATOR_ST_PWM - tristate "STMicroelectronics PWM voltage regulator" - depends on ARCH_STI - help - This driver supports ST's PWM controlled voltage regulators. - config REGULATOR_TI_ABB tristate "TI Adaptive Body Bias on-chip LDO" depends on ARCH_OMAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 236fdbb..f3cf5a5 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o +obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o @@ -66,7 +67,6 @@ obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o -obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o diff --git a/drivers/regulator/st-pwm.c b/drivers/regulator/pwm-regulator.c similarity index 44% rename from drivers/regulator/st-pwm.c rename to drivers/regulator/pwm-regulator.c index 5ea78df..d3f55ea 100644 --- a/drivers/regulator/st-pwm.c +++ b/drivers/regulator/pwm-regulator.c @@ -1,5 +1,5 @@ /* - * Regulator driver for ST's PWM Regulators + * Regulator driver for PWM Regulators * * Copyright (C) 2014 - STMicroelectronics Inc. * @@ -20,43 +20,40 @@ #include #include -#define ST_PWM_REG_PERIOD 8448 - -struct st_pwm_regulator_pdata { - const struct regulator_desc *desc; - struct st_pwm_voltages *duty_cycle_table; -}; - -struct st_pwm_regulator_data { - const struct st_pwm_regulator_pdata *pdata; +struct pwm_regulator_data { + struct regulator_desc desc; + struct pwm_voltages *duty_cycle_table; struct pwm_device *pwm; bool enabled; int state; }; -struct st_pwm_voltages { +struct pwm_voltages { unsigned int uV; unsigned int dutycycle; }; -static int st_pwm_regulator_get_voltage_sel(struct regulator_dev *dev) +static int pwm_regulator_get_voltage_sel(struct regulator_dev *dev) { - struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); return drvdata->state; } -static int st_pwm_regulator_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) +static int pwm_regulator_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) { - struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + unsigned int pwm_reg_period; int dutycycle; int ret; - dutycycle = (ST_PWM_REG_PERIOD / 100) * - drvdata->pdata->duty_cycle_table[selector].dutycycle; + pwm_reg_period = pwm_get_period(drvdata->pwm); - ret = pwm_config(drvdata->pwm, dutycycle, ST_PWM_REG_PERIOD); + dutycycle = (pwm_reg_period * + drvdata->duty_cycle_table[selector].dutycycle) / 100; + + ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period); if (ret) { dev_err(&dev->dev, "Failed to configure PWM\n"); return ret; @@ -76,61 +73,40 @@ static int st_pwm_regulator_set_voltage_sel(struct regulator_dev *dev, return 0; } -static int st_pwm_regulator_list_voltage(struct regulator_dev *dev, - unsigned selector) +static int pwm_regulator_list_voltage(struct regulator_dev *dev, + unsigned selector) { - struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); - if (selector >= dev->desc->n_voltages) + if (selector >= drvdata->desc.n_voltages) return -EINVAL; - return drvdata->pdata->duty_cycle_table[selector].uV; + return drvdata->duty_cycle_table[selector].uV; } -static struct regulator_ops st_pwm_regulator_voltage_ops = { - .set_voltage_sel = st_pwm_regulator_set_voltage_sel, - .get_voltage_sel = st_pwm_regulator_get_voltage_sel, - .list_voltage = st_pwm_regulator_list_voltage, +static struct regulator_ops pwm_regulator_voltage_ops = { + .set_voltage_sel = pwm_regulator_set_voltage_sel, + .get_voltage_sel = pwm_regulator_get_voltage_sel, + .list_voltage = pwm_regulator_list_voltage, .map_voltage = regulator_map_voltage_iterate, }; -static struct st_pwm_voltages b2105_duty_cycle_table[] = { - { .uV = 1114000, .dutycycle = 0, }, - { .uV = 1095000, .dutycycle = 10, }, - { .uV = 1076000, .dutycycle = 20, }, - { .uV = 1056000, .dutycycle = 30, }, - { .uV = 1036000, .dutycycle = 40, }, - { .uV = 1016000, .dutycycle = 50, }, - /* WARNING: Values above 50% duty-cycle cause boot failures. */ -}; - -static const struct regulator_desc b2105_desc = { - .name = "b2105-pwm-regulator", - .ops = &st_pwm_regulator_voltage_ops, +static const struct regulator_desc pwm_regulator_desc = { + .name = "pwm-regulator", + .ops = &pwm_regulator_voltage_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .n_voltages = ARRAY_SIZE(b2105_duty_cycle_table), .supply_name = "pwm", }; -static const struct st_pwm_regulator_pdata b2105_info = { - .desc = &b2105_desc, - .duty_cycle_table = b2105_duty_cycle_table, -}; - -static const struct of_device_id st_pwm_of_match[] = { - { .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, }, - { }, -}; -MODULE_DEVICE_TABLE(of, st_pwm_of_match); - -static int st_pwm_regulator_probe(struct platform_device *pdev) +static int pwm_regulator_probe(struct platform_device *pdev) { - struct st_pwm_regulator_data *drvdata; + struct pwm_regulator_data *drvdata; + struct property *prop; struct regulator_dev *regulator; struct regulator_config config = { }; struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_match; + int length, ret; if (!np) { dev_err(&pdev->dev, "Device Tree node missing\n"); @@ -141,12 +117,37 @@ static int st_pwm_regulator_probe(struct platform_device *pdev) if (!drvdata) return -ENOMEM; - of_match = of_match_device(st_pwm_of_match, &pdev->dev); - if (!of_match) { - dev_err(&pdev->dev, "failed to match of device\n"); - return -ENODEV; + memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(pwm_regulator_desc)); + + /* determine the number of voltage-table */ + prop = of_find_property(np, "voltage-table", &length); + if (!prop) { + dev_err(&pdev->dev, "No voltage-table\n"); + return -EINVAL; + } + + if ((length < sizeof(*drvdata->duty_cycle_table)) || + (length % sizeof(*drvdata->duty_cycle_table))) { + dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n", + length); + return -EINVAL; + } + + drvdata->desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table); + + drvdata->duty_cycle_table = devm_kzalloc(&pdev->dev, + length, GFP_KERNEL); + if (!drvdata->duty_cycle_table) + return -ENOMEM; + + /* read voltage table from DT property */ + ret = of_property_read_u32_array(np, "voltage-table", + (u32 *)drvdata->duty_cycle_table, + length / sizeof(u32)); + if (ret < 0) { + dev_err(&pdev->dev, "read voltage-table failed\n"); + return ret; } - drvdata->pdata = of_match->data; config.init_data = of_get_regulator_init_data(&pdev->dev, np); if (!config.init_data) @@ -163,28 +164,34 @@ static int st_pwm_regulator_probe(struct platform_device *pdev) } regulator = devm_regulator_register(&pdev->dev, - drvdata->pdata->desc, &config); + &drvdata->desc, &config); if (IS_ERR(regulator)) { dev_err(&pdev->dev, "Failed to register regulator %s\n", - drvdata->pdata->desc->name); + drvdata->desc.name); return PTR_ERR(regulator); } return 0; } -static struct platform_driver st_pwm_regulator_driver = { +static const struct of_device_id pwm_of_match[] = { + { .compatible = "pwm-regulator" }, + { }, +}; +MODULE_DEVICE_TABLE(of, pwm_of_match); + +static struct platform_driver pwm_regulator_driver = { .driver = { - .name = "st-pwm-regulator", + .name = "pwm-regulator", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(st_pwm_of_match), + .of_match_table = of_match_ptr(pwm_of_match), }, - .probe = st_pwm_regulator_probe, + .probe = pwm_regulator_probe, }; -module_platform_driver(st_pwm_regulator_driver); +module_platform_driver(pwm_regulator_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Lee Jones "); -MODULE_DESCRIPTION("ST PWM Regulator Driver"); -MODULE_ALIAS("platform:st_pwm-regulator"); +MODULE_DESCRIPTION("PWM Regulator Driver"); +MODULE_ALIAS("platform:pwm-regulator");