* [PATCH 0/4] ASoC: cs35l45: Adds support for brownout prevention engines
@ 2026-11-09 17:57 Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 1/4] ASoC: dt-bindings: cs35l45: Adds ABPE properties Ricardo Rivera-Matos via B4 Relay
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Ricardo Rivera-Matos via B4 Relay @ 2026-11-09 17:57 UTC (permalink / raw)
To: David Rhodes, Richard Fitzgerald, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: linux-sound, patches, devicetree, linux-kernel, Ricardo Rivera-Matos
The CS35L45 amplifier has two independent brownout prevention engines
used to prevent system brownout events induced by transient audio peaks.
The amplifier brownount prevention engine (ABPE) monitors the battery
voltage and applies attenuation to audio output in terms of either
decibles, voltage, or wattage. The ABPE response is configured across
four thresholds with four corresponding attenuation values. The attack,
hold, and release parameters of the associated limiter are also
configurable.
The boost converter brownout prevention engine (BBPE) monitors the
battery voltage and the current passing through the inductor in the
boost converter circuit and applies current limit to the boost
converter. The BBPE can be configured to monitor either both the battery
voltage and inductor current or only the battery voltage. When operating
in the combined response mode, the more conservative limitis applied.
The thresholds for the voltage response are configurable across four
levels and the thresholds for the inductor current response are
configurable across three levels. The BBPE's attack, hold, and release
parameters are configurable for both of the response limiters.
Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
---
Ricardo Rivera-Matos (4):
ASoC: dt-bindings: cs35l45: Adds ABPE properties
ASoC: cs35l45: Adds support for ABPE feature
ASoC: dt-bindings: cs35l45: Adds Boost BPE properties
ASoC: cs35l45: Adds Boost BPE configuration
.../devicetree/bindings/sound/cirrus,cs35l45.yaml | 415 ++++++++++++++
include/dt-bindings/sound/cs35l45.h | 45 ++
sound/soc/codecs/cs35l45-tables.c | 95 ++++
sound/soc/codecs/cs35l45.c | 601 +++++++++++++++++++++
sound/soc/codecs/cs35l45.h | 193 +++++++
5 files changed, 1349 insertions(+)
---
base-commit: cde5523c75f1320a55ac1d55a717ccbb566557f0
change-id: 20261102-cs35l45-bpe-340780e966df
Best regards,
--
Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] ASoC: dt-bindings: cs35l45: Adds ABPE properties
2026-11-09 17:57 [PATCH 0/4] ASoC: cs35l45: Adds support for brownout prevention engines Ricardo Rivera-Matos via B4 Relay
@ 2026-11-09 17:57 ` Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 2/4] ASoC: cs35l45: Adds support for ABPE feature Ricardo Rivera-Matos via B4 Relay
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ricardo Rivera-Matos via B4 Relay @ 2026-11-09 17:57 UTC (permalink / raw)
To: David Rhodes, Richard Fitzgerald, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: linux-sound, patches, devicetree, linux-kernel, Ricardo Rivera-Matos
From: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
Adds devicetree properties to configure the amplifier brownout
prevention engine (ABPE).
Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
---
.../devicetree/bindings/sound/cirrus,cs35l45.yaml | 161 +++++++++++++++++++++
1 file changed, 161 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
index e674811b22b2..2c118fa57ad1 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
@@ -16,6 +16,62 @@ description: |
allOf:
- $ref: dai-common.yaml#
+ - if:
+ required:
+ - cirrus,amplifier-bpe-enable
+ then:
+ required:
+ - cirrus,amplifier-bpe-response-mode
+ - cirrus,amplifier-bpe-thresholds-microvolt
+ - cirrus,amplifier-bpe-attack-rates
+ - cirrus,amplifier-bpe-hold-times-us
+ - cirrus,amplifier-bpe-release-rates
+ else:
+ properties:
+ cirrus,amplifier-bpe-response-mode: false
+ cirrus,amplifier-bpe-thresholds-microvolt: false
+ cirrus,amplifier-bpe-attenuation-levels-db: false
+ cirrus,amplifier-bpe-attenuation-levels-microvolt: false
+ cirrus,amplifier-bpe-attenuation-levels-microwatt: false
+ cirrus,amplifier-bpe-attack-rates: false
+ cirrus,amplifier-bpe-hold-times-us: false
+ cirrus,amplifier-bpe-release-rates: false
+ - if:
+ properties:
+ cirrus,amplifier-bpe-response-mode:
+ const: 0
+ required:
+ - cirrus,amplifier-bpe-response-mode
+ then:
+ required:
+ - cirrus,amplifier-bpe-attenuation-levels-db
+ properties:
+ cirrus,amplifier-bpe-attenuation-levels-microvolt: false
+ cirrus,amplifier-bpe-attenuation-levels-microwatt: false
+ - if:
+ properties:
+ cirrus,amplifier-bpe-response-mode:
+ const: 1
+ required:
+ - cirrus,amplifier-bpe-response-mode
+ then:
+ required:
+ - cirrus,amplifier-bpe-attenuation-levels-microvolt
+ properties:
+ cirrus,amplifier-bpe-attenuation-levels-db: false
+ cirrus,amplifier-bpe-attenuation-levels-microwatt: false
+ - if:
+ properties:
+ cirrus,amplifier-bpe-response-mode:
+ const: 2
+ required:
+ - cirrus,amplifier-bpe-response-mode
+ then:
+ required:
+ - cirrus,amplifier-bpe-attenuation-levels-microwatt
+ properties:
+ cirrus,amplifier-bpe-attenuation-levels-db: false
+ cirrus,amplifier-bpe-attenuation-levels-microvolt: false
properties:
compatible:
@@ -123,6 +179,103 @@ properties:
the current monitor (IMON) circuit is put into a low power operational
state.
+ cirrus,amplifier-bpe-enable:
+ type: boolean
+ description: Enable the amplifier brownout prevention engine (BPE).
+
+ cirrus,amplifier-bpe-response-mode:
+ description:
+ Amplifier BPE attack and release response mode. This property
+ determines the ABPE attenuation natural units.
+ 0 = logarithmic
+ 1 = linear voltage
+ 2 = linear power
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2]
+
+ cirrus,amplifier-bpe-thresholds-microvolt:
+ description:
+ Amplifier BPE response battery voltage thresholds for levels L3, L2,
+ L1, L0, in that order. Each level can be set independently.
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 2300000
+ maximum: 4500000
+ multipleOf: 10000
+
+ cirrus,amplifier-bpe-attenuation-levels-db:
+ description:
+ Amplifier BPE logarithmic audio output attenuation for levels L3, L2,
+ L1, L0, in whole dB steps. Half dB hardware settings are not
+ supported.
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 0
+ maximum: 15
+
+ cirrus,amplifier-bpe-attenuation-levels-microvolt:
+ description: |
+ Amplifier BPE linear voltage audio output attenuation for levels L3,
+ L2, L1, L0.
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 187500
+ maximum: 1000000
+ multipleOf: 31250
+
+ cirrus,amplifier-bpe-attenuation-levels-microwatt:
+ description: |
+ Amplifier BPE linear power audio output attenuation for levels L3,
+ L2, L1, L0.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 31250
+ maximum: 1000000
+ multipleOf: 31250
+
+ cirrus,amplifier-bpe-attack-rates:
+ description: |
+ Amplifier BPE attack rate register codes for levels L3, L2, L1, L0.
+ Code 0 is instantaneous; codes 1 through 8 select progressively
+ slower rates. The physical rate depends on the response mode.
+
+ See section 7.21.9 of the datasheet for a detailed description.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 0
+ maximum: 8
+
+ cirrus,amplifier-bpe-hold-times-us:
+ description: |
+ Amplifier BPE hold times for levels L3, L2, L1, L0. Infinite hold is
+ unsupported.
+ minItems: 4
+ maxItems: 4
+ items:
+ enum: [0, 250, 500, 1000, 5000, 10000, 25000, 50000,
+ 100000, 250000, 500000, 1000000, 2500000, 5000000, 10000000]
+
+ cirrus,amplifier-bpe-release-rates:
+ description: |
+ Amplifier BPE release rate register codes for levels L3, L2, L1, L0.
+ Code 0 is instantaneous; codes 1 through 14 select progressively
+ slower rates. The physical rate depends on the response mode.
+
+ See section 7.21.11 of the datasheet for a detailed description.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 0
+ maximum: 14
+
patternProperties:
"^cirrus,gpio-ctrl[1-3]$":
description:
@@ -251,6 +404,14 @@ examples:
cirrus,ldpm-group2-delay-ms = <1000>;
cirrus,ldpm-group2-vmon-select;
cirrus,ldpm-group2-imon-select;
+ cirrus,amplifier-bpe-enable;
+ cirrus,amplifier-bpe-response-mode = <0>;
+ cirrus,amplifier-bpe-thresholds-microvolt =
+ <3200000 3000000 2800000 2600000>;
+ cirrus,amplifier-bpe-attenuation-levels-db = <3 6 9 12>;
+ cirrus,amplifier-bpe-attack-rates = <6 6 6 6>;
+ cirrus,amplifier-bpe-hold-times-us = <500 500 500 500>;
+ cirrus,amplifier-bpe-release-rates = <5 5 5 5>;
cirrus,gpio-ctrl1 {
gpio-ctrl = <0x2>;
};
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/4] ASoC: cs35l45: Adds support for ABPE feature
2026-11-09 17:57 [PATCH 0/4] ASoC: cs35l45: Adds support for brownout prevention engines Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 1/4] ASoC: dt-bindings: cs35l45: Adds ABPE properties Ricardo Rivera-Matos via B4 Relay
@ 2026-11-09 17:57 ` Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 3/4] ASoC: dt-bindings: cs35l45: Adds Boost BPE properties Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 4/4] ASoC: cs35l45: Adds Boost BPE configuration Ricardo Rivera-Matos via B4 Relay
3 siblings, 0 replies; 5+ messages in thread
From: Ricardo Rivera-Matos via B4 Relay @ 2026-11-09 17:57 UTC (permalink / raw)
To: David Rhodes, Richard Fitzgerald, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: linux-sound, patches, devicetree, linux-kernel, Ricardo Rivera-Matos
From: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
Adds support for boot time configuration of the amplifier brownout
prevention engine (ABPE). This circuit monitors the battery voltage
and responds with a tunable limiter on the audio output signal.
This limiter has four response levels, three limiter response
profiles (logarithmic, linear voltage, and linear power), and
configurable attack, hold, and release characteristics.
Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
---
sound/soc/codecs/cs35l45-tables.c | 48 ++++++++
sound/soc/codecs/cs35l45.c | 223 ++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/cs35l45.h | 49 +++++++++
3 files changed, 320 insertions(+)
diff --git a/sound/soc/codecs/cs35l45-tables.c b/sound/soc/codecs/cs35l45-tables.c
index 554c8121a74f..95c39788b71b 100644
--- a/sound/soc/codecs/cs35l45-tables.c
+++ b/sound/soc/codecs/cs35l45-tables.c
@@ -77,6 +77,12 @@ static const struct reg_default cs35l45_defaults[] = {
{ CS35L45_DSP1RX6_INPUT, 0x00000028 },
{ CS35L45_DSP1RX7_INPUT, 0x0000003A },
{ CS35L45_DSP1RX8_INPUT, 0x00000028 },
+ { CS35L45_BPE_INST_THLD, 0x5A46321E },
+ { CS35L45_BPE_INST_ATTN, 0x060C1218 },
+ { CS35L45_BPE_INST_ATK_RATE, 0x06060606 },
+ { CS35L45_BPE_INST_HOLD_TIME, 0x02020202 },
+ { CS35L45_BPE_INST_RLS_RATE, 0x05050505 },
+ { CS35L45_BPE_MISC_CONFIG, 0x0000005A },
{ CS35L45_LDPM_CONFIG, 0x00003636 },
{ CS35L45_AMP_PCM_CONTROL, 0x00100000 },
{ CS35L45_AMP_GAIN, 0x00002300 },
@@ -164,6 +170,12 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
case CS35L45_DSP1RX6_INPUT:
case CS35L45_DSP1RX7_INPUT:
case CS35L45_DSP1RX8_INPUT:
+ case CS35L45_BPE_INST_THLD:
+ case CS35L45_BPE_INST_ATTN:
+ case CS35L45_BPE_INST_ATK_RATE:
+ case CS35L45_BPE_INST_HOLD_TIME:
+ case CS35L45_BPE_INST_RLS_RATE:
+ case CS35L45_BPE_MISC_CONFIG:
case CS35L45_HVLV_CONFIG:
case CS35L45_LDPM_CONFIG:
case CS35L45_AMP_PCM_CONTROL:
@@ -392,3 +404,39 @@ int cs35l45_get_ldpm_delay(u32 delay_ms)
return -EINVAL;
}
EXPORT_SYMBOL_NS_GPL(cs35l45_get_ldpm_delay, "SND_SOC_CS35L45");
+
+static const u32 cs35l45_bpe_hold_times_us[] = {
+ 0, 250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, 2500000,
+ 5000000, 10000000,
+};
+
+int cs35l45_bpe_pack_hold_times(u32 *hold_times, u32 *packed_code)
+{
+ int i, j;
+
+ for (i = 0; i < CS35L45_BPE_NUM_LEVELS; i++) {
+ for (j = 0; j < ARRAY_SIZE(cs35l45_bpe_hold_times_us); j++)
+ if (hold_times[i] == cs35l45_bpe_hold_times_us[j])
+ break;
+
+ if (j == ARRAY_SIZE(cs35l45_bpe_hold_times_us))
+ return -EINVAL;
+
+ *packed_code |= CS35L45_BPE_PACK_CODE(j, i);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l45_bpe_pack_hold_times, "SND_SOC_CS35L45");
+
+static const char * const cs35l45_bpe_attenuation_props[] = {
+ [BPE_MODE_LOGARITHMIC] = "cirrus,amplifier-bpe-attenuation-levels-db",
+ [BPE_MODE_LINEAR_VOLTAGE] = "cirrus,amplifier-bpe-attenuation-levels-microvolt",
+ [BPE_MODE_LINEAR_POWER] = "cirrus,amplifier-bpe-attenuation-levels-microwatt",
+};
+
+const char *cs35l45_bpe_get_attn_prop(const enum bpe_modes mode)
+{
+ return cs35l45_bpe_attenuation_props[mode];
+}
+EXPORT_SYMBOL_NS_GPL(cs35l45_bpe_get_attn_prop, "SND_SOC_CS35L45");
diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c
index 064ee612f05e..72f4ab1b89be 100644
--- a/sound/soc/codecs/cs35l45.c
+++ b/sound/soc/codecs/cs35l45.c
@@ -1148,6 +1148,225 @@ static void cs35l45_apply_sync_property_config(struct cs35l45_private *cs35l45)
CS35L45_SYNC_SW_TXID_MASK, val);
}
+static int cs35l45_bpe_read_array(struct cs35l45_private *cs35l45, const char *property,
+ u32 *values, size_t count)
+{
+ int num_values, ret;
+
+ if (!device_property_present(cs35l45->dev, property))
+ return dev_err_probe(cs35l45->dev, -EINVAL, "Missing %s\n", property);
+
+ num_values = device_property_count_u32(cs35l45->dev, property);
+ if (num_values < 0)
+ return dev_err_probe(cs35l45->dev, num_values, "Failed to count %s\n", property);
+
+ if (num_values != count)
+ return dev_err_probe(cs35l45->dev, -EINVAL, "%s must contain exactly %zu values\n",
+ property, count);
+
+ ret = device_property_read_u32_array(cs35l45->dev, property, values, count);
+ if (ret)
+ return dev_err_probe(cs35l45->dev, ret, "Failed to read %s\n", property);
+
+ return 0;
+}
+
+static int cs35l45_bpe_set_rls_rate(struct cs35l45_private *cs35l45)
+{
+ u32 values[CS35L45_BPE_NUM_LEVELS];
+ u32 packed = 0;
+ int i, ret;
+
+ ret = cs35l45_bpe_read_array(cs35l45, "cirrus,amplifier-bpe-release-rates", values,
+ ARRAY_SIZE(values));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < CS35L45_BPE_NUM_LEVELS; i++) {
+ if (values[i] > CS35L45_BPE_INST_RLS_RATE_MAX) {
+ dev_err(cs35l45->dev, "invalid ABPE release rate at level %d\n",
+ NUM_BPE_MODE - i);
+ return -EINVAL;
+ }
+
+ packed |= CS35L45_BPE_PACK_CODE(values[i], i);
+ }
+
+ return regmap_write(cs35l45->regmap, CS35L45_BPE_INST_RLS_RATE, packed);
+}
+
+static int cs35l45_bpe_set_hold_times(struct cs35l45_private *cs35l45)
+{
+ u32 values[CS35L45_BPE_NUM_LEVELS];
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bpe_read_array(cs35l45, "cirrus,amplifier-bpe-hold-times-us", values,
+ ARRAY_SIZE(values));
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bpe_pack_hold_times(values, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BPE_INST_HOLD_TIME, packed);
+}
+
+static int cs35l45_bpe_set_atk_rate(struct cs35l45_private *cs35l45)
+{
+ u32 values[CS35L45_BPE_NUM_LEVELS];
+ u32 packed = 0;
+ int i, ret;
+
+ ret = cs35l45_bpe_read_array(cs35l45, "cirrus,amplifier-bpe-attack-rates", values,
+ ARRAY_SIZE(values));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < CS35L45_BPE_NUM_LEVELS; i++) {
+ if (values[i] > CS35L45_BPE_INST_ATK_RATE_MAX) {
+ dev_err(cs35l45->dev, "invalid ABPE attack rate at level %d\n",
+ NUM_BPE_MODE - i);
+ return -EINVAL;
+ }
+
+ packed |= CS35L45_BPE_PACK_CODE(values[i], i);
+ }
+
+ return regmap_write(cs35l45->regmap, CS35L45_BPE_INST_ATK_RATE, packed);
+}
+
+static int cs35l45_bpe_set_attn(struct cs35l45_private *cs35l45, const enum bpe_modes mode)
+{
+ u32 values[CS35L45_BPE_NUM_LEVELS];
+ const char *prop_name;
+ u32 code, packed = 0;
+ int i, ret;
+
+ prop_name = cs35l45_bpe_get_attn_prop(mode);
+ ret = cs35l45_bpe_read_array(cs35l45, prop_name, values, ARRAY_SIZE(values));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < CS35L45_BPE_NUM_LEVELS; i++) {
+ switch (mode) {
+ case BPE_MODE_LOGARITHMIC:
+ if (values[i] > CS35L45_BPE_INST_ATTN_LOG_MAX_DB)
+ return -EINVAL;
+ code = values[i] * 2;
+ break;
+ case BPE_MODE_LINEAR_VOLTAGE:
+ if (!in_range(values[i], CS35L45_BPE_INST_ATTN_VOLT_MIN_UV,
+ CS35L45_BPE_INST_ATTN_VOLT_LEN_UV))
+ return -EINVAL;
+ code = (CS35L45_BPE_INST_ATTN_VOLT_MAX_UV - values[i]) /
+ CS35L45_BPE_INST_ATTN_STEP;
+ break;
+ case BPE_MODE_LINEAR_POWER:
+ if (!in_range(values[i], CS35L45_BPE_INST_ATTN_POWER_MIN_UW,
+ CS35L45_BPE_INST_ATTN_POWER_LEN_UW))
+ return -EINVAL;
+ code = (CS35L45_BPE_INST_ATTN_POWER_MAX_UW - values[i]) /
+ CS35L45_BPE_INST_ATTN_STEP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ packed |= CS35L45_BPE_PACK_CODE(code, i);
+ }
+
+ return regmap_write(cs35l45->regmap, CS35L45_BPE_INST_ATTN, packed);
+}
+
+static int cs35l45_bpe_set_thld(struct cs35l45_private *cs35l45)
+{
+ u32 values[CS35L45_BPE_NUM_LEVELS];
+ u32 code, packed = 0;
+ int i, ret;
+
+ ret = cs35l45_bpe_read_array(cs35l45, "cirrus,amplifier-bpe-thresholds-microvolt", values,
+ ARRAY_SIZE(values));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < CS35L45_BPE_NUM_LEVELS; i++) {
+ if (!in_range(values[i], CS35L45_BPE_INST_THLD_MIN_UV,
+ CS35L45_BPE_INST_THLD_LEN_UV)) {
+ dev_err(cs35l45->dev, "invalid ABPE threshold at level %d\n",
+ NUM_BPE_MODE - i);
+ return -EINVAL;
+ }
+
+ code = (values[i] - CS35L45_BPE_INST_THLD_MIN_UV) / CS35L45_BPE_INST_THLD_STEP_UV;
+ packed |= CS35L45_BPE_PACK_CODE(code, i);
+ }
+
+ return regmap_write(cs35l45->regmap, CS35L45_BPE_INST_THLD, packed);
+}
+
+static int cs35l45_bpe_set_mode(struct cs35l45_private *cs35l45, enum bpe_modes *mode)
+{
+ const char *prop;
+ int i, ret;
+
+ ret = device_property_read_u32(cs35l45->dev, "cirrus,amplifier-bpe-response-mode",
+ (u32 *)mode);
+ if (ret || *mode >= NUM_BPE_MODE) {
+ dev_err(cs35l45->dev, "invalid ABPE response mode\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < NUM_BPE_MODE; i++) {
+ prop = cs35l45_bpe_get_attn_prop(i);
+
+ if (i != *mode && device_property_present(cs35l45->dev, prop)) {
+ dev_err(cs35l45->dev, "ABPE attenuation property does not match mode\n");
+ return -EINVAL;
+ }
+ }
+
+ return regmap_update_bits(cs35l45->regmap, CS35L45_BPE_MISC_CONFIG,
+ CS35L45_BPE_MODE_SEL_MASK,
+ FIELD_PREP(CS35L45_BPE_MODE_SEL_MASK, *mode));
+}
+
+static int cs35l45_apply_abpe_config(struct cs35l45_private *cs35l45)
+{
+ enum bpe_modes mode;
+ int ret;
+
+ if (!device_property_read_bool(cs35l45->dev, "cirrus,amplifier-bpe-enable"))
+ return 0;
+
+ ret = cs35l45_bpe_set_mode(cs35l45, &mode);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bpe_set_thld(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bpe_set_attn(cs35l45, mode);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bpe_set_atk_rate(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bpe_set_hold_times(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bpe_set_rls_rate(cs35l45);
+ if (ret)
+ return ret;
+
+ return regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES2, CS35L45_ABPE_EN_MASK);
+}
+
static int cs35l45_apply_ldpm_config(struct cs35l45_private *cs35l45)
{
char prop_name[CS35L45_LDPM_PROP_NAME_MAX];
@@ -1303,6 +1522,10 @@ static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
if (ret < 0)
return ret;
+ ret = cs35l45_apply_abpe_config(cs35l45);
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h
index 5014c765adcb..573595924365 100644
--- a/sound/soc/codecs/cs35l45.h
+++ b/sound/soc/codecs/cs35l45.h
@@ -64,6 +64,12 @@
#define CS35L45_DSP1RX6_INPUT 0x00004C54
#define CS35L45_DSP1RX7_INPUT 0x00004C58
#define CS35L45_DSP1RX8_INPUT 0x00004C5C
+#define CS35L45_BPE_INST_THLD 0x00006064
+#define CS35L45_BPE_INST_ATTN 0x00006068
+#define CS35L45_BPE_INST_ATK_RATE 0x00006074
+#define CS35L45_BPE_INST_HOLD_TIME 0x00006080
+#define CS35L45_BPE_INST_RLS_RATE 0x00006084
+#define CS35L45_BPE_MISC_CONFIG 0x00006090
#define CS35L45_HVLV_CONFIG 0x00006400
#define CS35L45_LDPM_CONFIG 0x00006404
#define CS35L45_AMP_PCM_CONTROL 0x00007000
@@ -188,11 +194,41 @@
#define CS35L45_ASP_EN_SHIFT 27
#define CS35L45_AMP_DRE_EN_SHIFT 20
#define CS35L45_AMP_DRE_EN_MASK BIT(20)
+#define CS35L45_ABPE_EN_MASK BIT(12)
#define CS35L45_SYNC_EN_SHIFT 8
#define CS35L45_SYNC_EN_MASK BIT(8)
#define CS35L45_MEM_RDY_SHIFT 1
#define CS35L45_MEM_RDY_MASK BIT(1)
+/* BPE_INST_THLD */
+#define CS35L45_BPE_INST_THLD_MIN_UV 2300000
+#define CS35L45_BPE_INST_THLD_MAX_UV 4500000
+#define CS35L45_BPE_INST_THLD_LEN_UV (CS35L45_BPE_INST_THLD_MAX_UV - \
+ CS35L45_BPE_INST_THLD_MIN_UV + 1)
+#define CS35L45_BPE_INST_THLD_STEP_UV 10000
+
+/* BPE_INST_ATTN */
+#define CS35L45_BPE_INST_ATTN_LOG_MAX_DB 15
+#define CS35L45_BPE_INST_ATTN_LOG_SCALE 2
+#define CS35L45_BPE_INST_ATTN_VOLT_MIN_UV 187500
+#define CS35L45_BPE_INST_ATTN_VOLT_MAX_UV 1000000
+#define CS35L45_BPE_INST_ATTN_VOLT_LEN_UV (CS35L45_BPE_INST_ATTN_VOLT_MAX_UV - \
+ CS35L45_BPE_INST_ATTN_VOLT_MIN_UV + 1)
+#define CS35L45_BPE_INST_ATTN_POWER_MIN_UW 31250
+#define CS35L45_BPE_INST_ATTN_POWER_MAX_UW 1000000
+#define CS35L45_BPE_INST_ATTN_POWER_LEN_UW (CS35L45_BPE_INST_ATTN_POWER_MAX_UW - \
+ CS35L45_BPE_INST_ATTN_POWER_MIN_UW + 1)
+#define CS35L45_BPE_INST_ATTN_STEP 31250
+
+/* BPE_INST_ATK_RATE */
+#define CS35L45_BPE_INST_ATK_RATE_MAX 8
+
+/* BPE_INST_RLS_RATE */
+#define CS35L45_BPE_INST_RLS_RATE_MAX 14
+
+/* BPE_MISC_CONFIG */
+#define CS35L45_BPE_MODE_SEL_MASK GENMASK(5, 4)
+
/* ERROR_RELEASE */
#define CS35L45_GLOBAL_ERR_RLS_MASK BIT(11)
@@ -474,6 +510,13 @@ enum ldpm_groups {
NUM_LDPM_GROUP,
};
+enum bpe_modes {
+ BPE_MODE_LOGARITHMIC,
+ BPE_MODE_LINEAR_VOLTAGE,
+ BPE_MODE_LINEAR_POWER,
+ NUM_BPE_MODE,
+};
+
#define CS35L45_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_3LE| \
SNDRV_PCM_FMTBIT_S24_LE)
@@ -485,6 +528,10 @@ enum ldpm_groups {
#define CS35L45_LDPM_PROP_NAME_MAX 37
+#define CS35L45_BPE_NUM_LEVELS 4
+
+#define CS35L45_BPE_PACK_CODE(_code, _idx) (_code << (24 - (8 * _idx)))
+
/*
* IRQs
*/
@@ -561,6 +608,8 @@ int cs35l45_apply_patch(struct cs35l45_private *cs35l45);
int cs35l45_get_clk_freq_id(unsigned int freq);
int cs35l45_get_ldpm_pcm_thld(int pcm_thld_db);
int cs35l45_get_ldpm_delay(u32 delay_ms);
+int cs35l45_bpe_pack_hold_times(u32 *hold_times, u32 *packed_code);
+const char *cs35l45_bpe_get_attn_prop(const enum bpe_modes mode);
int cs35l45_probe(struct cs35l45_private *cs35l45);
void cs35l45_remove(struct cs35l45_private *cs35l45);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] ASoC: dt-bindings: cs35l45: Adds Boost BPE properties
2026-11-09 17:57 [PATCH 0/4] ASoC: cs35l45: Adds support for brownout prevention engines Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 1/4] ASoC: dt-bindings: cs35l45: Adds ABPE properties Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 2/4] ASoC: cs35l45: Adds support for ABPE feature Ricardo Rivera-Matos via B4 Relay
@ 2026-11-09 17:57 ` Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 4/4] ASoC: cs35l45: Adds Boost BPE configuration Ricardo Rivera-Matos via B4 Relay
3 siblings, 0 replies; 5+ messages in thread
From: Ricardo Rivera-Matos via B4 Relay @ 2026-11-09 17:57 UTC (permalink / raw)
To: David Rhodes, Richard Fitzgerald, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: linux-sound, patches, devicetree, linux-kernel, Ricardo Rivera-Matos
From: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
Documents devicetree properties for configuring the boost
brownout prevention engine (BBPE).
Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
---
.../devicetree/bindings/sound/cirrus,cs35l45.yaml | 254 +++++++++++++++++++++
include/dt-bindings/sound/cs35l45.h | 45 ++++
2 files changed, 299 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
index 2c118fa57ad1..9373ce4bc3a8 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
@@ -73,6 +73,64 @@ allOf:
cirrus,amplifier-bpe-attenuation-levels-db: false
cirrus,amplifier-bpe-attenuation-levels-microvolt: false
+ - if:
+ required:
+ - cirrus,boost-bpe-enable
+ then:
+ required:
+ - cirrus,boost-bpe-output-operating-mode
+ - cirrus,boost-bpe-output-attack-rate
+ - cirrus,boost-bpe-output-release-rate
+ - cirrus,boost-bpe-battery-limits-microamp
+ - cirrus,boost-bpe-battery-thresholds-microvolt
+ - cirrus,boost-bpe-battery-attack-rates
+ - cirrus,boost-bpe-battery-hold-times-us
+ - cirrus,boost-bpe-battery-release-rates
+ else:
+ properties:
+ cirrus,boost-bpe-output-operating-mode: false
+ cirrus,boost-bpe-output-attack-rate: false
+ cirrus,boost-bpe-output-release-rate: false
+ cirrus,boost-bpe-battery-limits-microamp: false
+ cirrus,boost-bpe-battery-thresholds-microvolt: false
+ cirrus,boost-bpe-battery-attack-rates: false
+ cirrus,boost-bpe-battery-hold-times-us: false
+ cirrus,boost-bpe-battery-release-rates: false
+ cirrus,boost-bpe-inductor-release-mode: false
+ cirrus,boost-bpe-inductor-threshold-microamp: false
+ cirrus,boost-bpe-inductor-threshold-deltas-microamp: false
+ cirrus,boost-bpe-inductor-threshold-hysteresis-microamp: false
+ cirrus,boost-bpe-inductor-delay-hysteresis-us: false
+ cirrus,boost-bpe-inductor-delays-ms: false
+ cirrus,boost-bpe-inductor-attack-rates: false
+ cirrus,boost-bpe-inductor-release-rates: false
+ - if:
+ properties:
+ cirrus,boost-bpe-output-operating-mode:
+ const: 0
+ required:
+ - cirrus,boost-bpe-output-operating-mode
+ then:
+ required:
+ - cirrus,boost-bpe-inductor-release-mode
+ - cirrus,boost-bpe-inductor-threshold-microamp
+ - cirrus,boost-bpe-inductor-threshold-deltas-microamp
+ - cirrus,boost-bpe-inductor-threshold-hysteresis-microamp
+ - cirrus,boost-bpe-inductor-delay-hysteresis-us
+ - cirrus,boost-bpe-inductor-delays-ms
+ - cirrus,boost-bpe-inductor-attack-rates
+ - cirrus,boost-bpe-inductor-release-rates
+ else:
+ properties:
+ cirrus,boost-bpe-inductor-release-mode: false
+ cirrus,boost-bpe-inductor-threshold-microamp: false
+ cirrus,boost-bpe-inductor-threshold-deltas-microamp: false
+ cirrus,boost-bpe-inductor-threshold-hysteresis-microamp: false
+ cirrus,boost-bpe-inductor-delay-hysteresis-us: false
+ cirrus,boost-bpe-inductor-delays-ms: false
+ cirrus,boost-bpe-inductor-attack-rates: false
+ cirrus,boost-bpe-inductor-release-rates: false
+
properties:
compatible:
enum:
@@ -165,6 +223,166 @@ properties:
- 0
- 1
+ cirrus,boost-bpe-enable:
+ type: boolean
+ description:
+ Enable the boost converter brownout protection engine (BBPE).
+ Configuration properties are applied before the engine is enabled.
+
+ cirrus,boost-bpe-inductor-release-mode:
+ description:
+ Selects whether the inductor current response releases instantly or
+ through the release counter. Required in combined mode. Use a
+ CS35L45_BST_BPE_IL_RELEASE_MODE_* constant.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+
+ cirrus,boost-bpe-output-operating-mode:
+ description:
+ Selects the operating mode for the BBPE output stage. The BBPE can be
+ configured to apply the minimum of the battery voltage and inductor
+ current response or the battery voltage response only. When operating in
+ battery voltage only mode, the inductor response related properties are
+ invalid.
+
+ Required when Boost BPE is enabled. Use a CS35L45_BST_BPE_OUTPUT_MODE_*
+ constant.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+
+ cirrus,boost-bpe-output-attack-rate:
+ description:
+ Boost BPE output attack-rate selector. Use a
+ CS35L45_BST_BPE_ATTACK_RATE_* constant.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 7
+
+ cirrus,boost-bpe-output-release-rate:
+ description:
+ Boost BPE output release-rate selector. Use a
+ CS35L45_BST_BPE_RELEASE_RATE_* constant.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 16
+
+ cirrus,boost-bpe-battery-limits-microamp:
+ description:
+ Boost converter current limits for battery voltage response levels 1
+ through 4, in ascending level order.
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 250000
+ maximum: 4625000
+ multipleOf: 62500
+
+ cirrus,boost-bpe-battery-thresholds-microvolt:
+ description:
+ Battery voltage thresholds for battery voltage response levels 0 through
+ 3, in ascending level order.
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 2300000
+ maximum: 4500000
+ multipleOf: 10000
+
+ cirrus,boost-bpe-battery-attack-rates:
+ description:
+ Attack-rate selectors for battery voltage response levels 1 through 3, in
+ ascending level order. Use CS35L45_BST_BPE_ATTACK_RATE_* constants.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 3
+ maxItems: 3
+ items:
+ minimum: 0
+ maximum: 7
+
+ cirrus,boost-bpe-battery-hold-times-us:
+ description:
+ Hold times for battery voltage response levels 0 through 3, in ascending
+ level order. Infinite hold is not supported.
+ minItems: 4
+ maxItems: 4
+ items:
+ enum: [0, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000]
+
+ cirrus,boost-bpe-battery-release-rates:
+ description:
+ Release-rate selectors for voltage response levels 0 through 3, in
+ ascending level order. Use CS35L45_BST_BPE_RELEASE_RATE_* constants.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 4
+ maxItems: 4
+ items:
+ minimum: 0
+ maximum: 16
+
+ cirrus,boost-bpe-inductor-threshold-microamp:
+ description:
+ Inductor current response level 1 threshold.
+ minimum: 250000
+ maximum: 4000000
+ multipleOf: 62500
+
+ cirrus,boost-bpe-inductor-threshold-deltas-microamp:
+ description:
+ Inductor current response threshold deltas 1 and 2, in that order.
+ minItems: 2
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 3750000
+ multipleOf: 62500
+
+ cirrus,boost-bpe-inductor-threshold-hysteresis-microamp:
+ description:
+ Release threshold hysteresis for inductor current response levels 1
+ and 2.
+ minimum: 0
+ maximum: 968750
+ multipleOf: 31250
+
+ cirrus,boost-bpe-inductor-delay-hysteresis-us:
+ description:
+ Release delay hysteresis for inductor current response levels 1 and 2.
+ minimum: 0
+ maximum: 992
+ multipleOf: 32
+
+ cirrus,boost-bpe-inductor-delays-ms:
+ description:
+ Entry delays for inductor current response levels 1 and 2, in ascending
+ level order.
+ minItems: 2
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 100
+
+ cirrus,boost-bpe-inductor-attack-rates:
+ description:
+ Attack-rate selectors for inductor current response levels 1 and 2, in
+ ascending level order. Use CS35L45_BST_BPE_ATTACK_RATE_* constants.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 2
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 7
+
+ cirrus,boost-bpe-inductor-release-rates:
+ description:
+ Release-rate selectors for inductor current response levels 1 and 2, in
+ ascending level order. Use CS35L45_BST_BPE_RELEASE_RATE_* constants.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 2
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 16
+
cirrus,ldpm-group2-vmon-select:
type: boolean
description:
@@ -412,6 +630,42 @@ examples:
cirrus,amplifier-bpe-attack-rates = <6 6 6 6>;
cirrus,amplifier-bpe-hold-times-us = <500 500 500 500>;
cirrus,amplifier-bpe-release-rates = <5 5 5 5>;
+ cirrus,boost-bpe-enable;
+ cirrus,boost-bpe-inductor-release-mode =
+ <CS35L45_BST_BPE_IL_RELEASE_MODE_COUNTER>;
+ cirrus,boost-bpe-output-operating-mode =
+ <CS35L45_BST_BPE_OUTPUT_MODE_BOTH>;
+ cirrus,boost-bpe-output-attack-rate =
+ <CS35L45_BST_BPE_ATTACK_RATE_31P25MA_PER_US>;
+ cirrus,boost-bpe-output-release-rate =
+ <CS35L45_BST_BPE_RELEASE_RATE_3P90625MA_PER_US>;
+ cirrus,boost-bpe-battery-limits-microamp =
+ <1000000 1500000 2000000 2500000>;
+ cirrus,boost-bpe-battery-thresholds-microvolt =
+ <4000000 3600000 3200000 2800000>;
+ cirrus,boost-bpe-battery-attack-rates =
+ <CS35L45_BST_BPE_ATTACK_RATE_INSTANT
+ CS35L45_BST_BPE_ATTACK_RATE_125MA_PER_US
+ CS35L45_BST_BPE_ATTACK_RATE_31P25MA_PER_US>;
+ cirrus,boost-bpe-battery-hold-times-us = <0 5 10 25>;
+ cirrus,boost-bpe-battery-release-rates =
+ <CS35L45_BST_BPE_RELEASE_RATE_INSTANT
+ CS35L45_BST_BPE_RELEASE_RATE_62P5MA_PER_US
+ CS35L45_BST_BPE_RELEASE_RATE_31P25MA_PER_US
+ CS35L45_BST_BPE_RELEASE_RATE_15P625MA_PER_US>;
+ cirrus,boost-bpe-inductor-threshold-microamp = <3000000>;
+ cirrus,boost-bpe-inductor-threshold-deltas-microamp =
+ <250000 500000>;
+ cirrus,boost-bpe-inductor-threshold-hysteresis-microamp =
+ <125000>;
+ cirrus,boost-bpe-inductor-delay-hysteresis-us = <64>;
+ cirrus,boost-bpe-inductor-delays-ms = <12 4>;
+ cirrus,boost-bpe-inductor-attack-rates =
+ <CS35L45_BST_BPE_ATTACK_RATE_INSTANT
+ CS35L45_BST_BPE_ATTACK_RATE_125MA_PER_US>;
+ cirrus,boost-bpe-inductor-release-rates =
+ <CS35L45_BST_BPE_RELEASE_RATE_INSTANT
+ CS35L45_BST_BPE_RELEASE_RATE_62P5MA_PER_US>;
cirrus,gpio-ctrl1 {
gpio-ctrl = <0x2>;
};
diff --git a/include/dt-bindings/sound/cs35l45.h b/include/dt-bindings/sound/cs35l45.h
index 5cb77d48b0b8..4a7535a81612 100644
--- a/include/dt-bindings/sound/cs35l45.h
+++ b/include/dt-bindings/sound/cs35l45.h
@@ -17,6 +17,51 @@
#define CS35L45_ASP_TX_HIZ_UNUSED 0x1
#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
+/*
+ * cirrus,boost-bpe-inductor-release-mode
+ */
+#define CS35L45_BST_BPE_IL_RELEASE_MODE_INSTANT 0x0
+#define CS35L45_BST_BPE_IL_RELEASE_MODE_COUNTER 0x1
+
+/*
+ * cirrus,boost-bpe-output-operating-mode
+ */
+#define CS35L45_BST_BPE_OUTPUT_MODE_BOTH 0x0
+#define CS35L45_BST_BPE_OUTPUT_MODE_VOLTAGE_ONLY 0x1
+
+/*
+ * Boost BPE attack-rate selectors
+ */
+#define CS35L45_BST_BPE_ATTACK_RATE_INSTANT 0x0
+#define CS35L45_BST_BPE_ATTACK_RATE_250MA_PER_US 0x1
+#define CS35L45_BST_BPE_ATTACK_RATE_125MA_PER_US 0x2
+#define CS35L45_BST_BPE_ATTACK_RATE_62P5MA_PER_US 0x3
+#define CS35L45_BST_BPE_ATTACK_RATE_31P25MA_PER_US 0x4
+#define CS35L45_BST_BPE_ATTACK_RATE_15P625MA_PER_US 0x5
+#define CS35L45_BST_BPE_ATTACK_RATE_7P8125MA_PER_US 0x6
+#define CS35L45_BST_BPE_ATTACK_RATE_3P90625MA_PER_US 0x7
+
+/*
+ * Boost BPE release-rate selectors
+ */
+#define CS35L45_BST_BPE_RELEASE_RATE_INSTANT 0x00
+#define CS35L45_BST_BPE_RELEASE_RATE_62P5MA_PER_US 0x01
+#define CS35L45_BST_BPE_RELEASE_RATE_31P25MA_PER_US 0x02
+#define CS35L45_BST_BPE_RELEASE_RATE_15P625MA_PER_US 0x03
+#define CS35L45_BST_BPE_RELEASE_RATE_7P8125MA_PER_US 0x04
+#define CS35L45_BST_BPE_RELEASE_RATE_3P90625MA_PER_US 0x05
+#define CS35L45_BST_BPE_RELEASE_RATE_1P953125MA_PER_US 0x06
+#define CS35L45_BST_BPE_RELEASE_RATE_0P976562MA_PER_US 0x07
+#define CS35L45_BST_BPE_RELEASE_RATE_0P488281MA_PER_US 0x08
+#define CS35L45_BST_BPE_RELEASE_RATE_0P244141MA_PER_US 0x09
+#define CS35L45_BST_BPE_RELEASE_RATE_0P122070MA_PER_US 0x0A
+#define CS35L45_BST_BPE_RELEASE_RATE_0P061035MA_PER_US 0x0B
+#define CS35L45_BST_BPE_RELEASE_RATE_0P030518MA_PER_US 0x0C
+#define CS35L45_BST_BPE_RELEASE_RATE_0P015259MA_PER_US 0x0D
+#define CS35L45_BST_BPE_RELEASE_RATE_0P007629MA_PER_US 0x0E
+#define CS35L45_BST_BPE_RELEASE_RATE_0P003815MA_PER_US 0x0F
+#define CS35L45_BST_BPE_RELEASE_RATE_0P001907MA_PER_US 0x10
+
/*
* cirrus,boost-low-power-mode
*
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/4] ASoC: cs35l45: Adds Boost BPE configuration
2026-11-09 17:57 [PATCH 0/4] ASoC: cs35l45: Adds support for brownout prevention engines Ricardo Rivera-Matos via B4 Relay
` (2 preceding siblings ...)
2026-11-09 17:57 ` [PATCH 3/4] ASoC: dt-bindings: cs35l45: Adds Boost BPE properties Ricardo Rivera-Matos via B4 Relay
@ 2026-11-09 17:57 ` Ricardo Rivera-Matos via B4 Relay
3 siblings, 0 replies; 5+ messages in thread
From: Ricardo Rivera-Matos via B4 Relay @ 2026-11-09 17:57 UTC (permalink / raw)
To: David Rhodes, Richard Fitzgerald, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
Takashi Iwai
Cc: linux-sound, patches, devicetree, linux-kernel, Ricardo Rivera-Matos
From: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
Adds support for boot time configuration of the boost
brownout prevention engine (BBPE). The engine monitors the
battery voltage and the current through the boost inductor
and applies a limit to the output current of the boost
converter via its controller logic.
Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
---
sound/soc/codecs/cs35l45-tables.c | 47 +++++
sound/soc/codecs/cs35l45.c | 378 ++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/cs35l45.h | 144 +++++++++++++++
3 files changed, 569 insertions(+)
diff --git a/sound/soc/codecs/cs35l45-tables.c b/sound/soc/codecs/cs35l45-tables.c
index 95c39788b71b..599415812bf5 100644
--- a/sound/soc/codecs/cs35l45-tables.c
+++ b/sound/soc/codecs/cs35l45-tables.c
@@ -54,6 +54,18 @@ static const struct reg_default cs35l45_defaults[] = {
{ CS35L45_SYNC_TX_RX_ENABLES, 0x00000200 },
{ CS35L45_SYNC_SW_TX_ID, 0x00000000 },
{ CS35L45_BOOST_LPMODE_CFG, 0x00000002 },
+ { CS35L45_BST_BPE_INST_THLD, 0x5A46321E },
+ { CS35L45_BST_BPE_INST_ILIM, 0x3C140C04 },
+ { CS35L45_BST_BPE_INST_ATK_RATE, 0x06060600 },
+ { CS35L45_BST_BPE_INST_HOLD_TIME, 0x02020202 },
+ { CS35L45_BST_BPE_INST_RLS_RATE, 0x06060606 },
+ { CS35L45_BST_BPE_MISC_CONFIG, 0x00008000 },
+ { CS35L45_BST_BPE_IL_LIM_THLD, 0x0006022C },
+ { CS35L45_BST_BPE_IL_LIM_DLY, 0x0000040C },
+ { CS35L45_BST_BPE_IL_LIM_ATK_RATE, 0x00000000 },
+ { CS35L45_BST_BPE_IL_LIM_RLS_RATE, 0x00000000 },
+ { CS35L45_BST_BPE_OUT_ATK_RATE, 0x00000002 },
+ { CS35L45_BST_BPE_OUT_RLS_RATE, 0x00000002 },
{ CS35L45_ASP_ENABLES1, 0x00000000 },
{ CS35L45_ASP_CONTROL1, 0x00000028 },
{ CS35L45_ASP_CONTROL2, 0x18180200 },
@@ -143,6 +155,18 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
case CS35L45_WKI2C_CTL:
case CS35L45_PWRMGT_STS:
case CS35L45_REFCLK_INPUT:
+ case CS35L45_BST_BPE_INST_THLD:
+ case CS35L45_BST_BPE_INST_ILIM:
+ case CS35L45_BST_BPE_INST_ATK_RATE:
+ case CS35L45_BST_BPE_INST_HOLD_TIME:
+ case CS35L45_BST_BPE_INST_RLS_RATE:
+ case CS35L45_BST_BPE_MISC_CONFIG:
+ case CS35L45_BST_BPE_IL_LIM_THLD:
+ case CS35L45_BST_BPE_IL_LIM_DLY:
+ case CS35L45_BST_BPE_IL_LIM_ATK_RATE:
+ case CS35L45_BST_BPE_IL_LIM_RLS_RATE:
+ case CS35L45_BST_BPE_OUT_ATK_RATE:
+ case CS35L45_BST_BPE_OUT_RLS_RATE:
case CS35L45_GLOBAL_SAMPLE_RATE:
case CS35L45_SYNC_TX_RX_ENABLES:
case CS35L45_SYNC_SW_TX_ID:
@@ -440,3 +464,26 @@ const char *cs35l45_bpe_get_attn_prop(const enum bpe_modes mode)
return cs35l45_bpe_attenuation_props[mode];
}
EXPORT_SYMBOL_NS_GPL(cs35l45_bpe_get_attn_prop, "SND_SOC_CS35L45");
+
+static const u32 cs35l45_bst_bpe_hold_times_us[] = {
+ 0, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000,
+};
+
+int cs35l45_bst_bpe_pack_hold_times(const u32 *hold_times, u32 *packed_code)
+{
+ int i, j;
+
+ for (i = 0; i < CS35L45_BST_BPE_NUM_LEVELS; i++) {
+ for (j = 0; j < ARRAY_SIZE(cs35l45_bst_bpe_hold_times_us); j++)
+ if (hold_times[i] == cs35l45_bst_bpe_hold_times_us[j])
+ break;
+
+ if (j == ARRAY_SIZE(cs35l45_bst_bpe_hold_times_us))
+ return -EINVAL;
+
+ *packed_code |= CS35L45_BST_BPE_PACK_CODE(j, i);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l45_bst_bpe_pack_hold_times, "SND_SOC_CS35L45");
diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c
index 72f4ab1b89be..c087f9db6ea7 100644
--- a/sound/soc/codecs/cs35l45.c
+++ b/sound/soc/codecs/cs35l45.c
@@ -1367,6 +1367,380 @@ static int cs35l45_apply_abpe_config(struct cs35l45_private *cs35l45)
return regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES2, CS35L45_ABPE_EN_MASK);
}
+static int cs35l45_bst_bpe_pack_array(struct cs35l45_private *cs35l45, const char *property,
+ size_t count, unsigned int first_lane, u32 min, u32 max,
+ u32 step, u32 *packed)
+{
+ u32 code, values[CS35L45_BST_BPE_NUM_LEVELS];
+ unsigned int i;
+ int ret;
+
+ if (!step || (first_lane + count) > ARRAY_SIZE(values))
+ return -EINVAL;
+
+ ret = cs35l45_bpe_read_array(cs35l45, property, values, count);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < count; i++) {
+ if (values[i] < min || values[i] > max)
+ return dev_err_probe(cs35l45->dev, -EINVAL,
+ "Invalid %s value %u at index %u\n",
+ property, values[i], i);
+
+ code = (values[i] - min) / step;
+
+ *packed |= CS35L45_BST_BPE_PACK_CODE(code, first_lane + i);
+ }
+
+ return 0;
+}
+
+static int cs35l45_bst_bpe_pack_scalar(struct cs35l45_private *cs35l45, const char *property,
+ u32 field_mask, unsigned int shift, u32 min, u32 max,
+ u32 step, u32 *packed)
+{
+ u32 value, code;
+ int ret;
+
+ if (!device_property_present(cs35l45->dev, property))
+ return -EINVAL;
+
+ ret = device_property_read_u32(cs35l45->dev, property, &value);
+ if (ret)
+ return dev_err_probe(cs35l45->dev, ret, "Failed to read %s\n", property);
+
+ if (!step || value < min || value > max)
+ return dev_err_probe(cs35l45->dev, -EINVAL, "Invalid %s value %u\n",
+ property, value);
+
+ code = (value - min) / step;
+ if (code > field_mask >> shift)
+ return dev_err_probe(cs35l45->dev, -EINVAL,
+ "%s value %u does not fit its field\n", property, value);
+
+ *packed |= code << shift;
+
+ return 0;
+}
+
+static int cs35l45_bst_bpe_set_inst_thld(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-battery-thresholds-microvolt",
+ CS35L45_BST_BPE_NUM_VOLTAGE_LEVELS, 0,
+ CS35L45_BST_BPE_INST_THLD_MIN_UV,
+ CS35L45_BST_BPE_INST_THLD_MAX_UV,
+ CS35L45_BST_BPE_INST_THLD_STEP_UV, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_INST_THLD, packed);
+}
+
+static int cs35l45_bst_bpe_set_inst_ilim(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-battery-limits-microamp",
+ CS35L45_BST_BPE_NUM_VOLTAGE_LEVELS, 0,
+ CS35L45_BST_BPE_INST_ILIM_MIN_UA,
+ CS35L45_BST_BPE_INST_ILIM_MAX_UA,
+ CS35L45_BST_BPE_INST_ILIM_STEP_UA, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_INST_ILIM, packed);
+}
+
+static int cs35l45_bst_bpe_set_inst_atk_rate(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-battery-attack-rates",
+ CS35L45_BST_BPE_NUM_VOLTAGE_ATTACK_LEVELS, 1, 0,
+ CS35L45_BST_BPE_ATTACK_RATE_3P90625MA_PER_US, 1, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_INST_ATK_RATE, packed);
+}
+
+static int cs35l45_bst_bpe_set_inst_hold_time(struct cs35l45_private *cs35l45)
+{
+ u32 values[CS35L45_BST_BPE_NUM_VOLTAGE_LEVELS];
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bpe_read_array(cs35l45, "cirrus,boost-bpe-battery-hold-times-us", values,
+ ARRAY_SIZE(values));
+ if (ret < 0)
+ return ret;
+
+ ret = cs35l45_bst_bpe_pack_hold_times(values, &packed);
+ if (ret)
+ return dev_err_probe(cs35l45->dev, ret, "Invalid Boost BPE hold time\n");
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_INST_HOLD_TIME, packed);
+}
+
+static int cs35l45_bst_bpe_set_inst_rls_rate(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-battery-release-rates",
+ CS35L45_BST_BPE_NUM_VOLTAGE_LEVELS, 0, 0,
+ CS35L45_BST_BPE_RELEASE_RATE_0P001907MA_PER_US, 1,
+ &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_INST_RLS_RATE, packed);
+}
+
+static int cs35l45_bst_bpe_set_out_atk_rate(struct cs35l45_private *cs35l45)
+{
+ u32 value;
+ int ret;
+
+ ret = device_property_read_u32(cs35l45->dev, "cirrus,boost-bpe-output-attack-rate",
+ &value);
+ if (ret)
+ return ret;
+
+ if (value > CS35L45_BST_BPE_ATTACK_RATE_3P90625MA_PER_US)
+ return -EINVAL;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_OUT_ATK_RATE, value);
+}
+
+static int cs35l45_bst_bpe_set_out_rls_rate(struct cs35l45_private *cs35l45)
+{
+ u32 value;
+ int ret;
+
+ ret = device_property_read_u32(cs35l45->dev, "cirrus,boost-bpe-output-release-rate",
+ &value);
+ if (ret)
+ return ret;
+
+ if (value > CS35L45_BST_BPE_RELEASE_RATE_0P001907MA_PER_US)
+ return -EINVAL;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_OUT_RLS_RATE, value);
+}
+
+static int cs35l45_bst_bpe_set_il_lim_thld(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_scalar(cs35l45, "cirrus,boost-bpe-inductor-threshold-microamp",
+ CS35L45_BST_BPE_IL_LIM1_THLD_MASK,
+ CS35L45_BST_BPE_IL_LIM1_THLD_SHIFT,
+ CS35L45_BST_BPE_IL_LIM_THLD_MIN_UA,
+ CS35L45_BST_BPE_IL_LIM_THLD_MAX_UA,
+ CS35L45_BST_BPE_IL_LIM_THLD_STEP_UA, &packed);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45,
+ "cirrus,boost-bpe-inductor-threshold-deltas-microamp",
+ CS35L45_BST_BPE_NUM_CURRENT_LEVELS, 1,
+ CS35L45_BST_BPE_IL_LIM_THLD_DEL_MIN_UA,
+ CS35L45_BST_BPE_IL_LIM_THLD_DEL_MAX_UA,
+ CS35L45_BST_BPE_IL_LIM_THLD_DEL_STEP_UA, &packed);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_pack_scalar(cs35l45,
+ "cirrus,boost-bpe-inductor-threshold-hysteresis-microamp",
+ CS35L45_BST_BPE_IL_LIM_THLD_HYST_MASK,
+ CS35L45_BST_BPE_IL_LIM_THLD_HYST_SHIFT,
+ CS35L45_BST_BPE_IL_LIM_THLD_HYST_MIN_UA,
+ CS35L45_BST_BPE_IL_LIM_THLD_HYST_MAX_UA,
+ CS35L45_BST_BPE_IL_LIM_THLD_HYST_STEP_UA, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_IL_LIM_THLD, packed);
+}
+
+static int cs35l45_bst_bpe_set_il_lim_dly(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_scalar(cs35l45, "cirrus,boost-bpe-inductor-delay-hysteresis-us",
+ CS35L45_BST_BPE_IL_LIM_DLY_HYST_MASK,
+ CS35L45_BST_BPE_IL_LIM_DLY_HYST_SHIFT,
+ CS35L45_BST_BPE_IL_LIM_DLY_HYST_MIN_US,
+ CS35L45_BST_BPE_IL_LIM_DLY_HYST_MAX_US,
+ CS35L45_BST_BPE_IL_LIM_DLY_HYST_STEP_US, &packed);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-inductor-delays-ms",
+ CS35L45_BST_BPE_NUM_CURRENT_LEVELS, 0,
+ CS35L45_BST_BPE_IL_LIM_DLY_MIN_MS,
+ CS35L45_BST_BPE_IL_LIM_DLY_MAX_MS,
+ CS35L45_BST_BPE_IL_LIM_DLY_STEP_MS, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_IL_LIM_DLY, packed);
+}
+
+static int cs35l45_bst_bpe_set_il_lim_atk_rate(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-inductor-attack-rates",
+ CS35L45_BST_BPE_NUM_CURRENT_LEVELS, 0, 0,
+ CS35L45_BST_BPE_ATTACK_RATE_3P90625MA_PER_US, 1, &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_IL_LIM_ATK_RATE, packed);
+}
+
+static int cs35l45_bst_bpe_set_il_lim_rls_rate(struct cs35l45_private *cs35l45)
+{
+ u32 packed = 0;
+ int ret;
+
+ ret = cs35l45_bst_bpe_pack_array(cs35l45, "cirrus,boost-bpe-inductor-release-rates",
+ CS35L45_BST_BPE_NUM_CURRENT_LEVELS, 0, 0,
+ CS35L45_BST_BPE_RELEASE_RATE_0P001907MA_PER_US, 1,
+ &packed);
+ if (ret)
+ return ret;
+
+ return regmap_write(cs35l45->regmap, CS35L45_BST_BPE_IL_LIM_RLS_RATE, packed);
+}
+
+static int cs35l45_bst_bpe_set_mode(struct cs35l45_private *cs35l45, u32 *output_mode)
+{
+ u32 release_mode, mask, packed;
+ int ret;
+
+ ret = device_property_read_u32(cs35l45->dev, "cirrus,boost-bpe-output-operating-mode",
+ output_mode);
+ if (ret)
+ return dev_err_probe(cs35l45->dev, ret, "Failed to read boost BPE op mode\n");
+
+ if ((*output_mode != CS35L45_BST_BPE_OUTPUT_MODE_BOTH) &&
+ (*output_mode != CS35L45_BST_BPE_OUTPUT_MODE_VOLTAGE_ONLY))
+ return dev_err_probe(cs35l45->dev, -EINVAL, "Invalid boost BPE op mode found\n");
+
+ mask = CS35L45_BST_BPE_OUT_OPMODE_SEL_MASK;
+ packed = FIELD_PREP(CS35L45_BST_BPE_OUT_OPMODE_SEL_MASK, *output_mode);
+
+ if (*output_mode == CS35L45_BST_BPE_OUTPUT_MODE_BOTH) {
+ ret = device_property_read_u32(cs35l45->dev,
+ "cirrus,boost-bpe-inductor-release-mode",
+ &release_mode);
+ if (ret)
+ return dev_err_probe(cs35l45->dev, ret,
+ "Failed to read inductor response release mode\n");
+
+ if ((release_mode != CS35L45_BST_BPE_IL_RELEASE_MODE_INSTANT) &&
+ (release_mode != CS35L45_BST_BPE_IL_RELEASE_MODE_COUNTER))
+ return dev_err_probe(cs35l45->dev, -EINVAL,
+ "Invalid boost BPE indductor current release mode\n");
+
+ mask |= CS35L45_BST_BPE_IL_LIM_MODE_MASK;
+ packed |= FIELD_PREP(CS35L45_BST_BPE_IL_LIM_MODE_MASK, release_mode);
+ }
+
+ return regmap_update_bits(cs35l45->regmap, CS35L45_BST_BPE_MISC_CONFIG, mask, packed);
+}
+
+static int cs35l45_bst_bpe_set_il_lim_limiter(struct cs35l45_private *cs35l45)
+{
+ int ret;
+
+ ret = cs35l45_bst_bpe_set_il_lim_thld(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_il_lim_dly(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_il_lim_atk_rate(cs35l45);
+ if (ret)
+ return ret;
+
+ return cs35l45_bst_bpe_set_il_lim_rls_rate(cs35l45);
+}
+
+static int cs35l45_bst_bpe_set_inst_limiter(struct cs35l45_private *cs35l45)
+{
+ int ret;
+
+ ret = cs35l45_bst_bpe_set_inst_thld(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_inst_ilim(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_inst_atk_rate(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_inst_hold_time(cs35l45);
+ if (ret)
+ return ret;
+
+ return cs35l45_bst_bpe_set_inst_rls_rate(cs35l45);
+}
+
+static int cs35l45_apply_boost_bpe_config(struct cs35l45_private *cs35l45)
+{
+ u32 output_mode;
+ int ret;
+
+ if (!device_property_read_bool(cs35l45->dev, "cirrus,boost-bpe-enable"))
+ return 0;
+
+ ret = cs35l45_bst_bpe_set_mode(cs35l45, &output_mode);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_inst_limiter(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_out_atk_rate(cs35l45);
+ if (ret)
+ return ret;
+
+ ret = cs35l45_bst_bpe_set_out_rls_rate(cs35l45);
+ if (ret)
+ return ret;
+
+ if (output_mode == CS35L45_BST_BPE_OUTPUT_MODE_BOTH) {
+ ret = cs35l45_bst_bpe_set_il_lim_limiter(cs35l45);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES2, CS35L45_BBPE_EN_MASK);
+ if (ret)
+ return dev_err_probe(cs35l45->dev, ret, "Failed to enable Boost BPE\n");
+
+ return 0;
+}
+
static int cs35l45_apply_ldpm_config(struct cs35l45_private *cs35l45)
{
char prop_name[CS35L45_LDPM_PROP_NAME_MAX];
@@ -1518,6 +1892,10 @@ static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
val << CS35L45_ASP_DOUT_HIZ_CTRL_SHIFT);
}
+ ret = cs35l45_apply_boost_bpe_config(cs35l45);
+ if (ret < 0)
+ return ret;
+
ret = cs35l45_apply_ldpm_config(cs35l45);
if (ret < 0)
return ret;
diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h
index 573595924365..8c94a7f42c65 100644
--- a/sound/soc/codecs/cs35l45.h
+++ b/sound/soc/codecs/cs35l45.h
@@ -41,6 +41,18 @@
#define CS35L45_BOOST_LPMODE_CFG 0x00003810
#define CS35L45_BOOST_DCM_CFG 0x0000380C
#define CS35L45_BOOST_OV_CFG 0x0000382C
+#define CS35L45_BST_BPE_INST_THLD 0x00003C00
+#define CS35L45_BST_BPE_INST_ILIM 0x00003C04
+#define CS35L45_BST_BPE_INST_ATK_RATE 0x00003C0C
+#define CS35L45_BST_BPE_INST_HOLD_TIME 0x00003C10
+#define CS35L45_BST_BPE_INST_RLS_RATE 0x00003C14
+#define CS35L45_BST_BPE_MISC_CONFIG 0x00003C20
+#define CS35L45_BST_BPE_IL_LIM_THLD 0x00003C24
+#define CS35L45_BST_BPE_IL_LIM_DLY 0x00003C28
+#define CS35L45_BST_BPE_IL_LIM_ATK_RATE 0x00003C2C
+#define CS35L45_BST_BPE_IL_LIM_RLS_RATE 0x00003C30
+#define CS35L45_BST_BPE_OUT_ATK_RATE 0x00003C34
+#define CS35L45_BST_BPE_OUT_RLS_RATE 0x00003C38
#define CS35L45_ASP_ENABLES1 0x00004800
#define CS35L45_ASP_CONTROL1 0x00004804
#define CS35L45_ASP_CONTROL2 0x00004808
@@ -191,6 +203,8 @@
#define CS35L45_BST_ENABLE 0x02
/* BLOCK_ENABLES2 */
+#define CS35L45_BBPE_EN_SHIFT 13
+#define CS35L45_BBPE_EN_MASK BIT(13)
#define CS35L45_ASP_EN_SHIFT 27
#define CS35L45_AMP_DRE_EN_SHIFT 20
#define CS35L45_AMP_DRE_EN_MASK BIT(20)
@@ -282,6 +296,126 @@
/* BOOST_LPMODE_CFG */
#define CS35L45_BST_LPMODE_SEL GENMASK(1, 0)
+/* BST_BPE_INST_THLD */
+#define CS35L45_BST_BPE_INST_L3_THLD_SHIFT 24
+#define CS35L45_BST_BPE_INST_L3_THLD_MASK GENMASK(31, 24)
+#define CS35L45_BST_BPE_INST_L2_THLD_SHIFT 16
+#define CS35L45_BST_BPE_INST_L2_THLD_MASK GENMASK(23, 16)
+#define CS35L45_BST_BPE_INST_L1_THLD_SHIFT 8
+#define CS35L45_BST_BPE_INST_L1_THLD_MASK GENMASK(15, 8)
+#define CS35L45_BST_BPE_INST_L0_THLD_SHIFT 0
+#define CS35L45_BST_BPE_INST_L0_THLD_MASK GENMASK(7, 0)
+
+#define CS35L45_BST_BPE_INST_THLD_MIN_UV 2300000
+#define CS35L45_BST_BPE_INST_THLD_MAX_UV 4500000
+#define CS35L45_BST_BPE_INST_THLD_STEP_UV 10000
+
+/* BST_BPE_INST_ILIM */
+#define CS35L45_BST_BPE_INST_L4_ILIM_SHIFT 24
+#define CS35L45_BST_BPE_INST_L4_ILIM_MASK GENMASK(30, 24)
+#define CS35L45_BST_BPE_INST_L3_ILIM_SHIFT 16
+#define CS35L45_BST_BPE_INST_L3_ILIM_MASK GENMASK(22, 16)
+#define CS35L45_BST_BPE_INST_L2_ILIM_SHIFT 8
+#define CS35L45_BST_BPE_INST_L2_ILIM_MASK GENMASK(14, 8)
+#define CS35L45_BST_BPE_INST_L1_ILIM_SHIFT 0
+#define CS35L45_BST_BPE_INST_L1_ILIM_MASK GENMASK(6, 0)
+
+#define CS35L45_BST_BPE_INST_ILIM_MIN_UA 250000
+#define CS35L45_BST_BPE_INST_ILIM_MAX_UA 4625000
+#define CS35L45_BST_BPE_INST_ILIM_STEP_UA 62500
+
+/* BST_BPE_INST_ATK_RATE */
+#define CS35L45_BST_BPE_INST_L3_ATK_RATE_SHIFT 24
+#define CS35L45_BST_BPE_INST_L3_ATK_RATE_MASK GENMASK(26, 24)
+#define CS35L45_BST_BPE_INST_L2_ATK_RATE_SHIFT 16
+#define CS35L45_BST_BPE_INST_L2_ATK_RATE_MASK GENMASK(18, 16)
+#define CS35L45_BST_BPE_INST_L1_ATK_RATE_SHIFT 8
+#define CS35L45_BST_BPE_INST_L1_ATK_RATE_MASK GENMASK(10, 8)
+
+/* BST_BPE_INST_HOLD_TIME */
+#define CS35L45_BST_BPE_INST_L3_HOLD_TIME_SHIFT 24
+#define CS35L45_BST_BPE_INST_L3_HOLD_TIME_MASK GENMASK(27, 24)
+#define CS35L45_BST_BPE_INST_L2_HOLD_TIME_SHIFT 16
+#define CS35L45_BST_BPE_INST_L2_HOLD_TIME_MASK GENMASK(19, 16)
+#define CS35L45_BST_BPE_INST_L1_HOLD_TIME_SHIFT 8
+#define CS35L45_BST_BPE_INST_L1_HOLD_TIME_MASK GENMASK(11, 8)
+#define CS35L45_BST_BPE_INST_L0_HOLD_TIME_SHIFT 0
+#define CS35L45_BST_BPE_INST_L0_HOLD_TIME_MASK GENMASK(3, 0)
+
+/* BST_BPE_INST_RLS_RATE */
+#define CS35L45_BST_BPE_INST_L3_RLS_RATE_SHIFT 24
+#define CS35L45_BST_BPE_INST_L3_RLS_RATE_MASK GENMASK(28, 24)
+#define CS35L45_BST_BPE_INST_L2_RLS_RATE_SHIFT 16
+#define CS35L45_BST_BPE_INST_L2_RLS_RATE_MASK GENMASK(20, 16)
+#define CS35L45_BST_BPE_INST_L1_RLS_RATE_SHIFT 8
+#define CS35L45_BST_BPE_INST_L1_RLS_RATE_MASK GENMASK(12, 8)
+#define CS35L45_BST_BPE_INST_L0_RLS_RATE_SHIFT 0
+#define CS35L45_BST_BPE_INST_L0_RLS_RATE_MASK GENMASK(4, 0)
+
+/* BST_BPE_MISC_CONFIG */
+#define CS35L45_BST_BPE_IL_LIM_MODE_SHIFT 15
+#define CS35L45_BST_BPE_IL_LIM_MODE_MASK BIT(15)
+#define CS35L45_BST_BPE_OUT_OPMODE_SEL_SHIFT 12
+#define CS35L45_BST_BPE_OUT_OPMODE_SEL_MASK GENMASK(13, 12)
+
+/* BST_BPE_IL_LIM_THLD */
+#define CS35L45_BST_BPE_IL_LIM_THLD_HYST_SHIFT 24
+#define CS35L45_BST_BPE_IL_LIM_THLD_HYST_MASK GENMASK(28, 24)
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL2_SHIFT 16
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL2_MASK GENMASK(23, 16)
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL1_SHIFT 8
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL1_MASK GENMASK(15, 8)
+#define CS35L45_BST_BPE_IL_LIM1_THLD_SHIFT 0
+#define CS35L45_BST_BPE_IL_LIM1_THLD_MASK GENMASK(7, 0)
+
+#define CS35L45_BST_BPE_IL_LIM_THLD_MIN_UA 250000
+#define CS35L45_BST_BPE_IL_LIM_THLD_MAX_UA 4000000
+#define CS35L45_BST_BPE_IL_LIM_THLD_STEP_UA 62500
+
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL_MIN_UA 0
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL_MAX_UA 3750000
+#define CS35L45_BST_BPE_IL_LIM_THLD_DEL_STEP_UA 62500
+
+#define CS35L45_BST_BPE_IL_LIM_THLD_HYST_MIN_UA 0
+#define CS35L45_BST_BPE_IL_LIM_THLD_HYST_MAX_UA 968750
+#define CS35L45_BST_BPE_IL_LIM_THLD_HYST_STEP_UA 31250
+
+/* BST_BPE_IL_LIM_DLY */
+#define CS35L45_BST_BPE_IL_LIM_DLY_HYST_SHIFT 16
+#define CS35L45_BST_BPE_IL_LIM_DLY_HYST_MASK GENMASK(20, 16)
+#define CS35L45_BST_BPE_IL_LIM2_DLY_SHIFT 8
+#define CS35L45_BST_BPE_IL_LIM2_DLY_MASK GENMASK(15, 8)
+#define CS35L45_BST_BPE_IL_LIM1_DLY_SHIFT 0
+#define CS35L45_BST_BPE_IL_LIM1_DLY_MASK GENMASK(7, 0)
+
+#define CS35L45_BST_BPE_IL_LIM_DLY_HYST_MIN_US 0
+#define CS35L45_BST_BPE_IL_LIM_DLY_HYST_MAX_US 992
+#define CS35L45_BST_BPE_IL_LIM_DLY_HYST_STEP_US 32
+
+#define CS35L45_BST_BPE_IL_LIM_DLY_MIN_MS 0
+#define CS35L45_BST_BPE_IL_LIM_DLY_MAX_MS 100
+#define CS35L45_BST_BPE_IL_LIM_DLY_STEP_MS 1
+
+/* BST_BPE_IL_LIM_ATK_RATE */
+#define CS35L45_BST_BPE_IL_LIM2_ATK_RATE_SHIFT 8
+#define CS35L45_BST_BPE_IL_LIM2_ATK_RATE_MASK GENMASK(10, 8)
+#define CS35L45_BST_BPE_IL_LIM1_ATK_RATE_SHIFT 0
+#define CS35L45_BST_BPE_IL_LIM1_ATK_RATE_MASK GENMASK(2, 0)
+
+/* BST_BPE_IL_LIM_RLS_RATE */
+#define CS35L45_BST_BPE_IL_LIM2_RLS_RATE_SHIFT 8
+#define CS35L45_BST_BPE_IL_LIM2_RLS_RATE_MASK GENMASK(12, 8)
+#define CS35L45_BST_BPE_IL_LIM1_RLS_RATE_SHIFT 0
+#define CS35L45_BST_BPE_IL_LIM1_RLS_RATE_MASK GENMASK(4, 0)
+
+/* BST_BPE_OUT_ATK_RATE */
+#define CS35L45_BST_BPE_OUT_ATK_RATE_SHIFT 0
+#define CS35L45_BST_BPE_OUT_ATK_RATE_MASK GENMASK(2, 0)
+
+/* BST_BPE_OUT_RLS_RATE */
+#define CS35L45_BST_BPE_OUT_RLS_RATE_SHIFT 0
+#define CS35L45_BST_BPE_OUT_RLS_RATE_MASK GENMASK(4, 0)
+
/* ASP_ENABLES_1 */
#define CS35L45_ASP_RX2_EN_SHIFT 17
#define CS35L45_ASP_RX1_EN_SHIFT 16
@@ -532,6 +666,15 @@ enum bpe_modes {
#define CS35L45_BPE_PACK_CODE(_code, _idx) (_code << (24 - (8 * _idx)))
+#define CS35L45_BST_BPE_NUM_VOLTAGE_LEVELS 4
+#define CS35L45_BST_BPE_NUM_VOLTAGE_ATTACK_LEVELS 3
+#define CS35L45_BST_BPE_NUM_CURRENT_LEVELS 2
+#define CS35L45_BST_BPE_NUM_LEVELS CS35L45_BST_BPE_NUM_VOLTAGE_LEVELS
+#define CS35L45_BST_BPE_NUM_HOLD_TIMES 12
+
+/* Boost BPE levels use ascending byte lanes; some arrays start at lane 1. */
+#define CS35L45_BST_BPE_PACK_CODE(_code, _idx) ((_code) << (8 * (_idx)))
+
/*
* IRQs
*/
@@ -609,6 +752,7 @@ int cs35l45_get_clk_freq_id(unsigned int freq);
int cs35l45_get_ldpm_pcm_thld(int pcm_thld_db);
int cs35l45_get_ldpm_delay(u32 delay_ms);
int cs35l45_bpe_pack_hold_times(u32 *hold_times, u32 *packed_code);
+int cs35l45_bst_bpe_pack_hold_times(const u32 *hold_times, u32 *packed_code);
const char *cs35l45_bpe_get_attn_prop(const enum bpe_modes mode);
int cs35l45_probe(struct cs35l45_private *cs35l45);
void cs35l45_remove(struct cs35l45_private *cs35l45);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-09 17:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 17:57 [PATCH 0/4] ASoC: cs35l45: Adds support for brownout prevention engines Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 1/4] ASoC: dt-bindings: cs35l45: Adds ABPE properties Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 2/4] ASoC: cs35l45: Adds support for ABPE feature Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 3/4] ASoC: dt-bindings: cs35l45: Adds Boost BPE properties Ricardo Rivera-Matos via B4 Relay
2026-11-09 17:57 ` [PATCH 4/4] ASoC: cs35l45: Adds Boost BPE configuration Ricardo Rivera-Matos via B4 Relay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®