Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: regulator: npm1300: workaround for LDO HW bug #83790

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions drivers/regulator/regulator_npm1300.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct regulator_npm1300_config {
struct gpio_dt_spec retention_gpios;
struct gpio_dt_spec pwm_gpios;
uint8_t soft_start;
bool ldo_disable_workaround;
};

struct regulator_npm1300_data {
Expand Down Expand Up @@ -357,19 +358,35 @@ int regulator_npm1300_set_mode(const struct device *dev, regulator_mode_t mode)
int regulator_npm1300_enable(const struct device *dev)
{
const struct regulator_npm1300_config *config = dev->config;
int ret;

switch (config->source) {
case NPM1300_SOURCE_BUCK1:
return mfd_npm1300_reg_write(config->mfd, BUCK_BASE, BUCK_OFFSET_EN_SET, 1U);
case NPM1300_SOURCE_BUCK2:
return mfd_npm1300_reg_write(config->mfd, BUCK_BASE, BUCK_OFFSET_EN_SET + 2U, 1U);
case NPM1300_SOURCE_LDO1:
return mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET, 1U);
ret = mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET, 1U);
break;
case NPM1300_SOURCE_LDO2:
return mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET + 2U, 1U);
ret = mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET + 2U, 1U);
break;
default:
return 0;
}

if (ret < 0) {
return ret;
}

if (!config->ldo_disable_workaround) {
uint8_t unused;

k_msleep(2);
return mfd_npm1300_reg_read(config->mfd, LDSW_BASE, LDSW_OFFSET_STATUS, &unused);
}

return ret;
}

int regulator_npm1300_disable(const struct device *dev)
Expand Down Expand Up @@ -655,7 +672,8 @@ static DEVICE_API(regulator, api) = {
.soft_start = DT_ENUM_IDX_OR(node_id, soft_start_microamp, UINT8_MAX), \
.enable_gpios = GPIO_DT_SPEC_GET_OR(node_id, enable_gpios, {0}), \
.retention_gpios = GPIO_DT_SPEC_GET_OR(node_id, retention_gpios, {0}), \
.pwm_gpios = GPIO_DT_SPEC_GET_OR(node_id, pwm_gpios, {0})}; \
.pwm_gpios = GPIO_DT_SPEC_GET_OR(node_id, pwm_gpios, {0}), \
.ldo_disable_workaround = DT_PROP(node_id, nordic_ldo_disable_workaround)}; \
\
DEVICE_DT_DEFINE(node_id, regulator_npm1300_init, NULL, &data_##id, &config_##id, \
POST_KERNEL, CONFIG_REGULATOR_NPM1300_INIT_PRIORITY, &api);
Expand Down
9 changes: 9 additions & 0 deletions dts/bindings/regulator/nordic,npm1300-regulator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,12 @@ child-binding:
- 50000
description: |
Soft start current limit in microamps.

nordic,ldo-disable-workaround:
type: boolean
description: |
Disable the SW workaround for LDO bug.
When nPM1300 is in ULP mode, LDO is supplied from VSYS and
then LDO is enabled, it can take long time until the LDO
output has reached its target voltage. To avoid this, an i2c
read is performed shortly after an LDO is enabled.
Comment on lines +100 to +107
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm tempted to think that this really belongs to Kconfig (as many other erratas), unless we strictly need per-instance control.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't strictly necessary, although it makes sense since each LDO is supplied separately. So while this bug might be present on one in a given design the other might be bug-free.

I was trying to find some information on how erratas are handled in Zephyr, but didn't find much. Is there any documentation you could point me to? I don't have a strong opinion on how we handle this. If it's better to do with Kconfig from your perspective I can do that.

Loading