From nobody Tue Jun 23 11:11:07 2026 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 25A33C433F5 for ; Mon, 7 Mar 2022 10:50:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241644AbiCGKv3 (ORCPT ); Mon, 7 Mar 2022 05:51:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41768 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242306AbiCGKtA (ORCPT ); Mon, 7 Mar 2022 05:49:00 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C879834660; Mon, 7 Mar 2022 02:08:35 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id m22so12957409pja.0; Mon, 07 Mar 2022 02:08:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cMODfEuB/bWL2mIF4xu/VOgQ2ijW069H0ypnoIgKd0A=; b=M1YG6t0tZx2PNV40LBHkm2dPqOslVeVJFboYB/KKJzOHxcUOzNOmwECiy0NX4KiwDs AbRjInZU+TO1/o1Xgs+V7alqvrJ+N7kIdaN4TxUdMzYctFmrX6fEKduhs0l18o2e4uBY PUR99j/GerK6aWC58d5KeZr0d2CRA+igY3PsjgzzWWuwbvaehFRrxA1EHgXG/c0cr8yM RBvCGpmCAJMwnnKdvkvTvcAPvYS2AtmIqYzPxD2IujgdQn+fN+J9qK/dbEFcDjrcoc82 7SCqaUlgsFwE4rinMw17QSFVvUUzN/PhhP4yHEhoGwC4fPmhfLBLhga/A/tkuc3Il3zJ U97g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cMODfEuB/bWL2mIF4xu/VOgQ2ijW069H0ypnoIgKd0A=; b=lqN2rUtZ7IYBkxvJOyJP79nKNPgJ7dpX8LTAzUpI71+Wvnw7UKIT4uc74uLJrRT3g7 zqoNXOn5e3Zzj2LwfL1wuuK86pISW04DsFkMkcQVMmuFgW5q8WZHKcyLECyKVWjTPHYo rWFsuhoAJgXRLvePviVr8bUWyOXet3g84mPwedQuF87zsCKRlG02Y5dZq+h3t/K3+1Vx T6ORnEzD6yrgF74skZfDLo1OtbbnTU3t6Byo947U7y2ZGndEkwFLkgjEczGLvbOhBoS2 Wqydl1u+w8mRvEP8Q6jHZAvxAn4KXSjTlYN/v3/2w5CTJQZcjfYFd3jCp4sHRwcvwGXL GnxA== X-Gm-Message-State: AOAM530FOMDRQzGBkL+4PGuospjYoKoDItZ3/UUZPgJ6B9hGLsbr0yOw jZcncH8Id8OpLrK8Q0wB0Yo= X-Google-Smtp-Source: ABdhPJy7zJvzZX7Vbmmoo5aUuYHkqyRxgHNY81pKhHdq1NM3OSMFj3s/DXLTGp/jlAx+JG95hI5fMA== X-Received: by 2002:a17:902:ef4f:b0:14f:6188:62ca with SMTP id e15-20020a170902ef4f00b0014f618862camr11118301plx.106.1646647715219; Mon, 07 Mar 2022 02:08:35 -0800 (PST) Received: from localhost.localdomain ([2402:7500:486:4335:5d3f:ee29:17d3:65af]) by smtp.gmail.com with ESMTPSA id n22-20020a056a0007d600b004f3ba7c23e2sm15140125pfu.37.2022.03.07.02.08.32 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Mar 2022 02:08:34 -0800 (PST) From: cy_huang To: broonie@kernel.org, robh+dt@kernel.org Cc: lgirdwood@gmail.com, cy_huang@richtek.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH 1/2] dt-bindings: regulator: Add bindings for Richtek RT5190A PMIC Date: Mon, 7 Mar 2022 18:08:23 +0800 Message-Id: <1646647704-2331-2-git-send-email-u0084500@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1646647704-2331-1-git-send-email-u0084500@gmail.com> References: <1646647704-2331-1-git-send-email-u0084500@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: ChiYuan Huang Add bindings for Richtek RT5190A PMIC. Signed-off-by: ChiYuan Huang --- .../regulator/richtek,rt5190a-regulator.yaml | 138 +++++++++++++++++= ++++ 1 file changed, 138 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/richtek,rt5= 190a-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt5190a-re= gulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt5190a-= regulator.yaml new file mode 100644 index 00000000..b9f5836 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/richtek,rt5190a-regulator= .yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/richtek,rt5190a-regulator.yam= l# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT5190A PMIC Regulator + +maintainers: + - ChiYuan Huang + +description: | + The RT5190A integrates 1 channel buck controller, 3 channels high effici= ency + synchronous buck converters, 1 LDO, I2C control interface and peripherial + logical control. + + It also supports mute AC OFF depop sound and quick setting storage while + input power is removed. + +properties: + compatible: + enum: + - richtek,rt5190a + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + vin2-supply: + description: phandle to buck2 input voltage. + + vin3-supply: + description: phandle to buck3 input voltage. + + vin4-supply: + description: phandle to buck4 input voltage. + + vinldo-supply: + description: phandle to ldo input voltage + + richtek,buck1-fixed-microvolt: + description: buck1 fixed voltage that depends on the external resistor. + $ref: "/schemas/types.yaml#/definitions/uint32" + + richtek,buck4-fixed-microvolt: + description: buck4 fixed voltage that depends on the external resistor. + $ref: "/schemas/types.yaml#/definitions/uint32" + + richtek,ldo-fixed-microvolt: + description: ldo fixed voltage that depends on the external resistor. + $ref: "/schemas/types.yaml#/definitions/uint32" + + richtek,mute-enable: + description: this can be used to enable mute function. + type: boolean + + regulators: + type: object + + patternProperties: + "^buck[1-4]$|^ldo$": + type: object + $ref: regulator.yaml# + description: | + regulator description for buck[1-4] and ldo. + + properties: + richtek,latchup-enable: + type: boolean + description: | + If specified, undervolt protection mode changes from the def= ault + hiccup to latchup. + + unevaluatedProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - richtek,buck1-fixed-microvolt + - richtek,buck4-fixed-microvolt + - richtek,ldo-fixed-microvolt + - regulators + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + rt5190a@64 { + compatible =3D "richtek,rt5190a"; + reg =3D <0x64>; + interrupts-extended =3D <&gpio26 0 IRQ_TYPE_LEVEL_LOW>; + vin2-supply =3D <&rt5190_buck1>; + vin3-supply =3D <&rt5190_buck1>; + vin4-supply =3D <&rt5190_buck1>; + richtek,buck1-fixed-microvolt =3D <5090000>; + richtek,buck4-fixed-microvolt =3D <850000>; + richtek,ldo-fixed-microvolt =3D <1200000>; + + regulators { + rt5190_buck1: buck1 { + regulator-name =3D "rt5190a-buck1"; + regulator-allowed-modes =3D <0 1>; + regulator-boot-on; + }; + buck2 { + regulator-name =3D "rt5190a-buck2"; + regulator-min-microvolt =3D <600000>; + regulator-max-microvolt =3D <1400000>; + regulator-boot-on; + }; + buck3 { + regulator-name =3D "rt5190a-buck3"; + regulator-min-microvolt =3D <600000>; + regulator-max-microvolt =3D <1400000>; + regulator-boot-on; + }; + buck4 { + regulator-name =3D "rt5190a-buck4"; + regulator-allowed-modes =3D <0 1>; + regulator-boot-on; + }; + ldo { + regulator-name =3D "rt5190a-ldo"; + regulator-boot-on; + }; + }; + }; + }; --=20 2.7.4 From nobody Tue Jun 23 11:11:07 2026 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 D5A29C433F5 for ; Mon, 7 Mar 2022 10:50:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241553AbiCGKvV (ORCPT ); Mon, 7 Mar 2022 05:51:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242309AbiCGKtA (ORCPT ); Mon, 7 Mar 2022 05:49:00 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D6B91369D1; Mon, 7 Mar 2022 02:08:39 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id 6so8606158pgg.0; Mon, 07 Mar 2022 02:08:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ufetOI9Ly8/LGJGPsU1o7i/HJNenI68BeElXdehsn3I=; b=LWCcEDjG5GLQEsdEXzjNoNjD83EEud8J0pHymZc/S6CfYmSOMxf+6pvrZgX/jSg/2H Ox1LozeLvDWfELNH3VO04RUjeWX1oJAqagHfrcgztz3yo2TEBq5rE7zeOXMRdrKZ22ze MvyuIuBqFBKU8fGtq7CrSJGdMtpobc5OeO5hlClC3gBZPu/JMjOICdgxUJjzjl5GJCuR vvQoBb6blfdwmTcLPW9lUoU/Xwl0xeoar/E58SmdoctEpGbdgpta5owdBEzU2z0Gb7cS +kQoKPS9kQxAO+0HhDnM8VzZGbzo5J3a8s7/bqXHzfDqqxLEndwhRZ7NbBaI4jVlpPDT fSPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ufetOI9Ly8/LGJGPsU1o7i/HJNenI68BeElXdehsn3I=; b=jbszltqOadiM4Z439NCGXmjJit/gCHax6/+e9Rrygb5O4whut4/FK4G6MrlxYgegov Lm7BTGWeWQ+EMZ42j+Nj+eAT1BB+ZO6aq6HmP2XWgYGTucqp6KXuPmy75iMLgmtZ8I0p dWX2U5iHaOJL1eJ6Ks0nKBYbRhOslvYbsZdpqp4r5yGHGvSd7FfgGCh6a7KVg5EWHK8w BWiPaWXKvQGhW2q02KmhLWL58rDPiUGMGAq8f8ryWEZtDmrZnh4oxGEvegd4ZUWyx2q0 yRbOcFrw4EsXH6cjK5Qe2FbFLhfEoMhK+xCtmVRzkCUIXlO7GTRVNGnIxahb8EmeB7l7 tmtQ== X-Gm-Message-State: AOAM530VphwiCAuEyHqjPoSHZuuG9xjSZmqQgG7I7Jd+mZe3krm0v/Pk /eFEf4KIQ1oFNlWE7uZkAHA= X-Google-Smtp-Source: ABdhPJzwX4PkQ7iD/njumM/d9vLcuLuNeSKIaJLngu3r6eOcTwi7EnTYbW3qqiLvrnxrPmCjtgkt1g== X-Received: by 2002:a63:491b:0:b0:373:cf6d:51c8 with SMTP id w27-20020a63491b000000b00373cf6d51c8mr9165804pga.250.1646647718968; Mon, 07 Mar 2022 02:08:38 -0800 (PST) Received: from localhost.localdomain ([2402:7500:486:4335:5d3f:ee29:17d3:65af]) by smtp.gmail.com with ESMTPSA id n22-20020a056a0007d600b004f3ba7c23e2sm15140125pfu.37.2022.03.07.02.08.35 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Mar 2022 02:08:38 -0800 (PST) From: cy_huang To: broonie@kernel.org, robh+dt@kernel.org Cc: lgirdwood@gmail.com, cy_huang@richtek.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH 2/2] regulator: rt5190a: Add support for Richtek RT5190A PMIC Date: Mon, 7 Mar 2022 18:08:24 +0800 Message-Id: <1646647704-2331-3-git-send-email-u0084500@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1646647704-2331-1-git-send-email-u0084500@gmail.com> References: <1646647704-2331-1-git-send-email-u0084500@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: ChiYuan Huang Add support for Richtek RT5190A PMIC. Signed-off-by: ChiYuan Huang --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/rt5190a-regulator.c | 461 ++++++++++++++++++++++++++++++= ++++ 3 files changed, 472 insertions(+) create mode 100644 drivers/regulator/rt5190a-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 1c35fed2..850e954 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1046,6 +1046,16 @@ config REGULATOR_RT5033 RT5033 PMIC. The device supports multiple regulators like current source, LDO and Buck. =20 +config REGULATOR_RT5190A + tristate "Richtek RT5190A PMIC" + depends on I2C + select REGMAP_I2C + help + This adds support for voltage regulator in Richtek RT5190A PMIC. + It integratas 1 channel buck controller, 3 channels high efficiency + buck converters, 1 LDO, mute AC OFF depop function, with the general + I2C control interface. + config REGULATOR_RT6160 tristate "Richtek RT6160 BuckBoost voltage regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 2e1b087..28d816a9 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -126,6 +126,7 @@ obj-$(CONFIG_REGULATOR_ROHM) +=3D rohm-regulator.o obj-$(CONFIG_REGULATOR_RT4801) +=3D rt4801-regulator.o obj-$(CONFIG_REGULATOR_RT4831) +=3D rt4831-regulator.o obj-$(CONFIG_REGULATOR_RT5033) +=3D rt5033-regulator.o +obj-$(CONFIG_REGULATOR_RT5190A) +=3D rt5190a-regulator.o obj-$(CONFIG_REGULATOR_RT6160) +=3D rt6160-regulator.o obj-$(CONFIG_REGULATOR_RT6245) +=3D rt6245-regulator.o obj-$(CONFIG_REGULATOR_RTMV20) +=3D rtmv20-regulator.o diff --git a/drivers/regulator/rt5190a-regulator.c b/drivers/regulator/rt51= 90a-regulator.c new file mode 100644 index 00000000..2ac5e37 --- /dev/null +++ b/drivers/regulator/rt5190a-regulator.c @@ -0,0 +1,461 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RT5190A_REG_MANUFACTURE 0x00 +#define RT5190A_REG_BUCK2VSEL 0x04 +#define RT5190A_REG_BUCK3VSEL 0x05 +#define RT5190A_REG_DCDCCNTL 0x06 +#define RT5190A_REG_ENABLE 0x07 +#define RT5190A_REG_DISCHARGE 0x09 +#define RT5190A_REG_PROTMODE 0x0A +#define RT5190A_REG_MUTECNTL 0x0B +#define RT5190A_REG_PGSTAT 0x0F +#define RT5190A_REG_OVINT 0x10 +#define RT5190A_REG_HOTDIEMASK 0x17 + +#define RT5190A_VSEL_MASK GENMASK(6, 0) +#define RT5190A_RID_BITMASK(rid) BIT(rid + 1) +#define RT5190A_BUCK1_DISCHG_MASK GENMASK(1, 0) +#define RT5190A_BUCK1_DISCHG_ONVAL 0x01 +#define RT5190A_OVERVOLT_MASK GENMASK(7, 0) +#define RT5190A_UNDERVOLT_MASK GENMASK(15, 8) +#define RT5190A_CH234OT_MASK BIT(29) +#define RT5190A_CHIPOT_MASK BIT(28) + +#define RT5190A_BUCK23_MINUV 600000 +#define RT5190A_BUCK23_MAXUV 1400000 +#define RT5190A_BUCK23_STEPUV 10000 +#define RT5190A_BUCK23_STEPNUM ((1400000 - 600000) / 10000 + 1) + +enum { + RT5190A_IDX_BUCK1 =3D 0, + RT5190A_IDX_BUCK2, + RT5190A_IDX_BUCK3, + RT5190A_IDX_BUCK4, + RT5190A_IDX_LDO, + RT5190A_MAX_IDX +}; + +struct rt5190a_priv { + struct device *dev; + struct regmap *regmap; + struct regulator_desc rdesc[RT5190A_MAX_IDX]; + struct regulator_dev *rdev[RT5190A_MAX_IDX]; + unsigned int buck1_fixed_uV; + unsigned int buck4_fixed_uV; + unsigned int ldo_fixed_uV; + bool mute_enable; +}; + +static int rt5190a_get_error_flags(struct regulator_dev *rdev, + unsigned int *flags) +{ + struct regmap *regmap =3D rdev_get_regmap(rdev); + int rid =3D rdev_get_id(rdev); + unsigned int pgood_stat; + int ret; + + ret =3D regmap_read(regmap, RT5190A_REG_PGSTAT, &pgood_stat); + if (ret) + return ret; + + if (!(pgood_stat & RT5190A_RID_BITMASK(rid))) + *flags =3D REGULATOR_ERROR_FAIL; + else + *flags =3D 0; + + return 0; +} + +static int rt5190a_fixed_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct regmap *regmap =3D rdev_get_regmap(rdev); + int rid =3D rdev_get_id(rdev); + unsigned int mask =3D RT5190A_RID_BITMASK(rid), val; + + 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, RT5190A_REG_DCDCCNTL, mask, val); +} + +static unsigned int rt5190a_fixed_buck_get_mode(struct regulator_dev *rdev) +{ + struct regmap *regmap =3D rdev_get_regmap(rdev); + int rid =3D rdev_get_id(rdev); + unsigned int val; + int ret; + + ret =3D regmap_read(regmap, RT5190A_REG_DCDCCNTL, &val); + if (ret) { + dev_err(&rdev->dev, "Failed to get mode [%d]\n", ret); + return ret; + } + + if (val & RT5190A_RID_BITMASK(rid)) + return REGULATOR_MODE_FAST; + + return REGULATOR_MODE_NORMAL; +} + +static const struct regulator_ops rt5190a_ranged_buck_ops =3D { + .enable =3D regulator_enable_regmap, + .disable =3D regulator_disable_regmap, + .is_enabled =3D regulator_is_enabled_regmap, + .set_voltage_sel =3D regulator_set_voltage_sel_regmap, + .get_voltage_sel =3D regulator_get_voltage_sel_regmap, + .list_voltage =3D regulator_list_voltage_linear, + .set_active_discharge =3D regulator_set_active_discharge_regmap, + .get_error_flags =3D rt5190a_get_error_flags, +}; + +static const struct regulator_ops rt5190a_fixed_buck_ops =3D { + .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 rt5190a_fixed_buck_set_mode, + .get_mode =3D rt5190a_fixed_buck_get_mode, + .get_error_flags =3D rt5190a_get_error_flags, +}; + +static const struct regulator_ops rt5190a_fixed_ldo_ops =3D { + .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, + .get_error_flags =3D rt5190a_get_error_flags, +}; + +static irqreturn_t rt5190a_irq_handler(int irq, void *data) +{ + struct rt5190a_priv *priv =3D data; + __le32 raws; + unsigned int events, fields; + static const struct { + unsigned int bitmask; + unsigned int report; + } event_tbl[] =3D { + { RT5190A_OVERVOLT_MASK, REGULATOR_ERROR_REGULATION_OUT }, + { RT5190A_UNDERVOLT_MASK, REGULATOR_ERROR_UNDER_VOLTAGE } + }; + int i, j, ret; + + ret =3D regmap_raw_read(priv->regmap, RT5190A_REG_OVINT, &raws, + sizeof(raws)); + if (ret) { + dev_err(priv->dev, "Failed to read events\n"); + return IRQ_NONE; + } + + events =3D le32_to_cpu(raws); + + /* Handle OV,UV events */ + for (i =3D 0; i < ARRAY_SIZE(event_tbl); i++) { + fields =3D events & event_tbl[i].bitmask; + fields >>=3D ffs(event_tbl[i].bitmask) - 1; + + for (j =3D 0; j < RT5190A_MAX_IDX; j++) { + if (!(fields & RT5190A_RID_BITMASK(j))) + continue; + + regulator_notifier_call_chain(priv->rdev[j], + event_tbl[i].report, + NULL); + } + } + + /* Handle CH234 OT event */ + if (events & RT5190A_CH234OT_MASK) { + for (j =3D RT5190A_IDX_BUCK2; j < RT5190A_IDX_LDO; j++) { + regulator_notifier_call_chain(priv->rdev[j], + REGULATOR_ERROR_OVER_TEMP, + NULL); + } + } + + /* Warning if CHIP OT occur */ + if (events & RT5190A_CHIPOT_MASK) + dev_warn(priv->dev, "CHIP overheat\n"); + + ret =3D regmap_raw_write(priv->regmap, RT5190A_REG_OVINT, &raws, + sizeof(raws)); + if (ret) + dev_err(priv->dev, "Failed to write-clear events\n"); + + return IRQ_HANDLED; +} + +static unsigned int rt5190a_of_map_mode(unsigned int mode) +{ + switch (mode) { + case 0: + return REGULATOR_MODE_NORMAL; + case 1: + return REGULATOR_MODE_FAST; + default: + return REGULATOR_MODE_INVALID; + } +} + +static int rt5190a_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + bool latchup_enable; + unsigned int mask =3D RT5190A_RID_BITMASK(desc->id), val; + + latchup_enable =3D of_property_read_bool(np, "richtek,latchup-enable"); + + /* latchup: 0, default hiccup: 1 */ + val =3D !latchup_enable ? mask : 0; + + return regmap_update_bits(cfg->regmap, RT5190A_REG_PROTMODE, mask, val); +} + +static void rt5190a_fillin_regulator_desc(struct rt5190a_priv *priv, int r= id) +{ + static const char *regu_name[] =3D { "buck1", "buck2", "buck3", "buck4", + "ldo" }; + static const char *supply[]=3D { NULL, "vin2", "vin3", "vin4", "vinldo" }; + struct regulator_desc *desc =3D priv->rdesc + rid; + + desc->name =3D desc->of_match =3D regu_name[rid]; + desc->supply_name =3D supply[rid]; + desc->regulators_node =3D "regulators"; + desc->owner =3D THIS_MODULE; + desc->type =3D REGULATOR_VOLTAGE; + desc->id =3D rid; + desc->enable_reg =3D RT5190A_REG_ENABLE; + desc->enable_mask =3D RT5190A_RID_BITMASK(rid); + desc->active_discharge_reg =3D RT5190A_REG_DISCHARGE; + desc->active_discharge_mask =3D RT5190A_RID_BITMASK(rid); + desc->active_discharge_on =3D RT5190A_RID_BITMASK(rid); + desc->of_parse_cb =3D rt5190a_of_parse_cb; + + switch (rid) { + case RT5190A_IDX_BUCK1: + desc->active_discharge_mask =3D RT5190A_BUCK1_DISCHG_MASK; + desc->active_discharge_on =3D RT5190A_BUCK1_DISCHG_ONVAL; + desc->fixed_uV =3D priv->buck1_fixed_uV; + desc->n_voltages =3D 1; + desc->ops =3D &rt5190a_fixed_buck_ops; + desc->of_map_mode =3D rt5190a_of_map_mode; + break; + case RT5190A_IDX_BUCK2: + desc->vsel_reg =3D RT5190A_REG_BUCK2VSEL; + desc->vsel_mask =3D RT5190A_VSEL_MASK; + desc->min_uV =3D RT5190A_BUCK23_MINUV; + desc->uV_step =3D RT5190A_BUCK23_STEPUV; + desc->n_voltages =3D RT5190A_BUCK23_STEPNUM; + desc->ops =3D &rt5190a_ranged_buck_ops; + break; + case RT5190A_IDX_BUCK3: + desc->vsel_reg =3D RT5190A_REG_BUCK3VSEL; + desc->vsel_mask =3D RT5190A_VSEL_MASK; + desc->min_uV =3D RT5190A_BUCK23_MINUV; + desc->uV_step =3D RT5190A_BUCK23_STEPUV; + desc->n_voltages =3D RT5190A_BUCK23_STEPNUM; + desc->ops =3D &rt5190a_ranged_buck_ops; + break; + case RT5190A_IDX_BUCK4: + desc->fixed_uV =3D priv->buck4_fixed_uV; + desc->n_voltages =3D 1; + desc->ops =3D &rt5190a_fixed_buck_ops; + desc->of_map_mode =3D rt5190a_of_map_mode; + break; + case RT5190A_IDX_LDO: + desc->fixed_uV =3D priv->ldo_fixed_uV; + desc->n_voltages =3D 1; + desc->ops =3D &rt5190a_fixed_ldo_ops; + break; + } +} + +static const struct reg_sequence rt5190a_init_patch[] =3D { + { 0x09, 0x3d, }, + { 0x0a, 0x3e, }, + { 0x0b, 0x01, }, + { 0x10, 0xff, }, + { 0x11, 0xff, }, + { 0x12, 0xff, }, + { 0x13, 0xff, }, + { 0x14, 0, }, + { 0x15, 0, }, + { 0x16, 0x3e, }, + { 0x17, 0, } +}; + +static int rt5190a_device_initialize(struct rt5190a_priv *priv) +{ + int ret; + + ret =3D regmap_register_patch(priv->regmap, rt5190a_init_patch, + ARRAY_SIZE(rt5190a_init_patch)); + if (ret) { + dev_err(priv->dev, "Failed to do register patch\n"); + return ret; + } + + if (priv->mute_enable) { + ret =3D regmap_write(priv->regmap, RT5190A_REG_MUTECNTL, 0x00); + if (ret) { + dev_err(priv->dev, "Failed to enable mute function\n"); + return ret; + } + } + + return 0; +} + +static int rt5190a_parse_device_config(struct rt5190a_priv *priv) +{ + struct device *dev =3D priv->dev; + int ret; + + ret =3D device_property_read_u32(dev, "richtek,buck1-fixed-microvolt", + &priv->buck1_fixed_uV); + if (ret) + return ret; + + ret =3D device_property_read_u32(dev, "richtek,buck4-fixed-microvolt", + &priv->buck4_fixed_uV); + if (ret) + return ret; + + ret =3D device_property_read_u32(dev, "richtek,ldo-fixed-microvolt", + &priv->ldo_fixed_uV); + if (ret) + return ret; + + priv->mute_enable =3D device_property_read_bool(dev, + "richtek,mute-enable"); + + return 0; +} + +static int rt5190a_device_check(struct rt5190a_priv *priv) +{ + u16 devid; + int ret; + + ret =3D regmap_raw_read(priv->regmap, RT5190A_REG_MANUFACTURE, &devid, + sizeof(devid)); + if (ret) + return ret; + + if (devid) { + dev_err(priv->dev, "Incorrect device id 0x%04x\n", devid); + return -ENODEV; + } + + return 0; +} + +static const struct regmap_config rt5190a_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D RT5190A_REG_HOTDIEMASK, +}; + +static int rt5190a_probe(struct i2c_client *i2c) +{ + struct rt5190a_priv *priv; + struct regulator_config cfg =3D {}; + int i, ret; + + priv =3D devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev =3D &i2c->dev; + + priv->regmap =3D devm_regmap_init_i2c(i2c, &rt5190a_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(&i2c->dev, "Failed to allocate regmap\n"); + return PTR_ERR(priv->regmap); + } + + ret =3D rt5190a_device_check(priv); + if (ret) { + dev_err(&i2c->dev, "Failed to check device %d\n", ret); + return ret; + } + + ret =3D rt5190a_parse_device_config(priv); + if (ret) { + dev_err(&i2c->dev, "Failed to parse device config\n"); + return ret; + } + + ret =3D rt5190a_device_initialize(priv); + if (ret) { + dev_err(&i2c->dev, "Failed to initialize the device\n"); + return ret; + } + + cfg.dev =3D &i2c->dev; + cfg.regmap =3D priv->regmap; + + for (i =3D 0; i < RT5190A_MAX_IDX; i++) { + struct regulator_desc *desc =3D priv->rdesc + i; + + rt5190a_fillin_regulator_desc(priv, i); + priv->rdev[i] =3D devm_regulator_register(&i2c->dev, desc, &cfg); + if (IS_ERR(priv->rdev[i])) { + dev_err(&i2c->dev, "Failed to register regulator %s\n", + desc->name); + return PTR_ERR(priv->rdev[i]); + } + } + + if (i2c->irq) { + ret =3D devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, + rt5190a_irq_handler, + IRQF_ONESHOT, + dev_name(&i2c->dev), priv); + if (ret) { + dev_err(&i2c->dev, "Failed to register interrupt\n"); + return ret; + } + } + + return 0; +} + +static const struct of_device_id __maybe_unused rt5190a_device_table[] =3D= { + { .compatible =3D "richtek,rt5190a", }, + {} +}; +MODULE_DEVICE_TABLE(of, rt5190a_device_table); + +static struct i2c_driver rt5190a_driver =3D { + .driver =3D { + .name =3D "rt5190a", + .of_match_table =3D rt5190a_device_table, + }, + .probe_new =3D rt5190a_probe, +}; +module_i2c_driver(rt5190a_driver); + +MODULE_AUTHOR("ChiYuan Huang "); +MODULE_DESCRIPTION("Richtek RT5190A Regulator Driver"); +MODULE_LICENSE("GPL v2"); --=20 2.7.4