diff --git a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts index c2b252865b7..b689470ed48 100644 --- a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts +++ b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts @@ -156,9 +156,9 @@ arduino_serial: &flexcomm12 { pca9420: pca9420@61 { reg = <0x61>; + compatible = "regulator-pmic"; pca9420_sw1: sw1_buck { - compatible = "regulator-pmic"; voltage-range = ; current-levels = ; num-voltages = <42>; @@ -175,7 +175,6 @@ arduino_serial: &flexcomm12 { }; pca9420_sw2: sw2_buck { - compatible = "regulator-pmic"; voltage-range = ; num-voltages = <50>; current-levels = ; @@ -192,7 +191,6 @@ arduino_serial: &flexcomm12 { }; pca9420_ldo1: ldo1_reg { - compatible = "regulator-pmic"; voltage-range = ; num-voltages = <9>; current-levels = ; @@ -209,7 +207,6 @@ arduino_serial: &flexcomm12 { }; pca9420_ldo2: ldo2_reg { - compatible = "regulator-pmic"; voltage-range = ; num-voltages = <50>; current-levels = ; diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts index 844dd6b2d29..532738fba6f 100644 --- a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts +++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts @@ -230,9 +230,9 @@ i2s1: &flexcomm3 { pca9420: pca9420@61 { reg = <0x61>; + compatible = "regulator-pmic"; pca9420_sw1: sw1_buck { - compatible = "regulator-pmic"; voltage-range = ; current-levels = ; num-voltages = <42>; @@ -249,7 +249,6 @@ i2s1: &flexcomm3 { }; pca9420_sw2: sw2_buck { - compatible = "regulator-pmic"; voltage-range = ; num-voltages = <50>; current-levels = ; @@ -266,7 +265,6 @@ i2s1: &flexcomm3 { }; pca9420_ldo1: ldo1_reg { - compatible = "regulator-pmic"; voltage-range = ; num-voltages = <9>; current-levels = ; @@ -283,7 +281,6 @@ i2s1: &flexcomm3 { }; pca9420_ldo2: ldo2_reg { - compatible = "regulator-pmic"; voltage-range = ; num-voltages = <50>; current-levels = ; diff --git a/drivers/regulator/regulator_pmic.c b/drivers/regulator/regulator_pmic.c index 04d2cb7ce69..84c7e30ad7e 100644 --- a/drivers/regulator/regulator_pmic.c +++ b/drivers/regulator/regulator_pmic.c @@ -308,32 +308,52 @@ static const struct regulator_driver_api api = { .disable = disable_regulator }; -#define CONFIGURE_REGULATOR(id) \ - static uint32_t pmic_reg_##id##_cur_limits[] = \ - DT_INST_PROP_OR(id, current_levels, {}); \ - static uint32_t pmic_reg_##id##_vol_range[] = \ - DT_INST_PROP(id, voltage_range); \ - 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), \ - .num_current_levels = DT_INST_PROP(id, num_current_levels), \ - .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), \ - .ilim_reg = DT_INST_PROP_OR(id, ilim_reg, 0), \ - .ilim_mask = DT_INST_PROP_OR(id, ilim_mask, 0), \ - .enable_inverted = DT_INST_PROP(id, enable_inverted), \ - .i2c = I2C_DT_SPEC_GET(DT_INST_PARENT(id)), \ - .voltage_array = pmic_reg_##id##_vol_range, \ - .current_array = pmic_reg_##id##_cur_limits, \ + +/* + * Each regulator output will be initialized as a separate device struct, + * and implement the regulator API. Since the DT binding is defined for the + * entire regulator, this macro will be called for each child node of the + * regulator device. This allows the regulator to have common DTS properties + * shared between each regulator output + */ +#define CONFIGURE_REGULATOR_OUTPUT(node, ord) \ + static uint32_t pmic_reg_##ord##_cur_limits[] = \ + DT_PROP_OR(node, current_levels, {}); \ + static uint32_t pmic_reg_##ord##_vol_range[] = \ + DT_PROP(node, voltage_range); \ + static struct regulator_data pmic_reg_##ord##_data; \ + static struct regulator_config pmic_reg_##ord##_cfg = { \ + .vsel_mask = DT_PROP(node, vsel_mask), \ + .vsel_reg = DT_PROP(node, vsel_reg), \ + .num_voltages = DT_PROP(node, num_voltages), \ + .num_current_levels = DT_PROP(node, num_current_levels), \ + .enable_reg = DT_PROP(node, enable_reg), \ + .enable_mask = DT_PROP(node, enable_mask), \ + .enable_val = DT_PROP(node, enable_val), \ + .min_uV = DT_PROP(node, min_uv), \ + .max_uV = DT_PROP(node, max_uv), \ + .ilim_reg = DT_PROP_OR(node, ilim_reg, 0), \ + .ilim_mask = DT_PROP_OR(node, ilim_mask, 0), \ + .enable_inverted = DT_PROP(node, enable_inverted), \ + .i2c = I2C_DT_SPEC_GET(DT_PARENT(node)), \ + .voltage_array = pmic_reg_##ord##_vol_range, \ + .current_array = pmic_reg_##ord##_cur_limits, \ }; \ - DEVICE_DT_INST_DEFINE(id, pmic_reg_init, NULL, \ - &pmic_reg_##id##_data, &pmic_reg_##id##_cfg, \ + DEVICE_DT_DEFINE(node, pmic_reg_init, NULL, \ + &pmic_reg_##ord##_data, \ + &pmic_reg_##ord##_cfg, \ POST_KERNEL, CONFIG_PMIC_REGULATOR_INIT_PRIORITY, \ &api); \ +/* Intermediate macros to extract DT node ordinal + * (used as a unique token for variable names) + */ +#define _CONFIGURE_REGULATOR_OUTPUT(node, ord) \ + CONFIGURE_REGULATOR_OUTPUT(node, ord) + +#define __CONFIGURE_REGULATOR_OUTPUT(node) \ + _CONFIGURE_REGULATOR_OUTPUT(node, DT_DEP_ORD(node)) + +#define CONFIGURE_REGULATOR(id) \ + DT_INST_FOREACH_CHILD(id, __CONFIGURE_REGULATOR_OUTPUT) DT_INST_FOREACH_STATUS_OKAY(CONFIGURE_REGULATOR) diff --git a/dts/bindings/regulator/regulator-pmic.yaml b/dts/bindings/regulator/regulator-pmic.yaml index 5d2fc391682..81756c8d7db 100644 --- a/dts/bindings/regulator/regulator-pmic.yaml +++ b/dts/bindings/regulator/regulator-pmic.yaml @@ -7,84 +7,86 @@ include: regulator.yaml compatible: "regulator-pmic" -properties: - 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. - current-levels: - type: array - required: false - description: | - Array of current limit values in uA, followed by the register value - that must be written to enable the current limit. For example, - [800000, 0x3] denotes a value of 0x3 must be written to the register - to set a current limit of 800mA - num-current-levels: - type: int - required: false - default: 0 - description: | - Number of current limit levels this regulator supports. If left as - default, regulator current support will be disabled. - ilim-reg: - type: int - required: false - description: | - Register to write the register value given in current-levels into - to set the current limit - ilim-mask: - type: int - required: false - description: | - Mask to apply to the current-levels value before writing it to the - ilim-reg value to set the current limit +child-binding: + description: Voltage output of PMIC controller regulator + properties: + 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. + current-levels: + type: array + required: false + description: | + Array of current limit values in uA, followed by the register value + that must be written to enable the current limit. For example, + [800000, 0x3] denotes a value of 0x3 must be written to the register + to set a current limit of 800mA + num-current-levels: + type: int + required: false + default: 0 + description: | + Number of current limit levels this regulator supports. If left as + default, regulator current support will be disabled. + ilim-reg: + type: int + required: false + description: | + Register to write the register value given in current-levels into + to set the current limit + ilim-mask: + type: int + required: false + description: | + Mask to apply to the current-levels value before writing it to the + ilim-reg value to set the current limit