From patchwork Fri Feb 17 02:06: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: 58319 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp649256wrn; Thu, 16 Feb 2023 18:23:50 -0800 (PST) X-Google-Smtp-Source: AK7set9M44+GGawW3RKj17MjyZTCJrhHWNCjVysmsMJEb8vTTJaKOwNONm/0hoGvbVrMFIeXy/pG X-Received: by 2002:a17:906:54e:b0:8b1:3009:536b with SMTP id k14-20020a170906054e00b008b13009536bmr8233903eja.29.1676600630321; Thu, 16 Feb 2023 18:23:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676600630; cv=none; d=google.com; s=arc-20160816; b=a3FredCfJRr8Q6pejcAgveonknrnPqF09HdgcMF4zWcTEurGXp5e7Dg0vivqU9DIC3 1DYS2n76+ESVtunBlTwiR/2f7sAqJBE5OOoLUtkPknr9O8paW/dVBuf87HpNxcqrh+Co 7EintMt/jZpa2ukQYeakq6Vvm97ixccmhVTxQQOc62XImd8cQHUqJYDjz1lZSCj6Fz0U Erp3yqnoC4ozavg4aEN1FTgBXtx6DRYdjRBzYIiyMVlUnlyq2t1GUuiD1XP059rVG9Ns mM1oAodfv2YOCGMd7TYWPRxpXziXm63RI90P1MZFXMOMRS08Z53A4L/sHxR6pv0B+ZVf 143Q== 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=hVQ7XpKQQOglh6806rRwVaGtSWopvdoLR/6aMneO4n8=; b=Lz+D3JBMcq3PvW2RoW0Dtdnh+6L9xGRBIzFMrH6rrZ2niq3vZwdxl3DrX66nBYDdRY rZxUmnLTbqhhvaH7OvESWuePBgGMhNfzvAZOFutReXOV1Dj5ERswSd//Oy8Gxm0ojK2H WmeUfgWG3s7owTd4I7BU1zgSHGVn2Mb4335QDNWZWj3W6zzk/GYRG0geYYCNa+az3sxB 3s3ya2om2lfv6Dq1xbfRZTDsxwNyH1DjVC/IBkPsWB5d6dqstEV64sePRsbp6VU0y8px YUe3lun8r0lw5ooUU3irFuKCKDFnuuH/CgO9JCwXZg+1PbjqVa2e7jG+1zaBDN5CXm8A tU6w== 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 n9-20020a056402514900b004acbe83b837si2398160edd.213.2023.02.16.18.23.25; Thu, 16 Feb 2023 18:23:50 -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 S230295AbjBQCHR (ORCPT + 99 others); Thu, 16 Feb 2023 21:07:17 -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 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?1758043182747317167?= X-GMAIL-MSGID: =?utf-8?q?1758043182747317167?= 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-high' 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,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..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 control. + Else, use the 'VSEL0' register group. This depends on external hardware + '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 = <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 = <300000>; + regulator-max-microvolt = <1300000>; + regulator-allowed-modes = <0 1>; + regulator-boot-on; + }; + }; From patchwork Fri Feb 17 02:06:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ChiYuan Huang X-Patchwork-Id: 58318 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp647180wrn; Thu, 16 Feb 2023 18:17:05 -0800 (PST) X-Google-Smtp-Source: AK7set9aa45NpPfSVVnR0fpNHrBE4FUjp8xOLEZpcgiCjLyWSnU6R0fttxLnce/XkZLx64fqhPUY X-Received: by 2002:a17:90b:1c09:b0:234:27a4:fba2 with SMTP id oc9-20020a17090b1c0900b0023427a4fba2mr8917123pjb.18.1676600225674; Thu, 16 Feb 2023 18:17:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676600225; cv=none; d=google.com; s=arc-20160816; b=W2PZaNr3DPX6z5gXakVPpB2xrIOR25sgBw1RNxxz69U96cUrSdodYJPQ5uFHQhepdu g4HqEQwpUn6dtvIQ+oH6qWWVSE7cGd0bdjhGVCs1aC2kDZeSm9suRjYYqkV865Z7xAss 0utZVBDs+zPENJhq+kBxidgy28o/BW5epP9NW6iS+kHWlY/2KZDmw7WfNtz9u5pTwYmx flSeIiY7ZHmsVXPBLMNsqnH66jeUtmbNb+BNDg5j4F+jdL4zEULbAO+0u3HmMX2K3x0K r1f6wdfv27ChskQ1B2DhuHD6/3nyfOf9mfbNLKnbsjN//UhedYy03TR55JgWc0wUlaf1 DPYg== 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=n+aOtCbwzPFfTT2C01lXwKLpbOkFHIVFHVmytkoaLpk=; b=jG0zNaufTSB1XjD45NnjSdjKdtJuGLydnUtV0vqJ4sSq9Zl92OWOaM2/WXaSidFyw0 zbN8M5MU4ogG8GKTGXGJB3noa6RIDVO5Zqyl8NSkjOrIj+XYXg8xJidJ/p5WybLcV7Iy hnFrC9wEl+i81Pwf+cbJ6RAW28nmUaobKJPC9awMmSxk3GVlvjz5eGuwxWcwDLd73Gpr mJcwNlOQgx991oUK6MKQJH4s+KBij2HzyZwqrtT6Wz1CzsckCSDRylyNSmtHvGuaRE7k ZbyJGGvTNUITJTgSLGQU4j/BGjQI9a8Lw3D0tHgd0xOlAMDq7tyRjvXk7dAejnEfD6lN ra2w== 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 q8-20020a17090aa00800b00234b66e3df3si1741244pjp.153.2023.02.16.18.16.52; Thu, 16 Feb 2023 18:17:05 -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 S230312AbjBQCHX (ORCPT + 99 others); Thu, 16 Feb 2023 21:07:23 -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 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?1758042758279352501?= X-GMAIL-MSGID: =?utf-8?q?1758042758279352501?= 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. +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");