[PATCH 1/2] power: pmic: Support pmic pf0900

From: Joy Zou joy.zou@nxp.com
Support NXP pmic pf0900
Reviewed-by: Ye Li ye.li@nxp.com Signed-off-by: Joy Zou joy.zou@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/power/pmic/Kconfig | 15 ++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pf0900.c | 174 +++++++++++++++++++++++ include/power/pf0900.h | 269 ++++++++++++++++++++++++++++++++++++ 4 files changed, 459 insertions(+) create mode 100644 drivers/power/pmic/pf0900.c create mode 100644 include/power/pf0900.h
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 562c1a3b122..1a5ef279ed6 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -171,6 +171,21 @@ config SPL_DM_PMIC_PCA9450 This config enables implementation of driver-model pmic uclass features for PMIC PCA9450 in SPL. The driver implements read/write operations.
+config DM_PMIC_PF0900 + bool "Enable Driver Model for PMIC PF0900" + depends on DM_I2C + help + This config enables implementation of driver-model pmic uclass features + for PMIC PF0900. The driver implements read/write operations. + +config SPL_DM_PMIC_PF0900 + bool "Enable Driver Model for PMIC PF0900 in SPL" + depends on SPL_DM_PMIC + depends on SPL_DM_I2C + help + This config enables implementation of driver-model pmic uclass features + for PMIC PF0900 in SPL. The driver implements read/write operations. + config DM_PMIC_PFUZE100 bool "Enable Driver Model for PMIC PFUZE100" ---help--- diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index a2d59deeed8..0041ab59406 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_)DM_PMIC_BD71837) += bd71837.o obj-$(CONFIG_$(SPL_)DM_PMIC_MP5416) += mp5416.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_$(SPL_)DM_PMIC_PCA9450) += pca9450.o +obj-$(CONFIG_$(SPL_)DM_PMIC_PF0900) += pf0900.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_AB8500) += ab8500.o diff --git a/drivers/power/pmic/pf0900.c b/drivers/power/pmic/pf0900.c new file mode 100644 index 00000000000..f38933ad94a --- /dev/null +++ b/drivers/power/pmic/pf0900.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2023 NXP + */ + +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <i2c.h> +#include <linux/err.h> +#include <log.h> +#include <asm/global_data.h> +#include <asm-generic/gpio.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/pf0900.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct pmic_child_info pmic_children_info[] = { + /* VAON */ + { .prefix = "V", .driver = PF0900_REGULATOR_DRIVER}, + /* sw */ + { .prefix = "S", .driver = PF0900_REGULATOR_DRIVER}, + /* ldo */ + { .prefix = "L", .driver = PF0900_REGULATOR_DRIVER}, + { }, +}; + +static int pf0900_reg_count(struct udevice *dev) +{ + return PF0900_MAX_REGISTER; +} + +static u8 crc8_j1850(u8 *data, u8 length) +{ + u8 t_crc; + u8 i, j; + + t_crc = 0xFF; + for (i = 0; i < length; i++) { + t_crc ^= data[i]; + for (j = 0; j < 8; j++) { + if ((t_crc & 0x80) != 0) { + t_crc <<= 1; + t_crc ^= 0x1D; + } else { + t_crc <<= 1; + } + } + } + return t_crc; +} + +static int pf0900_read(struct udevice *dev, uint reg, u8 *buff, + int len) +{ + u8 crcBuf[3]; + u8 data[2], crc; + int ret; + struct pf0900_priv *priv = dev_get_priv(dev); + + if (reg < PF0900_MAX_REGISTER) { + ret = dm_i2c_read(dev, reg, data, + priv->crc_en ? 2U : 1U); + if (ret) + return ret; + buff[0] = data[0]; + if (priv->crc_en) { + /* Get CRC */ + crcBuf[0] = priv->addr << 1U | 0x1U; + crcBuf[1] = reg; + crcBuf[2] = data[0]; + crc = crc8_j1850(crcBuf, 3U); + if (crc != data[1]) + return -EINVAL; + } + } else { + return -EINVAL; + } + return ret; +} + +static int pf0900_write(struct udevice *dev, uint reg, const u8 *buff, + int len) +{ + u8 crcBuf[3]; + u8 data[2]; + int ret; + struct pf0900_priv *priv = dev_get_priv(dev); + + if (reg < PF0900_MAX_REGISTER) { + data[0] = buff[0]; + if (priv->crc_en) { + /* Get CRC */ + crcBuf[0] = priv->addr << 1U; + crcBuf[1] = reg; + crcBuf[2] = data[0]; + data[1] = crc8_j1850(crcBuf, 3U); + } + /* Write data */ + ret = dm_i2c_write(dev, reg, data, + priv->crc_en ? 2U : 1U); + if (ret) + return ret; + } + return ret; +} + +static int pf0900_bind(struct udevice *dev) +{ + int children; + ofnode regulators_node; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found!", __func__, + dev->name); + return -ENXIO; + } + + children = pmic_bind_children(dev, regulators_node, + pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} + +static int pf0900_probe(struct udevice *dev) +{ + struct pf0900_priv *priv = dev_get_priv(dev); + unsigned int reg; + u8 dev_id; + int ret = 0; + + ret = ofnode_read_u32(dev_ofnode(dev), "reg", ®); + if (ret) + return ret; + priv->addr = reg; + + if (ofnode_read_bool(dev_ofnode(dev), "i2c-crc-enable")) + priv->crc_en = true; + ret = pf0900_read(dev, PF0900_REG_DEV_ID, &dev_id, 1); + if (ret) + return ret; + if ((dev_id & 0x1F) == 0) + return ret; + else + return -EINVAL; +} + +static struct dm_pmic_ops pf0900_ops = { + .reg_count = pf0900_reg_count, + .read = pf0900_read, + .write = pf0900_write, +}; + +static const struct udevice_id pf0900_ids[] = { + { .compatible = "nxp,pf0900", .data = PF0900_TYPE_PF0900, }, + { } +}; + +U_BOOT_DRIVER(pmic_pf0900) = { + .name = "pf0900 pmic", + .id = UCLASS_PMIC, + .of_match = pf0900_ids, + .bind = pf0900_bind, + .probe = pf0900_probe, + .ops = &pf0900_ops, + .priv_auto = sizeof(struct pf0900_priv), +}; diff --git a/include/power/pf0900.h b/include/power/pf0900.h new file mode 100644 index 00000000000..f0d93f1c795 --- /dev/null +++ b/include/power/pf0900.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2023 NXP + */ + +#ifndef PF0900_H_ +#define PF0900_H_ + +#define PF0900_REGULATOR_DRIVER "pf0900_regulator" + +struct pf0900_priv { + u8 addr; + bool crc_en; +}; + +enum pf0900_chip_type { + PF0900_TYPE_PF0900 = 0, + PF0900_TYPE_AMOUNT, +}; + +enum { + PF0900_SW1 = 0, + PF0900_SW2, + PF0900_SW3, + PF0900_SW4, + PF0900_SW5, + PF0900_LDO1, + PF0900_LDO2, + PF0900_LDO3, + PF0900_VAON, + PF0900_REGULATOR_CNT, +}; + +enum { + PF0900_DVS_LEVEL_RUN = 0, + PF0900_DVS_LEVEL_STANDBY, + PF0900_DVS_LEVEL_MAX, +}; + +#define PF0900_VAON_VOLTAGE_NUM 0x03 + +#define PF0900_SW1_VOLTAGE_NUM 0x100 +#define PF0900_SW2_VOLTAGE_NUM 0x100 +#define PF0900_SW3_VOLTAGE_NUM 0x100 +#define PF0900_SW4_VOLTAGE_NUM 0x100 +#define PF0900_SW5_VOLTAGE_NUM 0x100 + +#define PF0900_LDO1_VOLTAGE_NUM 0x20 +#define PF0900_LDO2_VOLTAGE_NUM 0x20 +#define PF0900_LDO3_VOLTAGE_NUM 0x20 + +enum { + PF0900_REG_DEV_ID = 0x00, + PF0900_REG_DEV_FAM = 0x01, + PF0900_REG_REV_ID = 0x02, + PF0900_REG_PROG_ID1 = 0x03, + PF0900_REG_PROG_ID2 = 0x04, + PF0900_REG_SYSTEM_INT = 0x05, + PF0900_REG_STATUS1_INT = 0x06, + PF0900_REG_STATUS1_MSK = 0x07, + PF0900_REG_STATUS1_SNS = 0x08, + PF0900_REG_STATUS2_INT = 0x09, + PF0900_REG_STATUS2_MSK = 0x0A, + PF0900_REG_STATUS2_SNS = 0x0B, + PF0900_REG_STATUS3_INT = 0x0C, + PF0900_REG_STATUS3_MSK = 0x0D, + PF0900_REG_SW_MODE_INT = 0x0E, + PF0900_REG_SW_MODE_MSK = 0x0F, + PF0900_REG_SW_ILIM_INT = 0x10, + PF0900_REG_SW_ILIM_MSK = 0x11, + PF0900_REG_SW_ILIM_SNS = 0x12, + PF0900_REG_LDO_ILIM_INT = 0x13, + PF0900_REG_LDO_ILIM_MSK = 0x14, + PF0900_REG_LDO_ILIM_SNS = 0x15, + PF0900_REG_SW_UV_INT = 0x16, + PF0900_REG_SW_UV_MSK = 0x17, + PF0900_REG_SW_UV_SNS = 0x18, + PF0900_REG_SW_OV_INT = 0x19, + PF0900_REG_SW_OV_MSK = 0x1A, + PF0900_REG_SW_OV_SNS = 0x1B, + PF0900_REG_LDO_UV_INT = 0x1C, + PF0900_REG_LDO_UV_MSK = 0x1D, + PF0900_REG_LDO_UV_SNS = 0x1E, + PF0900_REG_LDO_OV_INT = 0x1F, + PF0900_REG_LDO_OV_MSK = 0x20, + PF0900_REG_LDO_OV_SNS = 0x21, + PF0900_REG_PWRON_INT = 0x22, + PF0900_REG_IO_INT = 0x24, + PF0900_REG_IO_MSK = 0x25, + PF0900_REG_IO_SNS = 0x26, + PF0900_REG_IOSHORT_SNS = 0x27, + PF0900_REG_ABIST_OV1 = 0x28, + PF0900_REG_ABIST_OV2 = 0x29, + PF0900_REG_ABIST_UV1 = 0x2A, + PF0900_REG_ABIST_UV2 = 0x2B, + PF0900_REG_ABIST_IO = 0x2C, + PF0900_REG_TEST_FLAGS = 0x2D, + PF0900_REG_HFAULT_FLAGS = 0x2E, + PF0900_REG_FAULT_FLAGS = 0x2F, + PF0900_REG_FS0B_CFG = 0x30, + PF0900_REG_FCCU_CFG = 0x31, + PF0900_REG_RSTB_CFG1 = 0x32, + PF0900_REG_SYSTEM_CMD = 0x33, + PF0900_REG_FS0B_CMD = 0x34, + PF0900_REG_SECURE_WR1 = 0x35, + PF0900_REG_SECURE_WR2 = 0x36, + PF0900_REG_VMON_CFG1 = 0x37, + PF0900_REG_SYS_CFG1 = 0x38, + PF0900_REG_GPO_CFG = 0x39, + PF0900_REG_GPO_CTRL = 0x3A, + PF0900_REG_PWRUP_CFG = 0x3B, + PF0900_REG_RSTB_PWRUP = 0x3C, + PF0900_REG_GPIO1_PWRUP = 0x3D, + PF0900_REG_GPIO2_PWRUP = 0x3E, + PF0900_REG_GPIO3_PWRUP = 0x3F, + PF0900_REG_GPIO4_PWRUP = 0x40, + PF0900_REG_VMON1_PWRUP = 0x41, + PF0900_REG_VMON2_PWRUP = 0x42, + PF0900_REG_SW1_PWRUP = 0x43, + PF0900_REG_SW2_PWRUP = 0x44, + PF0900_REG_SW3_PWRUP = 0x45, + PF0900_REG_SW4_PWRUP = 0x46, + PF0900_REG_SW5_PWRUP = 0x47, + PF0900_REG_LDO1_PWRUP = 0x48, + PF0900_REG_LDO2_PWRUP = 0x49, + PF0900_REG_LDO3_PWRUP = 0x4A, + PF0900_REG_VAON_PWRUP = 0x4B, + PF0900_REG_FREQ_CTRL = 0x4C, + PF0900_REG_PWRON_CFG = 0x4D, + PF0900_REG_WD_CTRL1 = 0x4E, + PF0900_REG_WD_CTRL2 = 0x4F, + PF0900_REG_WD_CFG1 = 0x50, + PF0900_REG_WD_CFG2 = 0x51, + PF0900_REG_WD_CNT1 = 0x52, + PF0900_REG_WD_CNT2 = 0x53, + PF0900_REG_FAULT_CFG = 0x54, + PF0900_REG_FAULT_CNT = 0x55, + PF0900_REG_DFS_CNT = 0x56, + PF0900_REG_AMUX_CFG = 0x57, + PF0900_REG_VMON1_RUN_CFG = 0x58, + PF0900_REG_VMON1_STBY_CFG = 0x59, + PF0900_REG_VMON1_CTRL = 0x5A, + PF0900_REG_VMON2_RUN_CFG = 0x5B, + PF0900_REG_VMON2_STBY_CFG = 0x5C, + PF0900_REG_VMON2_CTRL = 0x5D, + PF0900_REG_SW1_VRUN = 0x5E, + PF0900_REG_SW1_VSTBY = 0x5F, + PF0900_REG_SW1_MODE = 0x60, + PF0900_REG_SW1_CFG1 = 0x61, + PF0900_REG_SW1_CFG2 = 0x62, + PF0900_REG_SW2_VRUN = 0x63, + PF0900_REG_SW2_VSTBY = 0x64, + PF0900_REG_SW2_MODE = 0x65, + PF0900_REG_SW2_CFG1 = 0x66, + PF0900_REG_SW2_CFG2 = 0x67, + PF0900_REG_SW3_VRUN = 0x68, + PF0900_REG_SW3_VSTBY = 0x69, + PF0900_REG_SW3_MODE = 0x6A, + PF0900_REG_SW3_CFG1 = 0x6B, + PF0900_REG_SW3_CFG2 = 0x6C, + PF0900_REG_SW4_VRUN = 0x6D, + PF0900_REG_SW4_VSTBY = 0x6E, + PF0900_REG_SW4_MODE = 0x6F, + PF0900_REG_SW4_CFG1 = 0x70, + PF0900_REG_SW4_CFG2 = 0x71, + PF0900_REG_SW5_VRUN = 0x72, + PF0900_REG_SW5_VSTBY = 0x73, + PF0900_REG_SW5_MODE = 0x74, + PF0900_REG_SW5_CFG1 = 0x75, + PF0900_REG_SW5_CFG2 = 0x76, + PF0900_REG_LDO1_RUN = 0x77, + PF0900_REG_LDO1_STBY = 0x78, + PF0900_REG_LDO1_CFG2 = 0x79, + PF0900_REG_LDO2_RUN = 0x7A, + PF0900_REG_LDO2_STBY = 0x7B, + PF0900_REG_LDO2_CFG2 = 0x7C, + PF0900_REG_LDO3_RUN = 0x7D, + PF0900_REG_LDO3_STBY = 0x7E, + PF0900_REG_LDO3_CFG2 = 0x7F, + PF0900_REG_VAON_CFG1 = 0x80, + PF0900_REG_VAON_CFG2 = 0x81, + PF0900_REG_SYS_DIAG = 0x82, + PF0900_MAX_REGISTER, +}; + +/* PF0900 SW MODE */ +#define SW_RUN_MODE_OFF 0x00 +#define SW_RUN_MODE_PWM 0x01 +#define SW_RUN_MODE_PFM 0x02 +#define SW_STBY_MODE_OFF 0x00 +#define SW_STBY_MODE_PWM 0x04 +#define SW_STBY_MODE_PFM 0x08 + +/* PF0900 SW MODE MASK */ +#define SW_RUN_MODE_MASK 0x03 +#define SW_STBY_MODE_MASK 0x0c + +/* PF0900 SW VRUN MASK */ +#define SW_VRUN_MASK 0xFF +#define SW_STBY_MASK 0xFF + +/* PF0900_REG_VAON_CFG1 bits */ +#define VAON_MASK 0x03 +#define VAON_1P8V 0x01 + +/* PF0900_REG_SWX_CFG1 MASK */ +#define SW_RAMP_MASK 0x18 + +/* PF0900_REG_LDO1_RUN MASK */ +#define VLDO1_RUN_MASK 0x1F +#define LDO1_RUN_EN_MASK 0x20 +#define LDO1_STBY_EN_MASK 0x20 + +/* PF0900_REG_LDO2_RUN MASK */ +#define VLDO2_RUN_MASK 0x1F +#define LDO2_RUN_EN_MASK 0x20 +#define LDO2_STBY_EN_MASK 0x20 + +/* PF0900_REG_LDO3_RUN MASK */ +#define VLDO3_RUN_MASK 0x1F +#define LDO3_RUN_EN_MASK 0x20 +#define LDO3_STBY_EN_MASK 0x20 + +/* PF0900_REG_GPO_CTRL MASK */ +#define GPO1_RUN_MASK 0x1 +#define GPO2_RUN_MASK 0x2 +#define GPO3_RUN_MASK 0x4 +#define GPO4_RUN_MASK 0x8 +#define GPO1_STBY_MASK 0x10 +#define GPO2_STBY_MASK 0x20 +#define GPO3_STBY_MASK 0x40 +#define GPO4_STBY_MASK 0x80 + +/* PF0900_REG_STSTEM_INT bits */ +#define IRQ_EWARN 0x80 +#define IRQ_GPIO 0x40 +#define IRQ_OV 0x20 +#define IRQ_UV 0x10 +#define IRQ_ILIM 0x08 +#define IRQ_MODE 0x04 +#define IRQ_STATUS2 0x02 +#define IRQ_STATUS1 0x01 + +/* PF0900_REG_STATUS1_INT bits */ +#define IRQ_SDWN 0x80 +#define IRQ_FREQ_RDY 0x40 +#define IRQ_DCRC 0x20 +#define IRQ_I2C_CRC 0x10 +#define IRQ_PWRUP 0x08 +#define IRQ_PWRDN 0x04 +#define IRQ_FSYNC_FLT 0x02 +#define IRQ_VIN_OV 0x01 + +/* PF0900_REG_STATUS2_INT bits */ +#define IRQ_VANA_OV 0x80 +#define IRQ_VDIG_OV 0x40 +#define IRQ_BGMON 0x20 +#define IRQ_CLKMON 0x10 +#define IRQ_THERM_155 0x08 +#define IRQ_THERM_140 0x04 +#define IRQ_THERM_125 0x02 +#define IRQ_THERM_110 0x01 + +/* PF0900_REG_STATUS3_INT bits */ +#define IRQ_BAD_CMD 0x04 +#define IRQ_LBIST_DONE 0x02 +#define IRQ_SHS 0x01 + +#endif

From: Joy Zou joy.zou@nxp.com
Add regulator driver for NXP PF0900
Signed-off-by: Joy Zou joy.zou@nxp.com Reviewed-by: Ye Li ye.li@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/power/regulator/Kconfig | 15 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/pf0900.c | 304 +++++++++++++++++++++++++++++++ 3 files changed, 320 insertions(+) create mode 100644 drivers/power/regulator/pf0900.c
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 958f337c7e7..b2f487b050b 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -96,6 +96,21 @@ config SPL_DM_REGULATOR_PCA9450 This config enables implementation of driver-model regulator uclass features for regulators on ROHM PCA9450 in SPL.
+config DM_REGULATOR_PF0900 + bool "Enable Driver Model for NXP PF0900 regulators" + depends on DM_REGULATOR && DM_PMIC_PF0900 + help + This config enables implementation of driver-model regulator uclass + features for regulators on NXP PF0900 PMICs. PF0900 contains 1 vaon, + 5 sws and 3 LDOS. The driver implements get/set api for value and enable. + +config SPL_DM_REGULATOR_PF0900 + bool "Enable Driver Model for NXP PF0900 regulators in SPL" + depends on DM_REGULATOR_PF0900 && SPL + help + This config enables implementation of driver-model regulator uclass + features for regulators on ROHM PF0900 in SPL. + config DM_REGULATOR_DA9063 bool "Enable Driver Model for REGULATOR DA9063" depends on DM_REGULATOR && DM_PMIC_DA9063 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 54db0885657..a49700dfd25 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DM_REGULATOR_NPCM8XX) += npcm8xx_regulator.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_BD71837) += bd71837.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_PCA9450) += pca9450.o +obj-$(CONFIG_$(SPL_)DM_REGULATOR_PF0900) += pf0900.o obj-$(CONFIG_$(SPL_)REGULATOR_PWM) += pwm_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_FAN53555) += fan53555.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_COMMON) += regulator_common.o diff --git a/drivers/power/regulator/pf0900.c b/drivers/power/regulator/pf0900.c new file mode 100644 index 00000000000..a56ad8fde32 --- /dev/null +++ b/drivers/power/regulator/pf0900.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * NXP PF0900 regulator driver + * Copyright 2023 NXP + * + */ + +#include <dm.h> +#include <errno.h> +#include <log.h> +#include <linux/bitops.h> +#include <power/pf0900.h> +#include <power/pmic.h> +#include <power/regulator.h> + +/** + * struct pf0900_vrange - describe linear range of voltages + * + * @min_volt: smallest voltage in range + * @min_sel: smallest selector in the range + * @max_sel: maximum selector in the range + * @step: how much voltage changes at each selector step + */ +struct pf0900_vrange { + unsigned int min_volt; + u8 min_sel; + u8 max_sel; + unsigned int step; +}; + +/** + * struct pf0900_plat - describe regulator control registers + * + * @name: name of the regulator. Used for matching the dt-entry + * @enable_reg: register address used to enable/disable regulator + * @enablemask: register mask used to enable/disable regulator + * @volt_reg: register address used to configure regulator voltage + * @volt_mask: register mask used to configure regulator voltage + * @ranges: pointer to ranges of regulator voltages and matching register + * values + * @numranges: number of voltage ranges pointed by ranges + */ +struct pf0900_plat { + const char *name; + u8 enable_reg; + u8 enablemask; + u8 volt_reg; + u8 volt_mask; + struct pf0900_vrange *ranges; + unsigned int numranges; +}; + +#define PCA_RANGE(_min, _sel_low, _sel_hi, _vstep) \ +{ \ + .min_volt = (_min), .min_sel = (_sel_low), \ + .max_sel = (_sel_hi), .step = (_vstep),\ +} + +#define PCA_DATA(_name, enreg, enmask, vreg, vmask, _range) \ +{ \ + .name = (_name), .enable_reg = (enreg), .enablemask = (enmask), \ + .volt_reg = (vreg), .volt_mask = (vmask), .ranges = (_range), \ + .numranges = ARRAY_SIZE(_range) \ +} + +static struct pf0900_vrange pf0900_vaon_vranges[] = { + PCA_RANGE(0, 0x00, 0x01, 0x00), + PCA_RANGE(1800000, 0x00, 0x01, 0x00), + PCA_RANGE(3000000, 0x00, 0x01, 0x00), + PCA_RANGE(3300000, 0x00, 0x01, 0x00), +}; + +static struct pf0900_vrange pf0900_sw1_vranges[] = { + PCA_RANGE(0, 0x00, 0x08, 0), + PCA_RANGE(500000, 0x09, 0x91, 6250), + PCA_RANGE(0, 0x92, 0x9E, 0), + PCA_RANGE(1500000, 0x9F, 0x9F, 0), + PCA_RANGE(1800000, 0xA0, 0xD8, 12500), + PCA_RANGE(0, 0xD9, 0xDF, 0), + PCA_RANGE(2800000, 0xE0, 0xF4, 25000), + PCA_RANGE(0, 0xF5, 0xFF, 0), +}; + +static struct pf0900_vrange pf0900_sw2345_vranges[] = { + PCA_RANGE(300000, 0x00, 0x00, 0), + PCA_RANGE(450000, 0x01, 0x91, 6250), + PCA_RANGE(0, 0x92, 0x9E, 0), + PCA_RANGE(1500000, 0x9F, 0x9F, 0), + PCA_RANGE(1800000, 0xA0, 0xD8, 12500), + PCA_RANGE(0, 0xD9, 0xDF, 0), + PCA_RANGE(2800000, 0xE0, 0xF4, 25000), + PCA_RANGE(0, 0xF5, 0xFF, 0), +}; + +static struct pf0900_vrange pf0900_ldo1_vranges[] = { + PCA_RANGE(750000, 0x00, 0x0F, 50000), + PCA_RANGE(1800000, 0x10, 0x1F, 100000), +}; + +static struct pf0900_vrange pf0900_ldo23_vranges[] = { + PCA_RANGE(650000, 0x00, 0x0D, 50000), + PCA_RANGE(1400000, 0x0E, 0x0F, 100000), + PCA_RANGE(1800000, 0x10, 0x1F, 100000), +}; + +static struct pf0900_plat pf0900_reg_data[] = { + PCA_DATA("VAON", PF0900_REG_VAON_CFG1, VAON_1P8V, + PF0900_REG_VAON_CFG1, VAON_MASK, + pf0900_vaon_vranges), + PCA_DATA("SW1", PF0900_REG_SW1_MODE, SW_RUN_MODE_PWM, + PF0900_REG_SW1_VRUN, SW_VRUN_MASK, + pf0900_sw1_vranges), + PCA_DATA("SW2", PF0900_REG_SW2_MODE, SW_RUN_MODE_PWM, + PF0900_REG_SW2_VRUN, SW_VRUN_MASK, + pf0900_sw2345_vranges), + PCA_DATA("SW3", PF0900_REG_SW3_MODE, SW_RUN_MODE_PWM, + PF0900_REG_SW3_VRUN, SW_VRUN_MASK, + pf0900_sw2345_vranges), + PCA_DATA("SW4", PF0900_REG_SW4_MODE, SW_RUN_MODE_PWM, + PF0900_REG_SW4_VRUN, SW_VRUN_MASK, + pf0900_sw2345_vranges), + PCA_DATA("SW5", PF0900_REG_SW5_MODE, SW_RUN_MODE_PWM, + PF0900_REG_SW5_VRUN, SW_VRUN_MASK, + pf0900_sw2345_vranges), + PCA_DATA("LDO1", PF0900_REG_LDO1_RUN, LDO1_RUN_EN_MASK, + PF0900_REG_LDO1_RUN, VLDO1_RUN_MASK, + pf0900_ldo1_vranges), + PCA_DATA("LDO2", PF0900_REG_LDO2_RUN, LDO2_RUN_EN_MASK, + PF0900_REG_LDO2_RUN, VLDO2_RUN_MASK, + pf0900_ldo23_vranges), + PCA_DATA("LDO3", PF0900_REG_LDO3_RUN, LDO3_RUN_EN_MASK, + PF0900_REG_LDO3_RUN, VLDO3_RUN_MASK, + pf0900_ldo23_vranges), +}; + +static int vrange_find_value(struct pf0900_vrange *r, unsigned int sel, + unsigned int *val) +{ + if (!val || sel < r->min_sel || sel > r->max_sel) + return -EINVAL; + + *val = r->min_volt + r->step * (sel - r->min_sel); + return 0; +} + +static int vrange_find_selector(struct pf0900_vrange *r, int val, + unsigned int *sel) +{ + int ret = -EINVAL; + int num_vals = r->max_sel - r->min_sel + 1; + + if (val >= r->min_volt && + val <= r->min_volt + r->step * (num_vals - 1)) { + if (r->step) { + *sel = r->min_sel + ((val - r->min_volt) / r->step); + ret = 0; + } else { + *sel = r->min_sel; + ret = 0; + } + } + return ret; +} + +static int pf0900_get_enable(struct udevice *dev) +{ + struct pf0900_plat *plat = dev_get_plat(dev); + int val; + + val = pmic_reg_read(dev->parent, plat->enable_reg); + if (val < 0) + return val; + + return (val & plat->enablemask); +} + +static int pf0900_set_enable(struct udevice *dev, bool enable) +{ + int val = 0; + int tmp = 0; + struct pf0900_plat *plat = dev_get_plat(dev); + + if (enable) + tmp = plat->enablemask; + val = pmic_reg_read(dev->parent, plat->enable_reg); + if (val < 0) + return val; + val = (tmp & plat->enablemask) | (val & (~plat->enablemask)); + + return pmic_reg_write(dev->parent, plat->enable_reg, val); +} + +static int pf0900_get_value(struct udevice *dev) +{ + struct pf0900_plat *plat = dev_get_plat(dev); + unsigned int reg, tmp; + int i, ret; + + ret = pmic_reg_read(dev->parent, plat->volt_reg); + if (ret < 0) + return ret; + + reg = ret; + reg &= plat->volt_mask; + + if (!strcmp(plat->name, "VAON")) + return plat->ranges[reg].min_volt; + + for (i = 0; i < plat->numranges; i++) { + struct pf0900_vrange *r = &plat->ranges[i]; + + if (!vrange_find_value(r, reg, &tmp)) + return tmp; + } + + pr_err("Unknown voltage value read from pmic\n"); + + return -EINVAL; +} + +static int pf0900_set_value(struct udevice *dev, int uvolt) +{ + struct pf0900_plat *plat = dev_get_plat(dev); + unsigned int sel; + int i, val, found = 0; + + for (i = 0; i < plat->numranges; i++) { + struct pf0900_vrange *r = &plat->ranges[i]; + + if (!strcmp(plat->name, "VAON")) { + if (r->min_volt == uvolt) { + sel = i; + found = 1; + break; + } + + continue; + } + + found = !vrange_find_selector(r, uvolt, &sel); + if (found) { + unsigned int tmp; + + /* + * We require exactly the requested value to be + * supported - this can be changed later if needed + */ + found = !vrange_find_value(r, sel, &tmp); + if (found && tmp == uvolt) + break; + found = 0; + } + } + + if (!found) + return -EINVAL; + + val = pmic_reg_read(dev->parent, plat->volt_reg); + if (val < 0) + return val; + val = (sel & plat->volt_mask) | (val & (~plat->volt_mask)); + return pmic_reg_write(dev->parent, plat->volt_reg, val); +} + +static int pf0900_regulator_probe(struct udevice *dev) +{ + struct pf0900_plat *plat = dev_get_plat(dev); + int i, type; + + type = dev_get_driver_data(dev_get_parent(dev)); + + if (type != PF0900_TYPE_PF0900) { + debug("Unknown PMIC type\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(pf0900_reg_data); i++) { + if (strcmp(dev->name, pf0900_reg_data[i].name)) + continue; + + *plat = pf0900_reg_data[i]; + + return 0; + } + + pr_err("Unknown regulator '%s'\n", dev->name); + + return -ENOENT; +} + +static const struct dm_regulator_ops pf0900_regulator_ops = { + .get_value = pf0900_get_value, + .set_value = pf0900_set_value, + .get_enable = pf0900_get_enable, + .set_enable = pf0900_set_enable, +}; + +U_BOOT_DRIVER(pf0900_regulator) = { + .name = PF0900_REGULATOR_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &pf0900_regulator_ops, + .probe = pf0900_regulator_probe, + .plat_auto = sizeof(struct pf0900_plat), +};

On Mon, Sep 30, 2024 at 11:22:43AM +0800, Peng Fan (OSS) wrote:
From: Joy Zou joy.zou@nxp.com
Add regulator driver for NXP PF0900
Signed-off-by: Joy Zou joy.zou@nxp.com Reviewed-by: Ye Li ye.li@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com
drivers/power/regulator/Kconfig | 15 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/pf0900.c | 304 +++++++++++++++++++++++++++++++ 3 files changed, 320 insertions(+) create mode 100644 drivers/power/regulator/pf0900.c
In addition to the MAINTAINERS comment: CHECK: Macro argument reuse '_range' - possible side-effects? #280: FILE: drivers/power/regulator/pf0900.c:59: +#define PCA_DATA(_name, enreg, enmask, vreg, vmask, _range) \ +{ \ + .name = (_name), .enable_reg = (enreg), .enablemask = (enmask), \ + .volt_reg = (vreg), .volt_mask = (vmask), .ranges = (_range), \ + .numranges = ARRAY_SIZE(_range) \ +}
And it's that last _range that I believe is being noted.

Hi Fabio, Tom
Seems Jaehoon is inactive. Will you help manage the the power related patchset or I could use fsl-qoirq tree to manage these drivers for i.MX?
Thanks, Peng.
Subject: [PATCH 1/2] power: pmic: Support pmic pf0900
From: Joy Zou joy.zou@nxp.com
Support NXP pmic pf0900
Reviewed-by: Ye Li ye.li@nxp.com Signed-off-by: Joy Zou joy.zou@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com
drivers/power/pmic/Kconfig | 15 ++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pf0900.c | 174 +++++++++++++++++++++++ include/power/pf0900.h | 269 ++++++++++++++++++++++++++++++++++++ 4 files changed, 459 insertions(+) create mode 100644 drivers/power/pmic/pf0900.c create mode 100644 include/power/pf0900.h
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 562c1a3b122..1a5ef279ed6 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -171,6 +171,21 @@ config SPL_DM_PMIC_PCA9450 This config enables implementation of driver-model pmic uclass features for PMIC PCA9450 in SPL. The driver implements read/write operations.
+config DM_PMIC_PF0900
- bool "Enable Driver Model for PMIC PF0900"
- depends on DM_I2C
- help
This config enables implementation of driver-model pmic
uclass features
for PMIC PF0900. The driver implements read/write
operations.
+config SPL_DM_PMIC_PF0900
- bool "Enable Driver Model for PMIC PF0900 in SPL"
- depends on SPL_DM_PMIC
- depends on SPL_DM_I2C
- help
This config enables implementation of driver-model pmic
uclass features
for PMIC PF0900 in SPL. The driver implements read/write
operations.
config DM_PMIC_PFUZE100 bool "Enable Driver Model for PMIC PFUZE100" ---help--- diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index a2d59deeed8..0041ab59406 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_)DM_PMIC_BD71837) += bd71837.o obj-$(CONFIG_$(SPL_)DM_PMIC_MP5416) += mp5416.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_$(SPL_)DM_PMIC_PCA9450) += pca9450.o +obj-$(CONFIG_$(SPL_)DM_PMIC_PF0900) += pf0900.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_AB8500) += ab8500.o diff --git a/drivers/power/pmic/pf0900.c b/drivers/power/pmic/pf0900.c new file mode 100644 index 00000000000..f38933ad94a --- /dev/null +++ b/drivers/power/pmic/pf0900.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright 2023 NXP
- */
+#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <i2c.h> +#include <linux/err.h> +#include <log.h> +#include <asm/global_data.h> +#include <asm-generic/gpio.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/pf0900.h>
+DECLARE_GLOBAL_DATA_PTR;
+static const struct pmic_child_info pmic_children_info[] = {
- /* VAON */
- { .prefix = "V", .driver = PF0900_REGULATOR_DRIVER},
- /* sw */
- { .prefix = "S", .driver = PF0900_REGULATOR_DRIVER},
- /* ldo */
- { .prefix = "L", .driver = PF0900_REGULATOR_DRIVER},
- { },
+};
+static int pf0900_reg_count(struct udevice *dev) {
- return PF0900_MAX_REGISTER;
+}
+static u8 crc8_j1850(u8 *data, u8 length) {
- u8 t_crc;
- u8 i, j;
- t_crc = 0xFF;
- for (i = 0; i < length; i++) {
t_crc ^= data[i];
for (j = 0; j < 8; j++) {
if ((t_crc & 0x80) != 0) {
t_crc <<= 1;
t_crc ^= 0x1D;
} else {
t_crc <<= 1;
}
}
- }
- return t_crc;
+}
+static int pf0900_read(struct udevice *dev, uint reg, u8 *buff,
int len)
+{
- u8 crcBuf[3];
- u8 data[2], crc;
- int ret;
- struct pf0900_priv *priv = dev_get_priv(dev);
- if (reg < PF0900_MAX_REGISTER) {
ret = dm_i2c_read(dev, reg, data,
priv->crc_en ? 2U : 1U);
if (ret)
return ret;
buff[0] = data[0];
if (priv->crc_en) {
/* Get CRC */
crcBuf[0] = priv->addr << 1U | 0x1U;
crcBuf[1] = reg;
crcBuf[2] = data[0];
crc = crc8_j1850(crcBuf, 3U);
if (crc != data[1])
return -EINVAL;
}
- } else {
return -EINVAL;
- }
- return ret;
+}
+static int pf0900_write(struct udevice *dev, uint reg, const u8 *buff,
int len)
+{
- u8 crcBuf[3];
- u8 data[2];
- int ret;
- struct pf0900_priv *priv = dev_get_priv(dev);
- if (reg < PF0900_MAX_REGISTER) {
data[0] = buff[0];
if (priv->crc_en) {
/* Get CRC */
crcBuf[0] = priv->addr << 1U;
crcBuf[1] = reg;
crcBuf[2] = data[0];
data[1] = crc8_j1850(crcBuf, 3U);
}
/* Write data */
ret = dm_i2c_write(dev, reg, data,
priv->crc_en ? 2U : 1U);
if (ret)
return ret;
- }
- return ret;
+}
+static int pf0900_bind(struct udevice *dev) {
- int children;
- ofnode regulators_node;
- regulators_node = dev_read_subnode(dev, "regulators");
- if (!ofnode_valid(regulators_node)) {
debug("%s: %s regulators subnode not found!",
__func__,
dev->name);
return -ENXIO;
- }
- children = pmic_bind_children(dev, regulators_node,
pmic_children_info);
- if (!children)
debug("%s: %s - no child found\n", __func__, dev-
name);
- /* Always return success for this device */
- return 0;
+}
+static int pf0900_probe(struct udevice *dev) {
- struct pf0900_priv *priv = dev_get_priv(dev);
- unsigned int reg;
- u8 dev_id;
- int ret = 0;
- ret = ofnode_read_u32(dev_ofnode(dev), "reg", ®);
- if (ret)
return ret;
- priv->addr = reg;
- if (ofnode_read_bool(dev_ofnode(dev), "i2c-crc-enable"))
priv->crc_en = true;
- ret = pf0900_read(dev, PF0900_REG_DEV_ID, &dev_id, 1);
- if (ret)
return ret;
- if ((dev_id & 0x1F) == 0)
return ret;
- else
return -EINVAL;
+}
+static struct dm_pmic_ops pf0900_ops = {
- .reg_count = pf0900_reg_count,
- .read = pf0900_read,
- .write = pf0900_write,
+};
+static const struct udevice_id pf0900_ids[] = {
- { .compatible = "nxp,pf0900", .data = PF0900_TYPE_PF0900, },
- { }
+};
+U_BOOT_DRIVER(pmic_pf0900) = {
- .name = "pf0900 pmic",
- .id = UCLASS_PMIC,
- .of_match = pf0900_ids,
- .bind = pf0900_bind,
- .probe = pf0900_probe,
- .ops = &pf0900_ops,
- .priv_auto = sizeof(struct pf0900_priv), };
diff --git a/include/power/pf0900.h b/include/power/pf0900.h new file mode 100644 index 00000000000..f0d93f1c795 --- /dev/null +++ b/include/power/pf0900.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright 2023 NXP
- */
+#ifndef PF0900_H_ +#define PF0900_H_
+#define PF0900_REGULATOR_DRIVER "pf0900_regulator"
+struct pf0900_priv {
- u8 addr;
- bool crc_en;
+};
+enum pf0900_chip_type {
- PF0900_TYPE_PF0900 = 0,
- PF0900_TYPE_AMOUNT,
+};
+enum {
- PF0900_SW1 = 0,
- PF0900_SW2,
- PF0900_SW3,
- PF0900_SW4,
- PF0900_SW5,
- PF0900_LDO1,
- PF0900_LDO2,
- PF0900_LDO3,
- PF0900_VAON,
- PF0900_REGULATOR_CNT,
+};
+enum {
- PF0900_DVS_LEVEL_RUN = 0,
- PF0900_DVS_LEVEL_STANDBY,
- PF0900_DVS_LEVEL_MAX,
+};
+#define PF0900_VAON_VOLTAGE_NUM 0x03
+#define PF0900_SW1_VOLTAGE_NUM 0x100 +#define PF0900_SW2_VOLTAGE_NUM 0x100 +#define PF0900_SW3_VOLTAGE_NUM 0x100 +#define PF0900_SW4_VOLTAGE_NUM 0x100 +#define PF0900_SW5_VOLTAGE_NUM 0x100
+#define PF0900_LDO1_VOLTAGE_NUM 0x20 +#define PF0900_LDO2_VOLTAGE_NUM 0x20 +#define PF0900_LDO3_VOLTAGE_NUM 0x20
+enum {
- PF0900_REG_DEV_ID = 0x00,
- PF0900_REG_DEV_FAM = 0x01,
- PF0900_REG_REV_ID = 0x02,
- PF0900_REG_PROG_ID1 = 0x03,
- PF0900_REG_PROG_ID2 = 0x04,
- PF0900_REG_SYSTEM_INT = 0x05,
- PF0900_REG_STATUS1_INT = 0x06,
- PF0900_REG_STATUS1_MSK = 0x07,
- PF0900_REG_STATUS1_SNS = 0x08,
- PF0900_REG_STATUS2_INT = 0x09,
- PF0900_REG_STATUS2_MSK = 0x0A,
- PF0900_REG_STATUS2_SNS = 0x0B,
- PF0900_REG_STATUS3_INT = 0x0C,
- PF0900_REG_STATUS3_MSK = 0x0D,
- PF0900_REG_SW_MODE_INT = 0x0E,
- PF0900_REG_SW_MODE_MSK = 0x0F,
- PF0900_REG_SW_ILIM_INT = 0x10,
- PF0900_REG_SW_ILIM_MSK = 0x11,
- PF0900_REG_SW_ILIM_SNS = 0x12,
- PF0900_REG_LDO_ILIM_INT = 0x13,
- PF0900_REG_LDO_ILIM_MSK = 0x14,
- PF0900_REG_LDO_ILIM_SNS = 0x15,
- PF0900_REG_SW_UV_INT = 0x16,
- PF0900_REG_SW_UV_MSK = 0x17,
- PF0900_REG_SW_UV_SNS = 0x18,
- PF0900_REG_SW_OV_INT = 0x19,
- PF0900_REG_SW_OV_MSK = 0x1A,
- PF0900_REG_SW_OV_SNS = 0x1B,
- PF0900_REG_LDO_UV_INT = 0x1C,
- PF0900_REG_LDO_UV_MSK = 0x1D,
- PF0900_REG_LDO_UV_SNS = 0x1E,
- PF0900_REG_LDO_OV_INT = 0x1F,
- PF0900_REG_LDO_OV_MSK = 0x20,
- PF0900_REG_LDO_OV_SNS = 0x21,
- PF0900_REG_PWRON_INT = 0x22,
- PF0900_REG_IO_INT = 0x24,
- PF0900_REG_IO_MSK = 0x25,
- PF0900_REG_IO_SNS = 0x26,
- PF0900_REG_IOSHORT_SNS = 0x27,
- PF0900_REG_ABIST_OV1 = 0x28,
- PF0900_REG_ABIST_OV2 = 0x29,
- PF0900_REG_ABIST_UV1 = 0x2A,
- PF0900_REG_ABIST_UV2 = 0x2B,
- PF0900_REG_ABIST_IO = 0x2C,
- PF0900_REG_TEST_FLAGS = 0x2D,
- PF0900_REG_HFAULT_FLAGS = 0x2E,
- PF0900_REG_FAULT_FLAGS = 0x2F,
- PF0900_REG_FS0B_CFG = 0x30,
- PF0900_REG_FCCU_CFG = 0x31,
- PF0900_REG_RSTB_CFG1 = 0x32,
- PF0900_REG_SYSTEM_CMD = 0x33,
- PF0900_REG_FS0B_CMD = 0x34,
- PF0900_REG_SECURE_WR1 = 0x35,
- PF0900_REG_SECURE_WR2 = 0x36,
- PF0900_REG_VMON_CFG1 = 0x37,
- PF0900_REG_SYS_CFG1 = 0x38,
- PF0900_REG_GPO_CFG = 0x39,
- PF0900_REG_GPO_CTRL = 0x3A,
- PF0900_REG_PWRUP_CFG = 0x3B,
- PF0900_REG_RSTB_PWRUP = 0x3C,
- PF0900_REG_GPIO1_PWRUP = 0x3D,
- PF0900_REG_GPIO2_PWRUP = 0x3E,
- PF0900_REG_GPIO3_PWRUP = 0x3F,
- PF0900_REG_GPIO4_PWRUP = 0x40,
- PF0900_REG_VMON1_PWRUP = 0x41,
- PF0900_REG_VMON2_PWRUP = 0x42,
- PF0900_REG_SW1_PWRUP = 0x43,
- PF0900_REG_SW2_PWRUP = 0x44,
- PF0900_REG_SW3_PWRUP = 0x45,
- PF0900_REG_SW4_PWRUP = 0x46,
- PF0900_REG_SW5_PWRUP = 0x47,
- PF0900_REG_LDO1_PWRUP = 0x48,
- PF0900_REG_LDO2_PWRUP = 0x49,
- PF0900_REG_LDO3_PWRUP = 0x4A,
- PF0900_REG_VAON_PWRUP = 0x4B,
- PF0900_REG_FREQ_CTRL = 0x4C,
- PF0900_REG_PWRON_CFG = 0x4D,
- PF0900_REG_WD_CTRL1 = 0x4E,
- PF0900_REG_WD_CTRL2 = 0x4F,
- PF0900_REG_WD_CFG1 = 0x50,
- PF0900_REG_WD_CFG2 = 0x51,
- PF0900_REG_WD_CNT1 = 0x52,
- PF0900_REG_WD_CNT2 = 0x53,
- PF0900_REG_FAULT_CFG = 0x54,
- PF0900_REG_FAULT_CNT = 0x55,
- PF0900_REG_DFS_CNT = 0x56,
- PF0900_REG_AMUX_CFG = 0x57,
- PF0900_REG_VMON1_RUN_CFG = 0x58,
- PF0900_REG_VMON1_STBY_CFG = 0x59,
- PF0900_REG_VMON1_CTRL = 0x5A,
- PF0900_REG_VMON2_RUN_CFG = 0x5B,
- PF0900_REG_VMON2_STBY_CFG = 0x5C,
- PF0900_REG_VMON2_CTRL = 0x5D,
- PF0900_REG_SW1_VRUN = 0x5E,
- PF0900_REG_SW1_VSTBY = 0x5F,
- PF0900_REG_SW1_MODE = 0x60,
- PF0900_REG_SW1_CFG1 = 0x61,
- PF0900_REG_SW1_CFG2 = 0x62,
- PF0900_REG_SW2_VRUN = 0x63,
- PF0900_REG_SW2_VSTBY = 0x64,
- PF0900_REG_SW2_MODE = 0x65,
- PF0900_REG_SW2_CFG1 = 0x66,
- PF0900_REG_SW2_CFG2 = 0x67,
- PF0900_REG_SW3_VRUN = 0x68,
- PF0900_REG_SW3_VSTBY = 0x69,
- PF0900_REG_SW3_MODE = 0x6A,
- PF0900_REG_SW3_CFG1 = 0x6B,
- PF0900_REG_SW3_CFG2 = 0x6C,
- PF0900_REG_SW4_VRUN = 0x6D,
- PF0900_REG_SW4_VSTBY = 0x6E,
- PF0900_REG_SW4_MODE = 0x6F,
- PF0900_REG_SW4_CFG1 = 0x70,
- PF0900_REG_SW4_CFG2 = 0x71,
- PF0900_REG_SW5_VRUN = 0x72,
- PF0900_REG_SW5_VSTBY = 0x73,
- PF0900_REG_SW5_MODE = 0x74,
- PF0900_REG_SW5_CFG1 = 0x75,
- PF0900_REG_SW5_CFG2 = 0x76,
- PF0900_REG_LDO1_RUN = 0x77,
- PF0900_REG_LDO1_STBY = 0x78,
- PF0900_REG_LDO1_CFG2 = 0x79,
- PF0900_REG_LDO2_RUN = 0x7A,
- PF0900_REG_LDO2_STBY = 0x7B,
- PF0900_REG_LDO2_CFG2 = 0x7C,
- PF0900_REG_LDO3_RUN = 0x7D,
- PF0900_REG_LDO3_STBY = 0x7E,
- PF0900_REG_LDO3_CFG2 = 0x7F,
- PF0900_REG_VAON_CFG1 = 0x80,
- PF0900_REG_VAON_CFG2 = 0x81,
- PF0900_REG_SYS_DIAG = 0x82,
- PF0900_MAX_REGISTER,
+};
+/* PF0900 SW MODE */ +#define SW_RUN_MODE_OFF 0x00 +#define SW_RUN_MODE_PWM 0x01 +#define SW_RUN_MODE_PFM 0x02 +#define SW_STBY_MODE_OFF 0x00 +#define SW_STBY_MODE_PWM 0x04 +#define SW_STBY_MODE_PFM 0x08
+/* PF0900 SW MODE MASK */ +#define SW_RUN_MODE_MASK 0x03 +#define SW_STBY_MODE_MASK 0x0c
+/* PF0900 SW VRUN MASK */ +#define SW_VRUN_MASK 0xFF +#define SW_STBY_MASK 0xFF
+/* PF0900_REG_VAON_CFG1 bits */ +#define VAON_MASK 0x03 +#define VAON_1P8V 0x01
+/* PF0900_REG_SWX_CFG1 MASK */ +#define SW_RAMP_MASK 0x18
+/* PF0900_REG_LDO1_RUN MASK */ +#define VLDO1_RUN_MASK 0x1F +#define LDO1_RUN_EN_MASK 0x20 +#define LDO1_STBY_EN_MASK 0x20
+/* PF0900_REG_LDO2_RUN MASK */ +#define VLDO2_RUN_MASK 0x1F +#define LDO2_RUN_EN_MASK 0x20 +#define LDO2_STBY_EN_MASK 0x20
+/* PF0900_REG_LDO3_RUN MASK */ +#define VLDO3_RUN_MASK 0x1F +#define LDO3_RUN_EN_MASK 0x20 +#define LDO3_STBY_EN_MASK 0x20
+/* PF0900_REG_GPO_CTRL MASK */ +#define GPO1_RUN_MASK 0x1 +#define GPO2_RUN_MASK 0x2 +#define GPO3_RUN_MASK 0x4 +#define GPO4_RUN_MASK 0x8 +#define GPO1_STBY_MASK 0x10 +#define GPO2_STBY_MASK 0x20 +#define GPO3_STBY_MASK 0x40 +#define GPO4_STBY_MASK 0x80
+/* PF0900_REG_STSTEM_INT bits */ +#define IRQ_EWARN 0x80 +#define IRQ_GPIO 0x40 +#define IRQ_OV 0x20 +#define IRQ_UV 0x10 +#define IRQ_ILIM 0x08 +#define IRQ_MODE 0x04 +#define IRQ_STATUS2 0x02 +#define IRQ_STATUS1 0x01
+/* PF0900_REG_STATUS1_INT bits */ +#define IRQ_SDWN 0x80 +#define IRQ_FREQ_RDY 0x40 +#define IRQ_DCRC 0x20 +#define IRQ_I2C_CRC 0x10 +#define IRQ_PWRUP 0x08 +#define IRQ_PWRDN 0x04 +#define IRQ_FSYNC_FLT 0x02 +#define IRQ_VIN_OV 0x01
+/* PF0900_REG_STATUS2_INT bits */ +#define IRQ_VANA_OV 0x80 +#define IRQ_VDIG_OV 0x40 +#define IRQ_BGMON 0x20 +#define IRQ_CLKMON 0x10 +#define IRQ_THERM_155 0x08 +#define IRQ_THERM_140 0x04 +#define IRQ_THERM_125 0x02 +#define IRQ_THERM_110 0x01
+/* PF0900_REG_STATUS3_INT bits */ +#define IRQ_BAD_CMD 0x04 +#define IRQ_LBIST_DONE 0x02 +#define IRQ_SHS 0x01
+#endif
2.35.3

On Tue, Oct 08, 2024 at 03:42:52PM +0000, Peng Fan wrote:
Hi Fabio, Tom
Seems Jaehoon is inactive. Will you help manage the the power related patchset or I could use fsl-qoirq tree to manage these drivers for i.MX?
I'll take a look through things and pick them up soon, thanks.

Subject: Re: [PATCH 1/2] power: pmic: Support pmic pf0900
On Tue, Oct 08, 2024 at 03:42:52PM +0000, Peng Fan wrote:
Hi Fabio, Tom
Seems Jaehoon is inactive. Will you help manage the the power
related
patchset or I could use fsl-qoirq tree to manage these drivers for i.MX?
I'll take a look through things and pick them up soon, thanks.
Appreciate your help on this.
Thanks, Peng.
-- Tom

On Mon, Sep 30, 2024 at 11:22:42AM +0800, Peng Fan (OSS) wrote:
From: Joy Zou joy.zou@nxp.com
Support NXP pmic pf0900
Reviewed-by: Ye Li ye.li@nxp.com Signed-off-by: Joy Zou joy.zou@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com
drivers/power/pmic/Kconfig | 15 ++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pf0900.c | 174 +++++++++++++++++++++++ include/power/pf0900.h | 269 ++++++++++++++++++++++++++++++++++++ 4 files changed, 459 insertions(+) create mode 100644 drivers/power/pmic/pf0900.c create mode 100644 include/power/pf0900.h
No MAINTAINERS update for this file. And
[snip]
+static u8 crc8_j1850(u8 *data, u8 length) +{
- u8 t_crc;
- u8 i, j;
- t_crc = 0xFF;
- for (i = 0; i < length; i++) {
t_crc ^= data[i];
for (j = 0; j < 8; j++) {
if ((t_crc & 0x80) != 0) {
t_crc <<= 1;
t_crc ^= 0x1D;
} else {
t_crc <<= 1;
}
}
- }
- return t_crc;
+}
This gets repeated in other drivers and I gather this is "CRC8 SAE J1850" algorithm? This should get put in lib/crc8.c and re-used as needed.

On Sun, Sep 29, 2024 at 11:19 PM Peng Fan (OSS) peng.fan@oss.nxp.com wrote:
+static int pf0900_read(struct udevice *dev, uint reg, u8 *buff,
int len)
+{
u8 crcBuf[3];
crc_buf[3] instead to avoid CamelCase.
participants (4)
-
Fabio Estevam
-
Peng Fan
-
Peng Fan (OSS)
-
Tom Rini