[PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices

Patch set adds basic support for PMICs used in many Tegra 3 devices. All PMIC drivers are based on datasheets provided by vendors. Implemented API include regulator set/get voltage enable/disable and basic PMIC r/w capabilities.
Drivers were tested by me on LG P895 (max77663), HTC One X (TPS80032) and ASUS TF300T (tps65911). Calculations and behavior were correct, predictable and reproducible.
Svyatoslav Ryhel (6): power: pmic: add the base max77663 pmic support power: regulator: max77663: add regulator support power: pmic: add the base TPS80031 PMIC support power: regulator: tps80031: add regulator support power: pmic: tps65910: add TPS65911 PMIC support power: regulator: tps65911: add regulator support
doc/device-tree-bindings/pmic/max77663.txt | 84 +++++ doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++ doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++ drivers/power/pmic/Kconfig | 12 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77663.c | 81 ++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +- drivers/power/pmic/tps80031.c | 82 ++++ drivers/power/regulator/Kconfig | 24 ++ drivers/power/regulator/Makefile | 3 + drivers/power/regulator/max77663_regulator.c | 362 ++++++++++++++++++ drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++ include/power/max77663.h | 40 ++ include/power/tps65910_pmic.h | 47 +++ include/power/tps80031.h | 42 +++ 16 files changed, 1627 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 drivers/power/regulator/max77663_regulator.c create mode 100644 drivers/power/regulator/tps65911_regulator.c create mode 100644 drivers/power/regulator/tps80031_regulator.c create mode 100644 include/power/max77663.h create mode 100644 include/power/tps80031.h

Add support to bind the regulators/child nodes with the pmic. Also adds the pmic i2c based read/write functions to access pmic registers.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- doc/device-tree-bindings/pmic/max77663.txt | 84 ++++++++++++++++++++++ drivers/power/pmic/Kconfig | 6 ++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77663.c | 81 +++++++++++++++++++++ include/power/max77663.h | 40 +++++++++++ 5 files changed, 212 insertions(+) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 include/power/max77663.h
diff --git a/doc/device-tree-bindings/pmic/max77663.txt b/doc/device-tree-bindings/pmic/max77663.txt new file mode 100644 index 0000000000..ddb7d3eb14 --- /dev/null +++ b/doc/device-tree-bindings/pmic/max77663.txt @@ -0,0 +1,84 @@ +MAXIM, MAX77663 PMIC + +This device uses two drivers: +- drivers/power/pmic/max77663.c (for parent device) +- drivers/power/regulator/max77663_regulator.c (for child regulators) + +This chapter describes the binding info for the PMIC driver and regulators. + +Required properties for PMIC: +- compatible: "maxim,max77663" +- reg: usually 0x1c or 0x3c + +With those two properties, the pmic device can be used for read/write only. +To bind each regulator, the optional regulators subnode should exists. + +Optional subnode: +- name: regulators (subnode list of each device's regulator) + +Regulators subnode contains set on supported regulators. + +Required properties: +- regulator-name: used for regulator uclass platform data '.name', + +List of supported regulator nodes names for max77663: +- sd0, sd1, sd2, sd3, ldo0, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8 + +Optional: +- regulator-min-microvolt: minimum allowed Voltage to set +- regulator-max-microvolt: minimum allowed Voltage to set +- regulator-always-on: regulator should be never disabled +- regulator-boot-on: regulator should be enabled by the bootloader + +Linux driver binding for this driver is compatible. + +Example: + +max77663@1c { + compatible = "maxim,max77663"; + reg = <0x1c>; + + regulators { + sd0 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + ... + + ldo0 { + regulator-name = "avdd_pll"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ... + + ldo2 { + regulator-name = "avdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo3 { + regulator-name = "vdd_sdmmc3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + }; + + ... + + ldo8 { + regulator-name = "avdd_dsi_csi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; +}; diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 176fb07c65..abea0fe4ed 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -184,6 +184,12 @@ config SPL_DM_PMIC_PFUZE100 This config enables implementation of driver-model pmic uclass features for PMIC PFUZE100 in SPL. The driver implements read/write operations.
+config DM_PMIC_MAX77663 + bool "Enable Driver Model for PMIC MAX77663" + ---help--- + This config enables implementation of driver-model pmic uclass features + for PMIC MAX77663. The driver implements read/write operations. + config DM_PMIC_MAX77686 bool "Enable Driver Model for PMIC MAX77686" ---help--- diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 0b3b3d62d0..414a9d8225 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_$(SPL_TPL_)DM_PMIC) += pmic-uclass.o obj-$(CONFIG_$(SPL_)DM_PMIC_FAN53555) += fan53555.o obj-$(CONFIG_$(SPL_)DM_PMIC_DA9063) += da9063.o +obj-$(CONFIG_$(SPL_)DM_PMIC_MAX77663) += max77663.o obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o diff --git a/drivers/power/pmic/max77663.c b/drivers/power/pmic/max77663.c new file mode 100644 index 0000000000..fa70d2d936 --- /dev/null +++ b/drivers/power/pmic/max77663.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/max77663.h> +#include <dm/device.h> + +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "ldo", .driver = MAX77663_LDO_DRIVER }, + { .prefix = "sd", .driver = MAX77663_SD_DRIVER }, + { }, +}; + +static int max77663_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + log_err("write error to device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int max77663_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + log_err("read error from device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int max77663_bind(struct udevice *dev) +{ + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + log_err("%s regulators subnode not found!\n", dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + log_err("%s - no child found\n", dev->name); + + /* Always return success for this device */ + return 0; +} + +static struct dm_pmic_ops max77663_ops = { + .read = max77663_read, + .write = max77663_write, +}; + +static const struct udevice_id max77663_ids[] = { + { .compatible = "maxim,max77663" }, + { } +}; + +U_BOOT_DRIVER(pmic_max77663) = { + .name = "max77663_pmic", + .id = UCLASS_PMIC, + .of_match = max77663_ids, + .bind = max77663_bind, + .ops = &max77663_ops, +}; diff --git a/include/power/max77663.h b/include/power/max77663.h new file mode 100644 index 0000000000..53a0976346 --- /dev/null +++ b/include/power/max77663.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#ifndef _MAX77663_H_ +#define _MAX77663_H_ + +#define MAX77663_LDO_NUM 9 +#define MAX77663_SD_NUM 5 + +/* Drivers name */ +#define MAX77663_LDO_DRIVER "max77663_ldo" +#define MAX77663_SD_DRIVER "max77663_sd" + +#define MAX77663_SD_STATUS_MASK 0x30 + +#define MAX77663_SD0_VOLT_MAX_HEX 0x40 +#define MAX77663_SD1_VOLT_MAX_HEX 0X4C +#define MAX77663_SD_VOLT_MAX_HEX 0XFF +#define MAX77663_SD_VOLT_MIN_HEX 0x02 + +#define MAX77663_SD0_VOLT_MAX 1400000 +#define MAX77663_SD1_VOLT_MAX 1550000 +#define MAX77663_SD_VOLT_MAX 3787500 +#define MAX77663_SD_VOLT_MIN 625000 + +#define MAX77663_SD_VOLT_BASE 600000 + +#define MAX77663_LDO_STATUS_MASK 0xC0 +#define MAX77663_LDO_VOLT_MASK 0x3F +#define MAX77663_LDO_VOLT_MAX_HEX 0x3F + +#define MAX77663_LDO01_VOLT_MAX 2375000 +#define MAX77663_LDO4_VOLT_MAX 1587500 +#define MAX77663_LDO_VOLT_MAX 3950000 + +#define MAX77663_LDO_VOLT_BASE 800000 + +#endif /* _MAX77663_H_ */

The driver provides regulator set/get voltage enable/disable functions for MAXIM MAX77663 PMICs.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/max77663_regulator.c | 362 +++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100644 drivers/power/regulator/max77663_regulator.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index eb5aa38c1c..571debd54e 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -141,6 +141,14 @@ 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 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..80501d2792 --- /dev/null +++ b/drivers/power/regulator/max77663_regulator.c @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#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 ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + if (ret & MAX77663_SD_STATUS_MASK) + *enable = true; + else + *enable = false; + + return 0; + } else if (op == PMIC_OP_SET) { + ret &= ~(MAX77663_SD_STATUS_MASK); + + if (*enable) + ret |= MAX77663_SD_STATUS_MASK; + + ret = pmic_reg_write(dev->parent, adr, ret); + if (ret) + return ret; + } + + return 0; +} + +static int max77663_sd_volt2hex(int sd, int uV) +{ + switch (sd) { + case 0: + /* SD0 has max voltage 1.4V */ + if (uV > MAX77663_SD0_VOLT_MAX) + return -EINVAL; + break; + case 1: + /* SD1 has max voltage 1.55V */ + if (uV > MAX77663_SD1_VOLT_MAX) + return -EINVAL; + break; + default: + /* SD2 and SD3 have max voltage 3.79V */ + if (uV > MAX77663_SD_VOLT_MAX) + return -EINVAL; + break; + }; + + if (uV < MAX77663_SD_VOLT_MIN) + uV = MAX77663_SD_VOLT_MIN; + + return (uV - MAX77663_SD_VOLT_BASE) / 12500; +} + +static int max77663_sd_hex2volt(int sd, int hex) +{ + switch (sd) { + case 0: + /* SD0 has max voltage 1.4V */ + if (hex > MAX77663_SD0_VOLT_MAX_HEX) + return -EINVAL; + break; + case 1: + /* SD1 has max voltage 1.55V */ + if (hex > MAX77663_SD1_VOLT_MAX_HEX) + return -EINVAL; + break; + default: + /* SD2 and SD3 have max voltage 3.79V */ + if (hex > MAX77663_SD_VOLT_MAX_HEX) + return -EINVAL; + break; + }; + + if (hex < MAX77663_SD_VOLT_MIN_HEX) + hex = MAX77663_SD_VOLT_MIN_HEX; + + return MAX77663_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 id = dev->driver_data; + int ret; + + if (op == PMIC_OP_GET) { + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + *uV = 0; + + ret = max77663_sd_hex2volt(id, ret); + if (ret < 0) + return ret; + *uV = ret; + + return 0; + } + + /* SD regulators use entire register for voltage */ + ret = max77663_sd_volt2hex(id, *uV); + if (ret < 0) + return ret; + + return pmic_reg_write(dev->parent, adr, ret); +} + +static int max77663_sd_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_BUCK; + uc_pdata->ctrl_reg = max77663_sd_reg[0][dev->driver_data]; + uc_pdata->volt_reg = max77663_sd_reg[1][dev->driver_data]; + + regulator_autoset(dev); + + 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 ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + if (ret & MAX77663_LDO_STATUS_MASK) + *enable = true; + else + *enable = false; + + return 0; + } else if (op == PMIC_OP_SET) { + ret &= ~(MAX77663_LDO_STATUS_MASK); + + if (*enable) + ret |= MAX77663_LDO_STATUS_MASK; + + ret = pmic_reg_write(dev->parent, adr, ret); + if (ret) + return ret; + } + + return 0; +} + +static int max77663_ldo_volt2hex(int ldo, int uV) +{ + switch (ldo) { + case 0: + case 1: + if (uV > MAX77663_LDO01_VOLT_MAX) + return -EINVAL; + + return (uV - MAX77663_LDO_VOLT_BASE) / 25000; + case 4: + if (uV > MAX77663_LDO4_VOLT_MAX) + return -EINVAL; + + return (uV - MAX77663_LDO_VOLT_BASE) / 12500; + default: + if (uV > MAX77663_LDO_VOLT_MAX) + return -EINVAL; + + return (uV - MAX77663_LDO_VOLT_BASE) / 50000; + }; +} + +static int max77663_ldo_hex2volt(int ldo, int hex) +{ + if (hex > MAX77663_LDO_VOLT_MAX_HEX) + return -EINVAL; + + switch (ldo) { + case 0: + case 1: + return (hex * 25000) + MAX77663_LDO_VOLT_BASE; + case 4: + return (hex * 12500) + MAX77663_LDO_VOLT_BASE; + default: + return (hex * 50000) + MAX77663_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 id = dev->driver_data; + int hex, ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + + ret = max77663_ldo_hex2volt(id, ret & MAX77663_LDO_VOLT_MASK); + if (ret < 0) + return ret; + + *uV = ret; + return 0; + } + + hex = max77663_ldo_volt2hex(id, *uV); + if (hex < 0) + return hex; + + ret &= ~(MAX77663_LDO_VOLT_MASK); + + return pmic_reg_write(dev->parent, adr, ret | hex); +} + +static int max77663_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + uc_pdata->ctrl_reg = max77663_ldo_reg[dev->driver_data]; + + regulator_autoset(dev); + + 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, +};

Add support to bind the regulators/child nodes with the pmic. Also adds the pmic i2c based read/write functions to access pmic registers.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++++++++++++++++++ drivers/power/pmic/Kconfig | 6 ++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/tps80031.c | 82 ++++++++++++++++++++++ include/power/tps80031.h | 42 +++++++++++ 5 files changed, 207 insertions(+) create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 include/power/tps80031.h
diff --git a/doc/device-tree-bindings/pmic/tps80031.txt b/doc/device-tree-bindings/pmic/tps80031.txt new file mode 100644 index 0000000000..577e6de1c1 --- /dev/null +++ b/doc/device-tree-bindings/pmic/tps80031.txt @@ -0,0 +1,76 @@ +Texas Instruments, TPS80031/TPS80032 PMIC + +This device uses two drivers: +- drivers/power/pmic/tps80031.c (for parent device) +- drivers/power/regulator/tps80031_regulator.c (for child regulators) + +This chapter describes the binding info for the PMIC driver and regulators. + +Required properties for PMIC: +- compatible: "ti,tps80031" or "ti,tps80032" +- reg: 0x48 + +With those two properties, the pmic device can be used for read/write only. +To bind each regulator, the optional regulators subnode should exists. + +Optional subnode: +- name: regulators (subnode list of each device's regulator) + +Regulators subnode contains set on supported regulators. + +Required properties: +- regulator-name: used for regulator uclass platform data '.name', + +List of supported regulator nodes names for tps80031/tps80032: +- smps1, smps2, smps3, smps4, smps5 +- ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldoln, ldousb + +SMPS5 in Linux 3.1.10 is referred as vio, but datasheet clearly names it SMPS5. + +Optional: +- regulator-min-microvolt: minimum allowed Voltage to set +- regulator-max-microvolt: minimum allowed Voltage to set +- regulator-always-on: regulator should be never disabled +- regulator-boot-on: regulator should be enabled by the bootloader + +Example: + +tps80032@48 { + compatible = "ti,tps80032"; + reg = <0x48>; + + regulators { + smps1 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + ... + + smps5 { + regulator-name = "vdd_1v8_gen"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo1 { + regulator-name = "avdd_dsi_csi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + }; + + ... + + ldousb { + regulator-name = "avdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; +}; diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index abea0fe4ed..d25fe1ce0d 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -347,6 +347,12 @@ config DM_PMIC_TPS65910 DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO pmic children.
+config DM_PMIC_TPS80031 + bool "Enable driver for Texas Instruments TPS80031/TPS80032 PMIC" + ---help--- + The TPS80031/TPS80032 are PMIC's containing several LDOs, SMPS. + This driver binds the pmic children. + config PMIC_STPMIC1 bool "Enable support for STMicroelectronics STPMIC1 PMIC" depends on DM_I2C diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 414a9d8225..55ee614364 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_$(SPL_)PMIC_RN5T567) += rn5t567.o obj-$(CONFIG_PMIC_TPS65090) += tps65090.o obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o +obj-$(CONFIG_$(SPL_)DM_PMIC_TPS80031) += tps80031.o obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o diff --git a/drivers/power/pmic/tps80031.c b/drivers/power/pmic/tps80031.c new file mode 100644 index 0000000000..b5f9370860 --- /dev/null +++ b/drivers/power/pmic/tps80031.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/tps80031.h> +#include <dm/device.h> + +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "ldo", .driver = TPS80031_LDO_DRIVER }, + { .prefix = "smps", .driver = TPS80031_SMPS_DRIVER }, + { }, +}; + +static int tps80031_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + log_err("write error to device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int tps80031_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + log_err("read error from device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int tps80031_bind(struct udevice *dev) +{ + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + log_err("%s regulators subnode not found!\n", dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + log_err("%s - no child found\n", dev->name); + + /* Always return success for this device */ + return 0; +} + +static struct dm_pmic_ops tps80031_ops = { + .read = tps80031_read, + .write = tps80031_write, +}; + +static const struct udevice_id tps80031_ids[] = { + { .compatible = "ti,tps80031" }, + { .compatible = "ti,tps80032" }, + { } +}; + +U_BOOT_DRIVER(pmic_tps80031) = { + .name = "tps80031_pmic", + .id = UCLASS_PMIC, + .of_match = tps80031_ids, + .bind = tps80031_bind, + .ops = &tps80031_ops, +}; diff --git a/include/power/tps80031.h b/include/power/tps80031.h new file mode 100644 index 0000000000..f514db910b --- /dev/null +++ b/include/power/tps80031.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#ifndef _TPS80031_H_ +#define _TPS80031_H_ + +#define TPS80031_LDO_NUM 9 +#define TPS80031_SMPS_NUM 5 + +/* Drivers name */ +#define TPS80031_LDO_DRIVER "tps80031_ldo" +#define TPS80031_SMPS_DRIVER "tps80031_smps" + +#define TPS80031_SMPS_OFFSET 0xE0 +#define TPS80031_OFFSET_FLAG BIT(3) + +#define TPS80031_REGULATOR_STATUS_MASK 0x3 +#define TPS80031_REGULATOR_MODE_ON 0x1 + +#define TPS80031_SMPS_VOLT_MASK 0x3F +#define TPS80031_SMPS_VOLT_MAX_HEX 0x39 +#define TPS80031_SMPS_VOLT_MAX 1400000 +#define TPS80031_SMPS_VOLT_BASE 600000 +#define TPS80031_SMPS_VOLT_BASE_OFFSET 700000 + +#define TPS80031_LDO_VOLT_MASK 0x3F +#define TPS80031_LDO_VOLT_MAX_HEX 0x18 +#define TPS80031_LDO_VOLT_MIN_HEX 0x01 +#define TPS80031_LDO_VOLT_MAX 3360000 +#define TPS80031_LDO_VOLT_MIN 1018000 +#define TPS80031_LDO_VOLT_BASE 916000 + +/* register groups */ +enum { + CTRL, + VOLT, + OFFSET, +}; + +#endif /* _TPS80031_H_ */

The driver provides regulator set/get voltage enable/disable functions for TI TPS80031/TPS80032 PMICs.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 drivers/power/regulator/tps80031_regulator.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 571debd54e..f297e408cd 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -355,6 +355,14 @@ config DM_REGULATOR_TPS62360 implements the get/set api for value only, as the power line is always on.
+config DM_REGULATOR_TPS80031 + bool "Enable driver for TPS80031/TPS80032 PMIC regulators" + depends on DM_PMIC_TPS80031 + ---help--- + This enables implementation of driver-model regulator uclass + features for TPS80031/TPS80032 PMICs. The driver implements + get/set api for: value and enable. + config DM_REGULATOR_STPMIC1 bool "Enable driver for STPMIC1 regulators" depends on DM_REGULATOR && PMIC_STPMIC1 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 8d73169b50..3ef55dc534 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o +obj-$(CONFIG_$(SPL_)DM_REGULATOR_TPS80031) += tps80031_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o obj-$(CONFIG_DM_REGULATOR_SCMI) += scmi_regulator.o diff --git a/drivers/power/regulator/tps80031_regulator.c b/drivers/power/regulator/tps80031_regulator.c new file mode 100644 index 0000000000..c970f5a92d --- /dev/null +++ b/drivers/power/regulator/tps80031_regulator.c @@ -0,0 +1,296 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/tps80031.h> + +static const char tps80031_smps_reg[][TPS80031_SMPS_NUM] = { + { 0x54, 0x5a, 0x66, 0x42, 0x48 }, + { 0x56, 0x5c, 0x68, 0x44, 0x4a }, + { BIT(3), BIT(4), BIT(6), BIT(0), BIT(1) }, +}; + +static const char tps80031_ldo_reg[][TPS80031_LDO_NUM] = { + { 0x9e, 0x86, 0x8e, 0x8a, 0x9a, 0x92, 0xa6, 0x96, 0xa2 }, + { 0x9f, 0x87, 0x8f, 0x8b, 0x9b, 0x93, 0xa7, 0x97, 0xa3 }, +}; + +static int tps80031_regulator_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 ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + if (ret & TPS80031_REGULATOR_MODE_ON) + *enable = true; + else + *enable = false; + + return 0; + } else if (op == PMIC_OP_SET) { + ret &= ~(TPS80031_REGULATOR_STATUS_MASK); + + if (*enable) + ret |= TPS80031_REGULATOR_MODE_ON; + + ret = pmic_reg_write(dev->parent, adr, ret); + if (ret) + return ret; + } + + return 0; +} + +static int tps80031_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = tps80031_regulator_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + + return enable; +} + +static int tps80031_set_enable(struct udevice *dev, bool enable) +{ + return tps80031_regulator_enable(dev, PMIC_OP_SET, &enable); +} + +static int tps80031_ldo_volt2hex(int uV) +{ + if (uV > TPS80031_LDO_VOLT_MAX) + return -EINVAL; + + if (uV < TPS80031_LDO_VOLT_MIN) + uV = TPS80031_LDO_VOLT_MIN; + + return DIV_ROUND_UP(uV - TPS80031_LDO_VOLT_BASE, 102000); +} + +static int tps80031_ldo_hex2volt(int hex) +{ + if (hex > TPS80031_LDO_VOLT_MAX_HEX) + return -EINVAL; + + if (hex < TPS80031_LDO_VOLT_MIN_HEX) + hex = TPS80031_LDO_VOLT_MIN_HEX; + + return TPS80031_LDO_VOLT_BASE + hex * 102000; +} + +static int tps80031_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->volt_reg; + int hex, ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + + ret = tps80031_ldo_hex2volt(ret & TPS80031_LDO_VOLT_MASK); + if (ret < 0) + return ret; + + *uV = ret; + return 0; + } + + hex = tps80031_ldo_volt2hex(*uV); + if (hex < 0) + return hex; + + ret &= ~TPS80031_LDO_VOLT_MASK; + + return pmic_reg_write(dev->parent, adr, ret | hex); +} + +static int tps80031_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + + if (dev->driver_data) { + u8 idx = dev->driver_data - 1; + + uc_pdata->ctrl_reg = tps80031_ldo_reg[CTRL][idx]; + uc_pdata->volt_reg = tps80031_ldo_reg[VOLT][idx]; + } else { + /* check for ldoln and ldousb cases */ + if (!strcmp("ldoln", dev->name)) { + uc_pdata->ctrl_reg = tps80031_ldo_reg[CTRL][7]; + uc_pdata->volt_reg = tps80031_ldo_reg[VOLT][7]; + } else if (!strcmp("ldousb", dev->name)) { + uc_pdata->ctrl_reg = tps80031_ldo_reg[CTRL][8]; + uc_pdata->volt_reg = tps80031_ldo_reg[VOLT][8]; + } + } + + regulator_autoset(dev); + + return 0; +} + +static int ldo_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = tps80031_ldo_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int ldo_set_value(struct udevice *dev, int uV) +{ + return tps80031_ldo_val(dev, PMIC_OP_SET, &uV); +} + +static const struct dm_regulator_ops tps80031_ldo_ops = { + .get_value = ldo_get_value, + .set_value = ldo_set_value, + .get_enable = tps80031_get_enable, + .set_enable = tps80031_set_enable, +}; + +U_BOOT_DRIVER(tps80031_ldo) = { + .name = TPS80031_LDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &tps80031_ldo_ops, + .probe = tps80031_ldo_probe, +}; + +static int tps80031_smps_volt2hex(u32 base, int uV) +{ + if (uV > TPS80031_LDO_VOLT_MAX) + return -EINVAL; + + if (uV < base) + return 1; + + return DIV_ROUND_UP(uV - base, 12500); +} + +static int tps80031_smps_hex2volt(u32 base, int hex) +{ + if (hex > TPS80031_LDO_VOLT_MAX_HEX) + return -EINVAL; + + if (!hex) + return 0; + + return base + hex * 12500; +} + +static int tps80031_smps_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 base, hex, ret; + + /* If offset flag was set then base voltage is higher */ + if (uc_pdata->flags & TPS80031_OFFSET_FLAG) + base = TPS80031_SMPS_VOLT_BASE_OFFSET; + else + base = TPS80031_SMPS_VOLT_BASE; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + + ret = tps80031_smps_hex2volt(base, ret & TPS80031_SMPS_VOLT_MASK); + if (ret < 0) + return ret; + + *uV = ret; + return 0; + } + + hex = tps80031_smps_volt2hex(base, *uV); + if (hex < 0) + return hex; + + ret &= ~TPS80031_SMPS_VOLT_MASK; + + return pmic_reg_write(dev->parent, adr, ret | hex); +} + +static int tps80031_smps_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + int idx = dev->driver_data - 1; + int ret; + + uc_pdata->type = REGULATOR_TYPE_BUCK; + + uc_pdata->ctrl_reg = tps80031_smps_reg[CTRL][idx]; + uc_pdata->volt_reg = tps80031_smps_reg[VOLT][idx]; + + /* Determine if smps regulator uses higher voltage */ + ret = pmic_reg_read(dev->parent, TPS80031_SMPS_OFFSET); + if (ret & tps80031_smps_reg[OFFSET][idx]) + uc_pdata->flags |= TPS80031_OFFSET_FLAG; + + regulator_autoset(dev); + + return 0; +} + +static int smps_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = tps80031_smps_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int smps_set_value(struct udevice *dev, int uV) +{ + return tps80031_smps_val(dev, PMIC_OP_SET, &uV); +} + +static const struct dm_regulator_ops tps80031_smps_ops = { + .get_value = smps_get_value, + .set_value = smps_set_value, + .get_enable = tps80031_get_enable, + .set_enable = tps80031_set_enable, +}; + +U_BOOT_DRIVER(tps80031_smps) = { + .name = TPS80031_SMPS_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &tps80031_smps_ops, + .probe = tps80031_smps_probe, +};

Add support to bind the regulators/child nodes with the pmic. Also adds the pmic i2c based read/write functions to access pmic registers.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++++++++++++++++++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +++++++- include/power/tps65910_pmic.h | 47 +++++++++++++ 3 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt
diff --git a/doc/device-tree-bindings/pmic/tps65911.txt b/doc/device-tree-bindings/pmic/tps65911.txt new file mode 100644 index 0000000000..29270efbfe --- /dev/null +++ b/doc/device-tree-bindings/pmic/tps65911.txt @@ -0,0 +1,78 @@ +Texas Instruments, TPS65911 PMIC + +This device uses two drivers: +- drivers/power/pmic/tps65910.c (for parent device) +- drivers/power/regulator/tps65911_regulator.c (for child regulators) + +This chapter describes the binding info for the PMIC driver and regulators. + +Required properties for PMIC: +- compatible: "ti,tps65911" +- reg: 0x2d + +With those two properties, the pmic device can be used for read/write only. +To bind each regulator, the optional regulators subnode should exists. + +Optional subnode: +- name: regulators (subnode list of each device's regulator) + +Regulators subnode contains set on supported regulators. + +Required properties: +- regulator-name: used for regulator uclass platform data '.name', + +List of supported regulator nodes names for tps65911: +- vdd1, vdd2, vddctrl, vddio +- ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8 + +vddio in datasheet is referred as vio, but for reduction of code and +unification of smps regulators it is named vddio. + +Optional: +- regulator-min-microvolt: minimum allowed Voltage to set +- regulator-max-microvolt: minimum allowed Voltage to set +- regulator-always-on: regulator should be never disabled +- regulator-boot-on: regulator should be enabled by the bootloader + +Example: + +tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + regulators { + vdd1 { + regulator-name = "vdd_1v2_backlight"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + }; + + ... + + vddio { + regulator-name = "vdd_1v8_gen"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + ... + + ldo8 { + regulator-name = "vdd_ddr_hs"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + }; +}; diff --git a/drivers/power/pmic/pmic_tps65910_dm.c b/drivers/power/pmic/pmic_tps65910_dm.c index e03ddc98d7..fb72344ee0 100644 --- a/drivers/power/pmic/pmic_tps65910_dm.c +++ b/drivers/power/pmic/pmic_tps65910_dm.c @@ -11,13 +11,19 @@ #include <power/regulator.h> #include <power/tps65910_pmic.h>
-static const struct pmic_child_info pmic_children_info[] = { +static const struct pmic_child_info tps65910_children_info[] = { { .prefix = "ldo_", .driver = TPS65910_LDO_DRIVER }, { .prefix = "buck_", .driver = TPS65910_BUCK_DRIVER }, { .prefix = "boost_", .driver = TPS65910_BOOST_DRIVER }, { }, };
+static const struct pmic_child_info tps65911_children_info[] = { + { .prefix = "vdd", .driver = TPS65911_VDD_DRIVER }, + { .prefix = "ldo", .driver = TPS65911_LDO_DRIVER }, + { }, +}; + static int pmic_tps65910_reg_count(struct udevice *dev) { return TPS65910_NUM_REGS; @@ -51,6 +57,7 @@ static int pmic_tps65910_bind(struct udevice *dev) { ofnode regulators_node; int children; + int type = dev_get_driver_data(dev);
regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { @@ -58,7 +65,19 @@ static int pmic_tps65910_bind(struct udevice *dev) return -EINVAL; }
- children = pmic_bind_children(dev, regulators_node, pmic_children_info); + switch (type) { + case TPS65910: + children = pmic_bind_children(dev, regulators_node, + tps65910_children_info); + break; + case TPS65911: + children = pmic_bind_children(dev, regulators_node, + tps65911_children_info); + break; + default: + log_err("unknown PMIC type\n"); + } + if (!children) debug("%s has no children (regulators)\n", dev->name);
@@ -82,7 +101,8 @@ static struct dm_pmic_ops pmic_tps65910_ops = { };
static const struct udevice_id pmic_tps65910_match[] = { - { .compatible = "ti,tps65910" }, + { .compatible = "ti,tps65910", .data = TPS65910 }, + { .compatible = "ti,tps65911", .data = TPS65911 }, { /* sentinel */ } };
diff --git a/include/power/tps65910_pmic.h b/include/power/tps65910_pmic.h index 66214786d3..10fe02b81a 100644 --- a/include/power/tps65910_pmic.h +++ b/include/power/tps65910_pmic.h @@ -6,6 +6,9 @@ #ifndef __TPS65910_PMIC_H_ #define __TPS65910_PMIC_H_
+#define TPS65910 1 +#define TPS65911 2 + #define TPS65910_I2C_SEL_MASK (0x1 << 4) #define TPS65910_VDD_SR_MASK (0x1 << 7) #define TPS65910_GAIN_SEL_MASK (0x3 << 6) @@ -126,4 +129,48 @@ struct tps65910_regulator_pdata { #define TPS65910_BOOST_DRIVER "tps65910_boost" #define TPS65910_LDO_DRIVER "tps65910_ldo"
+/* tps65911 i2c registers */ +enum { + TPS65911_REG_VIO = 0x20, + TPS65911_REG_VDD1, + TPS65911_REG_VDD1_OP, + TPS65911_REG_VDD1_SR, + TPS65911_REG_VDD2, + TPS65911_REG_VDD2_OP, + TPS65911_REG_VDD2_SR, + TPS65911_REG_VDDCTRL, + TPS65911_REG_VDDCTRL_OP, + TPS65911_REG_VDDCTRL_SR, + TPS65911_REG_LDO1 = 0x30, + TPS65911_REG_LDO2, + TPS65911_REG_LDO5, + TPS65911_REG_LDO8, + TPS65911_REG_LDO7, + TPS65911_REG_LDO6, + TPS65911_REG_LDO4, + TPS65911_REG_LDO3, +}; + +#define TPS65911_VDD_NUM 4 +#define TPS65911_LDO_NUM 8 + +#define TPS65911_VDD_VOLT_MAX 1500000 +#define TPS65911_VDD_VOLT_MIN 600000 +#define TPS65911_VDD_VOLT_BASE 562500 + +#define TPS65911_LDO_VOLT_MAX 3300000 +#define TPS65911_LDO_VOLT_BASE 800000 + +#define TPS65911_LDO_SEL_MASK (0x3f << 2) + +#define TPS65911_LDO124_VOLT_MAX_HEX 0x32 +#define TPS65911_LDO358_VOLT_MAX_HEX 0x19 +#define TPS65911_LDO358_VOLT_MIN_HEX 0x02 + +#define TPS65911_LDO124_VOLT_STEP 50000 +#define TPS65911_LDO358_VOLT_STEP 100000 + +#define TPS65911_VDD_DRIVER "tps65911_vdd" +#define TPS65911_LDO_DRIVER "tps65911_ldo" + #endif /* __TPS65910_PMIC_H_ */

The driver provides regulator set/get voltage enable/disable functions for TI TPS5911 PMIC.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ 3 files changed, 384 insertions(+) create mode 100644 drivers/power/regulator/tps65911_regulator.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index f297e408cd..3398f0fbee 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -345,6 +345,14 @@ config DM_REGULATOR_TPS65910 regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements the get/set api for value and enable.
+config DM_REGULATOR_TPS65911 + bool "Enable driver for TPS65911 PMIC regulators" + depends on DM_PMIC_TPS65910 + ---help--- + The TPS65911 PMIC provides 4 SMPSs and 8 LDOs. This driver supports all + regulator types of the TPS65911. It implements the get/set api for value + and enable. + config DM_REGULATOR_TPS62360 bool "Enable driver for TPS6236x Power Regulator" depends on DM_REGULATOR diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 3ef55dc534..c2ab1b7721 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o +obj-$(CONFIG_DM_REGULATOR_TPS65911) += tps65911_regulator.o obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_TPS80031) += tps80031_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o diff --git a/drivers/power/regulator/tps65911_regulator.c b/drivers/power/regulator/tps65911_regulator.c new file mode 100644 index 0000000000..84ae52c888 --- /dev/null +++ b/drivers/power/regulator/tps65911_regulator.c @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel clamor95@gmail.com + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/tps65910_pmic.h> + +/* fist row is control registers, second is voltage registers */ +static const char tps65911_vdd_reg[][TPS65911_VDD_NUM] = { + { TPS65911_REG_VDD1, TPS65911_REG_VDD2, + TPS65911_REG_VDDCTRL, TPS65911_REG_VIO }, + { TPS65911_REG_VDD1_OP, TPS65911_REG_VDD2_OP, + TPS65911_REG_VDDCTRL_OP, 0x00 }, +}; + +static const u32 tps65911_vio_range[] = { + 1500000, 1800000, 2500000, 3300000 +}; + +static const char tps65911_ldo_reg[TPS65911_LDO_NUM] = { + TPS65911_REG_LDO1, TPS65911_REG_LDO2, TPS65911_REG_LDO3, + TPS65911_REG_LDO4, TPS65911_REG_LDO5, TPS65911_REG_LDO6, + TPS65911_REG_LDO7, TPS65911_REG_LDO8 +}; + +static int tps65911_regulator_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 ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + if (ret & TPS65910_SUPPLY_STATE_ON) + *enable = true; + else + *enable = false; + + return 0; + } else if (op == PMIC_OP_SET) { + ret &= ~(TPS65910_SUPPLY_STATE_MASK); + + if (*enable) + ret |= TPS65910_SUPPLY_STATE_ON; + + ret = pmic_reg_write(dev->parent, adr, ret); + if (ret) + return ret; + } + + return 0; +} + +static int tps65911_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = tps65911_regulator_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + + return enable; +} + +static int tps65911_set_enable(struct udevice *dev, bool enable) +{ + return tps65911_regulator_enable(dev, PMIC_OP_SET, &enable); +} + +static int tps65911_vdd_volt2hex(int uV) +{ + if (uV > TPS65911_VDD_VOLT_MAX) + return -EINVAL; + + if (uV < TPS65911_VDD_VOLT_MIN) + uV = TPS65911_VDD_VOLT_MIN; + + return (uV - TPS65911_VDD_VOLT_BASE) / 12500; +} + +static int tps65911_vdd_hex2volt(int hex) +{ + if (hex > TPS65910_VDD_SEL_MAX) + return -EINVAL; + + if (hex < TPS65910_VDD_SEL_MIN) + hex = TPS65910_VDD_SEL_MIN; + + return TPS65911_VDD_VOLT_BASE + hex * 12500; +} + +static int tps65911_vio_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 ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + + ret |= TPS65910_SEL_MASK; + + *uV = tps65911_vio_range[ret >> 2]; + + return 0; + } + + /* vio has only 4 voltages available */ + switch (*uV) { + case 1500000: + ret = 0x00; + break; + case 1800000: + ret = 0x01; + break; + case 2500000: + ret = 0x02; + break; + case 3300000: + ret = 0x03; + break; + default: + return -EINVAL; + }; + + return pmic_reg_write(dev->parent, adr, ret); +} + +static int tps65911_vdd_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 ret; + + /* in case vdd is vio */ + if (!adr) + return tps65911_vio_val(dev, op, uV); + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + + ret = tps65911_vdd_hex2volt(ret); + if (ret < 0) + return ret; + + *uV = ret; + return 0; + } + + ret = tps65911_vdd_volt2hex(*uV); + if (ret < 0) + return ret; + + return pmic_reg_write(dev->parent, adr, ret); +} + +static int tps65911_vdd_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_BUCK; + + if (dev->driver_data) { + u8 idx = dev->driver_data - 1; + + uc_pdata->ctrl_reg = tps65911_vdd_reg[0][idx]; + uc_pdata->volt_reg = tps65911_vdd_reg[1][idx]; + } else { + /* check for vddctrl and vddio cases */ + if (!strcmp("vddctrl", dev->name)) { + uc_pdata->ctrl_reg = tps65911_vdd_reg[0][2]; + uc_pdata->volt_reg = tps65911_vdd_reg[1][2]; + } else if (!strcmp("vddio", dev->name)) { + uc_pdata->ctrl_reg = tps65911_vdd_reg[0][3]; + uc_pdata->volt_reg = tps65911_vdd_reg[1][3]; + } + } + + regulator_autoset(dev); + + return 0; +} + +static int vdd_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = tps65911_vdd_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int vdd_set_value(struct udevice *dev, int uV) +{ + return tps65911_vdd_val(dev, PMIC_OP_SET, &uV); +} + +static const struct dm_regulator_ops tps65911_vdd_ops = { + .get_value = vdd_get_value, + .set_value = vdd_set_value, + .get_enable = tps65911_get_enable, + .set_enable = tps65911_set_enable, +}; + +U_BOOT_DRIVER(tps65911_vdd) = { + .name = TPS65911_VDD_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &tps65911_vdd_ops, + .probe = tps65911_vdd_probe, +}; + +static int tps65911_ldo_volt2hex(int id, int uV) +{ + int step; + + if (uV > TPS65911_LDO_VOLT_MAX) + return -EINVAL; + + if (uV < TPS65911_LDO_VOLT_BASE) + uV = TPS65911_LDO_VOLT_BASE; + + switch (id) { + case 1: + case 2: + case 4: + step = TPS65911_LDO124_VOLT_STEP; + break; + case 3: + case 5: + case 6: + case 7: + case 8: + step = TPS65911_LDO358_VOLT_STEP; + break; + default: + return -EINVAL; + }; + + return ((uV - TPS65911_LDO_VOLT_BASE) / step) << 2; +} + +static int tps65911_ldo_hex2volt(int id, int hex) +{ + int step; + + switch (id) { + case 1: + case 2: + case 4: + if (hex > TPS65911_LDO124_VOLT_MAX_HEX) + return -EINVAL; + + step = TPS65911_LDO124_VOLT_STEP; + break; + case 3: + case 5: + case 6: + case 7: + case 8: + if (hex > TPS65911_LDO358_VOLT_MAX_HEX) + return -EINVAL; + + if (hex < TPS65911_LDO358_VOLT_MIN_HEX) + hex = TPS65911_LDO358_VOLT_MIN_HEX; + + step = TPS65911_LDO358_VOLT_STEP; + break; + default: + return -EINVAL; + }; + + return TPS65911_LDO_VOLT_BASE + hex * step; +} + +static int tps65911_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 id = dev->driver_data; + int hex, ret; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = 0; + ret &= TPS65911_LDO_SEL_MASK; + + ret = tps65911_ldo_hex2volt(id, ret >> 2); + if (ret < 0) + return ret; + + *uV = ret; + return 0; + } + + hex = tps65911_ldo_volt2hex(id, *uV); + if (hex < 0) + return hex; + + ret &= ~(TPS65911_LDO_SEL_MASK); + + return pmic_reg_write(dev->parent, adr, ret | hex); +} + +static int tps65911_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + u8 idx = dev->driver_data - 1; + + uc_pdata->type = REGULATOR_TYPE_LDO; + uc_pdata->ctrl_reg = tps65911_ldo_reg[idx]; + + regulator_autoset(dev); + + return 0; +} + +static int ldo_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = tps65911_ldo_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int ldo_set_value(struct udevice *dev, int uV) +{ + return tps65911_ldo_val(dev, PMIC_OP_SET, &uV); +} + +static const struct dm_regulator_ops tps65911_ldo_ops = { + .get_value = ldo_get_value, + .set_value = ldo_set_value, + .get_enable = tps65911_get_enable, + .set_enable = tps65911_set_enable, +}; + +U_BOOT_DRIVER(tps65911_ldo) = { + .name = TPS65911_LDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &tps65911_ldo_ops, + .probe = tps65911_ldo_probe, +};

Greetings!
I have one more improvement for these drivers which is implementation of do_poweroff ability directly into them. I have tested it already and it is a trivial task. What is non trivial is that pmic can be not responsible for poweroff if the device uses 2 or more pmics.
Solution I am looking into is use of 'system-power-controller' device tree property to indicate PMIC used for poweroff function. Issue I have encountered is how to properly convert dts prop into #ifdef to be able to hide or expose do_poweroff at will, and if this is allowed at all in u-boot.
Best regards, Svyatoslav R.
пт, 14 лип. 2023 р. о 19:16 Svyatoslav Ryhel clamor95@gmail.com пише:
Patch set adds basic support for PMICs used in many Tegra 3 devices. All PMIC drivers are based on datasheets provided by vendors. Implemented API include regulator set/get voltage enable/disable and basic PMIC r/w capabilities.
Drivers were tested by me on LG P895 (max77663), HTC One X (TPS80032) and ASUS TF300T (tps65911). Calculations and behavior were correct, predictable and reproducible.
Svyatoslav Ryhel (6): power: pmic: add the base max77663 pmic support power: regulator: max77663: add regulator support power: pmic: add the base TPS80031 PMIC support power: regulator: tps80031: add regulator support power: pmic: tps65910: add TPS65911 PMIC support power: regulator: tps65911: add regulator support
doc/device-tree-bindings/pmic/max77663.txt | 84 +++++ doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++ doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++ drivers/power/pmic/Kconfig | 12 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77663.c | 81 ++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +- drivers/power/pmic/tps80031.c | 82 ++++ drivers/power/regulator/Kconfig | 24 ++ drivers/power/regulator/Makefile | 3 + drivers/power/regulator/max77663_regulator.c | 362 ++++++++++++++++++ drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++ include/power/max77663.h | 40 ++ include/power/tps65910_pmic.h | 47 +++ include/power/tps80031.h | 42 +++ 16 files changed, 1627 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 drivers/power/regulator/max77663_regulator.c create mode 100644 drivers/power/regulator/tps65911_regulator.c create mode 100644 drivers/power/regulator/tps80031_regulator.c create mode 100644 include/power/max77663.h create mode 100644 include/power/tps80031.h
-- 2.39.2

Hi
-----Original Message----- From: Svyatoslav Ryhel clamor95@gmail.com Sent: Saturday, July 15, 2023 1:16 AM To: Jaehoon Chung jh80.chung@samsung.com; Simon Glass sjg@chromium.org; Svyatoslav Ryhel clamor95@gmail.com Cc: u-boot@lists.denx.de Subject: [PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices
Patch set adds basic support for PMICs used in many Tegra 3 devices. All PMIC drivers are based on datasheets provided by vendors. Implemented API include regulator set/get voltage enable/disable and basic PMIC r/w capabilities.
Drivers were tested by me on LG P895 (max77663), HTC One X (TPS80032) and ASUS TF300T (tps65911). Calculations and behavior were correct, predictable and reproducible.
I didn't find where those drivers is using. Do you have any plan to update the enabling CONFIG? I hope the enabling CONFIG will be included. Otherwise, I can't check whether its building is fine or not. If I missed some patches, let me know, plz
Until enabled CONFIG, these drivers can be dead codes.
Best Regards, Jaehoon Chung
Svyatoslav Ryhel (6): power: pmic: add the base max77663 pmic support power: regulator: max77663: add regulator support power: pmic: add the base TPS80031 PMIC support power: regulator: tps80031: add regulator support power: pmic: tps65910: add TPS65911 PMIC support power: regulator: tps65911: add regulator support
doc/device-tree-bindings/pmic/max77663.txt | 84 +++++ doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++ doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++ drivers/power/pmic/Kconfig | 12 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77663.c | 81 ++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +- drivers/power/pmic/tps80031.c | 82 ++++ drivers/power/regulator/Kconfig | 24 ++ drivers/power/regulator/Makefile | 3 + drivers/power/regulator/max77663_regulator.c | 362 ++++++++++++++++++ drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++ include/power/max77663.h | 40 ++ include/power/tps65910_pmic.h | 47 +++ include/power/tps80031.h | 42 +++ 16 files changed, 1627 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 drivers/power/regulator/max77663_regulator.c create mode 100644 drivers/power/regulator/tps65911_regulator.c create mode 100644 drivers/power/regulator/tps80031_regulator.c create mode 100644 include/power/max77663.h create mode 100644 include/power/tps80031.h
-- 2.39.2

20 липня 2023 р. 06:12:23 GMT+03:00, Jaehoon Chung jh80.chung@samsung.com написав(-ла):
Hi
-----Original Message----- From: Svyatoslav Ryhel clamor95@gmail.com Sent: Saturday, July 15, 2023 1:16 AM To: Jaehoon Chung jh80.chung@samsung.com; Simon Glass sjg@chromium.org; Svyatoslav Ryhel clamor95@gmail.com Cc: u-boot@lists.denx.de Subject: [PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices
Patch set adds basic support for PMICs used in many Tegra 3 devices. All PMIC drivers are based on datasheets provided by vendors. Implemented API include regulator set/get voltage enable/disable and basic PMIC r/w capabilities.
Drivers were tested by me on LG P895 (max77663), HTC One X (TPS80032) and ASUS TF300T (tps65911). Calculations and behavior were correct, predictable and reproducible.
I didn't find where those drivers is using. Do you have any plan to update the enabling CONFIG? I hope the enabling CONFIG will be included. Otherwise, I can't check whether its building is fine or not. If I missed some patches, let me know, plz
Until enabled CONFIG, these drivers can be dead codes.
Enabling configs is planned as next step of this https://patchwork.ozlabs.org/project/uboot/list/?series=361808 patchset (initial bringup of devices). Unfortunately tegra custodians are too "busy" to initiate merge of those devices.
Best Regards, Jaehoon Chung
Svyatoslav Ryhel (6): power: pmic: add the base max77663 pmic support power: regulator: max77663: add regulator support power: pmic: add the base TPS80031 PMIC support power: regulator: tps80031: add regulator support power: pmic: tps65910: add TPS65911 PMIC support power: regulator: tps65911: add regulator support
doc/device-tree-bindings/pmic/max77663.txt | 84 +++++ doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++ doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++ drivers/power/pmic/Kconfig | 12 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77663.c | 81 ++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +- drivers/power/pmic/tps80031.c | 82 ++++ drivers/power/regulator/Kconfig | 24 ++ drivers/power/regulator/Makefile | 3 + drivers/power/regulator/max77663_regulator.c | 362 ++++++++++++++++++ drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++ include/power/max77663.h | 40 ++ include/power/tps65910_pmic.h | 47 +++ include/power/tps80031.h | 42 +++ 16 files changed, 1627 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 drivers/power/regulator/max77663_regulator.c create mode 100644 drivers/power/regulator/tps65911_regulator.c create mode 100644 drivers/power/regulator/tps80031_regulator.c create mode 100644 include/power/max77663.h create mode 100644 include/power/tps80031.h
-- 2.39.2

-----Original Message----- From: Svyatoslav Ryhel clamor95@gmail.com Sent: Thursday, July 20, 2023 12:26 PM To: Jaehoon Chung jh80.chung@samsung.com; 'Simon Glass' sjg@chromium.org Cc: u-boot@lists.denx.de Subject: RE: [PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices
20 липня 2023 р. 06:12:23 GMT+03:00, Jaehoon Chung jh80.chung@samsung.com написав(-ла):
Hi
-----Original Message----- From: Svyatoslav Ryhel clamor95@gmail.com Sent: Saturday, July 15, 2023 1:16 AM To: Jaehoon Chung jh80.chung@samsung.com; Simon Glass sjg@chromium.org; Svyatoslav Ryhel clamor95@gmail.com Cc: u-boot@lists.denx.de Subject: [PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices
Patch set adds basic support for PMICs used in many Tegra 3 devices. All PMIC drivers are based on datasheets provided by vendors. Implemented API include regulator set/get voltage enable/disable and basic PMIC r/w capabilities.
Drivers were tested by me on LG P895 (max77663), HTC One X (TPS80032) and ASUS TF300T (tps65911). Calculations and behavior were correct, predictable and reproducible.
I didn't find where those drivers is using. Do you have any plan to update the enabling CONFIG? I hope the enabling CONFIG will be included. Otherwise, I can't check whether its building is fine or
not.
If I missed some patches, let me know, plz
Until enabled CONFIG, these drivers can be dead codes.
Enabling configs is planned as next step of this https://protect2.fireeye.com/v1/url?k=a8a63aa5- c92d2f85-a8a7b1ea-74fe485fb347-c1cc2b9c6f97e343&q=1&e=c08f18ed-4f66-46bb-b871- 17167bc5b502&u=https%3A%2F%2Fpatchwork.ozlabs.org%2Fproject%2Fuboot%2Flist%2F%3Fseries%3D361808 patchset (initial bringup of devices). Unfortunately tegra custodians are too "busy" to initiate merge of those devices.
Thanks for sharing information. :)
Best Regards, Jaehoon Chung
Best Regards, Jaehoon Chung
Svyatoslav Ryhel (6): power: pmic: add the base max77663 pmic support power: regulator: max77663: add regulator support power: pmic: add the base TPS80031 PMIC support power: regulator: tps80031: add regulator support power: pmic: tps65910: add TPS65911 PMIC support power: regulator: tps65911: add regulator support
doc/device-tree-bindings/pmic/max77663.txt | 84 +++++ doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++ doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++ drivers/power/pmic/Kconfig | 12 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77663.c | 81 ++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +- drivers/power/pmic/tps80031.c | 82 ++++ drivers/power/regulator/Kconfig | 24 ++ drivers/power/regulator/Makefile | 3 + drivers/power/regulator/max77663_regulator.c | 362 ++++++++++++++++++ drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++ include/power/max77663.h | 40 ++ include/power/tps65910_pmic.h | 47 +++ include/power/tps80031.h | 42 +++ 16 files changed, 1627 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 drivers/power/regulator/max77663_regulator.c create mode 100644 drivers/power/regulator/tps65911_regulator.c create mode 100644 drivers/power/regulator/tps80031_regulator.c create mode 100644 include/power/max77663.h create mode 100644 include/power/tps80031.h
-- 2.39.2

чт, 20 лип. 2023 р. о 09:17 Jaehoon Chung jh80.chung@samsung.com пише:
-----Original Message----- From: Svyatoslav Ryhel clamor95@gmail.com Sent: Thursday, July 20, 2023 12:26 PM To: Jaehoon Chung jh80.chung@samsung.com; 'Simon Glass' sjg@chromium.org Cc: u-boot@lists.denx.de Subject: RE: [PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices
20 липня 2023 р. 06:12:23 GMT+03:00, Jaehoon Chung jh80.chung@samsung.com написав(-ла):
Hi
-----Original Message----- From: Svyatoslav Ryhel clamor95@gmail.com Sent: Saturday, July 15, 2023 1:16 AM To: Jaehoon Chung jh80.chung@samsung.com; Simon Glass sjg@chromium.org; Svyatoslav Ryhel clamor95@gmail.com Cc: u-boot@lists.denx.de Subject: [PATCH v1 0/6] Add support for PMICs used on Tegra 3 devices
Patch set adds basic support for PMICs used in many Tegra 3 devices. All PMIC drivers are based on datasheets provided by vendors. Implemented API include regulator set/get voltage enable/disable and basic PMIC r/w capabilities.
Drivers were tested by me on LG P895 (max77663), HTC One X (TPS80032) and ASUS TF300T (tps65911). Calculations and behavior were correct, predictable and reproducible.
I didn't find where those drivers is using. Do you have any plan to update the enabling CONFIG? I hope the enabling CONFIG will be included. Otherwise, I can't check whether its building is fine or
not.
If I missed some patches, let me know, plz
Until enabled CONFIG, these drivers can be dead codes.
Enabling configs is planned as next step of this https://protect2.fireeye.com/v1/url?k=a8a63aa5- c92d2f85-a8a7b1ea-74fe485fb347-c1cc2b9c6f97e343&q=1&e=c08f18ed-4f66-46bb-b871- 17167bc5b502&u=https%3A%2F%2Fpatchwork.ozlabs.org%2Fproject%2Fuboot%2Flist%2F%3Fseries%3D361808 patchset (initial bringup of devices). Unfortunately tegra custodians are too "busy" to initiate merge of those devices.
Thanks for sharing information. :)
Ye, you're welcome I guess :) These mailing lists kill me. Search in patchwork for series called "Tegra: add ASUS/Google Nexus 7 (2012) support" it contains devices I have mentioned.
Best Regards, Jaehoon Chung
Best Regards, Jaehoon Chung
Svyatoslav Ryhel (6): power: pmic: add the base max77663 pmic support power: regulator: max77663: add regulator support power: pmic: add the base TPS80031 PMIC support power: regulator: tps80031: add regulator support power: pmic: tps65910: add TPS65911 PMIC support power: regulator: tps65911: add regulator support
doc/device-tree-bindings/pmic/max77663.txt | 84 +++++ doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++ doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++ drivers/power/pmic/Kconfig | 12 + drivers/power/pmic/Makefile | 2 + drivers/power/pmic/max77663.c | 81 ++++ drivers/power/pmic/pmic_tps65910_dm.c | 26 +- drivers/power/pmic/tps80031.c | 82 ++++ drivers/power/regulator/Kconfig | 24 ++ drivers/power/regulator/Makefile | 3 + drivers/power/regulator/max77663_regulator.c | 362 ++++++++++++++++++ drivers/power/regulator/tps65911_regulator.c | 375 +++++++++++++++++++ drivers/power/regulator/tps80031_regulator.c | 296 +++++++++++++++ include/power/max77663.h | 40 ++ include/power/tps65910_pmic.h | 47 +++ include/power/tps80031.h | 42 +++ 16 files changed, 1627 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/max77663.txt create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt create mode 100644 drivers/power/pmic/max77663.c create mode 100644 drivers/power/pmic/tps80031.c create mode 100644 drivers/power/regulator/max77663_regulator.c create mode 100644 drivers/power/regulator/tps65911_regulator.c create mode 100644 drivers/power/regulator/tps80031_regulator.c create mode 100644 include/power/max77663.h create mode 100644 include/power/tps80031.h
-- 2.39.2
participants (2)
-
Jaehoon Chung
-
Svyatoslav Ryhel