diff --git a/CODEOWNERS b/CODEOWNERS index 536a7ae1bf6..bde68572b59 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -315,6 +315,7 @@ /drivers/pwm/pwm_shell.c @henrikbrixandersen /drivers/pwm/*gecko* @sun681 /drivers/pwm/*it8xxx2* @RuibinChang +/drivers/regulator/*pmic* @danieldegrasse /drivers/sensor/ @MaureenHelm /drivers/sensor/ams_iAQcore/ @alexanderwachter /drivers/sensor/ens210/ @alexanderwachter diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts index 030cdbf177a..fd9bb43c2da 100644 --- a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts +++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts @@ -8,6 +8,7 @@ #include #include +#include / { model = "NXP MIMXRT685-EVK board"; @@ -203,6 +204,79 @@ i2s1: &flexcomm3 { dma-names = "tx"; }; +/* PCA9420 PMIC */ +&pmic_i2c { + status = "okay"; + compatible = "nxp,lpc-i2c"; + label = "PMIC_I2C"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + + pca9420: pca9420@61 { + label = "PCA9420_PMIC"; + reg = <0x61>; + + pca9420_sw1: sw1_buck { + label = "SW1_BUCK_REG"; + compatible = "regulator-pmic"; + voltage-range = ; + num-voltages = <42>; + vsel-reg = ; + vsel-mask = ; + enable-reg = ; + enable-mask = ; + enable-val = ; + min-uV = <500000>; + max-uV = <1800000>; + }; + + pca9420_sw2: sw2_buck { + label = "SW2_BUCK_REG"; + compatible = "regulator-pmic"; + voltage-range = ; + num-voltages = <50>; + vsel-reg = ; + vsel-mask = ; + enable-reg = ; + enable-mask = ; + enable-val = ; + min-uV = <1500000>; + max-uV = <3300000>; + }; + + pca9420_ldo1: ldo1_reg { + label = "LDO1_REG"; + compatible = "regulator-pmic"; + voltage-range = ; + num-voltages = <9>; + vsel-reg = ; + vsel-mask = ; + enable-reg = ; + enable-mask = ; + enable-val = ; + min-uV = <1700000>; + max-uV = <1900000>; + }; + + pca9420_ldo2: ldo2_reg { + label = "LDO2_REG"; + compatible = "regulator-pmic"; + voltage-range = ; + num-voltages = <50>; + vsel-reg = ; + vsel-mask = ; + enable-reg = ; + enable-mask = ; + enable-val = ; + min-uV = <1500000>; + max-uV = <3300000>; + }; + + + }; +}; + &flexspi { mx25um51345g: mx25um51345g@2 { compatible = "nxp,imx-flexspi-mx25um51345g"; diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index e89256d815b..41280d1ffac 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -4,3 +4,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_REGULATOR_FIXED regulator_fixed.c) +zephyr_library_sources_ifdef(CONFIG_REGULATOR_PMIC regulator_pmic.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 5fd18e2f85c..840929b7e16 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -13,5 +13,6 @@ module-str = regulator source "subsys/logging/Kconfig.template.log_config" source "drivers/regulator/Kconfig.fixed" +source "drivers/regulator/Kconfig.pmic" endif # REGULATOR diff --git a/drivers/regulator/Kconfig.pmic b/drivers/regulator/Kconfig.pmic new file mode 100644 index 00000000000..69dd44e6a5a --- /dev/null +++ b/drivers/regulator/Kconfig.pmic @@ -0,0 +1,22 @@ +# Copyright (c) 2021, NXP +# SPDX -License-Identifier: Apache-2.0 + +DT_COMPAT_PMIC_REG := regulator-pmic + +config REGULATOR_PMIC + bool "PMIC Regulator Driver" + depends on $(dt_compat_enabled,$(DT_COMPAT_PMIC_REG)) + default $(dt_compat_enabled,$(DT_COMPAT_PMIC_REG)) + select I2C + help + Enable the pmic regulator driver + +config PMIC_REGULATOR_INIT_PRIORITY + int "Regulator Init priority" + depends on REGULATOR_PMIC + default 75 + help + I2C based regulator init priority. + Must be greater than KERNEL_INIT_PRIORITY_DEVICE so I2C is initialized, + and less than SDMMC_INIT_PRIORITY, since the SDMMC driver uses an I2C + PMIC regulator diff --git a/drivers/regulator/regulator_pmic.c b/drivers/regulator/regulator_pmic.c new file mode 100644 index 00000000000..a7516ceb994 --- /dev/null +++ b/drivers/regulator/regulator_pmic.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2021 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief PMIC Regulator Driver + * This driver implements the regulator API within Zephyr, and additionally + * implements support for a broader API. Most consumers will want to use + * the API provided in drivers/regulator/consumer.h to manipulate the voltage + * levels of the regulator device. + * manipulate. + */ + +#define DT_DRV_COMPAT regulator_pmic + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(pmic_regulator, CONFIG_REGULATOR_LOG_LEVEL); + +struct regulator_data { + struct onoff_sync_service srv; +}; + +struct __packed voltage_range { + int uV; /* Voltage in uV */ + int reg_val; /* Register value for voltage */ +}; + +struct regulator_config { + struct voltage_range *voltages; + int num_voltages; + uint8_t vsel_reg; + uint8_t vsel_mask; + uint32_t max_uV; + uint32_t min_uV; + uint8_t enable_reg; + uint8_t enable_mask; + uint8_t enable_val; + bool enable_inverted; + uint8_t i2c_address; + const struct device *i2c_dev; + uint32_t voltage_array[]; +}; + +/** + * Modifies a register within the PMIC + * Returns 0 on success, or errno on error + */ +static int regulator_modify_register(const struct regulator_config *conf, + uint8_t reg, uint8_t reg_mask, uint8_t reg_val) +{ + uint8_t reg_current; + int rc; + + rc = i2c_reg_read_byte(conf->i2c_dev, conf->i2c_address, + reg, ®_current); + if (rc) { + return rc; + } + reg_current &= ~reg_mask; + reg_current |= reg_val; + return i2c_reg_write_byte(conf->i2c_dev, conf->i2c_address, reg, + reg_current); +} + + +/** + * Part of the extended regulator consumer API + * Returns the number of supported voltages + */ +int regulator_count_voltages(const struct device *dev) +{ + return ((struct regulator_config *)dev->config)->num_voltages; +} + +/** + * Part of the extended regulator consumer API + * Returns the supported voltage in uV for a given selector value + */ +int regulator_list_voltages(const struct device *dev, unsigned int selector) +{ + const struct regulator_config *config = dev->config; + + if (config->num_voltages <= selector) { + return -ENODEV; + } + return config->voltages[selector].uV; +} + +int regulator_is_supported_voltage(const struct device *dev, + int min_uV, int max_uV) +{ + const struct regulator_config *config = dev->config; + + return !((config->max_uV < min_uV) || (config->min_uV > max_uV)); +} + + + +static int enable_regulator(const struct device *dev, struct onoff_client *cli) +{ + k_spinlock_key_t key; + int rc; + uint8_t en_val; + struct regulator_data *data = dev->data; + const struct regulator_config *config = dev->config; + + LOG_DBG("Enabling regulator"); + rc = onoff_sync_lock(&data->srv, &key); + if (rc) { + /* Request has already enabled PMIC */ + return onoff_sync_finalize(&data->srv, key, cli, rc, true); + } + en_val = config->enable_inverted ? 0 : config->enable_val; + rc = regulator_modify_register(config, config->enable_reg, + config->enable_reg, en_val); + if (rc) { + return onoff_sync_finalize(&data->srv, key, NULL, rc, false); + } + return onoff_sync_finalize(&data->srv, key, cli, rc, true); +} + +static int disable_regulator(const struct device *dev) +{ + struct regulator_data *data = dev->data; + const struct regulator_config *config = dev->config; + k_spinlock_key_t key; + uint8_t dis_val; + int rc; + + LOG_DBG("Disabling regulator"); + rc = onoff_sync_lock(&data->srv, &key); + if (rc == 0) { + rc = -EINVAL; + return onoff_sync_finalize(&data->srv, key, NULL, rc, false); + } + dis_val = config->enable_inverted ? config->enable_val : 0; + rc = regulator_modify_register(config, config->enable_reg, + config->enable_reg, dis_val); + if (rc) { + /* Error writing configs */ + return onoff_sync_finalize(&data->srv, key, NULL, rc, true); + } + return onoff_sync_finalize(&data->srv, key, NULL, rc, true); +} + +static int pmic_reg_init(const struct device *dev) +{ + struct regulator_config *config = (struct regulator_config *)dev->config; + + LOG_INF("PMIC regulator initializing"); + /* Cast the voltage array set at compile time to the voltage range + * struct + */ + config->voltages = (struct voltage_range *)config->voltage_array; + /* Check to verify we have a valid I2C device */ + if (config->i2c_dev == NULL || !device_is_ready(config->i2c_dev)) { + return -ENODEV; + } + return 0; +} + + +static const struct regulator_driver_api api = { + .enable = enable_regulator, + .disable = disable_regulator +}; + +#define CONFIGURE_REGULATOR(id) \ + static struct regulator_data pmic_reg_##id##_data; \ + static struct regulator_config pmic_reg_##id##_cfg = { \ + .vsel_mask = DT_INST_PROP(id, vsel_mask), \ + .vsel_reg = DT_INST_PROP(id, vsel_reg), \ + .num_voltages = DT_INST_PROP(id, num_voltages), \ + .enable_reg = DT_INST_PROP(id, enable_reg), \ + .enable_mask = DT_INST_PROP(id, enable_mask), \ + .enable_val = DT_INST_PROP(id, enable_val), \ + .min_uV = DT_INST_PROP(id, min_uv), \ + .max_uV = DT_INST_PROP(id, max_uv), \ + .enable_inverted = DT_INST_PROP(id, enable_inverted), \ + .i2c_address = DT_REG_ADDR(DT_PARENT(DT_DRV_INST(id))), \ + .i2c_dev = DEVICE_DT_GET(DT_BUS(DT_PARENT(DT_DRV_INST(id)))), \ + .voltage_array = DT_INST_PROP(id, voltage_range), \ + }; \ + DEVICE_DT_INST_DEFINE(id, pmic_reg_init, NULL, \ + &pmic_reg_##id##_data, &pmic_reg_##id##_cfg, \ + POST_KERNEL, CONFIG_PMIC_REGULATOR_INIT_PRIORITY, \ + &api); \ + +DT_INST_FOREACH_STATUS_OKAY(CONFIGURE_REGULATOR) diff --git a/dts/bindings/regulator/regulator-pmic.yaml b/dts/bindings/regulator/regulator-pmic.yaml new file mode 100644 index 00000000000..c196e4df026 --- /dev/null +++ b/dts/bindings/regulator/regulator-pmic.yaml @@ -0,0 +1,65 @@ +# Copyright (c), 2021 NXP +# SPDX -License-Identifier: Apache-2.0 + +description: PMIC controlled regulator + +include: regulator.yaml + +compatible: "regulator-pmic" + +properties: + label: + required: false + voltage-range: + type: array + required: true + description: | + array of voltage values in uV, followed by the register value that + must be written to enable the voltage. For example, [3300000, 0x3] + denotes a value of 0x3 must be written to the register to set 3.3V + num-voltages: + type: int + required: true + description: number of voltages present in the voltage-range array. + vsel-reg: + type: int + required: true + description: I2C register to write voltage selection value to + vsel-mask: + type: int + required: true + description: | + Mask to apply to the voltage range value when written to vsel + register + enable-reg: + type: int + required: true + description: I2C register to write enable value to + enable-mask: + type: int + required: true + description: | + Mask to apply to the enable bit (either 1 for enabled, + or 0 for disabled) when writing it to the I2C enable register. + enable-val: + type: int + required: true + description: | + value to apply enable-mask to, and write to enable-reg in order + to enable the regulator output. + min-uV: + type: int + required: true + description: | + Minimum voltage in microvolts that this regulator supports + max-uV: + type: int + required: true + description: | + Maximum voltage in microvolts that this regulator supports + enable-inverted: + type: boolean + required: false + description: | + If the enable bit should be zero to turn the regulator on, add this + property. diff --git a/include/drivers/regulator/consumer.h b/include/drivers/regulator/consumer.h new file mode 100644 index 00000000000..d388ef37e53 --- /dev/null +++ b/include/drivers/regulator/consumer.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2021 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Regulator consumer API based on linux regulator API + * + * This API extends the Zephyr regulator API by implementing voltage + * and current level control for supported regulators. Currently, the only + * supported device is the NXP PCA9420 PMIC. + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PMIC_CONSUMER_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PMIC_CONSUMER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Return the number of supported voltage levels + * Returns the number of selectors, or negative errno. Selectors are + * numbered starting at zero, and typically correspond to bitfields + * in hardware registers. + * + * @param dev: Regulator device to count voltage levels for. + * @return number of selectors, or negative errno. + */ +int regulator_count_voltages(const struct device *dev); + +/** + * @brief Return supported voltage + * Returns a voltage that can be passed to @ref regulator_set_voltage(), zero + * if the selector code can't be used, or a negative errno. + * + * @param dev: Regulator device to get voltage for. + * @param selector: voltage selector code. + * @return voltage level in uV, or zero if selector code can't be used. + */ +int regulator_list_voltages(const struct device *dev, unsigned int selector); + +/** + * @brief Check if a voltage range can be supported. + * + * @param dev: Regulator to check range against. + * @param min_uV: Minimum voltage in microvolts + * @param max_uV: maximum voltage in microvolts + * @returns boolean or negative error code. + */ +int regulator_is_supported_voltage(const struct device *dev, int min_uV, int max_uV); + +/** + * @brief Set regulator output voltage. + * Sets a regulator to the closest supported output voltage. + * @param dev: Regulator to set voltage + * @param min_uV: Minimum acceptable voltage in microvolts + * @param max_uV: Maximum acceptable voltage in microvolts + */ +int regulator_set_voltage(const struct device *dev, int min_uV, int max_uV); + +/** + * @brief Get regulator output voltage. + * Returns the current regulator voltage in microvolts + * + * @param dev: Regulator to query + * @return voltage level in uV + */ +int regulator_get_voltage(const struct device *dev); + +/** + * @brief Set regulator output current limit + * Sets current sink to desired output current. + * @param dev: Regulator to set output current level + * @param min_uA: minimum microamps + * @param max_uA: maximum microamps + * @return 0 on success, or errno on error + */ +int regulator_set_current_limit(const struct device *dev); + +/** + * @brief Get regulator output current. + * Note the current limit must have been set for this call to succeed. + * @param dev: Regulator to query + * @return current limit in uA, or errno + */ +int regulator_get_current_limit(const struct device *dev); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dt-bindings/regulator/pca9420_i2c.h b/include/dt-bindings/regulator/pca9420_i2c.h new file mode 100644 index 00000000000..d6b64e2b885 --- /dev/null +++ b/include/dt-bindings/regulator/pca9420_i2c.h @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2021, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_I2C_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_I2C_H_ + +/* + * Voltage Ranges should be defined without commas, spaces, or brackets. These + * ranges will be inserted directly into the devicetree as arrays, so that the + * driver can parse them. + */ +#define PCA9420_SW1_VOLTAGE_RANGE \ + 500000 0x00 /* SW1 output voltage 0.500V. */\ + 525000 0x01 /* SW1 output voltage 0.525V. */\ + 550000 0x02 /* SW1 output voltage 0.550V. */\ + 575000 0x03 /* SW1 output voltage 0.575V. */\ + 600000 0x04 /* SW1 output voltage 0.600V. */\ + 625000 0x05 /* SW1 output voltage 0.625V. */\ + 650000 0x06 /* SW1 output voltage 0.650V. */\ + 675000 0x07 /* SW1 output voltage 0.675V. */\ + 700000 0x08 /* SW1 output voltage 0.700V. */\ + 725000 0x09 /* SW1 output voltage 0.725V. */\ + 750000 0x0A /* SW1 output voltage 0.750V. */\ + 775000 0x0B /* SW1 output voltage 0.775V. */\ + 800000 0x0C /* SW1 output voltage 0.800V. */\ + 825000 0x0D /* SW1 output voltage 0.825V. */\ + 850000 0x0E /* SW1 output voltage 0.850V. */\ + 875000 0x0F /* SW1 output voltage 0.875V. */\ + 900000 0x10 /* SW1 output voltage 0.900V. */\ + 925000 0x11 /* SW1 output voltage 0.925V. */\ + 950000 0x12 /* SW1 output voltage 0.950V. */\ + 975000 0x13 /* SW1 output voltage 0.975V. */\ + 1000000 0x14 /* SW1 output voltage 1.000V. */\ + 1025000 0x15 /* SW1 output voltage 1.025V. */\ + 1050000 0x16 /* SW1 output voltage 1.050V. */\ + 1075000 0x17 /* SW1 output voltage 1.075V. */\ + 1100000 0x18 /* SW1 output voltage 1.100V. */\ + 1125000 0x19 /* SW1 output voltage 1.125V. */\ + 1150000 0x1A /* SW1 output voltage 1.150V. */\ + 1175000 0x1B /* SW1 output voltage 1.175V. */\ + 1200000 0x1C /* SW1 output voltage 1.200V. */\ + 1225000 0x1D /* SW1 output voltage 1.225V. */\ + 1250000 0x1E /* SW1 output voltage 1.250V. */\ + 1275000 0x1F /* SW1 output voltage 1.275V. */\ + 1300000 0x20 /* SW1 output voltage 1.300V. */\ + 1325000 0x21 /* SW1 output voltage 1.325V. */\ + 1350000 0x22 /* SW1 output voltage 1.350V. */\ + 1375000 0x23 /* SW1 output voltage 1.375V. */\ + 1400000 0x24 /* SW1 output voltage 1.400V. */\ + 1425000 0x25 /* SW1 output voltage 1.425V. */\ + 1450000 0x26 /* SW1 output voltage 1.450V. */\ + 1475000 0x27 /* SW1 output voltage 1.475V. */\ + 1500000 0x28 /* SW1 output voltage 1.500V. */\ + 1800000 0x3F /* SW1 output voltage 1.800V. */\ + +#define PCA9420_SW2_VOLTAGE_RANGE \ + 1500000 0x00 /* SW2 output voltage 1.500V. */\ + 1525000 0x01 /* SW2 output voltage 1.525V. */\ + 1550000 0x02 /* SW2 output voltage 1.550V. */\ + 1575000 0x03 /* SW2 output voltage 1.575V. */\ + 1600000 0x04 /* SW2 output voltage 1.600V. */\ + 1625000 0x05 /* SW2 output voltage 1.625V. */\ + 1650000 0x06 /* SW2 output voltage 1.650V. */\ + 1675000 0x07 /* SW2 output voltage 1.675V. */\ + 1700000 0x08 /* SW2 output voltage 1.700V. */\ + 1725000 0x09 /* SW2 output voltage 1.725V. */\ + 1750000 0x0A /* SW2 output voltage 1.750V. */\ + 1775000 0x0B /* SW2 output voltage 1.775V. */\ + 1800000 0x0C /* SW2 output voltage 1.800V. */\ + 1825000 0x0D /* SW2 output voltage 1.825V. */\ + 1850000 0x0E /* SW2 output voltage 1.850V. */\ + 1875000 0x0F /* SW2 output voltage 1.875V. */\ + 1900000 0x10 /* SW2 output voltage 1.900V. */\ + 1925000 0x11 /* SW2 output voltage 1.925V. */\ + 1950000 0x12 /* SW2 output voltage 1.950V. */\ + 1975000 0x13 /* SW2 output voltage 1.975V. */\ + 2000000 0x14 /* SW2 output voltage 2.000V. */\ + 2025000 0x15 /* SW2 output voltage 2.025V. */\ + 2050000 0x16 /* SW2 output voltage 2.050V. */\ + 2075000 0x17 /* SW2 output voltage 2.075V. */\ + 2100000 0x18 /* SW2 output voltage 2.100V. */\ + 2700000 0x20 /* SW2 output voltage 2.700V. */\ + 2725000 0x21 /* SW2 output voltage 2.725V. */\ + 2750000 0x22 /* SW2 output voltage 2.750V. */\ + 2775000 0x23 /* SW2 output voltage 2.775V. */\ + 2800000 0x24 /* SW2 output voltage 2.800V. */\ + 2825000 0x25 /* SW2 output voltage 2.825V. */\ + 2850000 0x26 /* SW2 output voltage 2.850V. */\ + 2875000 0x27 /* SW2 output voltage 2.875V. */\ + 2900000 0x28 /* SW2 output voltage 2.900V. */\ + 2925000 0x29 /* SW2 output voltage 2.925V. */\ + 2950000 0x2A /* SW2 output voltage 2.950V. */\ + 2975000 0x2B /* SW2 output voltage 2.975V. */\ + 3000000 0x2C /* SW2 output voltage 3.000V. */\ + 3025000 0x2D /* SW2 output voltage 3.025V. */\ + 3050000 0x2E /* SW2 output voltage 3.050V. */\ + 3075000 0x2F /* SW2 output voltage 3.075V. */\ + 3100000 0x30 /* SW2 output voltage 3.100V. */\ + 3125000 0x31 /* SW2 output voltage 3.125V. */\ + 3150000 0x32 /* SW2 output voltage 3.150V. */\ + 3175000 0x33 /* SW2 output voltage 3.175V. */\ + 3200000 0x34 /* SW2 output voltage 3.200V. */\ + 3225000 0x35 /* SW2 output voltage 3.225V. */\ + 3250000 0x36 /* SW2 output voltage 3.250V. */\ + 3275000 0x37 /* SW2 output voltage 3.275V. */\ + 3300000 0x38 /* SW2 output voltage 3.300V. */\ + +#define PCA9420_LDO1_VOLTAGE_RANGE \ + 1700000 0x00 /* LDO1 output voltage 1.700V. */\ + 1725000 0x10 /* LDO1 output voltage 1.725V. */\ + 1750000 0x20 /* LDO1 output voltage 1.750V. */\ + 1775000 0x30 /* LDO1 output voltage 1.775V. */\ + 1800000 0x40 /* LDO1 output voltage 1.800V. */\ + 1825000 0x50 /* LDO1 output voltage 1.825V. */\ + 1850000 0x60 /* LDO1 output voltage 1.850V. */\ + 1875000 0x70 /* LDO1 output voltage 1.875V. */\ + 1900000 0x80 /* LDO1 output voltage 1.900V. */\ + +#define PCA9420_LDO2_VOLTAGE_RANGE \ + 1500000 0x00 /* LDO2 output voltage 1.500V. */\ + 1525000 0x01 /* LDO2 output voltage 1.525V. */\ + 1550000 0x02 /* LDO2 output voltage 1.550V. */\ + 1575000 0x03 /* LDO2 output voltage 1.575V. */\ + 1600000 0x04 /* LDO2 output voltage 1.600V. */\ + 1625000 0x05 /* LDO2 output voltage 1.625V. */\ + 1650000 0x06 /* LDO2 output voltage 1.650V. */\ + 1675000 0x07 /* LDO2 output voltage 1.675V. */\ + 1700000 0x08 /* LDO2 output voltage 1.700V. */\ + 1725000 0x09 /* LDO2 output voltage 1.725V. */\ + 1750000 0x0A /* LDO2 output voltage 1.750V. */\ + 1775000 0x0B /* LDO2 output voltage 1.775V. */\ + 1800000 0x0C /* LDO2 output voltage 1.800V. */\ + 1825000 0x0D /* LDO2 output voltage 1.825V. */\ + 1850000 0x0E /* LDO2 output voltage 1.850V. */\ + 1875000 0x0F /* LDO2 output voltage 1.875V. */\ + 1900000 0x10 /* LDO2 output voltage 1.900V. */\ + 1925000 0x11 /* LDO2 output voltage 1.925V. */\ + 1950000 0x12 /* LDO2 output voltage 1.950V. */\ + 1975000 0x13 /* LDO2 output voltage 1.975V. */\ + 2000000 0x14 /* LDO2 output voltage 2.000V. */\ + 2025000 0x15 /* LDO2 output voltage 2.025V. */\ + 2050000 0x16 /* LDO2 output voltage 2.050V. */\ + 2075000 0x17 /* LDO2 output voltage 2.075V. */\ + 2100000 0x18 /* LDO2 output voltage 2.100V. */\ + 2700000 0x20 /* LDO2 output voltage 2.700V. */\ + 2725000 0x21 /* LDO2 output voltage 2.725V. */\ + 2750000 0x22 /* LDO2 output voltage 2.750V. */\ + 2775000 0x23 /* LDO2 output voltage 2.775V. */\ + 2800000 0x24 /* LDO2 output voltage 2.800V. */\ + 2825000 0x25 /* LDO2 output voltage 2.825V. */\ + 2850000 0x26 /* LDO2 output voltage 2.850V. */\ + 2875000 0x27 /* LDO2 output voltage 2.875V. */\ + 2900000 0x28 /* LDO2 output voltage 2.900V. */\ + 2925000 0x29 /* LDO2 output voltage 2.925V. */\ + 2950000 0x2A /* LDO2 output voltage 2.950V. */\ + 2975000 0x2B /* LDO2 output voltage 2.975V. */\ + 3000000 0x2C /* LDO2 output voltage 3.000V. */\ + 3025000 0x2D /* LDO2 output voltage 3.025V. */\ + 3050000 0x2E /* LDO2 output voltage 3.050V. */\ + 3075000 0x2F /* LDO2 output voltage 3.075V. */\ + 3100000 0x30 /* LDO2 output voltage 3.100V. */\ + 3125000 0x31 /* LDO2 output voltage 3.125V. */\ + 3150000 0x32 /* LDO2 output voltage 3.150V. */\ + 3175000 0x33 /* LDO2 output voltage 3.175V. */\ + 3200000 0x34 /* LDO2 output voltage 3.200V. */\ + 3225000 0x35 /* LDO2 output voltage 3.225V. */\ + 3250000 0x36 /* LDO2 output voltage 3.250V. */\ + 3275000 0x37 /* LDO2 output voltage 3.275V. */\ + 3300000 0x38 /* LDO2 output voltage 3.300V. */\ + +#define PCA9420_CURRENT_LIMIT_LEVELS \ + 85000 0x00 /* min: 74mA, typ: 85mA, max: 98mA */\ + 225000 0x20 /* min: 222mA, typ: 225mA, max: 293mA */\ + 425000 0x40 /* min: 370mA, typ: 425mA, max: 489mA */\ + 595000 0x60 /* min: 517mA, typ: 595mA, max: 684mA */\ + 765000 0x80 /* min: 665mA, typ: 765mA, max: 880mA */\ + 935000 0xA0 /* min: 813mA, typ: 935mA, max: 1075mA */\ + 1105000 0xC0 /* min: 961mA, typ: 1105mA, max: 1271mA */\ + + + +/** Register memory map. See datasheet for more details. */ +/** General purpose registers */ +/** @brief Device Information register */ +#define PCA9420_DEV_INFO 0x00U +/** @brief Top level interrupt status */ +#define PCA9420_TOP_INT 0x01U +/** @brief Sub level interrupt 0 indication */ +#define PCA9420_SUB_INT0 0x02U +/*! @brief Sub level interrupt 0 mask */ +#define PCA9420_SUB_INT0_MASK 0x03U +/** @brief Sub level interrupt 1 indication */ +#define PCA9420_SUB_INT1 0x04U +/** @brief Sub level interrupt 1 mask */ +#define PCA9420_SUB_INT1_MASK 0x05U +/** @brief Sub level interrupt 2 indication */ +#define PCA9420_SUB_INT2 0x06U +/** @brief Sub level interrupt 2 mask */ +#define PCA9420_SUB_INT2_MASK 0x07U +/** @brief Top level system ctrl 0 */ +#define PCA9420_TOP_CNTL0 0x09U +/** @brief Top level system ctrl 1 */ +#define PCA9420_TOP_CNTL1 0x0AU +/** @brief Top level system ctrl 2 */ +#define PCA9420_TOP_CNTL2 0x0BU +/** @brief Top level system ctrl 3 */ +#define PCA9420_TOP_CNTL3 0x0CU +/** @brief Top level system ctrl 4 */ +#define PCA9420_TOP_CNTL4 0x0DU + +/** Battery charger registers */ +/** @brief Charger cntl reg 0 */ +#define PCA9420_CHG_CNTL0 0x10U +/** @brief Charger cntl reg 1 */ +#define PCA9420_CHG_CNTL1 0x11U +/** @brief Charger cntl reg 2 */ +#define PCA9420_CHG_CNTL2 0x12U +/** @brief Charger cntl reg 3 */ +#define PCA9420_CHG_CNTL3 0x13U +/** @brief Charger cntl reg 4 */ +#define PCA9420_CHG_CNTL4 0x14U +/** @brief Charger cntl reg 5 */ +#define PCA9420_CHG_CNTL5 0x15U +/** @brief Charger cntl reg 6 */ +#define PCA9420_CHG_CNTL6 0x16U +/** @brief Charger cntl reg 7 */ +#define PCA9420_CHG_CNTL7 0x17U +/** @brief Charger status reg 0 */ +#define PCA9420_CHG_STATUS_0 0x18U +/** @brief Charger status reg 1 */ +#define PCA9420_CHG_STATUS_1 0x19U +/** @brief Charger status reg 2 */ +#define PCA9420_CHG_STATUS_2 0x1AU +/** @brief Charger status reg 3 */ +#define PCA9420_CHG_STATUS_3 0x1BU + +/** Regulator status indication registers */ +/** @brief Regulator status indication */ +#define PCA9420_REG_STATUS 0x20U +/** @brief Active discharge control register */ +#define PCA9420_ACT_DISCHARGE_CNTL_1 0x21U +/** @brief Mode configuration for mode 0_0 */ +#define PCA9420_MODECFG_0_0 0x22U +/** @brief Mode configuration for mode 0_1 */ +#define PCA9420_MODECFG_0_1 0x23U +/** @brief Mode configuration for mode 0_2 */ +#define PCA9420_MODECFG_0_2 0x24U +/** @brief Mode configuration for mode 0_3 */ +#define PCA9420_MODECFG_0_3 0x25U +/** @brief Mode configuration for mode 1_0 */ +#define PCA9420_MODECFG_1_0 0x26U +/** @brief Mode configuration for mode 1_1 */ +#define PCA9420_MODECFG_1_1 0x27U +/** @brief Mode configuration for mode 1_2 */ +#define PCA9420_MODECFG_1_2 0x28U +/** @brief Mode configuration for mode 1_3 */ +#define PCA9420_MODECFG_1_3 0x29U +/** @brief Mode configuration for mode 2_0 */ +#define PCA9420_MODECFG_2_0 0x2AU +/** @brief Mode configuration for mode 2_1 */ +#define PCA9420_MODECFG_2_1 0x2BU +/** @brief Mode configuration for mode 2_2 */ +#define PCA9420_MODECFG_2_2 0x2CU +/** @brief Mode configuration for mode 2_3 */ +#define PCA9420_MODECFG_2_3 0x2DU +/** @brief Mode configuration for mode 3_0 */ +#define PCA9420_MODECFG_3_0 0x2EU +/** @brief Mode configuration for mode 3_1 */ +#define PCA9420_MODECFG_3_1 0x2FU +/** @brief Mode configuration for mode 3_2 */ +#define PCA9420_MODECFG_3_2 0x30U +/** @brief Mode configuration for mode 3_3 */ +#define PCA9420_MODECFG_3_3 0x31U + +/** Define the Register Masks of PCA9420. */ +/** @brief Device ID mask */ +#define PCA9420_DEV_INFO_DEV_ID_MASK 0xF0U +#define PCA9420_DEV_INFO_DEV_ID_SHIFT 0x04U +/** @brief Device revision mask */ +#define PCA9420_DEV_INFO_DEV_REV_MASK 0x0FU +#define PCA9420_DEV_INFO_DEV_REV_SHIFT 0x00U +/** @brief System level interrupt trigger */ +#define PCA9420_TOP_INT_SYS_INT_MASK 0x01U +#define PCA9420_TOP_INT_SYS_INT_SHIFT 0x03U +/** @brief charger block interrupt trigger */ +#define PCA9420_TOP_INT_CHG_INT_MASK 0x01U +#define PCA9420_TOP_INT_CHG_INT_SHIFT 0x02U +/** @brief buck regulator interrupt trigger */ +#define PCA9420_TOP_INT_SW_INT_MASK 0x01U +#define PCA9420_TOP_INT_SW_INT_SHIFT 0x01U +/** @brief ldo block interrupt trigger */ +#define PCA9420_TOP_INT_LDO_INT_MASK 0x01U +#define PCA9420_TOP_INT_LDO_INT_SHIFT 0x00U + +/** @brief VIN input current limit selection */ +#define PCA9420_TOP_CNTL0_VIN_ILIM_SEL_MASK 0xE0U +#define PCA9420_TOP_CNTL0_VIN_ILIM_SEL_SHIFT 0x05U + +/** @brief I2C Mode control mask */ +#define PCA9420_TOP_CNTL3_MODE_I2C_MASK 0x18U +#define PCA9420_TOP_CNTL3_MODE_I2C_SHIFT 0x03U +/** @brief Mode ship enable mask */ +#define PCA9420_MODECFG_0_SHIP_EN_MASK 0x80U +/* + * @brief Mode control selection mask. When this bit is set, the external + * PMIC pins MODESEL0 and MODESEL1 can be used to select the active mode + */ +#define PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK 0x40U +/** @brief Mode output voltage mask */ +#define PCA9420_MODECFG_0_SW1_OUT_MASK 0x3FU +/* + * @brief Mode configuration upon falling edge applied to ON pin. If set, + * the device will switch to mode 0 when a valid falling edge is applied. + * to the ON pin + */ +#define PCA9420_MODECFG_1_ON_CFG_MASK 0x40U +/** @brief SW2_OUT offset and voltage level mask */ +#define PCA9420_MODECFG_1_SW2_OUT_MASK 0x3FU +/** @brief LDO1_OUT voltage level mask */ +#define PCA9420_MODECFG_2_LDO1_OUT_MASK 0xF0U +#define PCA9420_MODECFG_2_LDO1_OUT_SHIFT 0x04U +/** @brief SW1 Enable */ +#define PCA9420_MODECFG_2_SW1_EN_MASK 0x08U +#define PCA9420_MODECFG_2_SW1_EN_VAL 0x08U +/** @brief SW2 Enable */ +#define PCA9420_MODECFG_2_SW2_EN_MASK 0x04U +#define PCA9420_MODECFG_2_SW2_EN_VAL 0x04U +/** @brief LDO1 Enable */ +#define PCA9420_MODECFG_2_LDO1_EN_MASK 0x02U +#define PCA9420_MODECFG_2_LDO1_EN_VAL 0x02U +/** @brief LDO2 Enable */ +#define PCA9420_MODECFG_2_LDO2_EN_MASK 0x01U +#define PCA9420_MODECFG_2_LDO2_EN_VAL 0x01U +/** @brief Watchdog timer setting mask */ +#define PCA9420_MODECFG_3_WDIMER_MASK 0xC0U +/** @brief LDO2_OUT offset and voltage level mask */ +#define PCA9420_MODECFG_3_LDO2_OUT_MASK 0x3FU + + + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_I2C_H_*/