From nobody Thu Sep 11 18:26:04 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0E4DC636CC for ; Fri, 17 Feb 2023 02:07:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230306AbjBQCHS (ORCPT ); Thu, 16 Feb 2023 21:07:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229793AbjBQCHO (ORCPT ); Thu, 16 Feb 2023 21:07:14 -0500 Received: from mg.richtek.com (mg.richtek.com [220.130.44.152]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BD50F498B9; Thu, 16 Feb 2023 18:07:11 -0800 (PST) X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 192.168.10.46 by mg.richtek.com with MailGates ESMTP Server V5.0(23463:0:AUTH_RELAY) (envelope-from ); Fri, 17 Feb 2023 10:07:00 +0800 (CST) Received: from ex4.rt.l (192.168.10.47) by ex3.rt.l (192.168.10.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.20; Fri, 17 Feb 2023 10:06:59 +0800 Received: from linuxcarl2.richtek.com (192.168.10.154) by ex4.rt.l (192.168.10.45) with Microsoft SMTP Server id 15.2.1118.20 via Frontend Transport; Fri, 17 Feb 2023 10:06:59 +0800 From: To: , , CC: , , , , Subject: [PATCH v2 1/2] dt-bindings: regulator: Add Richtek RT5739 Date: Fri, 17 Feb 2023 10:06:57 +0800 Message-ID: <1676599618-24819-2-git-send-email-cy_huang@richtek.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1676599618-24819-1-git-send-email-cy_huang@richtek.com> References: <1676599618-24819-1-git-send-email-cy_huang@richtek.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: ChiYuan Huang Add the binding document for Richtek RT5739. Signed-off-by: ChiYuan Huang Reviewed-by: Krzysztof Kozlowski --- Since v2: - Refine dt-binding patch subject - Shorten and refine title and description without too much marketing text. - Fix the typo from 'connecton' to 'connection' in 'richtek,vsel-active-hig= h' property description - Remove maxItems in property 'regulator-allowed-modes' - Fix the wrong min/max microvolt in binding example. Must be '300000' and '1300000', respectively. --- .../bindings/regulator/richtek,rt5739.yaml | 72 ++++++++++++++++++= ++++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/richtek,rt5= 739.yaml diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt5739.yam= l b/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml new file mode 100644 index 00000000..358297d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/richtek,rt5739.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT5739 Step-Down Buck Converter + +maintainers: + - ChiYuan Huang + +description: | + The RT5739 is a step-down switching buck converter that can deliver the + programmable output voltage from 300mV to 1300mV with wide input voltage + supply of 2.5V to 5.5V. It can provide up to 3.5A continuous current + capability at over 80% high efficiency. + +allOf: + - $ref: regulator.yaml# + +properties: + compatible: + enum: + - richtek,rt5739 + + reg: + maxItems: 1 + + enable-gpios: + maxItems: 1 + + richtek,vsel-active-high: + description: | + If property is present, use the 'VSEL1' register group for buck cont= rol. + Else, use the 'VSEL0' register group. This depends on external hardw= are + 'VSEL' pin connection. + type: boolean + + regulator-allowed-modes: + description: | + buck allowed operating mode + 0: Auto PFM/PWM mode + 1: Forced PWM mode + items: + enum: [0, 1] + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + regulator@50 { + compatible =3D "richtek,rt5739"; + reg =3D <0x50>; + enable-gpios =3D <&gpio26 1 GPIO_ACTIVE_HIGH>; + richtek,vsel-active-high; + regulator-name =3D "richtek,rt5739-buck"; + regulator-min-microvolt =3D <300000>; + regulator-max-microvolt =3D <1300000>; + regulator-allowed-modes =3D <0 1>; + regulator-boot-on; + }; + }; --=20 2.7.4 From nobody Thu Sep 11 18:26:04 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79E74C61DA4 for ; Fri, 17 Feb 2023 02:07:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230336AbjBQCHY (ORCPT ); Thu, 16 Feb 2023 21:07:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230294AbjBQCHR (ORCPT ); Thu, 16 Feb 2023 21:07:17 -0500 Received: from mg.richtek.com (mg.richtek.com [220.130.44.152]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 808374FC8A; Thu, 16 Feb 2023 18:07:13 -0800 (PST) X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 192.168.10.46 by mg.richtek.com with MailGates ESMTP Server V5.0(23463:0:AUTH_RELAY) (envelope-from ); Fri, 17 Feb 2023 10:07:00 +0800 (CST) Received: from ex4.rt.l (192.168.10.47) by ex3.rt.l (192.168.10.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.20; Fri, 17 Feb 2023 10:06:59 +0800 Received: from linuxcarl2.richtek.com (192.168.10.154) by ex4.rt.l (192.168.10.45) with Microsoft SMTP Server id 15.2.1118.20 via Frontend Transport; Fri, 17 Feb 2023 10:06:59 +0800 From: To: , , CC: , , , , Subject: [PATCH v2 2/2] regulator: Add support for Richtek RT5739 voltage regulator Date: Fri, 17 Feb 2023 10:06:58 +0800 Message-ID: <1676599618-24819-3-git-send-email-cy_huang@richtek.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1676599618-24819-1-git-send-email-cy_huang@richtek.com> References: <1676599618-24819-1-git-send-email-cy_huang@richtek.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: ChiYuan Huang The RT5739 is a step-down switching voltage regulator that supports output voltage ragne from 300mV to 1300mV with the wide input supply voltage range from 2.5V to 5.5V. Signed-off-by: ChiYuan Huang --- Since v2: no change --- drivers/regulator/Kconfig | 13 ++ drivers/regulator/Makefile | 1 + drivers/regulator/rt5739.c | 290 +++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 304 insertions(+) create mode 100644 drivers/regulator/rt5739.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 820c9a0..f7f992c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1112,6 +1112,19 @@ config REGULATOR_RT5190A buck converters, 1 LDO, mute AC OFF depop function, with the general I2C control interface. =20 +config REGULATOR_RT5739 + tristate "Rcihtek RT5739 Regulator" + depends on I2C + select REGMAP_I2C + help + This adds support for voltage regulator in Richtek RT5739. + It's a step-down switching voltage regulator. Using a proprietary + architecture with synchronous rectification, it is capable of + delivering 3.5A continuously at over 80% efficiency. + + This driver can also be built as a module. If so, the module + will be called rt5739. + config REGULATOR_RT5759 tristate "Richtek RT5759 Regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b9f5eb3..30a61fc 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -133,6 +133,7 @@ obj-$(CONFIG_REGULATOR_RT4831) +=3D rt4831-regulator.o obj-$(CONFIG_REGULATOR_RT5033) +=3D rt5033-regulator.o obj-$(CONFIG_REGULATOR_RT5120) +=3D rt5120-regulator.o obj-$(CONFIG_REGULATOR_RT5190A) +=3D rt5190a-regulator.o +obj-$(CONFIG_REGULATOR_RT5739) +=3D rt5739.o obj-$(CONFIG_REGULATOR_RT5759) +=3D rt5759-regulator.o obj-$(CONFIG_REGULATOR_RT6160) +=3D rt6160-regulator.o obj-$(CONFIG_REGULATOR_RT6190) +=3D rt6190-regulator.o diff --git a/drivers/regulator/rt5739.c b/drivers/regulator/rt5739.c new file mode 100644 index 00000000..0a9e102 --- /dev/null +++ b/drivers/regulator/rt5739.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Device driver for RT5739 regulator + * + * Copyright (C) 2023 Richtek Technology Corp. + * + * Author: ChiYuan Huang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RT5739_AUTO_MODE 0 +#define RT5739_FPWM_MODE 1 + +#define RT5739_REG_NSEL0 0x00 +#define RT5739_REG_NSEL1 0x01 +#define RT5739_REG_CNTL1 0x02 +#define RT5739_REG_ID1 0x03 +#define RT5739_REG_CNTL2 0x06 +#define RT5739_REG_CNTL4 0x08 + +#define RT5739_VSEL_MASK GENMASK(7, 0) +#define RT5739_MODEVSEL1_MASK BIT(1) +#define RT5739_MODEVSEL0_MASK BIT(0) +#define RT5739_VID_MASK GENMASK(7, 5) +#define RT5739_ACTD_MASK BIT(7) +#define RT5739_ENVSEL1_MASK BIT(1) +#define RT5739_ENVSEL0_MASK BIT(0) + +#define RT5739_VOLT_MINUV 300000 +#define RT5739_VOLT_MAXUV 1300000 +#define RT5739_VOLT_STPUV 5000 +#define RT5739_N_VOLTS 201 +#define RT5739_I2CRDY_TIMEUS 1000 + +static int rt5739_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + const struct regulator_desc *desc =3D rdev->desc; + struct regmap *regmap =3D rdev_get_regmap(rdev); + unsigned int mask, val; + + if (desc->vsel_reg =3D=3D RT5739_REG_NSEL0) + mask =3D RT5739_MODEVSEL0_MASK; + else + mask =3D RT5739_MODEVSEL1_MASK; + + switch (mode) { + case REGULATOR_MODE_FAST: + val =3D mask; + break; + case REGULATOR_MODE_NORMAL: + val =3D 0; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val); +} + +static unsigned int rt5739_get_mode(struct regulator_dev *rdev) +{ + const struct regulator_desc *desc =3D rdev->desc; + struct regmap *regmap =3D rdev_get_regmap(rdev); + unsigned int mask, val; + int ret; + + if (desc->vsel_reg =3D=3D RT5739_REG_NSEL0) + mask =3D RT5739_MODEVSEL0_MASK; + else + mask =3D RT5739_MODEVSEL1_MASK; + + ret =3D regmap_read(regmap, RT5739_REG_CNTL1, &val); + if (ret) + return REGULATOR_MODE_INVALID; + + if (val & mask) + return REGULATOR_MODE_FAST; + + return REGULATOR_MODE_NORMAL; +} + +static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV) +{ + const struct regulator_desc *desc =3D rdev->desc; + struct regmap *regmap =3D rdev_get_regmap(rdev); + unsigned int reg, vsel; + + if (uV < RT5739_VOLT_MINUV || uV > RT5739_VOLT_MAXUV) + return -EINVAL; + + if (desc->vsel_reg =3D=3D RT5739_REG_NSEL0) + reg =3D RT5739_REG_NSEL1; + else + reg =3D RT5739_REG_NSEL0; + + vsel =3D (uV - RT5739_VOLT_MINUV) / RT5739_VOLT_STPUV; + return regmap_write(regmap, reg, vsel); +} + +static int rt5739_set_suspend_enable(struct regulator_dev *rdev) +{ + const struct regulator_desc *desc =3D rdev->desc; + struct regmap *regmap =3D rdev_get_regmap(rdev); + unsigned int mask; + + if (desc->vsel_reg =3D=3D RT5739_REG_NSEL0) + mask =3D RT5739_ENVSEL1_MASK; + else + mask =3D RT5739_ENVSEL0_MASK; + + return regmap_update_bits(regmap, desc->enable_reg, mask, mask); +} + +static int rt5739_set_suspend_disable(struct regulator_dev *rdev) +{ + const struct regulator_desc *desc =3D rdev->desc; + struct regmap *regmap =3D rdev_get_regmap(rdev); + unsigned int mask; + + if (desc->vsel_reg =3D=3D RT5739_REG_NSEL0) + mask =3D RT5739_ENVSEL1_MASK; + else + mask =3D RT5739_ENVSEL0_MASK; + + return regmap_update_bits(regmap, desc->enable_reg, mask, 0); +} + +static int rt5739_set_suspend_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + const struct regulator_desc *desc =3D rdev->desc; + struct regmap *regmap =3D rdev_get_regmap(rdev); + unsigned int mask, val; + + if (desc->vsel_reg =3D=3D RT5739_REG_NSEL0) + mask =3D RT5739_MODEVSEL1_MASK; + else + mask =3D RT5739_MODEVSEL0_MASK; + + switch (mode) { + case REGULATOR_MODE_FAST: + val =3D mask; + break; + case REGULATOR_MODE_NORMAL: + val =3D 0; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val); +} + +static const struct regulator_ops rt5739_regulator_ops =3D { + .list_voltage =3D regulator_list_voltage_linear, + .get_voltage_sel =3D regulator_get_voltage_sel_regmap, + .set_voltage_sel =3D regulator_set_voltage_sel_regmap, + .enable =3D regulator_enable_regmap, + .disable =3D regulator_disable_regmap, + .is_enabled =3D regulator_is_enabled_regmap, + .set_active_discharge =3D regulator_set_active_discharge_regmap, + .set_mode =3D rt5739_set_mode, + .get_mode =3D rt5739_get_mode, + .set_suspend_voltage =3D rt5739_set_suspend_voltage, + .set_suspend_enable =3D rt5739_set_suspend_enable, + .set_suspend_disable =3D rt5739_set_suspend_disable, + .set_suspend_mode =3D rt5739_set_suspend_mode, +}; + +static unsigned int rt5739_of_map_mode(unsigned int mode) +{ + switch (mode) { + case RT5739_AUTO_MODE: + return REGULATOR_MODE_NORMAL; + case RT5739_FPWM_MODE: + return REGULATOR_MODE_FAST; + default: + return REGULATOR_MODE_INVALID; + } +} + +static void rt5739_init_regulator_desc(struct regulator_desc *desc, + bool vsel_active_high) +{ + /* Fixed */ + desc->name =3D "rt5739-regulator"; + desc->owner =3D THIS_MODULE; + desc->ops =3D &rt5739_regulator_ops; + desc->n_voltages =3D RT5739_N_VOLTS; + desc->min_uV =3D RT5739_VOLT_MINUV; + desc->uV_step =3D RT5739_VOLT_STPUV; + desc->vsel_mask =3D RT5739_VSEL_MASK; + desc->enable_reg =3D RT5739_REG_CNTL2; + desc->active_discharge_reg =3D RT5739_REG_CNTL1; + desc->active_discharge_mask =3D RT5739_ACTD_MASK; + desc->active_discharge_on =3D RT5739_ACTD_MASK; + desc->of_map_mode =3D rt5739_of_map_mode; + + /* Assigned by vsel level */ + if (vsel_active_high) { + desc->vsel_reg =3D RT5739_REG_NSEL1; + desc->enable_mask =3D RT5739_ENVSEL1_MASK; + } else { + desc->vsel_reg =3D RT5739_REG_NSEL0; + desc->enable_mask =3D RT5739_ENVSEL0_MASK; + } +} + +static const struct regmap_config rt5739_regmap_config =3D { + .name =3D "rt5739", + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D RT5739_REG_CNTL4, +}; + +static int rt5739_probe(struct i2c_client *i2c) +{ + struct device *dev =3D &i2c->dev; + struct regulator_desc *desc; + struct regmap *regmap; + struct gpio_desc *enable_gpio; + struct regulator_config cfg =3D {}; + struct regulator_dev *rdev; + bool vsel_acth; + unsigned int vid; + int ret; + + desc =3D devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + enable_gpio =3D devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(enable_gpio)) + return dev_err_probe(dev, PTR_ERR(enable_gpio), "Failed to get 'enable' = gpio\n"); + else if (enable_gpio) + usleep_range(RT5739_I2CRDY_TIMEUS, RT5739_I2CRDY_TIMEUS + 1000); + + regmap =3D devm_regmap_init_i2c(i2c, &rt5739_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n"); + + ret =3D regmap_read(regmap, RT5739_REG_ID1, &vid); + if (ret) + return dev_err_probe(dev, ret, "Failed to read VID\n"); + + /* RT5739: (VID & MASK) must be 0 */ + if (vid & RT5739_VID_MASK) + return dev_err_probe(dev, -ENODEV, "Incorrect VID (0x%02x)\n", vid); + + vsel_acth =3D device_property_read_bool(dev, "richtek,vsel-active-high"); + + rt5739_init_regulator_desc(desc, vsel_acth); + + cfg.dev =3D dev; + cfg.of_node =3D dev_of_node(dev); + cfg.init_data =3D of_get_regulator_init_data(dev, dev_of_node(dev), desc); + rdev =3D devm_regulator_register(dev, desc, &cfg); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n= "); + + return 0; +} + +static const struct of_device_id rt5739_device_table[] =3D { + { .compatible =3D "richtek,rt5739" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rt5739_device_table); + +static struct i2c_driver rt5739_driver =3D { + .driver =3D { + .name =3D "rt5739", + .of_match_table =3D rt5739_device_table, + }, + .probe_new =3D rt5739_probe, +}; +module_i2c_driver(rt5739_driver); + +MODULE_AUTHOR("ChiYuan Huang "); +MODULE_DESCRIPTION("Richtek RT5739 regulator driver"); +MODULE_LICENSE("GPL"); --=20 2.7.4