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

Add CP9314 regulator driver #68177

Merged
merged 3 commits into from Feb 27, 2024
Merged

Conversation

rriveramcrus
Copy link
Contributor

@rriveramcrus rriveramcrus commented Jan 26, 2024

Adds support for the CP9314 switched-capacitor regulator. Functional modes supported:

  • Both 3:1 and 2:1 converter op modes
  • Synchronous (shared clock) mode
  • Enable via GPIO or I2C

Only B0 silicon is supported.

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.

Is there a datasheet for this part available?

drivers/regulator/regulator_cp9314.c Outdated Show resolved Hide resolved
drivers/regulator/regulator_cp9314.c Outdated Show resolved Hide resolved
drivers/regulator/regulator_cp9314.h Outdated Show resolved Hide resolved
Comment on lines 46 to 230
static struct cp9314_reg_patch b0_reg_patch[18] = {
{CP9314_REG_CRUS_CTRL, GENMASK(7, 0), CP9314_CRUS_KEY_UNLOCK},
{CP9314_REG_LION_COMP_CTRL_3, CP9314_VIN_OV_CFG, 0x1B},
{CP9314_REG_LION_COMP_CTRL_1, CP9314_VOUT_OV_CFG_0, 0x30},
{CP9314_REG_LION_COMP_CTRL_2, CP9314_VOUT_OV_CFG_1, 0xC},
{CP9314_REG_VIN2OUT_OVP, CP9314_VIN2OUT_OVP, 0x2},
{CP9314_REG_VIN2OUT_UVP, CP9314_VIN2OUT_UVP, 0x1},
{CP9314_REG_VOUT_UVP, CP9314_VOUT_UVP_DIS, 0},
{CP9314_REG_VOUT_UVP, CP9314_VOUT_UVP, 0},
{CP9314_REG_LION_COMP_CTRL_1, CP9314_VIN_SWITCH_OK_DIS_0, 0},
{CP9314_REG_LION_COMP_CTRL_4, CP9314_VIN_SWITCH_OK_DIS_1, 0},
{CP9314_REG_LION_COMP_CTRL_1, CP9314_VIN_SWITCH_OK_CFG, 0},
{CP9314_REG_LION_CFG_3, CP9314_LB_MIN_FREQ_SEL_0, 0x80},
{CP9314_REG_LB_CTRL, CP9314_LB_MIN_FREQ_SEL_1, 0x4},
{CP9314_REG_TRIM_8, CP9314_MODE_CTRL_UPDATE_BW_0, 0x2},
{CP9314_REG_LION_CFG_3, CP9314_MODE_CTRL_UPDATE_BW_1, 0x2},
{CP9314_REG_IIN_OCP, CP9314_IIN_OCP_DIS, CP9314_IIN_OCP_DIS},
{CP9314_REG_IIN_PEAK_OCP, CP9314_IIN_PEAK_OCP_DIS, CP9314_IIN_PEAK_OCP_DIS},
{CP9314_REG_CRUS_CTRL, GENMASK(7, 0), CP9314_CRUS_KEY_LOCK},
};

static struct cp9314_reg_patch otp_1_patch[3] = {
{CP9314_REG_OPTION_REG_1, CP9314_LB1_DELAY_CFG, 0},
{CP9314_REG_BST_CP_PD_CFG, CP9314_LB1_BLANK_CFG, CP9314_LB1_BLANK_CFG},
{CP9314_REG_TSBAT_CTRL, CP9314_LB1_STOP_PHASE_SEL, CP9314_LB1_STOP_PHASE_SEL},
};
Copy link
Member

Choose a reason for hiding this comment

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

these probably deserve some docstring explaining what they are

Copy link
Member

Choose a reason for hiding this comment

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

ping

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack, let me know if the added comments are sufficient.

Copy link
Contributor

Choose a reason for hiding this comment

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

It could do with an overall comment for the block giving a rough indication of what it is for, so that users can see what is being fixed.
e.g.
/** Patch for b0 silicon to correct trim errata and feedback scaling errors */

{CP9314_REG_TSBAT_CTRL, CP9314_LB1_STOP_PHASE_SEL, CP9314_LB1_STOP_PHASE_SEL},
};

LOG_MODULE_REGISTER(CP9314);
Copy link
Member

Choose a reason for hiding this comment

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

by convention, move just after includes. This also misses a log level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

return ret;
}

data->op_mode = mode;
Copy link
Member

Choose a reason for hiding this comment

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

data->op_mode doesn't seem to be used anywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack. A leftover from the earlier silicon revision.

Comment on lines 186 to 188
int i, ret = 0;

for (i = 0; i < ARRAY_SIZE(b0_reg_patch); i++) {
Copy link
Member

Choose a reason for hiding this comment

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

i scope can be reduced, for (size_t i = 0U; ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

Comment on lines 189 to 190
ret |= i2c_reg_update_byte_dt(&config->i2c, b0_reg_patch[i].reg_addr,
b0_reg_patch[i].mask, b0_reg_patch[i].value);
Copy link
Member

@gmarull gmarull Jan 30, 2024

Choose a reason for hiding this comment

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

you should fail fast, also, errno can't be ored together.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

return ret;
}

k_msleep(200);
Copy link
Member

Choose a reason for hiding this comment

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

magic sleep, please define

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

uint8_t value;
int i, ret;

/**
Copy link
Member

Choose a reason for hiding this comment

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

not a doxygen docstring, use /*

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

return -ENOTSUP;
}

data->rev_id = value;
Copy link
Member

Choose a reason for hiding this comment

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

data->rev_id is not used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

Comment on lines 16 to 24
/**
* @name CP9314 Regulator modes
* @{
*/
/** 2:1 mode */
#define CP9314_MODE_2TO1 1
/** 3:1 mode */
#define CP9314_MODE_3TO1 2
/** @} */
Copy link
Member

Choose a reason for hiding this comment

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

can datasheet or details about these modes be provided? are these regulation modes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rriveramcrus
Copy link
Contributor Author

@aasinclair and @gmarull

Is there a datasheet for this part available?

Unfortunately not one that can be shared. This is kind of a more quirky power IC, so I can expand on a bit here and update some of the block comments in the source as well.

The power converter:

This IC is meant for portable systems with 2 or 3 battery cells in series (ex. Laptop). The ICs purpose is to take the 2 or 3 cell battery voltage and buck down to a single cell battery voltage, this is the 2:1/3:1 operational modes.

This sort of power converter (switched capacitor) is able to convert the power without resistive elements (greatly reducing heat aka power wasted) but is fixed to these sort of n:1 operational modes. So it's not really aiming for a regulated target voltage but rather only performing the immediate large power conversion.

The functionality:

The IC conversion operation can be switched on and off via GPIO or I2C command from the host. The operational mode (2:1 or 3:1) can be controlled via I2C from the host. Additionally, the IC can exist standalone or paired in parallel via a shared clock line provided by the initiator instance of the IC. In this mode, the ICs each have a unique I2C address and must be configured by the host based on their ADDR_LVL.

Let me know if this is enough detail to clarify what's going on in the source.

Thanks
Ricardo

drivers/regulator/Kconfig.cp9314 Show resolved Hide resolved
drivers/regulator/regulator_cp9314.c Show resolved Hide resolved
@aasinclair
Copy link
Contributor

This IC is meant for portable systems with 2 or 3 battery cells in series (ex. Laptop). The ICs purpose is to take the 2 or 3 cell battery voltage and buck down to a single cell battery voltage, this is the 2:1/3:1 operational modes.

This sort of power converter (switched capacitor) is able to convert the power without resistive elements (greatly reducing heat aka power wasted) but is fixed to these sort of n:1 operational modes. So it's not really aiming for a regulated target voltage but rather only performing the immediate large power conversion.

Is this something that the user is expected to change at runtime, or is it likely to be fixed by the design?
Is there another default mode, or is it 2:1/3:1?

Thanks

@rriveramcrus
Copy link
Contributor Author

@aasinclair ,

Is this something that the user is expected to change at runtime, or is it likely to be fixed by the design?

It is fixed to the design. I will take an action to remove the runtime control of the op mode.

Is there another default mode, or is it 2:1/3:1?

The default is set with a resistor. We do have one customer using the same BOM for two different SKUs (therefore different op modes), so the driver needs to be able to initialize and overwrite the op mode.

@rriveramcrus
Copy link
Contributor Author

rriveramcrus commented Feb 8, 2024

@aasinclair ,

It is fixed to the design. I will take an action to remove the runtime control of the op mode.

Ah, my bad. If I get rid of .set_mode member of the regulator_driver_api, then regulator_common_init() would not be able to set config->initial_mode. I could add an initialization flag to regulator_cp9314_data and conditionally prevent any post-init regulator_set_mode calls from succeeding.

Let me know if you would rather the initialization flag approach or just leaving it alone.

@aasinclair
Copy link
Contributor

@aasinclair ,

It is fixed to the design. I will take an action to remove the runtime control of the op mode.

Ah, my bad. If I get rid of .set_mode member of the regulator_driver_api, then regulator_common_init() would not be able to set config->initial_mode. I could add an initialization flag to regulator_cp9314_data and conditionally prevent any post-init regulator_set_mode calls from succeeding.

Let me know if you would rather the initialization flag approach or just leaving it alone.

I think this would be better implemented as a custom property, rather than as a mode.
E.g something like this:

nxp,ground-select:
type: string
enum:
- "VREFL3V" # 0
- "VSSA" # 1

@rriveramcrus rriveramcrus force-pushed the cp9314-latest branch 2 times, most recently from c1f6dcd to 6621d76 Compare February 15, 2024 17:45
@rriveramcrus
Copy link
Contributor Author

@aasinclair

I think this would be better implemented as a custom property, rather than as a mode.

Implemented it as cirrus,initial-converter-mode


include:
- name: i2c-device.yaml
- name: regulator.yaml
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't this filter allowed props?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack. The only regulator we can use right now is regulator-boot-on. Some protection properties may be added from regulator.yaml down the line.

Comment on lines 46 to 230
static struct cp9314_reg_patch b0_reg_patch[18] = {
{CP9314_REG_CRUS_CTRL, GENMASK(7, 0), CP9314_CRUS_KEY_UNLOCK},
{CP9314_REG_LION_COMP_CTRL_3, CP9314_VIN_OV_CFG, 0x1B},
{CP9314_REG_LION_COMP_CTRL_1, CP9314_VOUT_OV_CFG_0, 0x30},
{CP9314_REG_LION_COMP_CTRL_2, CP9314_VOUT_OV_CFG_1, 0xC},
{CP9314_REG_VIN2OUT_OVP, CP9314_VIN2OUT_OVP, 0x2},
{CP9314_REG_VIN2OUT_UVP, CP9314_VIN2OUT_UVP, 0x1},
{CP9314_REG_VOUT_UVP, CP9314_VOUT_UVP_DIS, 0},
{CP9314_REG_VOUT_UVP, CP9314_VOUT_UVP, 0},
{CP9314_REG_LION_COMP_CTRL_1, CP9314_VIN_SWITCH_OK_DIS_0, 0},
{CP9314_REG_LION_COMP_CTRL_4, CP9314_VIN_SWITCH_OK_DIS_1, 0},
{CP9314_REG_LION_COMP_CTRL_1, CP9314_VIN_SWITCH_OK_CFG, 0},
{CP9314_REG_LION_CFG_3, CP9314_LB_MIN_FREQ_SEL_0, 0x80},
{CP9314_REG_LB_CTRL, CP9314_LB_MIN_FREQ_SEL_1, 0x4},
{CP9314_REG_TRIM_8, CP9314_MODE_CTRL_UPDATE_BW_0, 0x2},
{CP9314_REG_LION_CFG_3, CP9314_MODE_CTRL_UPDATE_BW_1, 0x2},
{CP9314_REG_IIN_OCP, CP9314_IIN_OCP_DIS, CP9314_IIN_OCP_DIS},
{CP9314_REG_IIN_PEAK_OCP, CP9314_IIN_PEAK_OCP_DIS, CP9314_IIN_PEAK_OCP_DIS},
{CP9314_REG_CRUS_CTRL, GENMASK(7, 0), CP9314_CRUS_KEY_LOCK},
};

static struct cp9314_reg_patch otp_1_patch[3] = {
{CP9314_REG_OPTION_REG_1, CP9314_LB1_DELAY_CFG, 0},
{CP9314_REG_BST_CP_PD_CFG, CP9314_LB1_BLANK_CFG, CP9314_LB1_BLANK_CFG},
{CP9314_REG_TSBAT_CTRL, CP9314_LB1_STOP_PHASE_SEL, CP9314_LB1_STOP_PHASE_SEL},
};
Copy link
Member

Choose a reason for hiding this comment

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

ping

drivers/regulator/regulator_cp9314.c Outdated Show resolved Hide resolved
Comment on lines 19 to 24
*/
/** 2:1 mode */
#define CP9314_MODE_2TO1 1
/** 3:1 mode */
#define CP9314_MODE_3TO1 2
/** @} */
Copy link
Member

Choose a reason for hiding this comment

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

are these used now? If for the new vendor property, please, add an example in the bindings file showing its usage.

Copy link
Member

Choose a reason for hiding this comment

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

also, an enum on such property (if used there) to avoid user mistakes would be useful as well

Copy link
Contributor

Choose a reason for hiding this comment

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

If you use enums & ENUM_IDX macros, you can remove this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

dts/bindings/regulator/cirrus,cp9314.yaml Outdated Show resolved Hide resolved
drivers/regulator/regulator_cp9314.c Outdated Show resolved Hide resolved
tests/drivers/build_all/regulator/i2c.dtsi Outdated Show resolved Hide resolved
Comment on lines 19 to 24
*/
/** 2:1 mode */
#define CP9314_MODE_2TO1 1
/** 3:1 mode */
#define CP9314_MODE_3TO1 2
/** @} */
Copy link
Contributor

Choose a reason for hiding this comment

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

If you use enums & ENUM_IDX macros, you can remove this file.

dts/bindings/regulator/cirrus,cp9314.yaml Outdated Show resolved Hide resolved
drivers/regulator/regulator_cp9314.c Outdated Show resolved Hide resolved
Adds devicetree bindings for the Cirrus CP9314 Switched
Capacitor 3:1/2:1 DC/DC converter.

Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
aasinclair
aasinclair previously approved these changes Feb 21, 2024
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.

Typo nit, but otherwise looks great.

drivers/regulator/regulator_cp9314.c Outdated Show resolved Hide resolved
Adds support for the CP9314 switched capacitor converter. The
CP9314 is a multi-level DC/DC converter capable of operating in
2:1 and 3:1 modes.

Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
Adds the CP9314 device to the regulator build_all test suite.

Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
@aescolar aescolar merged commit aff2564 into zephyrproject-rtos:main Feb 27, 2024
18 checks passed
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants