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: add LDO/DCDC support for Smartbond. #65226

Merged

Conversation

kasjer
Copy link
Contributor

@kasjer kasjer commented Nov 15, 2023

This add regulator driver for Smartbond DA1469X SOC. Driver can control VDD, V14, V18, V18P, V30 rails, full voltage range supported by SOC is covered.
For VDD, V14, V18, V18P DCDC can be configured.

Special VDD_CLAMP (always on) and VDD_SLEPP are added to allow configuration of VDD in sleep modes.

Whole configuration can be done in device tree and alter changed by Zephyr regulator API.

@kasjer
Copy link
Contributor Author

kasjer commented Nov 16, 2023

@gmarull separate PR as requested


config REGULATOR_DA1469X_INIT_PRIORITY
int "Renesas DA1469x regulators driver init priority"
default KERNEL_INIT_PRIORITY_OBJECTS
Copy link
Member

Choose a reason for hiding this comment

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

this is a device, please use a number or KERNEL_INIT_PRIORITY_DEVICE

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Comment on lines 60 to 64
static const uint32_t voltages_vdd[] = {
900000, 1000000, 1100000, 1200000
};

static const uint32_t voltages_vdd_sleep[] = {
750000, 800000, 850000, 900000,
};

static const uint32_t voltages_v14[] = {
1200000, 1250000, 1300000, 1350000,
1400000, 1450000, 1500000, 1550000
};

static const uint32_t voltages_v30[] = {
3000000, 3300000
};

static const uint32_t voltages_v18[] = {
1200000, 1800000
};
Copy link
Member

Choose a reason for hiding this comment

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

these are all linear, so linear range can be used for these. See an example where some are linear and some are not: https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/regulator/regulator_npm6001.c

Copy link
Contributor Author

Choose a reason for hiding this comment

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

V30 was non-liner till 3.45 was remove per @ioannis-karachalios request.
Voltages are selected by indices in registers since at lease one is non-linear all are treated the same with district values kept in code.
If Renesas decides yet again that V30 (or other rail) can have other values code will not require extensive change.

Copy link
Contributor

Choose a reason for hiding this comment

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

Linear range API can support non-contiguous ranges, e.g:

static const struct linear_range charger_volt_ranges[] = {
LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to linear ranges

Comment on lines 152 to 153
default:
break;
Copy link
Member

Choose a reason for hiding this comment

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

-ENOTSUP?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

const struct regulator_da1469x_config *config = dev->config;

switch (config->rail) {
case VDD:
Copy link
Member

Choose a reason for hiding this comment

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

__fallthrough;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this is required in Zephyr for series of cases with no code. __fallthrough would be needed if case with some statements was continued in next case without break.

Comment on lines 205 to 206
default:
break;
Copy link
Member

Choose a reason for hiding this comment

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

-ENOTSUP?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Comment on lines 331 to 350
case VDD:
DCDC_REG_SET(VDD, CUR_LIM_MAX_HV, ((max_ua / 30000) - 1));
DCDC_REG_SET(VDD, CUR_LIM_MAX_LV, ((max_ua / 30000) - 1));
DCDC_REG_SET(VDD, CUR_LIM_MIN, ((max_ua / 30000) - 1));
break;
case V14:
DCDC_REG_SET(V14, CUR_LIM_MAX_HV, ((max_ua / 30000) - 1));
DCDC_REG_SET(V14, CUR_LIM_MAX_LV, ((max_ua / 30000) - 1));
DCDC_REG_SET(V14, CUR_LIM_MIN, ((max_ua / 30000) - 1));
break;
case V18:
DCDC_REG_SET(V18, CUR_LIM_MAX_HV, ((max_ua / 30000) - 1));
DCDC_REG_SET(V18, CUR_LIM_MAX_LV, ((max_ua / 30000) - 1));
DCDC_REG_SET(V18, CUR_LIM_MIN, ((max_ua / 30000) - 1));
break;
case V18P:
DCDC_REG_SET(V18P, CUR_LIM_MAX_HV, ((max_ua / 30000) - 1));
DCDC_REG_SET(V18P, CUR_LIM_MAX_LV, ((max_ua / 30000) - 1));
DCDC_REG_SET(V18P, CUR_LIM_MIN, ((max_ua / 30000) - 1));
break;
Copy link
Member

Choose a reason for hiding this comment

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

magic numbers here, remember current is given in a range as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to linear ranges

DCDC_REG_SET(V18P, CUR_LIM_MIN, ((max_ua / 30000) - 1));
break;
default:
ret = -ENOSYS;
Copy link
Member

Choose a reason for hiding this comment

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

incorrect usage of ENOSYS, should be ENOTSUP

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

regulator_common_data_init(dev);

if (config->rail == V30) {
POWER_REG_SET(LDO_3V0_REF, DT_INST_PROP_OR(DT_NODELABEL(V30),
Copy link
Member

Choose a reason for hiding this comment

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

this is unsafe: what if we have >1 instance of V30? please, store the value in driver's config

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no point is storing it drivers config. There is only one V30 rail in this soc.

Copy link
Member

Choose a reason for hiding this comment

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

yes, but driver is designed to be multi-instance, and this construct is wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

valued set from config

Comment on lines +102 to +106
regulator-init-microvolt = <706000>;
};
vdd_sleep: VDD_SLEEP {
regulator-boot-on;
regulator-init-microvolt = <750000>;
Copy link
Member

Choose a reason for hiding this comment

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

are all these init values board specific? why are they defined in soc dts files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are not board specific, they can be changed for board but they are soc specific values used here to achieve lowest power consumption.

#define DA1469X_MODE_LDO_VBAT_ON 0x10
#define DA1469X_MODE_V30_VBAT_CLAMP_ON 0x20

#define DCDC_REG_FIELD_MSK(dcdc, field) \
Copy link
Contributor

Choose a reason for hiding this comment

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

Have these macros come from an SDK, or were they written specifically for this driver?
I find them rather difficult to follow.

I think this would be better approached with a description structure for each regulator containing appropriate masks and fields, e.g:
https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/regulator/regulator_pca9420.c

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All macros removed, pure SDK fields used across file

Comment on lines 112 to 115
DCDC_REG_SET(VDD, ENABLE_HV,
!!(config->flags & DA1469X_MODE_DCDC_HIGH_BATTERY_VOLTAGE_ON));
DCDC_REG_SET(VDD, ENABLE_LV,
!!(config->flags & DA1469X_MODE_DCDC_LOW_BATTERY_VOLTAGE_ON));
Copy link
Contributor

Choose a reason for hiding this comment

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

These could be combined into a single write.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

after rework registers modified in one write

@kasjer kasjer force-pushed the kasjer/da1469x-regulators branch 2 times, most recently from 2b9e663 to 161e2ac Compare November 21, 2023 09:28
Copy link
Contributor

@aasinclair aasinclair left a comment

Choose a reason for hiding this comment

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

Thanks for reworking this, looks great.
Just a config nit from me remaining.

Comment on lines 11 to 19
if REGULATOR_DA1469X

config REGULATOR_DA1469X_INIT_PRIORITY
int "Renesas DA1469x regulators driver init priority"
default KERNEL_INIT_PRIORITY_DEVICE
help
Init priority for the Renesas DA1469x regulators driver.

endif # REGULATOR_DA1469X
Copy link
Contributor

Choose a reason for hiding this comment

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

Single configs should use depends

Suggested change
if REGULATOR_DA1469X
config REGULATOR_DA1469X_INIT_PRIORITY
int "Renesas DA1469x regulators driver init priority"
default KERNEL_INIT_PRIORITY_DEVICE
help
Init priority for the Renesas DA1469x regulators driver.
endif # REGULATOR_DA1469X
config REGULATOR_DA1469X_INIT_PRIORITY
int "Renesas DA1469x regulators driver init priority"
default KERNEL_INIT_PRIORITY_DEVICE
depends on REGULATOR_DA1469X
help
Init priority for the Renesas DA1469x regulators driver.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aasinclair thanks for a hint, change applied as suggested

This add regulator driver for Smartbond DA1469X SOC.
Driver can control VDD, V14, V18, V18P, V30 rails,
full voltage range supported by SOC is covered.
For VDD, V14, V18, V18P DCDC can be configured.

Special VDD_CLAMP (always on) and VDD_SLEPP are added
to allow configuration of VDD in sleep modes.

Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
@fabiobaltieri fabiobaltieri merged commit 46bbe05 into zephyrproject-rtos:main Nov 22, 2023
18 checks passed
@kasjer kasjer deleted the kasjer/da1469x-regulators branch November 24, 2023 07:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Devicetree Binding PR modifies or adds a Device Tree binding area: Regulators platform: Renesas SmartBond Renesas Electronics Corporation, SmartBond
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants