From: "Jaehoon Chung" <jh80.chung@samsung.com>
To: "'Svyatoslav Ryhel'" <clamor95@gmail.com>,
"'Tom Rini'" <trini@konsulko.com>,
"'Simon Glass'" <sjg@chromium.org>
Cc: <u-boot@lists.denx.de>
Subject: RE: [PATCH v9 4/8] power: regulator: max77663: add regulator support
Date: Tue, 31 Oct 2023 17:58:42 +0900 [thread overview]
Message-ID: <008b01da0bd8$72de3e60$589abb20$@samsung.com> (raw)
In-Reply-To: <20231027082615.306943-5-clamor95@gmail.com>
> -----Original Message-----
> From: Svyatoslav Ryhel <clamor95@gmail.com>
> Sent: Friday, October 27, 2023 5:26 PM
> To: Tom Rini <trini@konsulko.com>; Jaehoon Chung <jh80.chung@samsung.com>; Simon Glass
> <sjg@chromium.org>; Svyatoslav Ryhel <clamor95@gmail.com>
> Cc: u-boot@lists.denx.de
> Subject: [PATCH v9 4/8] power: regulator: max77663: add regulator support
>
> The driver provides regulator set/get voltage
> enable/disable functions for MAXIM MAX77663 PMICs.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Best Regards,
Jaehoon Chung
> ---
> drivers/power/regulator/Kconfig | 9 +
> drivers/power/regulator/Makefile | 1 +
> drivers/power/regulator/max77663_regulator.c | 375 +++++++++++++++++++
> 3 files changed, 385 insertions(+)
> create mode 100644 drivers/power/regulator/max77663_regulator.c
>
> diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
> index eb5aa38c1c..581816294c 100644
> --- a/drivers/power/regulator/Kconfig
> +++ b/drivers/power/regulator/Kconfig
> @@ -141,6 +141,15 @@ config SPL_REGULATOR_PWM
> This config enables implementation of driver-model regulator uclass
> features for PWM regulators in SPL.
>
> +config DM_REGULATOR_MAX77663
> + bool "Enable Driver Model for REGULATOR MAX77663"
> + depends on DM_REGULATOR && DM_PMIC_MAX77663
> + ---help---
> + This config enables implementation of driver-model regulator uclass
> + features for REGULATOR MAX77663. The driver supports both DC-to-DC
> + Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
> + found in MAX77663 PMIC and implements get/set api for value and enable.
> +
> config DM_REGULATOR_MAX77686
> bool "Enable Driver Model for REGULATOR MAX77686"
> depends on DM_REGULATOR && DM_PMIC_MAX77686
> diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
> index d9e0cd5949..8d73169b50 100644
> --- a/drivers/power/regulator/Makefile
> +++ b/drivers/power/regulator/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722_regulator.o
> obj-$(CONFIG_$(SPL_)REGULATOR_AXP) += axp_regulator.o
> obj-$(CONFIG_$(SPL_)REGULATOR_AXP_USB_POWER) += axp_usb_power.o
> obj-$(CONFIG_$(SPL_)DM_REGULATOR_DA9063) += da9063.o
> +obj-$(CONFIG_$(SPL_)DM_REGULATOR_MAX77663) += max77663_regulator.o
> obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
> obj-$(CONFIG_DM_REGULATOR_NPCM8XX) += npcm8xx_regulator.o
> obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o
> diff --git a/drivers/power/regulator/max77663_regulator.c
> b/drivers/power/regulator/max77663_regulator.c
> new file mode 100644
> index 0000000000..ea4b7c63e5
> --- /dev/null
> +++ b/drivers/power/regulator/max77663_regulator.c
> @@ -0,0 +1,375 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
> + */
> +
> +#include <dm.h>
> +#include <power/pmic.h>
> +#include <power/regulator.h>
> +#include <power/max77663.h>
> +
> +/* fist row is control registers, second is voltage registers */
> +static const char max77663_sd_reg[][MAX77663_SD_NUM] = {
> + { 0x1d, 0x1e, 0x1f, 0x20, 0x21 },
> + { 0x16, 0x17, 0x18, 0x19, 0x2a },
> +};
> +
> +static const char max77663_ldo_reg[MAX77663_LDO_NUM] = {
> + 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33
> +};
> +
> +static int max77663_sd_enable(struct udevice *dev, int op, bool *enable)
> +{
> + struct dm_regulator_uclass_plat *uc_pdata =
> + dev_get_uclass_plat(dev);
> + u32 adr = uc_pdata->ctrl_reg;
> + int val, ret;
> +
> + val = pmic_reg_read(dev->parent, adr);
> + if (val < 0)
> + return val;
> +
> + if (op == PMIC_OP_GET) {
> + if (val & SD_STATUS_MASK)
> + *enable = true;
> + else
> + *enable = false;
> +
> + return 0;
> + } else if (op == PMIC_OP_SET) {
> + val &= ~SD_STATUS_MASK;
> +
> + if (*enable)
> + val |= SD_STATUS_MASK;
> +
> + ret = pmic_reg_write(dev->parent, adr, val);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * max77663_*_volt2hex() - convert voltage in uV into
> + * applicable to register hex value
> + *
> + * @idx: regulator index
> + * @uV: voltage in uV
> + *
> + * Return: voltage in hex on success, -ve on failure
> + */
> +static int max77663_sd_volt2hex(int idx, int uV)
> +{
> + switch (idx) {
> + case 0:
> + /* SD0 has max voltage 1.4V */
> + if (uV > SD0_VOLT_MAX)
> + return -EINVAL;
> + break;
> + case 1:
> + /* SD1 has max voltage 1.55V */
> + if (uV > SD1_VOLT_MAX)
> + return -EINVAL;
> + break;
> + default:
> + /* SD2 and SD3 have max voltage 3.79V */
> + if (uV > SD_VOLT_MAX)
> + return -EINVAL;
> + break;
> + };
> +
> + if (uV < SD_VOLT_MIN)
> + uV = SD_VOLT_MIN;
> +
> + return (uV - SD_VOLT_BASE) / 12500;
> +}
> +
> +/**
> + * max77663_*_hex2volt() - convert register hex value into
> + * actual voltage in uV
> + *
> + * @idx: regulator index
> + * @hex: hex value of register
> + *
> + * Return: voltage in uV on success, -ve on failure
> + */
> +static int max77663_sd_hex2volt(int idx, int hex)
> +{
> + switch (idx) {
> + case 0:
> + /* SD0 has max voltage 1.4V */
> + if (hex > SD0_VOLT_MAX_HEX)
> + return -EINVAL;
> + break;
> + case 1:
> + /* SD1 has max voltage 1.55V */
> + if (hex > SD1_VOLT_MAX_HEX)
> + return -EINVAL;
> + break;
> + default:
> + /* SD2 and SD3 have max voltage 3.79V */
> + if (hex > SD_VOLT_MAX_HEX)
> + return -EINVAL;
> + break;
> + };
> +
> + if (hex < SD_VOLT_MIN_HEX)
> + hex = SD_VOLT_MIN_HEX;
> +
> + return SD_VOLT_BASE + hex * 12500;
> +}
> +
> +static int max77663_sd_val(struct udevice *dev, int op, int *uV)
> +{
> + struct dm_regulator_uclass_plat *uc_pdata =
> + dev_get_uclass_plat(dev);
> + u32 adr = uc_pdata->volt_reg;
> + int idx = dev->driver_data;
> + int hex, ret;
> +
> + if (op == PMIC_OP_GET) {
> + hex = pmic_reg_read(dev->parent, adr);
> + if (hex < 0)
> + return hex;
> +
> + *uV = 0;
> +
> + ret = max77663_sd_hex2volt(idx, hex);
> + if (ret < 0)
> + return ret;
> + *uV = ret;
> +
> + return 0;
> + }
> +
> + /* SD regulators use entire register for voltage */
> + hex = max77663_sd_volt2hex(idx, *uV);
> + if (hex < 0)
> + return hex;
> +
> + return pmic_reg_write(dev->parent, adr, hex);
> +}
> +
> +static int max77663_sd_probe(struct udevice *dev)
> +{
> + struct dm_regulator_uclass_plat *uc_pdata =
> + dev_get_uclass_plat(dev);
> + int idx = dev->driver_data;
> +
> + uc_pdata->type = REGULATOR_TYPE_BUCK;
> + uc_pdata->ctrl_reg = max77663_sd_reg[0][idx];
> + uc_pdata->volt_reg = max77663_sd_reg[1][idx];
> +
> + return 0;
> +}
> +
> +static int sd_get_value(struct udevice *dev)
> +{
> + int uV;
> + int ret;
> +
> + ret = max77663_sd_val(dev, PMIC_OP_GET, &uV);
> + if (ret)
> + return ret;
> +
> + return uV;
> +}
> +
> +static int sd_set_value(struct udevice *dev, int uV)
> +{
> + return max77663_sd_val(dev, PMIC_OP_SET, &uV);
> +}
> +
> +static int sd_get_enable(struct udevice *dev)
> +{
> + bool enable = false;
> + int ret;
> +
> + ret = max77663_sd_enable(dev, PMIC_OP_GET, &enable);
> + if (ret)
> + return ret;
> +
> + return enable;
> +}
> +
> +static int sd_set_enable(struct udevice *dev, bool enable)
> +{
> + return max77663_sd_enable(dev, PMIC_OP_SET, &enable);
> +}
> +
> +static const struct dm_regulator_ops max77663_sd_ops = {
> + .get_value = sd_get_value,
> + .set_value = sd_set_value,
> + .get_enable = sd_get_enable,
> + .set_enable = sd_set_enable,
> +};
> +
> +U_BOOT_DRIVER(max77663_sd) = {
> + .name = MAX77663_SD_DRIVER,
> + .id = UCLASS_REGULATOR,
> + .ops = &max77663_sd_ops,
> + .probe = max77663_sd_probe,
> +};
> +
> +static int max77663_ldo_enable(struct udevice *dev, int op, bool *enable)
> +{
> + struct dm_regulator_uclass_plat *uc_pdata =
> + dev_get_uclass_plat(dev);
> + u32 adr = uc_pdata->ctrl_reg;
> + int val, ret;
> +
> + val = pmic_reg_read(dev->parent, adr);
> + if (val < 0)
> + return val;
> +
> + if (op == PMIC_OP_GET) {
> + if (val & LDO_STATUS_MASK)
> + *enable = true;
> + else
> + *enable = false;
> +
> + return 0;
> + } else if (op == PMIC_OP_SET) {
> + val &= ~LDO_STATUS_MASK;
> +
> + if (*enable)
> + val |= LDO_STATUS_MASK;
> +
> + ret = pmic_reg_write(dev->parent, adr, val);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int max77663_ldo_volt2hex(int idx, int uV)
> +{
> + switch (idx) {
> + case 0:
> + case 1:
> + if (uV > LDO01_VOLT_MAX)
> + return -EINVAL;
> +
> + return (uV - LDO_VOLT_BASE) / 25000;
> + case 4:
> + if (uV > LDO4_VOLT_MAX)
> + return -EINVAL;
> +
> + return (uV - LDO_VOLT_BASE) / 12500;
> + default:
> + if (uV > LDO_VOLT_MAX)
> + return -EINVAL;
> +
> + return (uV - LDO_VOLT_BASE) / 50000;
> + };
> +}
> +
> +static int max77663_ldo_hex2volt(int idx, int hex)
> +{
> + if (hex > LDO_VOLT_MAX_HEX)
> + return -EINVAL;
> +
> + switch (idx) {
> + case 0:
> + case 1:
> + return (hex * 25000) + LDO_VOLT_BASE;
> + case 4:
> + return (hex * 12500) + LDO_VOLT_BASE;
> + default:
> + return (hex * 50000) + LDO_VOLT_BASE;
> + };
> +}
> +
> +static int max77663_ldo_val(struct udevice *dev, int op, int *uV)
> +{
> + struct dm_regulator_uclass_plat *uc_pdata =
> + dev_get_uclass_plat(dev);
> + u32 adr = uc_pdata->ctrl_reg;
> + int idx = dev->driver_data;
> + int hex, val, ret;
> +
> + val = pmic_reg_read(dev->parent, adr);
> + if (val < 0)
> + return val;
> +
> + if (op == PMIC_OP_GET) {
> + *uV = 0;
> +
> + ret = max77663_ldo_hex2volt(idx, val & LDO_VOLT_MASK);
> + if (ret < 0)
> + return ret;
> +
> + *uV = ret;
> + return 0;
> + }
> +
> + hex = max77663_ldo_volt2hex(idx, *uV);
> + if (hex < 0)
> + return hex;
> +
> + val &= ~LDO_VOLT_MASK;
> +
> + return pmic_reg_write(dev->parent, adr, val | hex);
> +}
> +
> +static int max77663_ldo_probe(struct udevice *dev)
> +{
> + struct dm_regulator_uclass_plat *uc_pdata =
> + dev_get_uclass_plat(dev);
> + int idx = dev->driver_data;
> +
> + uc_pdata->type = REGULATOR_TYPE_LDO;
> + uc_pdata->ctrl_reg = max77663_ldo_reg[idx];
> +
> + return 0;
> +}
> +
> +static int ldo_get_value(struct udevice *dev)
> +{
> + int uV;
> + int ret;
> +
> + ret = max77663_ldo_val(dev, PMIC_OP_GET, &uV);
> + if (ret)
> + return ret;
> +
> + return uV;
> +}
> +
> +static int ldo_set_value(struct udevice *dev, int uV)
> +{
> + return max77663_ldo_val(dev, PMIC_OP_SET, &uV);
> +}
> +
> +static int ldo_get_enable(struct udevice *dev)
> +{
> + bool enable = false;
> + int ret;
> +
> + ret = max77663_ldo_enable(dev, PMIC_OP_GET, &enable);
> + if (ret)
> + return ret;
> +
> + return enable;
> +}
> +
> +static int ldo_set_enable(struct udevice *dev, bool enable)
> +{
> + return max77663_ldo_enable(dev, PMIC_OP_SET, &enable);
> +}
> +
> +static const struct dm_regulator_ops max77663_ldo_ops = {
> + .get_value = ldo_get_value,
> + .set_value = ldo_set_value,
> + .get_enable = ldo_get_enable,
> + .set_enable = ldo_set_enable,
> +};
> +
> +U_BOOT_DRIVER(max77663_ldo) = {
> + .name = MAX77663_LDO_DRIVER,
> + .id = UCLASS_REGULATOR,
> + .ops = &max77663_ldo_ops,
> + .probe = max77663_ldo_probe,
> +};
> --
> 2.39.2
next prev parent reply other threads:[~2023-10-31 8:58 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-27 8:26 [PATCH v9 0/8] Add support for PMICs used on Tegra 3 devices Svyatoslav Ryhel
2023-10-27 8:26 ` [PATCH v9 1/8] power: pmic: palmas: support TI TPS65913 PMIC Svyatoslav Ryhel
2023-10-31 6:44 ` Jaehoon Chung
2023-11-04 13:57 ` Tom Rini
2023-10-27 8:26 ` [PATCH v9 2/8] power: regulator: palmas: fix ldoln and ldousb detection Svyatoslav Ryhel
2023-10-27 8:26 ` [PATCH v9 3/8] power: pmic: add the base MAX77663 PMIC support Svyatoslav Ryhel
2023-10-31 8:57 ` Jaehoon Chung
2023-10-31 9:08 ` Svyatoslav Ryhel
2023-10-27 8:26 ` [PATCH v9 4/8] power: regulator: max77663: add regulator support Svyatoslav Ryhel
2023-10-31 8:58 ` Jaehoon Chung [this message]
2023-10-27 8:26 ` [PATCH v9 5/8] power: pmic: add the base TPS80031 PMIC support Svyatoslav Ryhel
2023-10-27 8:26 ` [PATCH v9 6/8] power: regulator: tps80031: add regulator support Svyatoslav Ryhel
2023-10-27 8:26 ` [PATCH v9 7/8] power: pmic: tps65910: add TPS65911 PMIC support Svyatoslav Ryhel
2023-10-27 8:26 ` [PATCH v9 8/8] power: regulator: tps65911: add regulator support Svyatoslav Ryhel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='008b01da0bd8$72de3e60$589abb20$@samsung.com' \
--to=jh80.chung@samsung.com \
--cc=clamor95@gmail.com \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.