From ec1af5e0687ee32082f72b758c580f8c4bc00a76 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 3 Oct 2023 09:36:37 +0300 Subject: configs: transformer_t30: convert bootmenu option Convert refresh USB to enter console. Transformers have full size USB and a dock keyboard so access to U-Boot console would be handy. Signed-off-by: Svyatoslav Ryhel --- include/configs/transformer-common.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include') diff --git a/include/configs/transformer-common.h b/include/configs/transformer-common.h index dcdda1ec5b4..3b7db0ab142 100644 --- a/include/configs/transformer-common.h +++ b/include/configs/transformer-common.h @@ -64,19 +64,14 @@ "else echo SPI flash backup FAILED! Aborting ...;" \ "poweroff; fi\0" -#define TRANSFORMER_REFRESH_USB \ - "refresh_usb=usb start; usb reset; usb tree; usb info;" \ - "pause 'Press ANY key to return to bootmenu...'; bootmenu\0" - #define TRANSFORMER_BOOTMENU \ TRANSFORMER_FLASH_UBOOT \ TRANSFORMER_FLASH_SPI \ - TRANSFORMER_REFRESH_USB \ "bootmenu_0=mount internal storage=usb start && ums 0 mmc 0; bootmenu\0" \ "bootmenu_1=mount external storage=usb start && ums 0 mmc 1; bootmenu\0" \ "bootmenu_2=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu\0" \ "bootmenu_3=update bootloader=run flash_uboot\0" \ - "bootmenu_4=refresh USB=run refresh_usb\0" \ + "bootmenu_4=enter console=usb start; setenv skip_boot 1; exit\0" \ "bootmenu_5=reboot RCM=enterrcm\0" \ "bootmenu_6=reboot=reset\0" \ "bootmenu_7=power off=poweroff\0" \ -- cgit v1.3.1 From f2ed5849947f1e0dc1578a68b43af7ff928565be Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 27 Oct 2023 11:26:10 +0300 Subject: power: pmic: add the base MAX77663 PMIC support 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 Reviewed-by: Simon Glass Reviewed-by: Jaehoon Chung --- doc/device-tree-bindings/pmic/max77663.txt | 84 ++++++++++++++++++++++++++++++ drivers/power/pmic/Kconfig | 9 ++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max77663.c | 81 ++++++++++++++++++++++++++++ include/power/max77663.h | 42 +++++++++++++++ 5 files changed, 217 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 (limited to 'include') diff --git a/doc/device-tree-bindings/pmic/max77663.txt b/doc/device-tree-bindings/pmic/max77663.txt new file mode 100644 index 00000000000..ddb7d3eb143 --- /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 4a6f0ce093a..54665d7e2bf 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -184,6 +184,15 @@ 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. + This is a Power Management IC with a decent set of peripherals from which + 4 DC-to-DC Step-Down (SD) Regulators, 9 Low-Dropout Linear (LDO) Regulators, + 8 GPIOs, Real-Time Clock (RTC) and more with I2C Compatible Interface. + 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 0b3b3d62d0e..414a9d8225b 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 00000000000..fac97ed221e --- /dev/null +++ b/drivers/power/pmic/max77663.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include + +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) +{ + int ret; + + ret = dm_i2c_write(dev, reg, buff, len); + if (ret) { + log_debug("write error to device: %p register: %#x!\n", dev, reg); + return ret; + } + + return 0; +} + +static int max77663_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + int ret; + + ret = dm_i2c_read(dev, reg, buff, len); + if (ret) { + log_debug("read error from device: %p register: %#x!\n", dev, reg); + return ret; + } + + 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 00000000000..0f764bcbcc0 --- /dev/null +++ b/include/power/max77663.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#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" + +/* Step-Down (SD) Regulator calculations */ +#define SD_STATUS_MASK 0x30 + +#define SD0_VOLT_MAX_HEX 0x40 +#define SD1_VOLT_MAX_HEX 0x4c +#define SD_VOLT_MAX_HEX 0xff +#define SD_VOLT_MIN_HEX 0x02 + +#define SD0_VOLT_MAX 1400000 +#define SD1_VOLT_MAX 1550000 +#define SD_VOLT_MAX 3787500 +#define SD_VOLT_MIN 625000 + +#define SD_VOLT_BASE 600000 + +/* Low-Dropout Linear (LDO) Regulator calculations */ +#define LDO_STATUS_MASK 0xc0 +#define LDO_VOLT_MASK 0x3f +#define LDO_VOLT_MAX_HEX 0x3f + +#define LDO01_VOLT_MAX 2375000 +#define LDO4_VOLT_MAX 1587500 +#define LDO_VOLT_MAX 3950000 + +#define LDO_VOLT_BASE 800000 + +#endif /* _MAX77663_H_ */ -- cgit v1.3.1 From 51201e49b05266fce231a0957afa3278a1e49177 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 27 Oct 2023 11:26:12 +0300 Subject: power: pmic: add the base TPS80031 PMIC support 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 Reviewed-by: Simon Glass --- doc/device-tree-bindings/pmic/tps80031.txt | 76 +++++++++++++++++++++++++++ drivers/power/pmic/Kconfig | 11 ++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/tps80031.c | 82 ++++++++++++++++++++++++++++++ include/power/tps80031.h | 45 ++++++++++++++++ 5 files changed, 215 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 (limited to 'include') diff --git a/doc/device-tree-bindings/pmic/tps80031.txt b/doc/device-tree-bindings/pmic/tps80031.txt new file mode 100644 index 00000000000..577e6de1c1f --- /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 54665d7e2bf..454a6e0cf87 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -351,6 +351,17 @@ 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--- + This config enables implementation of driver-model pmic uclass features + for TPS80031/TPS80032 PMICs. The driver implements read/write operations. + This is a Power Management IC with a decent set of peripherals from which + 5 Buck Converters refered as Switched-mode power supply (SMPS), 11 General- + Purpose Low-Dropout Voltage Regulators (LDO), USB OTG Module, Real-Time + Clock (RTC) with Timer and Alarm Wake-Up, Two Digital PWM Outputs and more + with I2C Compatible Interface. PMIC occupies 4 I2C addresses. + 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 414a9d8225b..55ee614364b 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 00000000000..6b36ebbf7db --- /dev/null +++ b/drivers/power/pmic/tps80031.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include + +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) +{ + int ret; + + ret = dm_i2c_write(dev, reg, buff, len); + if (ret) { + log_debug("write error to device: %p register: %#x!\n", dev, reg); + return ret; + } + + return 0; +} + +static int tps80031_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + int ret; + + ret = dm_i2c_read(dev, reg, buff, len); + if (ret) { + log_debug("read error from device: %p register: %#x!\n", dev, reg); + return ret; + } + + 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 00000000000..c80692a8af6 --- /dev/null +++ b/include/power/tps80031.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#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(0) + +#define REGULATOR_STATUS_MASK 0x3 +#define REGULATOR_MODE_ON 0x1 + +/* Switched-Mode Power Supply Regulator calculations */ +#define SMPS_VOLT_MASK 0x3f +#define SMPS_VOLT_LINEAR_HEX 0x39 +#define SMPS_VOLT_NLINEAR_HEX 0x3a +#define SMPS_VOLT_LINEAR 1300000 +#define SMPS_VOLT_BASE 600000 +#define SMPS_VOLT_BASE_OFFSET 700000 + +/* Low-Dropout Linear (LDO) Regulator calculations */ +#define LDO_VOLT_MASK 0x3f +#define LDO_VOLT_MAX_HEX 0x18 +#define LDO_VOLT_MIN_HEX 0x01 +#define LDO_VOLT_MAX 3360000 +#define LDO_VOLT_MIN 1018000 +#define LDO_VOLT_BASE 916000 + +/* register groups */ +enum { + CTRL, + VOLT, + OFFSET, +}; + +#endif /* _TPS80031_H_ */ -- cgit v1.3.1 From 8e5c9c5affe948d4f35501d5d7b2fa2c46483404 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 27 Oct 2023 11:26:14 +0300 Subject: power: pmic: tps65910: add TPS65911 PMIC support 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 Reviewed-by: Simon Glass --- doc/device-tree-bindings/pmic/tps65911.txt | 78 ++++++++++++++++++++++++++++++ drivers/power/pmic/pmic_tps65910_dm.c | 15 ++++-- include/power/tps65910_pmic.h | 44 +++++++++++++++++ 3 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 doc/device-tree-bindings/pmic/tps65911.txt (limited to 'include') diff --git a/doc/device-tree-bindings/pmic/tps65911.txt b/doc/device-tree-bindings/pmic/tps65911.txt new file mode 100644 index 00000000000..29270efbfe0 --- /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 8ead1db802a..0a4911cef61 100644 --- a/drivers/power/pmic/pmic_tps65910_dm.c +++ b/drivers/power/pmic/pmic_tps65910_dm.c @@ -12,13 +12,19 @@ #include #include -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 = "ldo", .driver = TPS65911_LDO_DRIVER }, + { .prefix = "vdd", .driver = TPS65911_VDD_DRIVER }, + { }, +}; + static int pmic_tps65910_reg_count(struct udevice *dev) { return TPS65910_NUM_REGS; @@ -50,6 +56,8 @@ static int pmic_tps65910_read(struct udevice *dev, uint reg, u8 *buffer, static int pmic_tps65910_bind(struct udevice *dev) { + const struct pmic_child_info *tps6591x_children_info = + (struct pmic_child_info *)dev_get_driver_data(dev); ofnode regulators_node; int children; @@ -59,7 +67,7 @@ static int pmic_tps65910_bind(struct udevice *dev) return -EINVAL; } - children = pmic_bind_children(dev, regulators_node, pmic_children_info); + children = pmic_bind_children(dev, regulators_node, tps6591x_children_info); if (!children) debug("%s has no children (regulators)\n", dev->name); @@ -83,7 +91,8 @@ static struct dm_pmic_ops pmic_tps65910_ops = { }; static const struct udevice_id pmic_tps65910_match[] = { - { .compatible = "ti,tps65910" }, + { .compatible = "ti,tps65910", .data = (ulong)&tps65910_children_info }, + { .compatible = "ti,tps65911", .data = (ulong)&tps65911_children_info }, { /* sentinel */ } }; diff --git a/include/power/tps65910_pmic.h b/include/power/tps65910_pmic.h index 66214786d3e..7d6545abdf0 100644 --- a/include/power/tps65910_pmic.h +++ b/include/power/tps65910_pmic.h @@ -126,4 +126,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_ */ -- cgit v1.3.1 From fa1e72ea3d62f561fb990113ce404ad603d61e83 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 24 Oct 2023 10:49:05 +0300 Subject: sysreset: implement MAX77663 sysreset functions MAX77663 PMIC has embedded poweroff function used by some device to initiane device power off. Implement it as sysreset driver. Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/max77663.c | 11 +++++++- drivers/sysreset/Kconfig | 7 +++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_max77663.c | 52 ++++++++++++++++++++++++++++++++++++ include/power/max77663.h | 5 ++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 drivers/sysreset/sysreset_max77663.c (limited to 'include') diff --git a/drivers/power/pmic/max77663.c b/drivers/power/pmic/max77663.c index fac97ed221e..68c3cbbc646 100644 --- a/drivers/power/pmic/max77663.c +++ b/drivers/power/pmic/max77663.c @@ -44,7 +44,16 @@ static int max77663_read(struct udevice *dev, uint reg, uint8_t *buff, int len) static int max77663_bind(struct udevice *dev) { ofnode regulators_node; - int children; + int children, ret; + + if (IS_ENABLED(CONFIG_SYSRESET_MAX77663)) { + ret = device_bind_driver(dev, MAX77663_RST_DRIVER, + "sysreset", NULL); + if (ret) { + log_err("cannot bind SYSRESET (ret = %d)\n", ret); + return ret; + } + } regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index eab556c3499..bc358961012 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -74,6 +74,13 @@ config SYSRESET_GPIO example on Microblaze where reset logic can be controlled via GPIO pin which triggers cpu reset. +config SYSRESET_MAX77663 + bool "Enable support for MAX77663 PMIC System Reset" + depends on DM_PMIC_MAX77663 + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system power management functions found in MAX77663 PMIC. + config SYSRESET_MICROBLAZE bool "Enable support for Microblaze soft reset" depends on MICROBLAZE diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index a9ac1237542..c31f51c581a 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_STI) += sysreset_sti.o obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o obj-$(CONFIG_POWEROFF_GPIO) += poweroff_gpio.o obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o +obj-$(CONFIG_$(SPL_TPL_)SYSRESET_MAX77663) += sysreset_max77663.o obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o diff --git a/drivers/sysreset/sysreset_max77663.c b/drivers/sysreset/sysreset_max77663.c new file mode 100644 index 00000000000..8febcf8de6c --- /dev/null +++ b/drivers/sysreset/sysreset_max77663.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include + +static int max77663_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + int val; + + val = pmic_reg_read(dev->parent, MAX77663_REG_ONOFF_CFG1); + if (val < 0) + return val; + + /* clear both bits */ + val &= ~ONOFF_SFT_RST; + val &= ~ONOFF_PWR_OFF; + + switch (type) { + case SYSRESET_POWER: + /* MAX77663: SFT_RST > ONOFF_CFG1 */ + pmic_reg_write(dev->parent, MAX77663_REG_ONOFF_CFG1, + val | ONOFF_SFT_RST); + break; + case SYSRESET_POWER_OFF: + /* MAX77663: PWR_OFF > ONOFF_CFG1 */ + pmic_reg_write(dev->parent, MAX77663_REG_ONOFF_CFG1, + val | ONOFF_PWR_OFF); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops max77663_sysreset = { + .request = max77663_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_max77663) = { + .id = UCLASS_SYSRESET, + .name = MAX77663_RST_DRIVER, + .ops = &max77663_sysreset, +}; diff --git a/include/power/max77663.h b/include/power/max77663.h index 0f764bcbcc0..b3ae3dabf46 100644 --- a/include/power/max77663.h +++ b/include/power/max77663.h @@ -12,6 +12,7 @@ /* Drivers name */ #define MAX77663_LDO_DRIVER "max77663_ldo" #define MAX77663_SD_DRIVER "max77663_sd" +#define MAX77663_RST_DRIVER "max77663_rst" /* Step-Down (SD) Regulator calculations */ #define SD_STATUS_MASK 0x30 @@ -39,4 +40,8 @@ #define LDO_VOLT_BASE 800000 +#define MAX77663_REG_ONOFF_CFG1 0x41 +#define ONOFF_SFT_RST BIT(7) +#define ONOFF_PWR_OFF BIT(1) + #endif /* _MAX77663_H_ */ -- cgit v1.3.1 From 9d937cdc2ce831adfef969ced5e35b72a3131dea Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 24 Oct 2023 10:49:06 +0300 Subject: sysreset: implement TPS80031 sysreset functions TPS80031/TPS80032 PMICs have embedded power control functions used by some device to initiane device power off. Implement it as sysreset driver. Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/tps80031.c | 11 +++++++++- drivers/sysreset/Kconfig | 8 ++++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_tps80031.c | 40 ++++++++++++++++++++++++++++++++++++ include/power/tps80031.h | 5 +++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 drivers/sysreset/sysreset_tps80031.c (limited to 'include') diff --git a/drivers/power/pmic/tps80031.c b/drivers/power/pmic/tps80031.c index 6b36ebbf7db..a2f935b0c6d 100644 --- a/drivers/power/pmic/tps80031.c +++ b/drivers/power/pmic/tps80031.c @@ -44,7 +44,16 @@ static int tps80031_read(struct udevice *dev, uint reg, uint8_t *buff, int len) static int tps80031_bind(struct udevice *dev) { ofnode regulators_node; - int children; + int children, ret; + + if (IS_ENABLED(CONFIG_SYSRESET_TPS80031)) { + ret = device_bind_driver(dev, TPS80031_RST_DRIVER, + "sysreset", NULL); + if (ret) { + log_err("cannot bind SYSRESET (ret = %d)\n", ret); + return ret; + } + } regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index bc358961012..cdb4ae2bb11 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -157,6 +157,14 @@ config SYSRESET_TI_SCI This enables the system reset driver support over TI System Control Interface available on some new TI's SoCs. +config SYSRESET_TPS80031 + bool "Enable support for TPS80031/TPS80032 PMIC System Reset" + depends on DM_PMIC_TPS80031 + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system power management functions found in TPS80031/TPS80032 + PMICs. + config SYSRESET_SYSCON bool "Enable support for mfd syscon reboot driver" select REGMAP diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index c31f51c581a..f62db899da7 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o obj-$(CONFIG_SYSRESET_SOCFPGA_SOC64) += sysreset_socfpga_soc64.o obj-$(CONFIG_SYSRESET_TEGRA) += sysreset_tegra.o obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o +obj-$(CONFIG_$(SPL_TPL_)SYSRESET_TPS80031) += sysreset_tps80031.o obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o obj-$(CONFIG_SYSRESET_RESETCTL) += sysreset_resetctl.o diff --git a/drivers/sysreset/sysreset_tps80031.c b/drivers/sysreset/sysreset_tps80031.c new file mode 100644 index 00000000000..50024fe4e79 --- /dev/null +++ b/drivers/sysreset/sysreset_tps80031.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include + +static int tps80031_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + switch (type) { + case SYSRESET_POWER: + /* TPS80031: SW_RESET > PHOENIX_DEV_ON */ + pmic_reg_write(dev->parent, TPS80031_PHOENIX_DEV_ON, SW_RESET); + break; + case SYSRESET_POWER_OFF: + /* TPS80031: DEVOFF > PHOENIX_DEV_ON */ + pmic_reg_write(dev->parent, TPS80031_PHOENIX_DEV_ON, DEVOFF); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops tps80031_sysreset = { + .request = tps80031_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_tps80031) = { + .id = UCLASS_SYSRESET, + .name = TPS80031_RST_DRIVER, + .ops = &tps80031_sysreset, +}; diff --git a/include/power/tps80031.h b/include/power/tps80031.h index c80692a8af6..983c841bfe3 100644 --- a/include/power/tps80031.h +++ b/include/power/tps80031.h @@ -12,6 +12,7 @@ /* Drivers name */ #define TPS80031_LDO_DRIVER "tps80031_ldo" #define TPS80031_SMPS_DRIVER "tps80031_smps" +#define TPS80031_RST_DRIVER "tps80031_rst" #define TPS80031_SMPS_OFFSET 0xe0 #define TPS80031_OFFSET_FLAG BIT(0) @@ -35,6 +36,10 @@ #define LDO_VOLT_MIN 1018000 #define LDO_VOLT_BASE 916000 +#define TPS80031_PHOENIX_DEV_ON 0x25 +#define SW_RESET BIT(6) +#define DEVOFF BIT(0) + /* register groups */ enum { CTRL, -- cgit v1.3.1 From 8b8a00eaf47719ee04338eff9cd94b0408779d9d Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 24 Oct 2023 10:49:07 +0300 Subject: sysreset: implement TPS65910 sysreset functions TPS65910/TPS65911 PMICs have embedded power control functions used by some device to initiane device power off. Implement it as sysreset driver. Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/pmic_tps65910_dm.c | 12 +++++++- drivers/sysreset/Kconfig | 8 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_tps65910.c | 54 +++++++++++++++++++++++++++++++++++ include/power/tps65910_pmic.h | 7 +++++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 drivers/sysreset/sysreset_tps65910.c (limited to 'include') diff --git a/drivers/power/pmic/pmic_tps65910_dm.c b/drivers/power/pmic/pmic_tps65910_dm.c index 0a4911cef61..ecf836eb0e6 100644 --- a/drivers/power/pmic/pmic_tps65910_dm.c +++ b/drivers/power/pmic/pmic_tps65910_dm.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -59,7 +60,16 @@ static int pmic_tps65910_bind(struct udevice *dev) const struct pmic_child_info *tps6591x_children_info = (struct pmic_child_info *)dev_get_driver_data(dev); ofnode regulators_node; - int children; + int children, ret; + + if (IS_ENABLED(CONFIG_SYSRESET_TPS65910)) { + ret = device_bind_driver(dev, TPS65910_RST_DRIVER, + "sysreset", NULL); + if (ret) { + log_err("cannot bind SYSRESET (ret = %d)\n", ret); + return ret; + } + } regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index cdb4ae2bb11..659170d1568 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -157,6 +157,14 @@ config SYSRESET_TI_SCI This enables the system reset driver support over TI System Control Interface available on some new TI's SoCs. +config SYSRESET_TPS65910 + bool "Enable support for TPS65910/TPS65911 PMIC System Reset" + depends on DM_PMIC_TPS65910 + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system power management functions found in TPS65910/TPS65911 + PMICs. + config SYSRESET_TPS80031 bool "Enable support for TPS80031/TPS80032 PMIC System Reset" depends on DM_PMIC_TPS80031 diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index f62db899da7..0d96a204a95 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o obj-$(CONFIG_SYSRESET_SOCFPGA_SOC64) += sysreset_socfpga_soc64.o obj-$(CONFIG_SYSRESET_TEGRA) += sysreset_tegra.o obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o +obj-$(CONFIG_$(SPL_TPL_)SYSRESET_TPS65910) += sysreset_tps65910.o obj-$(CONFIG_$(SPL_TPL_)SYSRESET_TPS80031) += sysreset_tps80031.o obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o diff --git a/drivers/sysreset/sysreset_tps65910.c b/drivers/sysreset/sysreset_tps65910.c new file mode 100644 index 00000000000..98da56661c0 --- /dev/null +++ b/drivers/sysreset/sysreset_tps65910.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include + +static int tps65910_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + int val; + + val = pmic_reg_read(dev->parent, TPS65910_REG_DEVICE_CTRL); + if (val < 0) + return val; + + /* define power-off to be sequential */ + val |= PWR_OFF_SEQ; + pmic_reg_write(dev->parent, TPS65910_REG_DEVICE_CTRL, val); + + val &= ~DEV_ON; + + switch (type) { + case SYSRESET_POWER: + /* TPS65910: DEV_OFF_RST > DEVICE_CTRL */ + pmic_reg_write(dev->parent, TPS65910_REG_DEVICE_CTRL, + val | DEV_OFF_RST); + break; + case SYSRESET_POWER_OFF: + /* TPS65910: DEV_OFF > DEVICE_CTRL */ + pmic_reg_write(dev->parent, TPS65910_REG_DEVICE_CTRL, + val | DEV_OFF); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops tps65910_sysreset = { + .request = tps65910_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_tps65910) = { + .id = UCLASS_SYSRESET, + .name = TPS65910_RST_DRIVER, + .ops = &tps65910_sysreset, +}; diff --git a/include/power/tps65910_pmic.h b/include/power/tps65910_pmic.h index 7d6545abdf0..2026ec2f426 100644 --- a/include/power/tps65910_pmic.h +++ b/include/power/tps65910_pmic.h @@ -17,6 +17,12 @@ #define TPS65910_SUPPLY_STATE_OFF 0x0 #define TPS65910_SUPPLY_STATE_ON 0x1 +/* TPS65910 DEVICE_CTRL bits */ +#define PWR_OFF_SEQ BIT(7) +#define DEV_OFF_RST BIT(3) +#define DEV_ON BIT(2) +#define DEV_OFF BIT(0) + /* i2c registers */ enum { TPS65910_REG_RTC_SEC = 0x00, @@ -125,6 +131,7 @@ struct tps65910_regulator_pdata { #define TPS65910_BUCK_DRIVER "tps65910_buck" #define TPS65910_BOOST_DRIVER "tps65910_boost" #define TPS65910_LDO_DRIVER "tps65910_ldo" +#define TPS65910_RST_DRIVER "tps65910_rst" /* tps65911 i2c registers */ enum { -- cgit v1.3.1 From 4afdc7a3c63d99b53676d31cc38e18de15a036f5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 24 Oct 2023 10:49:08 +0300 Subject: sysreset: implement PALMAS sysreset functions PALMAS PMIC family has embedded poweroff function used by some device to initiane device power off. Implement it as sysreset driver. Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/palmas.c | 33 ++++++++++++++++++++++-- drivers/sysreset/Kconfig | 7 +++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_palmas.c | 52 ++++++++++++++++++++++++++++++++++++++ include/power/palmas.h | 11 ++++++++ 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 drivers/sysreset/sysreset_palmas.c (limited to 'include') diff --git a/drivers/power/pmic/palmas.c b/drivers/power/pmic/palmas.c index b2e8a2930c1..32f2a938b28 100644 --- a/drivers/power/pmic/palmas.c +++ b/drivers/power/pmic/palmas.c @@ -8,13 +8,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include static const struct pmic_child_info pmic_children_info[] = { { .prefix = "ldo", .driver = PALMAS_LDO_DRIVER }, @@ -47,7 +47,16 @@ static int palmas_bind(struct udevice *dev) { ofnode pmic_node = ofnode_null(), regulators_node; ofnode subnode; - int children; + int children, ret; + + if (IS_ENABLED(CONFIG_SYSRESET_PALMAS)) { + ret = device_bind_driver(dev, PALMAS_RST_DRIVER, + "sysreset", NULL); + if (ret) { + log_err("cannot bind SYSRESET (ret = %d)\n", ret); + return ret; + } + } dev_for_each_subnode(subnode, dev) { const char *name; @@ -81,6 +90,24 @@ static int palmas_bind(struct udevice *dev) return 0; } +static int palmas_probe(struct udevice *dev) +{ + struct dm_i2c_chip *chip = dev_get_parent_plat(dev); + struct palmas_priv *priv = dev_get_priv(dev); + struct udevice *bus = dev_get_parent(dev); + u32 chip2_addr = chip->chip_addr + 1; + int ret; + + /* Palmas PMIC is multi chip and chips are located in a row */ + ret = i2c_get_chip(bus, chip2_addr, 1, &priv->chip2); + if (ret) { + log_err("cannot get second PMIC I2C chip (err %d)\n", ret); + return ret; + } + + return 0; +} + static struct dm_pmic_ops palmas_ops = { .read = palmas_read, .write = palmas_write, @@ -98,5 +125,7 @@ U_BOOT_DRIVER(pmic_palmas) = { .id = UCLASS_PMIC, .of_match = palmas_ids, .bind = palmas_bind, + .probe = palmas_probe, .ops = &palmas_ops, + .priv_auto = sizeof(struct palmas_priv), }; diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 659170d1568..0e52f996283 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -109,6 +109,13 @@ config SYSRESET_SPL_AT91 This enables the system reset driver support for Microchip/Atmel SoCs in SPL. +config SYSRESET_PALMAS + bool "Enable support for PALMAS System Reset" + depends on PMIC_PALMAS + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system power management functions found in PLAMAS PMIC family. + config SYSRESET_PSCI bool "Enable support for PSCI System Reset" depends on ARM_PSCI_FW diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index 0d96a204a95..c9f1c625aeb 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_$(SPL_TPL_)SYSRESET_MAX77663) += sysreset_max77663.o obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o +obj-$(CONFIG_$(SPL_TPL_)SYSRESET_PALMAS) += sysreset_palmas.o obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o obj-$(CONFIG_SYSRESET_SBI) += sysreset_sbi.o obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o diff --git a/drivers/sysreset/sysreset_palmas.c b/drivers/sysreset/sysreset_palmas.c new file mode 100644 index 00000000000..9e3aa403488 --- /dev/null +++ b/drivers/sysreset/sysreset_palmas.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include + +static int palmas_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + struct palmas_priv *priv = dev_get_priv(dev->parent); + int ret; + + /* + * Mask INT3 on second page which detects vbus + * or device will immediately turn on. + */ + ret = dm_i2c_reg_clrset(priv->chip2, PALMAS_INT3_MASK, + MASK_VBUS, MASK_VBUS); + if (ret < 0) + return ret; + + switch (type) { + case SYSRESET_POWER: + /* PALMAS: SW_RST > DEV_CTRL */ + pmic_reg_write(dev->parent, PALMAS_DEV_CTRL, SW_RST); + break; + case SYSRESET_POWER_OFF: + /* PALMAS: DEV_OFF > DEV_CTRL */ + pmic_reg_write(dev->parent, PALMAS_DEV_CTRL, DEV_OFF); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops palmas_sysreset = { + .request = palmas_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_palmas) = { + .id = UCLASS_SYSRESET, + .name = PALMAS_RST_DRIVER, + .ops = &palmas_sysreset, +}; diff --git a/include/power/palmas.h b/include/power/palmas.h index df5f15c5bd6..0a612052f01 100644 --- a/include/power/palmas.h +++ b/include/power/palmas.h @@ -2,6 +2,10 @@ #define TPS659038 0x1 #define TPS65917 0x2 +struct palmas_priv { + struct udevice *chip2; +}; + /* I2C device address for pmic palmas */ #define PALMAS_I2C_ADDR (0x12 >> 1) #define PALMAS_LDO_NUM 11 @@ -10,6 +14,7 @@ /* Drivers name */ #define PALMAS_LDO_DRIVER "palmas_ldo" #define PALMAS_SMPS_DRIVER "palmas_smps" +#define PALMAS_RST_DRIVER "palmas_rst" #define PALMAS_SMPS_VOLT_MASK 0x7F #define PALMAS_SMPS_RANGE_MASK 0x80 @@ -24,3 +29,9 @@ #define PALMAS_LDO_MODE_MASK 0x1 #define PALMAS_LDO_STATUS_MASK 0x10 #define PALMAS_LDO_BYPASS_EN 0x40 + +#define PALMAS_DEV_CTRL 0xA0 +#define SW_RST BIT(1) +#define DEV_OFF 0x00 +#define PALMAS_INT3_MASK 0x1B +#define MASK_VBUS BIT(7) -- cgit v1.3.1