From patchwork Wed Feb 15 02:00:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ChiYuan Huang X-Patchwork-Id: 57342 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp3318488wrn; Tue, 14 Feb 2023 18:14:58 -0800 (PST) X-Google-Smtp-Source: AK7set8Xzfs8aIBORjIJ2EiBdi3/f1mNlfRwdf4mWuAKqcWxeRLDHNcUBl66ZSuK/rTQmBS7O79Y X-Received: by 2002:a17:906:ce31:b0:8ae:707:e129 with SMTP id sd17-20020a170906ce3100b008ae0707e129mr655153ejb.19.1676427298137; Tue, 14 Feb 2023 18:14:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676427298; cv=none; d=google.com; s=arc-20160816; b=Y79urZFu05JbjmOEC/qYHgfbl/9M99MXQDoCZBFaeV9NYohbPRGi4qdL6gzBpqE5l0 hFJsj+XgBAJSpLsOirFAI4cYiAONh800Ms1xzrCrjGe0Lmj7L8ebQy9Sc2ulKZua374S kyHO25TgsNJoT0mVBKaJHrpzOafpx3L27aN8PRk3exaveQKwQ88YZug0dzvvLUIyjbng rWjsGQCVc1TVofSakpT5ZRpzmrtjVQywE4EKshguFtVVkuQ+7XuPtPxFzL/osG8qs/BR MRJKKZS2M8BDakGj6uhNNMJb0RIppCFw27XZ9VyIQ9kmtWX0HocsHEdDOIzi9gmpuXod a7FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=RHxT32M0m+S990yFe9hwRSEpBOIFCoR4V6tkdGf+etQ=; b=pwq/XqgsQi/3bxzVXxl9NDfeAXZTO0FinEvE14PcYYLMxaxdunVcZkzqgxFa2hho0V KaS/1LyqNnW0DwSA2jvBY4F4fB2Jb0WhOSRxlGFE7etLoZC7BLP6eUWKg+AzP61j1fh7 f/ztgezxAqTnLhBRylDuNQm6zr7MWJSsDOKblMLbF8p1Ny+8/NhXlADrSW6v/MpvQdnN EWfisq4/A11AdR1Ls2JDp/R+MkPqsDYwPyquic60JUO3oEE4Iw3MhVfu/n7d5vCpyjqm qm0KLSh2GSTP5b6UUFC+UXQzkax0kFlQbLmywm8/oB3ORMxLNYUhWBlHXknMZNbMrHo5 l7tw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id uj42-20020a170907c9aa00b008b131d04030si3190531ejc.155.2023.02.14.18.14.34; Tue, 14 Feb 2023 18:14:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232762AbjBOCBW (ORCPT + 99 others); Tue, 14 Feb 2023 21:01:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229536AbjBOCBT (ORCPT ); Tue, 14 Feb 2023 21:01:19 -0500 Received: from mg.richtek.com (mg.richtek.com [220.130.44.152]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3277423640; Tue, 14 Feb 2023 18:01:15 -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(23451:0:AUTH_RELAY) (envelope-from ); Wed, 15 Feb 2023 10:00:59 +0800 (CST) Received: from ex3.rt.l (192.168.10.46) 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; Wed, 15 Feb 2023 10:00:58 +0800 Received: from linuxcarl2.richtek.com (192.168.10.154) by ex3.rt.l (192.168.10.45) with Microsoft SMTP Server id 15.2.1118.20 via Frontend Transport; Wed, 15 Feb 2023 10:00:58 +0800 From: To: , , CC: , , , , Subject: [PATCH 1/2] dt-bindings: regulator: Add bindings for Richtek RT5739 Date: Wed, 15 Feb 2023 10:00:56 +0800 Message-ID: <1676426457-1389-2-git-send-email-cy_huang@richtek.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1676426457-1389-1-git-send-email-cy_huang@richtek.com> References: <1676426457-1389-1-git-send-email-cy_huang@richtek.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757861430223802337?= X-GMAIL-MSGID: =?utf-8?q?1757861430223802337?= From: ChiYuan Huang Add the binding document for Richtek RT5739. Signed-off-by: ChiYuan Huang --- .../bindings/regulator/richtek,rt5739.yaml | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml new file mode 100644 index 00000000..7dc4f78 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml @@ -0,0 +1,80 @@ +# 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 2.4MHz 3.5A Step-Down Converter + +maintainers: + - ChiYuan Huang + +description: | + The RT5739 is a step-down switching voltage regulator that delivers a + digitally programmable output from an input voltage supply of 2.5V to 5.5V. + The output voltage is programmed through an I2C interface capable of + operating up to 3.4MHz. + + Using a proprietary architecture with synchronous rectification, the RT5739 + is capable of delivering 3.5A continuously at over 80% efficiency, + maintaining that efficiency at load current as low as 10mA. The regulator + operates at a normal fixed frequency of 2.4MHz, which reduces the value of + the external components. Additional output capacitance can be added to + improve regulation during load transients without affecting stability. + +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 control. + Else, use the 'VSEL0' register group. This depends on external hardware + 'VSEL' pin connecton. + type: boolean + + regulator-allowed-modes: + description: | + buck allowed operating mode + 0: Auto PFM/PWM mode + 1: Forced PWM mode + maxItems: 2 + items: + enum: [0, 1] + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@50 { + compatible = "richtek,rt5739"; + reg = <0x50>; + enable-gpios = <&gpio26 1 GPIO_ACTIVE_HIGH>; + richtek,vsel-active-high; + regulator-name = "richtek,rt5739-buck"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <13000000>; + regulator-allowed-modes = <0 1>; + regulator-boot-on; + }; + }; From patchwork Wed Feb 15 02:00:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ChiYuan Huang X-Patchwork-Id: 57341 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp3318213wrn; Tue, 14 Feb 2023 18:14:15 -0800 (PST) X-Google-Smtp-Source: AK7set/AMbNUN6Iyr80hCvw1KXMtiTsx9cfaEgSS3+yAvIiUgSytyzthMRTxGtwJ/6GnFf6ygvii X-Received: by 2002:a17:90a:3e07:b0:234:2ac7:6781 with SMTP id j7-20020a17090a3e0700b002342ac76781mr958903pjc.26.1676427255146; Tue, 14 Feb 2023 18:14:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676427255; cv=none; d=google.com; s=arc-20160816; b=tMYHmpS9nsYcNKhVHeFQqHG9O9Ss6wNAUsCoKnUgCYiE/wlsXDTu7576uZ1Jh/wl/w 7L0Fc4SkfYHrDqSrEKA691MREdFVaEjcjidRsbokB7l8eGuSKdZbZFqpDquSuqFWj6QZ Kz0U7ls+C4CRL7d8w7WWE2ej2iWla71qleeNuWqDqjF+8HyIA5ofQ1gycklYfEFk0XS1 9aT+MvWOhqfua1nIYRWkdcXRMcSBwU+ewS9VTsswjK0cMgwtrfiyN/gg3rVL/LdQjrgT H7r8AksOZP8MDo+yN1qNq7BvEhDJt2Hw0LpHGLUaW2bORZBEzo08N9QqYIaoYywd2sCo iuSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=zxEfhuj9QcjQTAWyID+etZH3qoNifCsPr0lS0JCEvqk=; b=lh5FSiytH/3jj0GNUIafYXIP4rUPYCxio19ju3HQAGK+O8HgWYbhqQlVlxh4rgEqu9 4emW1AtJPlPxDsF+9IsqCaEHmie9/+LSlaXUj+KbVOx7EDN1Xx8tQp25kT3KdzoNwK9+ U7j6pGZUKFq+vlw3+bPRy4yQ/ThnM3UyMLaqraL6LzCMAdUICbRlCltldXtdubP+ucrN n2nFPLvzy0oZa+XvV4wP9GgirLCv9CHmpu0Rfdrxg8TZ6p05/sgwqy93DQ0rWoH+VjUh eFHXIQ+8Gem6d7ZPTOQnV44c1FvDn80abZ8Mimp56NpwZr9MycYRRH+9R2Aicrgt31R7 2Mmg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id mh17-20020a17090b4ad100b00233efa8d3e5si754625pjb.20.2023.02.14.18.14.01; Tue, 14 Feb 2023 18:14:14 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231881AbjBOCBV (ORCPT + 99 others); Tue, 14 Feb 2023 21:01:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229595AbjBOCBT (ORCPT ); Tue, 14 Feb 2023 21:01:19 -0500 Received: from mg.richtek.com (mg.richtek.com [220.130.44.152]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 32EA123852; Tue, 14 Feb 2023 18:01:15 -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(23451:0:AUTH_RELAY) (envelope-from ); Wed, 15 Feb 2023 10:00:59 +0800 (CST) Received: from ex3.rt.l (192.168.10.46) 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; Wed, 15 Feb 2023 10:00:58 +0800 Received: from linuxcarl2.richtek.com (192.168.10.154) by ex3.rt.l (192.168.10.45) with Microsoft SMTP Server id 15.2.1118.20 via Frontend Transport; Wed, 15 Feb 2023 10:00:58 +0800 From: To: , , CC: , , , , Subject: [PATCH 2/2] regulator: Add support for Richtek RT5739 voltage regulator Date: Wed, 15 Feb 2023 10:00:57 +0800 Message-ID: <1676426457-1389-3-git-send-email-cy_huang@richtek.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1676426457-1389-1-git-send-email-cy_huang@richtek.com> References: <1676426457-1389-1-git-send-email-cy_huang@richtek.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757861385425025235?= X-GMAIL-MSGID: =?utf-8?q?1757861385425025235?= 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 --- 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. +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) += rt4831-regulator.o obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o obj-$(CONFIG_REGULATOR_RT5120) += rt5120-regulator.o obj-$(CONFIG_REGULATOR_RT5190A) += rt5190a-regulator.o +obj-$(CONFIG_REGULATOR_RT5739) += rt5739.o obj-$(CONFIG_REGULATOR_RT5759) += rt5759-regulator.o obj-$(CONFIG_REGULATOR_RT6160) += rt6160-regulator.o obj-$(CONFIG_REGULATOR_RT6190) += 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 = rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int mask, val; + + if (desc->vsel_reg == RT5739_REG_NSEL0) + mask = RT5739_MODEVSEL0_MASK; + else + mask = RT5739_MODEVSEL1_MASK; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = mask; + break; + case REGULATOR_MODE_NORMAL: + val = 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 = rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int mask, val; + int ret; + + if (desc->vsel_reg == RT5739_REG_NSEL0) + mask = RT5739_MODEVSEL0_MASK; + else + mask = RT5739_MODEVSEL1_MASK; + + ret = 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 = rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int reg, vsel; + + if (uV < RT5739_VOLT_MINUV || uV > RT5739_VOLT_MAXUV) + return -EINVAL; + + if (desc->vsel_reg == RT5739_REG_NSEL0) + reg = RT5739_REG_NSEL1; + else + reg = RT5739_REG_NSEL0; + + vsel = (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 = rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int mask; + + if (desc->vsel_reg == RT5739_REG_NSEL0) + mask = RT5739_ENVSEL1_MASK; + else + mask = 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 = rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int mask; + + if (desc->vsel_reg == RT5739_REG_NSEL0) + mask = RT5739_ENVSEL1_MASK; + else + mask = 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 = rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int mask, val; + + if (desc->vsel_reg == RT5739_REG_NSEL0) + mask = RT5739_MODEVSEL1_MASK; + else + mask = RT5739_MODEVSEL0_MASK; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = mask; + break; + case REGULATOR_MODE_NORMAL: + val = 0; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val); +} + +static const struct regulator_ops rt5739_regulator_ops = { + .list_voltage = regulator_list_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_active_discharge = regulator_set_active_discharge_regmap, + .set_mode = rt5739_set_mode, + .get_mode = rt5739_get_mode, + .set_suspend_voltage = rt5739_set_suspend_voltage, + .set_suspend_enable = rt5739_set_suspend_enable, + .set_suspend_disable = rt5739_set_suspend_disable, + .set_suspend_mode = 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 = "rt5739-regulator"; + desc->owner = THIS_MODULE; + desc->ops = &rt5739_regulator_ops; + desc->n_voltages = RT5739_N_VOLTS; + desc->min_uV = RT5739_VOLT_MINUV; + desc->uV_step = RT5739_VOLT_STPUV; + desc->vsel_mask = RT5739_VSEL_MASK; + desc->enable_reg = RT5739_REG_CNTL2; + desc->active_discharge_reg = RT5739_REG_CNTL1; + desc->active_discharge_mask = RT5739_ACTD_MASK; + desc->active_discharge_on = RT5739_ACTD_MASK; + desc->of_map_mode = rt5739_of_map_mode; + + /* Assigned by vsel level */ + if (vsel_active_high) { + desc->vsel_reg = RT5739_REG_NSEL1; + desc->enable_mask = RT5739_ENVSEL1_MASK; + } else { + desc->vsel_reg = RT5739_REG_NSEL0; + desc->enable_mask = RT5739_ENVSEL0_MASK; + } +} + +static const struct regmap_config rt5739_regmap_config = { + .name = "rt5739", + .reg_bits = 8, + .val_bits = 8, + .max_register = RT5739_REG_CNTL4, +}; + +static int rt5739_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct regulator_desc *desc; + struct regmap *regmap; + struct gpio_desc *enable_gpio; + struct regulator_config cfg = {}; + struct regulator_dev *rdev; + bool vsel_acth; + unsigned int vid; + int ret; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + enable_gpio = 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 = 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 = 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 = device_property_read_bool(dev, "richtek,vsel-active-high"); + + rt5739_init_regulator_desc(desc, vsel_acth); + + cfg.dev = dev; + cfg.of_node = dev_of_node(dev); + cfg.init_data = of_get_regulator_init_data(dev, dev_of_node(dev), desc); + rdev = 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[] = { + { .compatible = "richtek,rt5739" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rt5739_device_table); + +static struct i2c_driver rt5739_driver = { + .driver = { + .name = "rt5739", + .of_match_table = rt5739_device_table, + }, + .probe_new = rt5739_probe, +}; +module_i2c_driver(rt5739_driver); + +MODULE_AUTHOR("ChiYuan Huang "); +MODULE_DESCRIPTION("Richtek RT5739 regulator driver"); +MODULE_LICENSE("GPL");