From patchwork Fri Apr 8 09:47:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wadim Egorov X-Patchwork-Id: 8782431 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id DD3BFC0553 for ; Fri, 8 Apr 2016 09:52:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 89C9A202B8 for ; Fri, 8 Apr 2016 09:52:08 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B0297202AE for ; Fri, 8 Apr 2016 09:52:06 +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 1aoT5C-0001v9-CR; Fri, 08 Apr 2016 09:52:06 +0000 Received: from mail.rapiddevelopmentkit.de ([217.6.246.34] helo=root.phytec.de) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aoT57-0001ir-1a for linux-rockchip@lists.infradead.org; Fri, 08 Apr 2016 09:52:05 +0000 Received: from idefix.phytec.de (idefix.phytec.de [172.16.0.10]) by root.phytec.de (Postfix) with ESMTP id AFADBA0042C; Fri, 8 Apr 2016 11:52:14 +0200 (CEST) Received: from augenblix.phytec.de ([172.16.0.56]) by idefix.phytec.de (IBM Domino Release 9.0.1FP5 HF413) with ESMTP id 2016040811513510-26597 ; Fri, 8 Apr 2016 11:51:35 +0200 From: Wadim Egorov To: linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org Subject: [RFC 2/3] regulator: rk808: Add support for rk818 Date: Fri, 8 Apr 2016 11:47:40 +0200 Message-Id: <1460108861-32818-3-git-send-email-w.egorov@phytec.de> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1460108861-32818-1-git-send-email-w.egorov@phytec.de> References: <1460108861-32818-1-git-send-email-w.egorov@phytec.de> X-MIMETrack: Itemize by SMTP Server on Idefix/Phytec(Release 9.0.1FP5 HF413|March 21, 2016) at 08.04.2016 11:51:35, Serialize by Router on Idefix/Phytec(Release 9.0.1FP5 HF413|March 21, 2016) at 08.04.2016 11:51:35, Serialize complete at 08.04.2016 11:51:35 X-TNEFEvaluated: 1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160408_025201_534838_5B4D3460 X-CRM114-Status: GOOD ( 18.78 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, pawel.moll@arm.com, ijc+devicetree@hellion.org.uk, broonie@kernel.org, lgirdwood@gmail.com, dianders@chromium.org, robh+dt@kernel.org, galak@codeaurora.org, zyw@rock-chips.com, lee.jones@linaro.org 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=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, 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 Add support for the rk818 regulator. The regulator module consists of 4 DCDCs, 9 LDOs, 1 switch and 1 BOOST converter which is used to power OTG and HDMI5V. The output voltages are configurable and are meant to supply power to the main processor and other components. Signed-off-by: Wadim Egorov --- drivers/regulator/rk808-regulator.c | 343 +++++++++++++++++++++++++++++++++--- 1 file changed, 322 insertions(+), 21 deletions(-) diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index d86a3dc..b2bbca7 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -6,6 +6,9 @@ * Author: Chris Zhong * Author: Zhang Qing * + * Copyright (C) 2016 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -32,6 +35,12 @@ #define RK808_BUCK4_VSEL_MASK 0xf #define RK808_LDO_VSEL_MASK 0x1f +#define RK818_BUCK_VSEL_MASK 0x3f +#define RK818_BUCK4_VSEL_MASK 0x1f +#define RK818_LDO_VSEL_MASK 0x1f +#define RK818_LDO3_ON_VSEL_MASK 0xf +#define RK818_BOOST_ON_VSEL_MASK 0xe0 + /* Ramp rate definitions for buck1 / buck2 only */ #define RK808_RAMP_RATE_OFFSET 3 #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) @@ -87,6 +96,15 @@ static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000), }; +static const struct regulator_linear_range rk818_buck4_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(1800000, 0, 18, 100000), +}; + +static const struct regulator_linear_range rk818_boost_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(4700000, 0, 7, 100000), +}; + + static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev) { struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev); @@ -506,6 +524,238 @@ static const struct regulator_desc rk808_reg[] = { }, }; +static const struct regulator_desc rk818_reg[] = { + { + .name = "DCDC_REG1", + .supply_name = "vcc1", + .id = RK818_ID_DCDC1, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 64, + .linear_ranges = rk808_buck_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges), + .vsel_reg = RK818_BUCK1_ON_VSEL_REG, + .vsel_mask = RK818_BUCK_VSEL_MASK, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(0), + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG2", + .supply_name = "vcc2", + .id = RK818_ID_DCDC2, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 64, + .linear_ranges = rk808_buck_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges), + .vsel_reg = RK818_BUCK2_ON_VSEL_REG, + .vsel_mask = RK818_BUCK_VSEL_MASK, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(1), + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG3", + .supply_name = "vcc3", + .id = RK818_ID_DCDC3, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(2), + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG4", + .supply_name = "vcc4", + .id = RK818_ID_DCDC4, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 19, + .linear_ranges = rk818_buck4_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk818_buck4_voltage_ranges), + .vsel_reg = RK818_BUCK4_ON_VSEL_REG, + .vsel_mask = RK818_BUCK4_VSEL_MASK, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(3), + .owner = THIS_MODULE, + }, { + .name = "DCDC_BOOST", + .supply_name = "boost", + .id = RK818_ID_BOOST, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 8, + .linear_ranges = rk818_boost_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk818_boost_voltage_ranges), + .vsel_reg = RK818_BOOST_LDO9_ON_VSEL_REG, + .vsel_mask = RK818_BOOST_ON_VSEL_MASK, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(4), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG1", + .supply_name = "vcc6", + .id = RK818_ID_LDO1, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK818_LDO1_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(0), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG2", + .supply_name = "vcc6", + .id = RK818_ID_LDO2, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK818_LDO2_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(1), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG3", + .supply_name = "vcc7", + .id = RK818_ID_LDO3, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 16, + .linear_ranges = rk808_ldo3_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges), + .vsel_reg = RK818_LDO3_ON_VSEL_REG, + .vsel_mask = RK818_LDO3_ON_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(2), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG4", + .supply_name = "vcc8", + .id = RK818_ID_LDO4, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK818_LDO4_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(3), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG5", + .supply_name = "vcc7", + .id = RK818_ID_LDO5, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK818_LDO5_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(4), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG6", + .supply_name = "vcc8", + .id = RK818_ID_LDO6, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 18, + .linear_ranges = rk808_ldo6_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), + .vsel_reg = RK818_LDO6_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(5), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG7", + .supply_name = "vcc7", + .id = RK818_ID_LDO7, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 18, + .linear_ranges = rk808_ldo6_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), + .vsel_reg = RK818_LDO7_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(6), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG8", + .supply_name = "vcc8", + .id = RK818_ID_LDO8, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK818_LDO8_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_LDO_EN_REG, + .enable_mask = BIT(7), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "LDO_REG9", + .supply_name = "vcc9", + .id = RK818_ID_LDO9, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK818_BOOST_LDO9_ON_VSEL_REG, + .vsel_mask = RK818_LDO_VSEL_MASK, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(5), + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "SWITCH_REG", + .supply_name = "vcc9", + .id = RK818_ID_SWITCH, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(6), + .owner = THIS_MODULE, + }, { + .name = "HDMI_SWITCH", + .supply_name = "h_5v", + .id = RK818_ID_HDMI_SWITCH, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .enable_reg = RK818_H5V_EN_REG, + .enable_mask = BIT(0), + .owner = THIS_MODULE, + }, { + .name = "OTG_SWITCH", + .supply_name = "usb", + .id = RK818_ID_OTG_SWITCH, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .enable_reg = RK818_DCDC_EN_REG, + .enable_mask = BIT(7), + .owner = THIS_MODULE, + }, +}; + static struct of_regulator_match rk808_reg_matches[] = { [RK808_ID_DCDC1] = { .name = "DCDC_REG1" }, [RK808_ID_DCDC2] = { .name = "DCDC_REG2" }, @@ -523,11 +773,32 @@ static struct of_regulator_match rk808_reg_matches[] = { [RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" }, }; +static struct of_regulator_match rk818_reg_matches[] = { + [RK818_ID_DCDC1] = { .name = "DCDC_REG1" }, + [RK818_ID_DCDC2] = { .name = "DCDC_REG2" }, + [RK818_ID_DCDC3] = { .name = "DCDC_REG3" }, + [RK818_ID_DCDC4] = { .name = "DCDC_REG4" }, + [RK818_ID_BOOST] = { .name = "DCDC_BOOST" }, + [RK818_ID_LDO1] = { .name = "LDO_REG1" }, + [RK818_ID_LDO2] = { .name = "LDO_REG2" }, + [RK818_ID_LDO3] = { .name = "LDO_REG3" }, + [RK818_ID_LDO4] = { .name = "LDO_REG4" }, + [RK818_ID_LDO5] = { .name = "LDO_REG5" }, + [RK818_ID_LDO6] = { .name = "LDO_REG6" }, + [RK818_ID_LDO7] = { .name = "LDO_REG7" }, + [RK818_ID_LDO8] = { .name = "LDO_REG8" }, + [RK818_ID_LDO9] = { .name = "LDO_REG9" }, + [RK818_ID_SWITCH] = { .name = "SWITCH_REG" }, + [RK818_ID_HDMI_SWITCH] = { .name = "HDMI_SWITCH" }, + [RK818_ID_OTG_SWITCH] = { .name = "OTG_SWITCH" }, +}; + static int rk808_regulator_dt_parse_pdata(struct device *dev, struct device *client_dev, struct regmap *map, struct rk808_regulator_data *pdata) { + struct rk808 *rk808 = dev_get_drvdata(dev->parent); struct device_node *np; int tmp, ret, i; @@ -535,8 +806,12 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev, if (!np) return -ENXIO; - ret = of_regulator_match(dev, np, rk808_reg_matches, - RK808_NUM_REGULATORS); + if (rk808->variant == RK808_ID) + ret = of_regulator_match(dev, np, rk808_reg_matches, + RK808_NUM_REGULATORS); + else if (rk808->variant == RK818_ID) + ret = of_regulator_match(dev, np, rk818_reg_matches, + RK818_NUM_REGULATORS); if (ret < 0) goto dt_parse_end; @@ -586,27 +861,53 @@ static int rk808_regulator_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); - /* Instantiate the regulators */ - for (i = 0; i < RK808_NUM_REGULATORS; i++) { - if (!rk808_reg_matches[i].init_data || - !rk808_reg_matches[i].of_node) - continue; - - config.dev = &client->dev; - config.driver_data = pdata; - config.regmap = rk808->regmap; - config.of_node = rk808_reg_matches[i].of_node; - config.init_data = rk808_reg_matches[i].init_data; - - rk808_rdev = devm_regulator_register(&pdev->dev, - &rk808_reg[i], &config); - if (IS_ERR(rk808_rdev)) { - dev_err(&client->dev, - "failed to register %d regulator\n", i); - return PTR_ERR(rk808_rdev); + if (rk808->variant == RK818_ID) { + /* Instantiate the regulators */ + for (i = 0; i < RK818_NUM_REGULATORS; i++) { + if (!rk818_reg_matches[i].init_data || + !rk818_reg_matches[i].of_node) + continue; + + config.dev = &client->dev; + config.driver_data = pdata; + config.regmap = rk808->regmap; + config.of_node = rk818_reg_matches[i].of_node; + config.init_data = rk818_reg_matches[i].init_data; + + rk808_rdev = devm_regulator_register(&pdev->dev, + &rk818_reg[i], &config); + if (IS_ERR(rk808_rdev)) { + dev_err(&client->dev, + "failed to register %d regulator\n", i); + return PTR_ERR(rk808_rdev); + } + } + } else if (rk808->variant == RK808_ID) { + /* Instantiate the regulators */ + for (i = 0; i < RK808_NUM_REGULATORS; i++) { + if (!rk808_reg_matches[i].init_data || + !rk808_reg_matches[i].of_node) + continue; + + config.dev = &client->dev; + config.driver_data = pdata; + config.regmap = rk808->regmap; + config.of_node = rk808_reg_matches[i].of_node; + config.init_data = rk808_reg_matches[i].init_data; + + rk808_rdev = devm_regulator_register(&pdev->dev, + &rk808_reg[i], &config); + if (IS_ERR(rk808_rdev)) { + dev_err(&client->dev, + "failed to register %d regulator\n", i); + return PTR_ERR(rk808_rdev); + } } + } else { + dev_err(&client->dev, "unsupported RK8XX ID %lu\n", + rk808->variant); + return -EINVAL; } - return 0; }