diff --git a/drivers/gpio/Kconfig.npm13xx b/drivers/gpio/Kconfig.npm13xx index 828b4e1382f..1d3bade047d 100644 --- a/drivers/gpio/Kconfig.npm13xx +++ b/drivers/gpio/Kconfig.npm13xx @@ -4,7 +4,7 @@ config GPIO_NPM13XX bool "nPM13xx GPIO driver" default y - depends on DT_HAS_NORDIC_NPM1300_GPIO_ENABLED + depends on DT_HAS_NORDIC_NPM1300_GPIO_ENABLED || DT_HAS_NORDIC_NPM1304_GPIO_ENABLED select I2C select MFD help diff --git a/drivers/gpio/gpio_npm13xx.c b/drivers/gpio/gpio_npm13xx.c index c74fc244d93..d6eeb4b73b0 100644 --- a/drivers/gpio/gpio_npm13xx.c +++ b/drivers/gpio/gpio_npm13xx.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_npm1300_gpio - #include #include @@ -212,18 +210,25 @@ static int gpio_npm13xx_init(const struct device *dev) return 0; } -#define GPIO_NPM13XX_DEFINE(n) \ - static const struct gpio_npm13xx_config gpio_npm13xx_config##n = { \ +#define GPIO_NPM13XX_DEFINE(partno, n) \ + static const struct gpio_npm13xx_config gpio_##partno##_config##n = { \ .common = \ { \ .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ }, \ .mfd = DEVICE_DT_GET(DT_INST_PARENT(n))}; \ \ - static struct gpio_npm13xx_data gpio_npm13xx_data##n; \ + static struct gpio_npm13xx_data gpio_##partno##_data##n; \ \ - DEVICE_DT_INST_DEFINE(n, gpio_npm13xx_init, NULL, &gpio_npm13xx_data##n, \ - &gpio_npm13xx_config##n, POST_KERNEL, \ + DEVICE_DT_INST_DEFINE(n, gpio_npm13xx_init, NULL, &gpio_##partno##_data##n, \ + &gpio_##partno##_config##n, POST_KERNEL, \ CONFIG_GPIO_NPM13XX_INIT_PRIORITY, &gpio_npm13xx_api); -DT_INST_FOREACH_STATUS_OKAY(GPIO_NPM13XX_DEFINE) +#define DT_DRV_COMPAT nordic_npm1300_gpio +#define GPIO_NPM1300_DEFINE(n) GPIO_NPM13XX_DEFINE(npm1300, n) +DT_INST_FOREACH_STATUS_OKAY(GPIO_NPM1300_DEFINE) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1304_gpio +#define GPIO_NPM1304_DEFINE(n) GPIO_NPM13XX_DEFINE(npm1304, n) +DT_INST_FOREACH_STATUS_OKAY(GPIO_NPM1304_DEFINE) diff --git a/drivers/led/Kconfig.npm13xx b/drivers/led/Kconfig.npm13xx index e3f40f42a19..5431c7c8326 100644 --- a/drivers/led/Kconfig.npm13xx +++ b/drivers/led/Kconfig.npm13xx @@ -4,7 +4,7 @@ config LED_NPM13XX bool "nPM13xx LED driver" default y - depends on DT_HAS_NORDIC_NPM1300_LED_ENABLED + depends on DT_HAS_NORDIC_NPM1300_LED_ENABLED || DT_HAS_NORDIC_NPM1304_LED_ENABLED select I2C select MFD help diff --git a/drivers/led/led_npm13xx.c b/drivers/led/led_npm13xx.c index eed9b1256be..f00864fc74a 100644 --- a/drivers/led/led_npm13xx.c +++ b/drivers/led/led_npm13xx.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_npm1300_led - #include #include @@ -87,14 +85,21 @@ static int led_npm13xx_init(const struct device *dev) return 0; } -#define LED_NPM13XX_DEFINE(n) \ - static const struct led_npm13xx_config led_npm13xx_config##n = { \ +#define LED_NPM13XX_DEFINE(partno, n) \ + static const struct led_npm13xx_config led_##partno##_config##n = { \ .mfd = DEVICE_DT_GET(DT_INST_PARENT(n)), \ .mode = {DT_INST_ENUM_IDX(n, nordic_led0_mode), \ DT_INST_ENUM_IDX(n, nordic_led1_mode), \ DT_INST_ENUM_IDX(n, nordic_led2_mode)}}; \ \ - DEVICE_DT_INST_DEFINE(n, &led_npm13xx_init, NULL, NULL, &led_npm13xx_config##n, \ + DEVICE_DT_INST_DEFINE(n, &led_npm13xx_init, NULL, NULL, &led_##partno##_config##n, \ POST_KERNEL, CONFIG_LED_INIT_PRIORITY, &led_npm13xx_api); -DT_INST_FOREACH_STATUS_OKAY(LED_NPM13XX_DEFINE) +#define DT_DRV_COMPAT nordic_npm1300_led +#define LED_NPM1300_DEFINE(n) LED_NPM13XX_DEFINE(npm1300, n) +DT_INST_FOREACH_STATUS_OKAY(LED_NPM1300_DEFINE) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1304_led +#define LED_NPM1304_DEFINE(n) LED_NPM13XX_DEFINE(npm1304, n) +DT_INST_FOREACH_STATUS_OKAY(LED_NPM1304_DEFINE) diff --git a/drivers/mfd/Kconfig.npm13xx b/drivers/mfd/Kconfig.npm13xx index 63f18ac9a3b..6170c074aa8 100644 --- a/drivers/mfd/Kconfig.npm13xx +++ b/drivers/mfd/Kconfig.npm13xx @@ -4,7 +4,7 @@ config MFD_NPM13XX bool "nPM13xx PMIC multi-function device driver" default y - depends on DT_HAS_NORDIC_NPM1300_ENABLED + depends on DT_HAS_NORDIC_NPM1300_ENABLED || DT_HAS_NORDIC_NPM1304_ENABLED select I2C help Enable the Nordic nPM13xx PMIC multi-function device driver diff --git a/drivers/mfd/mfd_npm13xx.c b/drivers/mfd/mfd_npm13xx.c index 9847e4a9e49..0d0b8e89f5f 100644 --- a/drivers/mfd/mfd_npm13xx.c +++ b/drivers/mfd/mfd_npm13xx.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_npm1300 - #include #include @@ -308,18 +306,26 @@ int mfd_npm13xx_remove_callback(const struct device *dev, struct gpio_callback * return gpio_manage_callback(&data->callbacks, callback, false); } -#define MFD_NPM13XX_DEFINE(inst) \ - static struct mfd_npm13xx_data data_##inst; \ +#define MFD_NPM13XX_DEFINE(partno, n) \ + static struct mfd_npm13xx_data mfd_##partno##_data##n; \ \ - static const struct mfd_npm13xx_config config##inst = { \ - .i2c = I2C_DT_SPEC_INST_GET(inst), \ - .host_int_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, host_int_gpios, {0}), \ - .pmic_int_pin = DT_INST_PROP_OR(inst, pmic_int_pin, 0), \ - .active_time = DT_INST_ENUM_IDX(inst, ship_to_active_time_ms), \ - .lp_reset = DT_INST_ENUM_IDX_OR(inst, long_press_reset, 0), \ + static const struct mfd_npm13xx_config mfd_##partno##_config##n = { \ + .i2c = I2C_DT_SPEC_INST_GET(n), \ + .host_int_gpios = GPIO_DT_SPEC_INST_GET_OR(n, host_int_gpios, {0}), \ + .pmic_int_pin = DT_INST_PROP_OR(n, pmic_int_pin, 0), \ + .active_time = DT_INST_ENUM_IDX(n, ship_to_active_time_ms), \ + .lp_reset = DT_INST_ENUM_IDX_OR(n, long_press_reset, 0), \ }; \ \ - DEVICE_DT_INST_DEFINE(inst, mfd_npm13xx_init, NULL, &data_##inst, &config##inst, \ - POST_KERNEL, CONFIG_MFD_NPM13XX_INIT_PRIORITY, NULL); + DEVICE_DT_INST_DEFINE(n, mfd_npm13xx_init, NULL, &mfd_##partno##_data##n, \ + &mfd_##partno##_config##n, POST_KERNEL, \ + CONFIG_MFD_NPM13XX_INIT_PRIORITY, NULL); + +#define DT_DRV_COMPAT nordic_npm1300 +#define MFD_NPM1300_DEFINE(n) MFD_NPM13XX_DEFINE(npm1300, n) +DT_INST_FOREACH_STATUS_OKAY(MFD_NPM1300_DEFINE) -DT_INST_FOREACH_STATUS_OKAY(MFD_NPM13XX_DEFINE) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1304 +#define MFD_NPM1304_DEFINE(n) MFD_NPM13XX_DEFINE(npm1304, n) +DT_INST_FOREACH_STATUS_OKAY(MFD_NPM1304_DEFINE) diff --git a/drivers/regulator/Kconfig.npm13xx b/drivers/regulator/Kconfig.npm13xx index 4d243b8cdf8..a075ca72dc7 100644 --- a/drivers/regulator/Kconfig.npm13xx +++ b/drivers/regulator/Kconfig.npm13xx @@ -4,7 +4,7 @@ config REGULATOR_NPM13XX bool "nPM13xx PMIC regulator driver" default y - depends on DT_HAS_NORDIC_NPM1300_REGULATOR_ENABLED + depends on DT_HAS_NORDIC_NPM1300_REGULATOR_ENABLED || DT_HAS_NORDIC_NPM1304_REGULATOR_ENABLED select I2C select MFD help diff --git a/drivers/regulator/regulator_npm13xx.c b/drivers/regulator/regulator_npm13xx.c index 89ee1993ed3..c07970bb5c6 100644 --- a/drivers/regulator/regulator_npm13xx.c +++ b/drivers/regulator/regulator_npm13xx.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_npm1300_regulator - #include #include @@ -689,9 +687,6 @@ int regulator_npm13xx_init(const struct device *dev) } ret = regulator_npm13xx_set_pin_ctrl(dev, &config->pwm_gpios, NPM13XX_GPIO_TYPE_PWM); - if (ret != 0) { - return ret; - } return ret; } @@ -712,13 +707,13 @@ static DEVICE_API(regulator, api) = { !!(DT_PROP_BY_IDX(node_id, prop, 1) & GPIO_ACTIVE_LOW)}), \ ({NPM13XX_GPIO_UNUSED, false})) -#define REGULATOR_NPM13XX_DEFINE(node_id, id, _source) \ +#define REGULATOR_NPM13XX_DEFINE(partno, node_id, id, _source) \ BUILD_ASSERT(DT_PROP_LEN_OR(node_id, enable_gpio_config, 2) == 2); \ BUILD_ASSERT(DT_PROP_LEN_OR(node_id, retention_gpio_config, 2) == 2); \ BUILD_ASSERT(DT_PROP_LEN_OR(node_id, pwm_gpio_config, 2) == 2); \ - static struct regulator_npm13xx_data data_##id; \ + static struct regulator_npm13xx_data regulator_##partno##_data_##id; \ \ - static const struct regulator_npm13xx_config config_##id = { \ + static const struct regulator_npm13xx_config regulator_##partno##_config_##id = { \ .common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \ .mfd = DEVICE_DT_GET(DT_GPARENT(node_id)), \ .source = _source, \ @@ -730,30 +725,39 @@ static DEVICE_API(regulator, api) = { .active_discharge = DT_PROP(node_id, active_discharge), \ .ldo_disable_workaround = DT_PROP(node_id, nordic_anomaly38_disable_workaround)}; \ \ - DEVICE_DT_DEFINE(node_id, regulator_npm13xx_init, NULL, &data_##id, &config_##id, \ - POST_KERNEL, CONFIG_REGULATOR_NPM13XX_INIT_PRIORITY, &api); + DEVICE_DT_DEFINE(node_id, regulator_npm13xx_init, NULL, ®ulator_##partno##_data_##id, \ + ®ulator_##partno##_config_##id, POST_KERNEL, \ + CONFIG_REGULATOR_NPM13XX_INIT_PRIORITY, &api); -#define REGULATOR_NPM13XX_DEFINE_COND(inst, child, source) \ - COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \ - (REGULATOR_NPM13XX_DEFINE(DT_INST_CHILD(inst, child), child##inst, source)), \ +#define REGULATOR_NPM13XX_DEFINE_COND(partno, n, child, source) \ + COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(n, child)), \ + (REGULATOR_NPM13XX_DEFINE(partno, DT_INST_CHILD(n, child), child##n, source)), \ ()) -#define REGULATOR_NPM13XX_DEFINE_ALL(inst) \ - static const struct regulator_npm13xx_pconfig config_##inst = { \ - .mfd = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ - .dvs_state_pins = {GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, dvs_gpios, 0, {0}), \ - GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, dvs_gpios, 1, {0}), \ - GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, dvs_gpios, 2, {0}), \ - GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, dvs_gpios, 3, {0}), \ - GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, dvs_gpios, 4, {0})}}; \ +#define REGULATOR_NPM13XX_DEFINE_ALL(partno, n) \ + static const struct regulator_npm13xx_pconfig regulator_##partno##_config##n = { \ + .mfd = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .dvs_state_pins = {GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, dvs_gpios, 0, {0}), \ + GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, dvs_gpios, 1, {0}), \ + GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, dvs_gpios, 2, {0}), \ + GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, dvs_gpios, 3, {0}), \ + GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, dvs_gpios, 4, {0})}}; \ \ - DEVICE_DT_INST_DEFINE(inst, regulator_npm13xx_common_init, NULL, NULL, &config_##inst, \ - POST_KERNEL, CONFIG_REGULATOR_NPM13XX_COMMON_INIT_PRIORITY, \ + DEVICE_DT_INST_DEFINE(n, regulator_npm13xx_common_init, NULL, NULL, \ + ®ulator_##partno##_config##n, POST_KERNEL, \ + CONFIG_REGULATOR_NPM13XX_COMMON_INIT_PRIORITY, \ &parent_api); \ \ - REGULATOR_NPM13XX_DEFINE_COND(inst, buck1, NPM13XX_SOURCE_BUCK1) \ - REGULATOR_NPM13XX_DEFINE_COND(inst, buck2, NPM13XX_SOURCE_BUCK2) \ - REGULATOR_NPM13XX_DEFINE_COND(inst, ldo1, NPM13XX_SOURCE_LDO1) \ - REGULATOR_NPM13XX_DEFINE_COND(inst, ldo2, NPM13XX_SOURCE_LDO2) + REGULATOR_NPM13XX_DEFINE_COND(partno, n, buck1, NPM13XX_SOURCE_BUCK1) \ + REGULATOR_NPM13XX_DEFINE_COND(partno, n, buck2, NPM13XX_SOURCE_BUCK2) \ + REGULATOR_NPM13XX_DEFINE_COND(partno, n, ldo1, NPM13XX_SOURCE_LDO1) \ + REGULATOR_NPM13XX_DEFINE_COND(partno, n, ldo2, NPM13XX_SOURCE_LDO2) + +#define DT_DRV_COMPAT nordic_npm1300_regulator +#define REGULATOR_NPM1300_DEFINE_ALL(n) REGULATOR_NPM13XX_DEFINE_ALL(npm1300, n) +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NPM1300_DEFINE_ALL) -DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NPM13XX_DEFINE_ALL) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1304_regulator +#define REGULATOR_NPM1304_DEFINE_ALL(n) REGULATOR_NPM13XX_DEFINE_ALL(npm1304, n) +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NPM1304_DEFINE_ALL) diff --git a/drivers/sensor/nordic/npm13xx_charger/Kconfig b/drivers/sensor/nordic/npm13xx_charger/Kconfig index e511e393fa2..a113a4ede47 100644 --- a/drivers/sensor/nordic/npm13xx_charger/Kconfig +++ b/drivers/sensor/nordic/npm13xx_charger/Kconfig @@ -5,7 +5,7 @@ config NPM13XX_CHARGER bool "nPM13xx Charger" default y - depends on DT_HAS_NORDIC_NPM1300_CHARGER_ENABLED + depends on DT_HAS_NORDIC_NPM1300_CHARGER_ENABLED || DT_HAS_NORDIC_NPM1304_CHARGER_ENABLED select I2C select MFD select REQUIRES_FULL_LIBC diff --git a/drivers/sensor/nordic/npm13xx_charger/npm13xx_charger.c b/drivers/sensor/nordic/npm13xx_charger/npm13xx_charger.c index bf5afe2d3f4..08e2763e655 100644 --- a/drivers/sensor/nordic/npm13xx_charger/npm13xx_charger.c +++ b/drivers/sensor/nordic/npm13xx_charger/npm13xx_charger.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_npm1300_charger - #include #include #include @@ -16,7 +14,10 @@ struct npm13xx_charger_config { const struct device *mfd; int32_t term_microvolt; int32_t term_warm_microvolt; + const struct linear_range term_volt_ranges[2U]; int32_t current_microamp; + const struct linear_range current_range; + const int32_t full_scale_discharge_factors[2U]; int32_t dischg_limit_microamp; uint8_t dischg_limit_idx; int32_t vbus_limit_microamp; @@ -137,14 +138,22 @@ struct adc_results_t { #define DIETEMP_FACTOR_DIV 5000 /* Linear range for charger terminal voltage */ -static const struct linear_range charger_volt_ranges[] = { - LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)}; +#define NPM1300_CHARGER_VOLT_RANGES \ + {LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)} +#define NPM1304_CHARGER_VOLT_RANGES \ + {LINEAR_RANGE_INIT(3600000, 50000, 0U, 1U), LINEAR_RANGE_INIT(4000000, 50000, 2U, 15U)} /* Linear range for charger current */ -static const struct linear_range charger_current_range = LINEAR_RANGE_INIT(32000, 2000, 16U, 400U); +#define NPM1300_CHARGER_CURRENT_RANGE LINEAR_RANGE_INIT(32000, 2000, 16U, 400U) +#define NPM1304_CHARGER_CURRENT_RANGE LINEAR_RANGE_INIT(4000, 500, 8U, 200U) + +/* Full-scale factors for calculating current */ +#define NPM1300_FULL_SCALE_DISCHARGE_FACTORS {112, 100} +#define NPM1304_FULL_SCALE_DISCHARGE_FACTORS {415, 400} +static const int32_t full_scale_charge_factors[] = {125, 100}; /* Allowed values for discharge limit */ -static const uint16_t discharge_limits[] = {84U, 415U}; +static const uint16_t npm1300_discharge_limits[] = {84U, 415U}; /* Linear range for vbusin current limit */ static const struct linear_range vbus_current_range = LINEAR_RANGE_INIT(100000, 100000, 1U, 15U); @@ -193,41 +202,49 @@ static void calc_current(const struct npm13xx_charger_config *const config, int32_t full_scale_ua; int32_t current_ua; - /* Largest value of discharge limit and charge limit is 1A. - * We can therefore guarantee that multiplying the uA by 1000 does not overflow. - * 1000 * 1'000'000 uA < 2**31 - * 1000000000 < 2147483648 - */ switch (data->ibat_stat) { case IBAT_STAT_DISCHARGE: - /* Ref: PS v1.2 Section 7.1.7: Full scale multiplied by 1.12 */ - full_scale_ua = -(1000 * config->dischg_limit_microamp) / 893; + /* nPM1300: Largest discharge limit is 1A. Multiplying it by 112 will not overflow. + * 112 * -1_000_000 > INT32_MIN + * -112_000_000 > -2_147_483_648 + * nPM1304: Discharge limit is 125mA. Multiplying it by 415 will not overflow. + * 415 * -125_000 > INT32_MIN + * -51_875_000 > -2_147_483_648 + */ + full_scale_ua = -config->dischg_limit_microamp * + config->full_scale_discharge_factors[0] / + config->full_scale_discharge_factors[1]; break; case IBAT_STAT_CHARGE_TRICKLE: /* Fallthrough */ case IBAT_STAT_CHARGE_COOL: /* Fallthrough */ case IBAT_STAT_CHARGE_NORMAL: - /* Ref: PS v1.2 Section 7.1.7: Full scale multiplied by 1.25 */ - full_scale_ua = (1000 * config->current_microamp) / 800; + /* nPM1300: Largest charge limit is 800mA. Multiplying it by 125 will not overflow. + * 125 * 800_000 < INT32_MAX + * 100_000_000 < 2_147_483_647 + * nPM1304: Largest charge limit is even lower - no overflow. + */ + full_scale_ua = config->current_microamp * full_scale_charge_factors[0] / + full_scale_charge_factors[1]; break; default: full_scale_ua = 0; break; } - /* Largest possible value for data->current is 1023 - * Limits for full_scale_ua are -1'119'820 and 1'000'000 - * 1023 * -1119820 > -2**31 - * -1145575860 > -2147483648 - * 1023 * 1000000 < 2**31 - * 1023000000 < 2147483648 + /* Largest possible value for data->current is 1023 (10-bit ADC) + * Limits for full_scale_ua are -1_120_000 and 1_000_000 + * 1023 * -1_120_000 > INT32_MIN + * -1_145_760_000 > -2_147_483_648 + * 1023 * 1_000_000 < INT32_MAX + * 1_023_000_000 < 2_147_483_647 */ __ASSERT_NO_MSG(data->current <= 1023); __ASSERT_NO_MSG(full_scale_ua <= 1000000); - __ASSERT_NO_MSG(full_scale_ua >= -1119820); + __ASSERT_NO_MSG(full_scale_ua >= -1120000); - current_ua = (data->current * full_scale_ua) / 1024; + current_ua = (data->current * full_scale_ua) / 1023; (void)sensor_value_from_micro(valp, current_ua); } @@ -324,9 +341,6 @@ int npm13xx_charger_sample_fetch(const struct device *dev, enum sensor_channel c /* Read vbus status */ ret = mfd_npm13xx_reg_read(config->mfd, VBUS_BASE, VBUS_OFFSET_STATUS, &data->vbus_stat); - if (ret != 0) { - return ret; - } return ret; } @@ -532,9 +546,9 @@ int npm13xx_charger_init(const struct device *dev) } /* Configure termination voltages */ - ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), - config->term_microvolt, config->term_microvolt, - &idx); + ret = linear_range_group_get_win_index( + config->term_volt_ranges, ARRAY_SIZE(config->term_volt_ranges), + config->term_microvolt, config->term_microvolt, &idx); if (ret == -EINVAL) { return ret; } @@ -543,9 +557,9 @@ int npm13xx_charger_init(const struct device *dev) return ret; } - ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), - config->term_warm_microvolt, - config->term_warm_microvolt, &idx); + ret = linear_range_group_get_win_index( + config->term_volt_ranges, ARRAY_SIZE(config->term_volt_ranges), + config->term_warm_microvolt, config->term_warm_microvolt, &idx); if (ret == -EINVAL) { return ret; } @@ -556,22 +570,29 @@ int npm13xx_charger_init(const struct device *dev) } /* Set current, allow rounding down to closest value */ - ret = linear_range_get_win_index(&charger_current_range, - config->current_microamp - charger_current_range.step, + ret = linear_range_get_win_index(&config->current_range, + config->current_microamp - config->current_range.step + 1, config->current_microamp, &idx); if (ret == -EINVAL) { return ret; } - ret = mfd_npm13xx_reg_write2(config->mfd, CHGR_BASE, CHGR_OFFSET_ISET, idx / 2U, idx & 1U); - if (ret != 0) { - return ret; - } + if (config->dischg_limit_idx == UINT8_MAX) { + /* Set only charge current MSB for nPM1304 */ + ret = mfd_npm13xx_reg_write(config->mfd, CHGR_BASE, CHGR_OFFSET_ISET, idx); + } else { + /* Set charge current MSB and LSB and discharge limit for nPM1300 */ + ret = mfd_npm13xx_reg_write2(config->mfd, CHGR_BASE, CHGR_OFFSET_ISET, idx / 2U, + idx & 1U); + if (ret != 0) { + return ret; + } - /* Set discharge limit */ - ret = mfd_npm13xx_reg_write2(config->mfd, CHGR_BASE, CHGR_OFFSET_ISET_DISCHG, - discharge_limits[config->dischg_limit_idx] / 2U, - discharge_limits[config->dischg_limit_idx] & 1U); + ret = mfd_npm13xx_reg_write2( + config->mfd, CHGR_BASE, CHGR_OFFSET_ISET_DISCHG, + npm1300_discharge_limits[config->dischg_limit_idx] / 2U, + npm1300_discharge_limits[config->dischg_limit_idx] & 1U); + } if (ret != 0) { return ret; } @@ -666,19 +687,23 @@ static DEVICE_API(sensor, npm13xx_charger_battery_driver_api) = { .attr_get = npm13xx_charger_attr_get, }; -#define NPM13XX_CHARGER_INIT(n) \ - BUILD_ASSERT(DT_INST_ENUM_IDX(n, dischg_limit_microamp) < ARRAY_SIZE(discharge_limits)); \ +#define NPM13XX_CHARGER_INIT(partno, n) \ + BUILD_ASSERT(DT_INST_ENUM_IDX_OR(n, dischg_limit_microamp, 0) < \ + ARRAY_SIZE(npm1300_discharge_limits)); \ \ - static struct npm13xx_charger_data npm13xx_charger_data_##n; \ + static struct npm13xx_charger_data charger_##partno##_data##n; \ \ - static const struct npm13xx_charger_config npm13xx_charger_config_##n = { \ + static const struct npm13xx_charger_config charger_##partno##_config##n = { \ .mfd = DEVICE_DT_GET(DT_INST_PARENT(n)), \ .term_microvolt = DT_INST_PROP(n, term_microvolt), \ .term_warm_microvolt = \ DT_INST_PROP_OR(n, term_warm_microvolt, DT_INST_PROP(n, term_microvolt)), \ + .term_volt_ranges = partno##_CHARGER_VOLT_RANGES, \ .current_microamp = DT_INST_PROP(n, current_microamp), \ + .current_range = partno##_CHARGER_CURRENT_RANGE, \ + .full_scale_discharge_factors = partno##_FULL_SCALE_DISCHARGE_FACTORS, \ .dischg_limit_microamp = DT_INST_PROP(n, dischg_limit_microamp), \ - .dischg_limit_idx = DT_INST_ENUM_IDX(n, dischg_limit_microamp), \ + .dischg_limit_idx = DT_INST_ENUM_IDX_OR(n, dischg_limit_microamp, UINT8_MAX), \ .vbus_limit_microamp = DT_INST_PROP(n, vbus_limit_microamp), \ .thermistor_ohms = DT_INST_PROP(n, thermistor_ohms), \ .thermistor_idx = DT_INST_ENUM_IDX(n, thermistor_ohms), \ @@ -696,9 +721,17 @@ static DEVICE_API(sensor, npm13xx_charger_battery_driver_api) = { DT_INST_PROP_OR(n, thermistor_warm_millidegrees, INT32_MAX), \ DT_INST_PROP_OR(n, thermistor_hot_millidegrees, INT32_MAX)}}; \ \ - SENSOR_DEVICE_DT_INST_DEFINE(n, &npm13xx_charger_init, NULL, &npm13xx_charger_data_##n, \ - &npm13xx_charger_config_##n, POST_KERNEL, \ + SENSOR_DEVICE_DT_INST_DEFINE(n, &npm13xx_charger_init, NULL, &charger_##partno##_data##n, \ + &charger_##partno##_config##n, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, \ &npm13xx_charger_battery_driver_api); -DT_INST_FOREACH_STATUS_OKAY(NPM13XX_CHARGER_INIT) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1300_charger +#define NPM1300_CHARGER_INIT(n) NPM13XX_CHARGER_INIT(NPM1300, n) +DT_INST_FOREACH_STATUS_OKAY(NPM1300_CHARGER_INIT) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1304_charger +#define NPM1304_CHARGER_INIT(n) NPM13XX_CHARGER_INIT(NPM1304, n) +DT_INST_FOREACH_STATUS_OKAY(NPM1304_CHARGER_INIT) diff --git a/drivers/watchdog/Kconfig.npm13xx b/drivers/watchdog/Kconfig.npm13xx index 2318349c85e..910da6574a9 100644 --- a/drivers/watchdog/Kconfig.npm13xx +++ b/drivers/watchdog/Kconfig.npm13xx @@ -4,7 +4,7 @@ config WDT_NPM13XX bool "nPM13xx Watchdog driver" default y - depends on DT_HAS_NORDIC_NPM1300_WDT_ENABLED + depends on DT_HAS_NORDIC_NPM1300_WDT_ENABLED || DT_HAS_NORDIC_NPM1304_WDT_ENABLED select I2C select MFD help diff --git a/drivers/watchdog/wdt_npm13xx.c b/drivers/watchdog/wdt_npm13xx.c index cfbee7f3398..351da6b7d5a 100644 --- a/drivers/watchdog/wdt_npm13xx.c +++ b/drivers/watchdog/wdt_npm13xx.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_npm13xx_wdt - #include #include @@ -154,15 +152,23 @@ static int wdt_npm13xx_init(const struct device *dev) return 0; } -#define WDT_NPM13XX_DEFINE(n) \ - static struct wdt_npm13xx_data data##n; \ +#define WDT_NPM13XX_DEFINE(partno, n) \ + static struct wdt_npm13xx_data wdt_##partno##_data##n; \ \ - static const struct wdt_npm13xx_config config##n = { \ + static const struct wdt_npm13xx_config wdt_##partno##_config##n = { \ .mfd = DEVICE_DT_GET(DT_INST_PARENT(n)), \ .reset_gpios = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, &wdt_npm13xx_init, NULL, &data##n, &config##n, POST_KERNEL, \ + DEVICE_DT_INST_DEFINE(n, &wdt_npm13xx_init, NULL, &wdt_##partno##_data##n, \ + &wdt_##partno##_config##n, POST_KERNEL, \ CONFIG_WDT_NPM13XX_INIT_PRIORITY, &wdt_npm13xx_api); -DT_INST_FOREACH_STATUS_OKAY(WDT_NPM13XX_DEFINE) +#define DT_DRV_COMPAT nordic_npm1300_wdt +#define WDT_NPM1300_DEFINE(n) WDT_NPM13XX_DEFINE(npm1300, n) +DT_INST_FOREACH_STATUS_OKAY(WDT_NPM1300_DEFINE) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nordic_npm1304_wdt +#define WDT_NPM1304_DEFINE(n) WDT_NPM13XX_DEFINE(npm1304, n) +DT_INST_FOREACH_STATUS_OKAY(WDT_NPM1304_DEFINE)