* [PATCH v2 0/4] Add support for CS42L43B codec to CS42L43 driver
@ 2026-01-16 15:20 Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 1/4] ASoC: sdw_utils: Add CS42L43B codec info Maciej Strozek
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Maciej Strozek @ 2026-01-16 15:20 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai, Lee Jones, Krzysztof Kozlowski
Cc: Jaroslav Kysela, Bard Liao, Peter Ujfalusi, linux-kernel,
linux-sound, patches, devicetree, Maciej Strozek
Hello,
Introducing CS42L43B, a variant of the CS42L43 codec with changes to
PDM (DMIC) inputs, RAM/ROM memory and extra channels to two SoundWire
ports and ISRCs, and can be supported by the existing CS42L43 driver
with some modifications.
Support is split into four commits:
1. Add CS42L43B codec info to SoundWire utils
2. Add dt binding for the new variant
3. MFD driver part 1/2
4. ASoC codec driver part 2/2
Regards,
Maciej
---
Changes in v2:
- Rework the mechanism to identify the new variant along with some
error handling improvements.
- Added some comments in cs42l43_readable_register() for clarity.
- Add handling of the I2C path for the B variant
- Add a dt binding for the new variant
---
Maciej Strozek (4):
ASoC: sdw_utils: Add CS42L43B codec info
ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant
mfd: cs42l43: Add support for the B variant
ASoC: cs42l43: Add support for the B variant
.../bindings/sound/cirrus,cs42l43.yaml | 3 +
drivers/mfd/cs42l43-i2c.c | 7 +-
drivers/mfd/cs42l43-sdw.c | 4 +-
drivers/mfd/cs42l43.c | 93 ++-
drivers/mfd/cs42l43.h | 2 +-
include/linux/mfd/cs42l43-regs.h | 76 ++
include/linux/mfd/cs42l43.h | 1 +
sound/soc/codecs/cs42l43.c | 756 +++++++++++++++---
sound/soc/codecs/cs42l43.h | 4 +-
sound/soc/sdw_utils/soc_sdw_utils.c | 54 ++
10 files changed, 848 insertions(+), 152 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/4] ASoC: sdw_utils: Add CS42L43B codec info
2026-01-16 15:20 [PATCH v2 0/4] Add support for CS42L43B codec to CS42L43 driver Maciej Strozek
@ 2026-01-16 15:20 ` Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 2/4] ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant Maciej Strozek
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Maciej Strozek @ 2026-01-16 15:20 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai, Lee Jones, Krzysztof Kozlowski
Cc: Jaroslav Kysela, Bard Liao, Peter Ujfalusi, linux-kernel,
linux-sound, patches, devicetree, Maciej Strozek
Add codec_info for a new variant of CS42L43. It can resue existing info
but needs a new part_id.
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
---
No changes in v2
---
sound/soc/sdw_utils/soc_sdw_utils.c | 54 +++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 6bf81ed132d8..8b59d181a70e 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -721,6 +721,60 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
.dai_num = 4,
},
+ {
+ .part_id = 0x2A3B,
+ .name_prefix = "cs42l43",
+ .count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar,
+ .add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar,
+ .dais = {
+ {
+ .direction = {true, false},
+ .codec_name = "cs42l43-codec",
+ .dai_name = "cs42l43-dp5",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l43_hs_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {false, true},
+ .codec_name = "cs42l43-codec",
+ .dai_name = "cs42l43-dp1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l43_dmic_rtd_init,
+ .widgets = generic_dmic_widgets,
+ .num_widgets = ARRAY_SIZE(generic_dmic_widgets),
+ .quirk = SOC_SDW_CODEC_MIC,
+ .quirk_exclude = true,
+ },
+ {
+ .direction = {false, true},
+ .codec_name = "cs42l43-codec",
+ .dai_name = "cs42l43-dp2",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ {
+ .direction = {true, false},
+ .codec_name = "cs42l43-codec",
+ .dai_name = "cs42l43-dp6",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_cs42l43_spk_init,
+ .rtd_init = asoc_sdw_cs42l43_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ .quirk = SOC_SDW_CODEC_SPKR | SOC_SDW_SIDECAR_AMPS,
+ },
+ },
+ .dai_num = 4,
+ },
{
.part_id = 0x4245,
.name_prefix = "cs42l45",
--
2.48.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/4] ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant
2026-01-16 15:20 [PATCH v2 0/4] Add support for CS42L43B codec to CS42L43 driver Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 1/4] ASoC: sdw_utils: Add CS42L43B codec info Maciej Strozek
@ 2026-01-16 15:20 ` Maciej Strozek
2026-01-17 11:39 ` Krzysztof Kozlowski
2026-01-16 15:20 ` [PATCH v2 3/4] mfd: cs42l43: Add support for the B variant Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 4/4] ASoC: " Maciej Strozek
3 siblings, 1 reply; 7+ messages in thread
From: Maciej Strozek @ 2026-01-16 15:20 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai, Lee Jones, Krzysztof Kozlowski
Cc: Jaroslav Kysela, Bard Liao, Peter Ujfalusi, linux-kernel,
linux-sound, patches, devicetree, Maciej Strozek
CS42L43B variant adds dedicated PDM interface, SoundWire Clock Gearing
support and more decimators to ISRCs.
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
---
Documentation/devicetree/bindings/sound/cirrus,cs42l43.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs42l43.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs42l43.yaml
index 99a536601cc7..376928d1f64b 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,cs42l43.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,cs42l43.yaml
@@ -16,6 +16,8 @@ description: |
DAC for headphone output, two integrated Class D amplifiers for
loudspeakers, and two ADCs for wired headset microphone input or
stereo line input. PDM inputs are provided for digital microphones.
+ CS42L43B variant adds dedicated PDM interface, SoundWire Clock Gearing
+ support and more decimators to ISRCs.
allOf:
- $ref: dai-common.yaml#
@@ -24,6 +26,7 @@ properties:
compatible:
enum:
- cirrus,cs42l43
+ - cirrus,cs42l43b
reg:
maxItems: 1
--
2.48.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/4] mfd: cs42l43: Add support for the B variant
2026-01-16 15:20 [PATCH v2 0/4] Add support for CS42L43B codec to CS42L43 driver Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 1/4] ASoC: sdw_utils: Add CS42L43B codec info Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 2/4] ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant Maciej Strozek
@ 2026-01-16 15:20 ` Maciej Strozek
2026-01-22 11:59 ` Lee Jones
2026-01-16 15:20 ` [PATCH v2 4/4] ASoC: " Maciej Strozek
3 siblings, 1 reply; 7+ messages in thread
From: Maciej Strozek @ 2026-01-16 15:20 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai, Lee Jones, Krzysztof Kozlowski
Cc: Jaroslav Kysela, Bard Liao, Peter Ujfalusi, linux-kernel,
linux-sound, patches, devicetree, Maciej Strozek
Introducing CS42L43B codec, a variant of CS42L43 which can be driven by
the same driver.
Changes in CS42L43 driver specific for CS42L43B:
- Decimator 1 and 2 are dedicated to ADC, can't be selected for PDM
- Decimators 3 and 4 are connected to PDM1
- Added Decimator 5 and 6 for PDM2
- Supports SoundWire Clock Gearing
- Updated ROM requiring no patching
- Reduced RAM space
- Each ISRC has 4 decimators now
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
---
Changes in v2:
- Rework the mechanism to identify the new variant along with some
error handling improvements.
- Added some comments in cs42l43_readable_register() for clarity.
- Add handling of the I2C path for the B variant
---
drivers/mfd/cs42l43-i2c.c | 7 ++-
drivers/mfd/cs42l43-sdw.c | 4 +-
drivers/mfd/cs42l43.c | 93 +++++++++++++++++++++++++++-----
drivers/mfd/cs42l43.h | 2 +-
include/linux/mfd/cs42l43-regs.h | 76 ++++++++++++++++++++++++++
include/linux/mfd/cs42l43.h | 1 +
6 files changed, 166 insertions(+), 17 deletions(-)
diff --git a/drivers/mfd/cs42l43-i2c.c b/drivers/mfd/cs42l43-i2c.c
index a2ab001a600a..0a0ab5e549a5 100644
--- a/drivers/mfd/cs42l43-i2c.c
+++ b/drivers/mfd/cs42l43-i2c.c
@@ -47,6 +47,7 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
cs42l43->irq = i2c->irq;
/* A device on an I2C is always attached by definition. */
cs42l43->attached = true;
+ cs42l43->variant_id = (long)device_get_match_data(cs42l43->dev);
cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap);
if (IS_ERR(cs42l43->regmap))
@@ -58,7 +59,8 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id cs42l43_of_match[] = {
- { .compatible = "cirrus,cs42l43", },
+ { .compatible = "cirrus,cs42l43", .data = (void *)CS42L43_DEVID_VAL },
+ { .compatible = "cirrus,cs42l43b", .data = (void *)CS42L43B_DEVID_VAL },
{}
};
MODULE_DEVICE_TABLE(of, cs42l43_of_match);
@@ -66,7 +68,8 @@ MODULE_DEVICE_TABLE(of, cs42l43_of_match);
#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id cs42l43_acpi_match[] = {
- { "CSC4243", 0 },
+ { "CSC4243", CS42L43_DEVID_VAL },
+ { "CSC2A3B", CS42L43B_DEVID_VAL },
{}
};
MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match);
diff --git a/drivers/mfd/cs42l43-sdw.c b/drivers/mfd/cs42l43-sdw.c
index 023f7e1a30f8..4b11cf5de614 100644
--- a/drivers/mfd/cs42l43-sdw.c
+++ b/drivers/mfd/cs42l43-sdw.c
@@ -178,6 +178,7 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
cs42l43->dev = dev;
cs42l43->sdw = sdw;
+ cs42l43->variant_id = (int)id->driver_data;
cs42l43->regmap = devm_regmap_init_sdw(sdw, &cs42l43_sdw_regmap);
if (IS_ERR(cs42l43->regmap))
@@ -188,7 +189,8 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
}
static const struct sdw_device_id cs42l43_sdw_id[] = {
- SDW_SLAVE_ENTRY(0x01FA, 0x4243, 0),
+ SDW_SLAVE_ENTRY(0x01FA, 0x4243, (void *) CS42L43_DEVID_VAL),
+ SDW_SLAVE_ENTRY(0x01FA, 0x2A3B, (void *) CS42L43B_DEVID_VAL),
{}
};
MODULE_DEVICE_TABLE(sdw, cs42l43_sdw_id);
diff --git a/drivers/mfd/cs42l43.c b/drivers/mfd/cs42l43.c
index 107cfb983fec..6b6b2bbe7e8f 100644
--- a/drivers/mfd/cs42l43.c
+++ b/drivers/mfd/cs42l43.c
@@ -115,9 +115,14 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_DECIM_HPF_WNF_CTRL2, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL3, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL4, 0x00000001 },
+ { CS42L43B_DECIM_HPF_WNF_CTRL5, 0x00000001 },
+ { CS42L43B_DECIM_HPF_WNF_CTRL6, 0x00000001 },
{ CS42L43_DMIC_PDM_CTRL, 0x00000000 },
{ CS42L43_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 },
{ CS42L43_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 },
+ { CS42L43B_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 },
+ { CS42L43B_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 },
+ { CS42L43B_DECIM_VOL_CTRL_CH5_CH6, 0x20122012 },
{ CS42L43_INTP_VOLUME_CTRL1, 0x00000180 },
{ CS42L43_INTP_VOLUME_CTRL2, 0x00000180 },
{ CS42L43_AMP1_2_VOL_RAMP, 0x00000022 },
@@ -155,8 +160,12 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_SWIRE_DP2_CH2_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP3_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP3_CH2_INPUT, 0x00000000 },
+ { CS42L43B_SWIRE_DP3_CH3_INPUT, 0x00000000 },
+ { CS42L43B_SWIRE_DP3_CH4_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP4_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP4_CH2_INPUT, 0x00000000 },
+ { CS42L43B_SWIRE_DP4_CH3_INPUT, 0x00000000 },
+ { CS42L43B_SWIRE_DP4_CH4_INPUT, 0x00000000 },
{ CS42L43_ASRC_INT1_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT2_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT3_INPUT1, 0x00000000 },
@@ -169,10 +178,14 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_ISRC1INT2_INPUT1, 0x00000000 },
{ CS42L43_ISRC1DEC1_INPUT1, 0x00000000 },
{ CS42L43_ISRC1DEC2_INPUT1, 0x00000000 },
+ { CS42L43B_ISRC1DEC3_INPUT1, 0x00000000 },
+ { CS42L43B_ISRC1DEC4_INPUT1, 0x00000000 },
{ CS42L43_ISRC2INT1_INPUT1, 0x00000000 },
{ CS42L43_ISRC2INT2_INPUT1, 0x00000000 },
{ CS42L43_ISRC2DEC1_INPUT1, 0x00000000 },
{ CS42L43_ISRC2DEC2_INPUT1, 0x00000000 },
+ { CS42L43B_ISRC2DEC3_INPUT1, 0x00000000 },
+ { CS42L43B_ISRC2DEC4_INPUT1, 0x00000000 },
{ CS42L43_EQ1MIX_INPUT1, 0x00800000 },
{ CS42L43_EQ1MIX_INPUT2, 0x00800000 },
{ CS42L43_EQ1MIX_INPUT3, 0x00800000 },
@@ -269,6 +282,8 @@ EXPORT_SYMBOL_NS_GPL(cs42l43_reg_default, "MFD_CS42L43");
bool cs42l43_readable_register(struct device *dev, unsigned int reg)
{
+ struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
+
switch (reg) {
case CS42L43_DEVID:
case CS42L43_REVID:
@@ -292,7 +307,6 @@ bool cs42l43_readable_register(struct device *dev, unsigned int reg)
case CS42L43_ADC_B_CTRL1 ... CS42L43_ADC_B_CTRL2:
case CS42L43_DECIM_HPF_WNF_CTRL1 ... CS42L43_DECIM_HPF_WNF_CTRL4:
case CS42L43_DMIC_PDM_CTRL:
- case CS42L43_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43_DECIM_VOL_CTRL_CH3_CH4:
case CS42L43_INTP_VOLUME_CTRL1 ... CS42L43_INTP_VOLUME_CTRL2:
case CS42L43_AMP1_2_VOL_RAMP:
case CS42L43_ASP_CTRL:
@@ -387,8 +401,16 @@ bool cs42l43_readable_register(struct device *dev, unsigned int reg)
case CS42L43_BOOT_CONTROL:
case CS42L43_BLOCK_EN:
case CS42L43_SHUTTER_CONTROL:
- case CS42L43_MCU_SW_REV ... CS42L43_MCU_RAM_MAX:
- return true;
+ case CS42L43B_MCU_SW_REV ... CS42L43B_MCU_RAM_MAX:
+ return true; // registers present on all variants
+ case CS42L43_MCU_SW_REV ... CS42L43B_MCU_SW_REV - 1:
+ case CS42L43B_MCU_RAM_MAX + 1 ... CS42L43_MCU_RAM_MAX:
+ case CS42L43_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43_DECIM_VOL_CTRL_CH3_CH4:
+ return cs42l43->variant_id == CS42L43_DEVID_VAL; // regs only in CS42L43 variant
+ case CS42L43B_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43B_DECIM_HPF_WNF_CTRL6:
+ case CS42L43B_SWIRE_DP3_CH3_INPUT ... CS42L43B_SWIRE_DP4_CH4_INPUT:
+ case CS42L43B_ISRC1DEC3_INPUT1 ... CS42L43B_ISRC2DEC4_INPUT1:
+ return cs42l43->variant_id == CS42L43B_DEVID_VAL; // regs only in CS42L43B variant
default:
return false;
}
@@ -597,15 +619,27 @@ static int cs42l43_wait_for_attach(struct cs42l43 *cs42l43)
static int cs42l43_mcu_stage_2_3(struct cs42l43 *cs42l43, bool shadow)
{
unsigned int need_reg = CS42L43_NEED_CONFIGS;
+ unsigned int boot_reg;
unsigned int val;
int ret;
- if (shadow)
- need_reg = CS42L43_FW_SH_BOOT_CFG_NEED_CONFIGS;
+ switch (cs42l43->variant_id) {
+ case CS42L43_DEVID_VAL:
+ if (shadow)
+ need_reg = CS42L43_FW_SH_BOOT_CFG_NEED_CONFIGS;
+ boot_reg = CS42L43_BOOT_STATUS;
+ break;
+ case CS42L43B_DEVID_VAL:
+ need_reg = CS42L43B_NEED_CONFIGS;
+ boot_reg = CS42L43B_BOOT_STATUS;
+ break;
+ default:
+ return -EINVAL;
+ }
regmap_write(cs42l43->regmap, need_reg, 0);
- ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_BOOT_STATUS,
+ ret = regmap_read_poll_timeout(cs42l43->regmap, boot_reg,
val, (val == CS42L43_MCU_BOOT_STAGE3),
CS42L43_MCU_POLL_US, CS42L43_MCU_CMD_TIMEOUT_US);
if (ret) {
@@ -644,13 +678,25 @@ static int cs42l43_mcu_stage_3_2(struct cs42l43 *cs42l43)
*/
static int cs42l43_mcu_disable(struct cs42l43 *cs42l43)
{
- unsigned int val;
+ unsigned int val, cfg_reg, ctrl_reg;
int ret;
- regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG,
- CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL);
- regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION,
- CS42L43_FW_MM_CTRL_MCU_SEL_MASK);
+ switch (cs42l43->variant_id) {
+ case CS42L43_DEVID_VAL:
+ cfg_reg = CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG;
+ ctrl_reg = CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION;
+ break;
+ case CS42L43B_DEVID_VAL:
+ cfg_reg = CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG;
+ ctrl_reg = CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_write(cs42l43->regmap, cfg_reg, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL);
+ regmap_write(cs42l43->regmap, ctrl_reg, CS42L43_FW_MM_CTRL_MCU_SEL_MASK);
+
regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, CS42L43_CONTROL_IND_MASK);
regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, 0);
@@ -740,18 +786,32 @@ static int cs42l43_mcu_update_step(struct cs42l43 *cs42l43)
{
unsigned int mcu_rev, bios_rev, boot_status, secure_cfg;
bool patched, shadow;
+ int boot_status_reg, mcu_sw_rev_reg;
int ret;
+ switch (cs42l43->variant_id) {
+ case CS42L43_DEVID_VAL:
+ boot_status_reg = CS42L43_BOOT_STATUS;
+ mcu_sw_rev_reg = CS42L43_MCU_SW_REV;
+ break;
+ case CS42L43B_DEVID_VAL:
+ boot_status_reg = CS42L43B_BOOT_STATUS;
+ mcu_sw_rev_reg = CS42L43B_MCU_SW_REV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
/* Clear any stale software interrupt bits. */
regmap_read(cs42l43->regmap, CS42L43_SOFT_INT, &mcu_rev);
- ret = regmap_read(cs42l43->regmap, CS42L43_BOOT_STATUS, &boot_status);
+ ret = regmap_read(cs42l43->regmap, boot_status_reg, &boot_status);
if (ret) {
dev_err(cs42l43->dev, "Failed to read boot status: %d\n", ret);
return ret;
}
- ret = regmap_read(cs42l43->regmap, CS42L43_MCU_SW_REV, &mcu_rev);
+ ret = regmap_read(cs42l43->regmap, mcu_sw_rev_reg, &mcu_rev);
if (ret) {
dev_err(cs42l43->dev, "Failed to read firmware revision: %d\n", ret);
return ret;
@@ -918,6 +978,13 @@ static void cs42l43_boot_work(struct work_struct *work)
switch (devid) {
case CS42L43_DEVID_VAL:
+ case CS42L43B_DEVID_VAL:
+ if (devid != cs42l43->variant_id) {
+ dev_err(cs42l43->dev,
+ "Device ID (0x%06x) does not match variant ID (0x%06x)\n",
+ devid, cs42l43->variant_id);
+ goto err;
+ }
break;
default:
dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid);
diff --git a/drivers/mfd/cs42l43.h b/drivers/mfd/cs42l43.h
index f3da783930f5..a0068f6572e2 100644
--- a/drivers/mfd/cs42l43.h
+++ b/drivers/mfd/cs42l43.h
@@ -9,7 +9,7 @@
#ifndef CS42L43_CORE_INT_H
#define CS42L43_CORE_INT_H
-#define CS42L43_N_DEFAULTS 176
+#define CS42L43_N_DEFAULTS 189
struct dev_pm_ops;
struct device;
diff --git a/include/linux/mfd/cs42l43-regs.h b/include/linux/mfd/cs42l43-regs.h
index c39a49269cb7..68831f113589 100644
--- a/include/linux/mfd/cs42l43-regs.h
+++ b/include/linux/mfd/cs42l43-regs.h
@@ -1181,4 +1181,80 @@
/* CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG */
#define CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL 0xF05AA50F
+/* CS42L43B VARIANT REGISTERS */
+#define CS42L43B_DEVID_VAL 0x0042A43B
+
+#define CS42L43B_DECIM_VOL_CTRL_CH1_CH2 0x00008280
+#define CS42L43B_DECIM_VOL_CTRL_CH3_CH4 0x00008284
+
+#define CS42L43B_DECIM_VOL_CTRL_CH5_CH6 0x00008290
+#define CS42L43B_DECIM_VOL_CTRL_UPDATE 0x0000829C
+
+#define CS42L43B_DECIM_HPF_WNF_CTRL5 0x000082A0
+#define CS42L43B_DECIM_HPF_WNF_CTRL6 0x000082A4
+
+#define CS42L43B_SWIRE_DP3_CH3_INPUT 0x0000C320
+#define CS42L43B_SWIRE_DP3_CH4_INPUT 0x0000C330
+#define CS42L43B_SWIRE_DP4_CH3_INPUT 0x0000C340
+#define CS42L43B_SWIRE_DP4_CH4_INPUT 0x0000C350
+
+#define CS42L43B_ISRC1DEC3_INPUT1 0x0000C780
+#define CS42L43B_ISRC1DEC4_INPUT1 0x0000C790
+#define CS42L43B_ISRC2DEC3_INPUT1 0x0000C7A0
+#define CS42L43B_ISRC2DEC4_INPUT1 0x0000C7B0
+
+#define CS42L43B_FW_MISSION_CTRL_NEED_CONFIGS 0x00117E00
+#define CS42L43B_FW_MISSION_CTRL_HAVE_CONFIGS 0x00117E04
+#define CS42L43B_FW_MISSION_CTRL_PATCH_START_ADDR_REG 0x00117E08
+#define CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION 0x00117E0C
+#define CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG 0x00117E10
+
+#define CS42L43B_MCU_SW_REV 0x00117314
+#define CS42L43B_PATCH_START_ADDR 0x00117318
+#define CS42L43B_CONFIG_SELECTION 0x0011731C
+#define CS42L43B_NEED_CONFIGS 0x00117320
+#define CS42L43B_BOOT_STATUS 0x00117330
+
+#define CS42L43B_FW_MISSION_CTRL_NEED_CONFIGS 0x00117E00
+#define CS42L43B_FW_MISSION_CTRL_HAVE_CONFIGS 0x00117E04
+#define CS42L43B_FW_MISSION_CTRL_PATCH_START_ADDR_REG 0x00117E08
+#define CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION 0x00117E0C
+#define CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG 0x00117E10
+
+#define CS42L43B_MCU_RAM_MAX 0x00117FFF
+
+/* CS42L43B_DECIM_DECIM_VOL_CTRL_CH5_CH6 */
+#define CS42L43B_DECIM6_MUTE_MASK 0x80000000
+#define CS42L43B_DECIM6_MUTE_SHIFT 31
+#define CS42L43B_DECIM6_VOL_MASK 0x3FC00000
+#define CS42L43B_DECIM6_VOL_SHIFT 22
+#define CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_MASK 0x00380000
+#define CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_SHIFT 19
+#define CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_MASK 0x00070000
+#define CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_SHIFT 16
+#define CS42L43B_DECIM5_MUTE_MASK 0x00008000
+#define CS42L43B_DECIM5_MUTE_SHIFT 15
+#define CS42L43B_DECIM5_VOL_MASK 0x00003FC0
+#define CS42L43B_DECIM5_VOL_SHIFT 6
+#define CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_MASK 0x00000038
+#define CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_SHIFT 3
+#define CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_MASK 0x00000007
+#define CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_SHIFT 0
+
+/* CS42L43B_DECIM_VOL_CTRL_UPDATE */
+#define CS42L43B_DECIM6_PATH1_VOL_TRIG_MASK 0x00000800
+#define CS42L43B_DECIM6_PATH1_VOL_TRIG_SHIFT 11
+#define CS42L43B_DECIM5_PATH1_VOL_TRIG_MASK 0x00000100
+#define CS42L43B_DECIM5_PATH1_VOL_TRIG_SHIFT 8
+#define CS42L43B_DECIM4_VOL_UPDATE_MASK 0x00000020
+#define CS42L43B_DECIM4_VOL_UPDATE_SHIFT 5
+
+/* CS42L43_ISRC1_CTRL..CS42L43_ISRC2_CTRL */
+#define CS42L43B_ISRC_DEC4_EN_MASK 0x00000008
+#define CS42L43B_ISRC_DEC4_EN_SHIFT 3
+#define CS42L43B_ISRC_DEC4_EN_WIDTH 1
+#define CS42L43B_ISRC_DEC3_EN_MASK 0x00000004
+#define CS42L43B_ISRC_DEC3_EN_SHIFT 2
+#define CS42L43B_ISRC_DEC3_EN_WIDTH 1
+
#endif /* CS42L43_CORE_REGS_H */
diff --git a/include/linux/mfd/cs42l43.h b/include/linux/mfd/cs42l43.h
index 2239d8585e78..8313f9e8c722 100644
--- a/include/linux/mfd/cs42l43.h
+++ b/include/linux/mfd/cs42l43.h
@@ -98,6 +98,7 @@ struct cs42l43 {
bool sdw_pll_active;
bool attached;
bool hw_lock;
+ int variant_id;
};
#endif /* CS42L43_CORE_EXT_H */
--
2.48.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 4/4] ASoC: cs42l43: Add support for the B variant
2026-01-16 15:20 [PATCH v2 0/4] Add support for CS42L43B codec to CS42L43 driver Maciej Strozek
` (2 preceding siblings ...)
2026-01-16 15:20 ` [PATCH v2 3/4] mfd: cs42l43: Add support for the B variant Maciej Strozek
@ 2026-01-16 15:20 ` Maciej Strozek
3 siblings, 0 replies; 7+ messages in thread
From: Maciej Strozek @ 2026-01-16 15:20 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai, Lee Jones, Krzysztof Kozlowski
Cc: Jaroslav Kysela, Bard Liao, Peter Ujfalusi, linux-kernel,
linux-sound, patches, devicetree, Maciej Strozek
Introducing CS42L43B codec, a variant of CS42L43 which can be driven by
the same driver.
Changes in CS42L43 driver specific for CS42L43B:
- Decimator 1 and 2 are dedicated to ADC, can't be selected for PDM
- Decimators 3 and 4 are connected to PDM1
- Added Decimator 5 and 6 for PDM2
- Supports SoundWire Clock Gearing
- Updated ROM requiring no patching
- Reduced RAM space
- Each ISRC has 4 decimators now
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
---
Changes in v2:
- Adjustments to variant identification following fixes from v2 mfd patch
---
sound/soc/codecs/cs42l43.c | 756 ++++++++++++++++++++++++++++++-------
sound/soc/codecs/cs42l43.h | 4 +-
2 files changed, 625 insertions(+), 135 deletions(-)
diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c
index fd02d8a57e0f..842d16e39de8 100644
--- a/sound/soc/codecs/cs42l43.c
+++ b/sound/soc/codecs/cs42l43.c
@@ -45,12 +45,25 @@ static SOC_VALUE_ENUM_SINGLE_DECL(cs42l43_##name##_enum, reg, \
static const struct snd_kcontrol_new cs42l43_##name##_mux = \
SOC_DAPM_ENUM("Route", cs42l43_##name##_enum)
+#define CS42L43B_DECL_MUX(name, reg) \
+static SOC_VALUE_ENUM_SINGLE_DECL(cs42l43_##name##_enum, reg, \
+ 0, CS42L43_MIXER_SRC_MASK, \
+ cs42l43b_mixer_texts, cs42l43b_mixer_values); \
+static const struct snd_kcontrol_new cs42l43_##name##_mux = \
+ SOC_DAPM_ENUM("Route", cs42l43_##name##_enum)
+
#define CS42L43_DECL_MIXER(name, reg) \
CS42L43_DECL_MUX(name##_in1, reg); \
CS42L43_DECL_MUX(name##_in2, reg + 0x4); \
CS42L43_DECL_MUX(name##_in3, reg + 0x8); \
CS42L43_DECL_MUX(name##_in4, reg + 0xC)
+#define CS42L43B_DECL_MIXER(name, reg) \
+ CS42L43B_DECL_MUX(name##_in1, reg); \
+ CS42L43B_DECL_MUX(name##_in2, reg + 0x4); \
+ CS42L43B_DECL_MUX(name##_in3, reg + 0x8); \
+ CS42L43B_DECL_MUX(name##_in4, reg + 0xC)
+
#define CS42L43_DAPM_MUX(name_str, name) \
SND_SOC_DAPM_MUX(name_str " Input", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_mux)
@@ -99,11 +112,23 @@ static const struct snd_kcontrol_new cs42l43_##name##_mux = \
{ name_str, "EQ1", "EQ" }, \
{ name_str, "EQ2", "EQ" }
+#define CS42L43B_BASE_ROUTES(name_str) \
+ { name_str, "Decimator 5", "Decimator 5" }, \
+ { name_str, "Decimator 6", "Decimator 6" }, \
+ { name_str, "ISRC1 DEC3", "ISRC1DEC3" }, \
+ { name_str, "ISRC1 DEC4", "ISRC1DEC4" }, \
+ { name_str, "ISRC2 DEC3", "ISRC2DEC3" }, \
+ { name_str, "ISRC2 DEC4", "ISRC2DEC4" }
+
#define CS42L43_MUX_ROUTES(name_str, widget) \
{ widget, NULL, name_str " Input" }, \
{ name_str " Input", NULL, "Mixer Core" }, \
CS42L43_BASE_ROUTES(name_str " Input")
+#define CS42L43B_MUX_ROUTES(name_str, widget) \
+ CS42L43_MUX_ROUTES(name_str, widget), \
+ CS42L43B_BASE_ROUTES(name_str " Input")
+
#define CS42L43_MIXER_ROUTES(name_str, widget) \
{ name_str " Mixer", NULL, name_str " Input 1" }, \
{ name_str " Mixer", NULL, name_str " Input 2" }, \
@@ -116,6 +141,13 @@ static const struct snd_kcontrol_new cs42l43_##name##_mux = \
CS42L43_BASE_ROUTES(name_str " Input 3"), \
CS42L43_BASE_ROUTES(name_str " Input 4")
+#define CS42L43B_MIXER_ROUTES(name_str, widget) \
+ CS42L43_MIXER_ROUTES(name_str, widget), \
+ CS42L43B_BASE_ROUTES(name_str " Input 1"), \
+ CS42L43B_BASE_ROUTES(name_str " Input 2"), \
+ CS42L43B_BASE_ROUTES(name_str " Input 3"), \
+ CS42L43B_BASE_ROUTES(name_str " Input 4")
+
#define CS42L43_MIXER_VOLUMES(name_str, base) \
SOC_SINGLE_RANGE_TLV(name_str " Input 1 Volume", base, \
CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
@@ -300,6 +332,7 @@ static int cs42l43_startup(struct snd_pcm_substream *substream, struct snd_soc_d
struct snd_soc_component *component = dai->component;
struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
struct cs42l43 *cs42l43 = priv->core;
+ int ret;
int provider = !dai->id || !!regmap_test_bits(cs42l43->regmap,
CS42L43_ASP_CLK_CONFIG2,
CS42L43_ASP_MASTER_MODE_MASK);
@@ -309,6 +342,14 @@ static int cs42l43_startup(struct snd_pcm_substream *substream, struct snd_soc_d
else
priv->constraint.mask = CS42L43_CONSUMER_RATE_MASK;
+ if (cs42l43->variant_id == CS42L43_DEVID_VAL && (dai->id == 3 || dai->id == 4)) {
+ ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ 1, 2);
+ if (ret < 0)
+ return ret;
+ }
+
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&priv->constraint);
@@ -590,12 +631,25 @@ static int cs42l43_dai_probe(struct snd_soc_dai *dai)
"Decimator 2 Switch",
"Decimator 3 Switch",
"Decimator 4 Switch",
+ "Decimator 5 Switch",
+ "Decimator 6 Switch",
};
- int i;
+ int control_size, i;
static_assert(ARRAY_SIZE(controls) == ARRAY_SIZE(priv->kctl));
- for (i = 0; i < ARRAY_SIZE(controls); i++) {
+ switch (priv->core->variant_id) {
+ case CS42L43_DEVID_VAL:
+ control_size = ARRAY_SIZE(controls) - 2; // ignore Decimator 5 and 6
+ break;
+ case CS42L43B_DEVID_VAL:
+ control_size = ARRAY_SIZE(controls);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ for (i = 0; i < control_size; i++) {
if (priv->kctl[i])
continue;
@@ -703,7 +757,7 @@ static struct snd_soc_dai_driver cs42l43_dais[] = {
.capture = {
.stream_name = "DP3 Capture",
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 4,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L43_SDW_FORMATS,
},
@@ -715,7 +769,7 @@ static struct snd_soc_dai_driver cs42l43_dais[] = {
.capture = {
.stream_name = "DP4 Capture",
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 4,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = CS42L43_SDW_FORMATS,
},
@@ -808,6 +862,10 @@ static SOC_ENUM_SINGLE_DECL(cs42l43_dec3_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL3
CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL4,
CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec5_wnf_corner, CS42L43B_DECIM_HPF_WNF_CTRL5,
+ CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec6_wnf_corner, CS42L43B_DECIM_HPF_WNF_CTRL6,
+ CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
static const char * const cs42l43_hpf_corner_text[] = {
"3Hz", "12Hz", "48Hz", "96Hz",
@@ -821,6 +879,10 @@ static SOC_ENUM_SINGLE_DECL(cs42l43_dec3_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL3
CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL4,
CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec5_hpf_corner, CS42L43B_DECIM_HPF_WNF_CTRL5,
+ CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec6_hpf_corner, CS42L43B_DECIM_HPF_WNF_CTRL6,
+ CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
static SOC_ENUM_SINGLE_DECL(cs42l43_dec1_ramp_up, CS42L43_DECIM_VOL_CTRL_CH1_CH2,
CS42L43_DECIM1_VI_RAMP_SHIFT, cs42l43_ramp_text);
@@ -839,6 +901,31 @@ static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_ramp_up, CS42L43_DECIM_VOL_CTRL_CH3_CH4
static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_ramp_down, CS42L43_DECIM_VOL_CTRL_CH3_CH4,
CS42L43_DECIM4_VD_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec1_ramp_up, CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM1_VI_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec1_ramp_down, CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM1_VD_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec2_ramp_up, CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM2_VI_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec2_ramp_down, CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM2_VD_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec3_ramp_up, CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM3_VI_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec3_ramp_down, CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM3_VD_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec4_ramp_up, CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM4_VI_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec4_ramp_down, CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM4_VD_RAMP_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec5_ramp_up, CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec5_ramp_down, CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec6_ramp_up, CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_SHIFT, cs42l43_ramp_text);
+static SOC_ENUM_SINGLE_DECL(cs42l43b_dec6_ramp_down, CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_SHIFT, cs42l43_ramp_text);
+
static DECLARE_TLV_DB_SCALE(cs42l43_speaker_tlv, -6400, 50, 0);
static SOC_ENUM_SINGLE_DECL(cs42l43_speaker_ramp_up, CS42L43_AMP1_2_VOL_RAMP,
@@ -898,6 +985,37 @@ static const unsigned int cs42l43_mixer_values[] = {
0x58, 0x59, // EQ1, 2
};
+static const char * const cs42l43b_mixer_texts[] = {
+ "None",
+ "Tone Generator 1", "Tone Generator 2",
+ "Decimator 1", "Decimator 2", "Decimator 3", "Decimator 4", "Decimator 5", "Decimator 6",
+ "ASPRX1", "ASPRX2", "ASPRX3", "ASPRX4", "ASPRX5", "ASPRX6",
+ "DP5RX1", "DP5RX2", "DP6RX1", "DP6RX2", "DP7RX1", "DP7RX2",
+ "ASRC INT1", "ASRC INT2", "ASRC INT3", "ASRC INT4",
+ "ASRC DEC1", "ASRC DEC2", "ASRC DEC3", "ASRC DEC4",
+ "ISRC1 INT1", "ISRC1 INT2",
+ "ISRC1 DEC1", "ISRC1 DEC2", "ISRC1 DEC3", "ISRC1 DEC4",
+ "ISRC2 INT1", "ISRC2 INT2",
+ "ISRC2 DEC1", "ISRC2 DEC2", "ISRC2 DEC3", "ISRC2 DEC4",
+ "EQ1", "EQ2",
+};
+
+static const unsigned int cs42l43b_mixer_values[] = {
+ 0x00, // None
+ 0x04, 0x05, // Tone Generator 1, 2
+ 0x10, 0x11, 0x80, 0x81, 0x12, 0x13, // Decimator 1, 2, 3, 4, 5, 6
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, // ASPRX1,2,3,4,5,6
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, // DP5, 6, 7RX1, 2
+ 0x40, 0x41, 0x42, 0x43, // ASRC INT1, 2, 3, 4
+ 0x44, 0x45, 0x46, 0x47, // ASRC DEC1, 2, 3, 4
+ 0x50, 0x51, // ISRC1 INT1, 2
+ 0x52, 0x53, 0x78, 0x79, // ISRC1 DEC1, 2, 3, 4
+ 0x54, 0x55, // ISRC2 INT1, 2
+ 0x56, 0x57, 0x7A, 0x7B, // ISRC2 DEC1, 2, 3, 4
+ 0x58, 0x59, // EQ1, 2
+};
+
+/* A variant */
CS42L43_DECL_MUX(asptx1, CS42L43_ASPTX1_INPUT);
CS42L43_DECL_MUX(asptx2, CS42L43_ASPTX2_INPUT);
CS42L43_DECL_MUX(asptx3, CS42L43_ASPTX3_INPUT);
@@ -946,6 +1064,63 @@ CS42L43_DECL_MIXER(amp2, CS42L43_AMP2MIX_INPUT1);
CS42L43_DECL_MIXER(amp3, CS42L43_AMP3MIX_INPUT1);
CS42L43_DECL_MIXER(amp4, CS42L43_AMP4MIX_INPUT1);
+/* B variant */
+CS42L43B_DECL_MUX(b_asptx1, CS42L43_ASPTX1_INPUT);
+CS42L43B_DECL_MUX(b_asptx2, CS42L43_ASPTX2_INPUT);
+CS42L43B_DECL_MUX(b_asptx3, CS42L43_ASPTX3_INPUT);
+CS42L43B_DECL_MUX(b_asptx4, CS42L43_ASPTX4_INPUT);
+CS42L43B_DECL_MUX(b_asptx5, CS42L43_ASPTX5_INPUT);
+CS42L43B_DECL_MUX(b_asptx6, CS42L43_ASPTX6_INPUT);
+
+CS42L43B_DECL_MUX(b_dp1tx1, CS42L43_SWIRE_DP1_CH1_INPUT);
+CS42L43B_DECL_MUX(b_dp1tx2, CS42L43_SWIRE_DP1_CH2_INPUT);
+CS42L43B_DECL_MUX(b_dp1tx3, CS42L43_SWIRE_DP1_CH3_INPUT);
+CS42L43B_DECL_MUX(b_dp1tx4, CS42L43_SWIRE_DP1_CH4_INPUT);
+CS42L43B_DECL_MUX(b_dp2tx1, CS42L43_SWIRE_DP2_CH1_INPUT);
+CS42L43B_DECL_MUX(b_dp2tx2, CS42L43_SWIRE_DP2_CH2_INPUT);
+CS42L43B_DECL_MUX(b_dp3tx1, CS42L43_SWIRE_DP3_CH1_INPUT);
+CS42L43B_DECL_MUX(b_dp3tx2, CS42L43_SWIRE_DP3_CH2_INPUT);
+CS42L43B_DECL_MUX(b_dp3tx3, CS42L43B_SWIRE_DP3_CH3_INPUT);
+CS42L43B_DECL_MUX(b_dp3tx4, CS42L43B_SWIRE_DP3_CH4_INPUT);
+CS42L43B_DECL_MUX(b_dp4tx1, CS42L43_SWIRE_DP4_CH1_INPUT);
+CS42L43B_DECL_MUX(b_dp4tx2, CS42L43_SWIRE_DP4_CH2_INPUT);
+CS42L43B_DECL_MUX(b_dp4tx3, CS42L43B_SWIRE_DP4_CH3_INPUT);
+CS42L43B_DECL_MUX(b_dp4tx4, CS42L43B_SWIRE_DP4_CH4_INPUT);
+
+CS42L43B_DECL_MUX(b_asrcint1, CS42L43_ASRC_INT1_INPUT1);
+CS42L43B_DECL_MUX(b_asrcint2, CS42L43_ASRC_INT2_INPUT1);
+CS42L43B_DECL_MUX(b_asrcint3, CS42L43_ASRC_INT3_INPUT1);
+CS42L43B_DECL_MUX(b_asrcint4, CS42L43_ASRC_INT4_INPUT1);
+CS42L43B_DECL_MUX(b_asrcdec1, CS42L43_ASRC_DEC1_INPUT1);
+CS42L43B_DECL_MUX(b_asrcdec2, CS42L43_ASRC_DEC2_INPUT1);
+CS42L43B_DECL_MUX(b_asrcdec3, CS42L43_ASRC_DEC3_INPUT1);
+CS42L43B_DECL_MUX(b_asrcdec4, CS42L43_ASRC_DEC4_INPUT1);
+
+CS42L43B_DECL_MUX(b_isrc1int1, CS42L43_ISRC1INT1_INPUT1);
+CS42L43B_DECL_MUX(b_isrc1int2, CS42L43_ISRC1INT2_INPUT1);
+CS42L43B_DECL_MUX(b_isrc1dec1, CS42L43_ISRC1DEC1_INPUT1);
+CS42L43B_DECL_MUX(b_isrc1dec2, CS42L43_ISRC1DEC2_INPUT1);
+CS42L43B_DECL_MUX(b_isrc1dec3, CS42L43B_ISRC1DEC3_INPUT1);
+CS42L43B_DECL_MUX(b_isrc1dec4, CS42L43B_ISRC1DEC4_INPUT1);
+CS42L43B_DECL_MUX(b_isrc2int1, CS42L43_ISRC2INT1_INPUT1);
+CS42L43B_DECL_MUX(b_isrc2int2, CS42L43_ISRC2INT2_INPUT1);
+CS42L43B_DECL_MUX(b_isrc2dec1, CS42L43_ISRC2DEC1_INPUT1);
+CS42L43B_DECL_MUX(b_isrc2dec2, CS42L43_ISRC2DEC2_INPUT1);
+CS42L43B_DECL_MUX(b_isrc2dec3, CS42L43B_ISRC2DEC3_INPUT1);
+CS42L43B_DECL_MUX(b_isrc2dec4, CS42L43B_ISRC2DEC4_INPUT1);
+
+CS42L43B_DECL_MUX(b_spdif1, CS42L43_SPDIF1_INPUT1);
+CS42L43B_DECL_MUX(b_spdif2, CS42L43_SPDIF2_INPUT1);
+
+CS42L43B_DECL_MIXER(b_eq1, CS42L43_EQ1MIX_INPUT1);
+CS42L43B_DECL_MIXER(b_eq2, CS42L43_EQ2MIX_INPUT1);
+
+CS42L43B_DECL_MIXER(b_amp1, CS42L43_AMP1MIX_INPUT1);
+CS42L43B_DECL_MIXER(b_amp2, CS42L43_AMP2MIX_INPUT1);
+
+CS42L43B_DECL_MIXER(b_amp3, CS42L43_AMP3MIX_INPUT1);
+CS42L43B_DECL_MIXER(b_amp4, CS42L43_AMP4MIX_INPUT1);
+
static int cs42l43_dapm_get_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1174,44 +1349,6 @@ static const struct snd_kcontrol_new cs42l43_controls[] = {
SOC_ENUM("Decimator 3 HPF Corner Frequency", cs42l43_dec3_hpf_corner),
SOC_ENUM("Decimator 4 HPF Corner Frequency", cs42l43_dec4_hpf_corner),
- SOC_SINGLE_TLV("Decimator 1 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
- CS42L43_DECIM1_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
- SOC_SINGLE_EXT("Decimator 1 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
- CS42L43_DECIM1_MUTE_SHIFT, 1, 1,
- cs42l43_decim_get, cs42l43_dapm_put_volsw),
- SOC_SINGLE_TLV("Decimator 2 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
- CS42L43_DECIM2_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
- SOC_SINGLE_EXT("Decimator 2 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
- CS42L43_DECIM2_MUTE_SHIFT, 1, 1,
- cs42l43_decim_get, cs42l43_dapm_put_volsw),
- SOC_SINGLE_TLV("Decimator 3 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
- CS42L43_DECIM3_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
- SOC_SINGLE_EXT("Decimator 3 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
- CS42L43_DECIM3_MUTE_SHIFT, 1, 1,
- cs42l43_decim_get, cs42l43_dapm_put_volsw),
- SOC_SINGLE_TLV("Decimator 4 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
- CS42L43_DECIM4_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
- SOC_SINGLE_EXT("Decimator 4 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
- CS42L43_DECIM4_MUTE_SHIFT, 1, 1,
- cs42l43_decim_get, cs42l43_dapm_put_volsw),
-
- SOC_ENUM_EXT("Decimator 1 Ramp Up", cs42l43_dec1_ramp_up,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 1 Ramp Down", cs42l43_dec1_ramp_down,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 2 Ramp Up", cs42l43_dec2_ramp_up,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 2 Ramp Down", cs42l43_dec2_ramp_down,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 3 Ramp Up", cs42l43_dec3_ramp_up,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 3 Ramp Down", cs42l43_dec3_ramp_down,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 4 Ramp Up", cs42l43_dec4_ramp_up,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
- SOC_ENUM_EXT("Decimator 4 Ramp Down", cs42l43_dec4_ramp_down,
- cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
-
SOC_DOUBLE_R_EXT("Speaker Digital Switch",
CS42L43_INTP_VOLUME_CTRL1, CS42L43_INTP_VOLUME_CTRL2,
CS42L43_AMP_MUTE_SHIFT, 1, 1,
@@ -1601,35 +1738,81 @@ static int cs42l43_mic_ev(struct snd_soc_dapm_widget *w,
unsigned int *val;
int ret;
- switch (w->shift) {
- case CS42L43_ADC1_EN_SHIFT:
- case CS42L43_PDM1_DIN_L_EN_SHIFT:
- reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;
- ramp = CS42L43_DECIM1_VD_RAMP_MASK;
- mute = CS42L43_DECIM1_MUTE_MASK;
- val = &priv->decim_cache[0];
- break;
- case CS42L43_ADC2_EN_SHIFT:
- case CS42L43_PDM1_DIN_R_EN_SHIFT:
- reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;
- ramp = CS42L43_DECIM2_VD_RAMP_MASK;
- mute = CS42L43_DECIM2_MUTE_MASK;
- val = &priv->decim_cache[1];
- break;
- case CS42L43_PDM2_DIN_L_EN_SHIFT:
- reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;
- ramp = CS42L43_DECIM3_VD_RAMP_MASK;
- mute = CS42L43_DECIM3_MUTE_MASK;
- val = &priv->decim_cache[2];
- break;
- case CS42L43_PDM2_DIN_R_EN_SHIFT:
- reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;
- ramp = CS42L43_DECIM4_VD_RAMP_MASK;
- mute = CS42L43_DECIM4_MUTE_MASK;
- val = &priv->decim_cache[3];
- break;
- default:
- dev_err(priv->dev, "Invalid microphone shift: %d\n", w->shift);
+ if (cs42l43->variant_id == CS42L43_DEVID_VAL) {
+ switch (w->shift) {
+ case CS42L43_ADC1_EN_SHIFT:
+ case CS42L43_PDM1_DIN_L_EN_SHIFT:
+ reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;
+ ramp = CS42L43_DECIM1_VD_RAMP_MASK;
+ mute = CS42L43_DECIM1_MUTE_MASK;
+ val = &priv->decim_cache[0];
+ break;
+ case CS42L43_ADC2_EN_SHIFT:
+ case CS42L43_PDM1_DIN_R_EN_SHIFT:
+ reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;
+ ramp = CS42L43_DECIM2_VD_RAMP_MASK;
+ mute = CS42L43_DECIM2_MUTE_MASK;
+ val = &priv->decim_cache[1];
+ break;
+ case CS42L43_PDM2_DIN_L_EN_SHIFT:
+ reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;
+ ramp = CS42L43_DECIM3_VD_RAMP_MASK;
+ mute = CS42L43_DECIM3_MUTE_MASK;
+ val = &priv->decim_cache[2];
+ break;
+ case CS42L43_PDM2_DIN_R_EN_SHIFT:
+ reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;
+ ramp = CS42L43_DECIM4_VD_RAMP_MASK;
+ mute = CS42L43_DECIM4_MUTE_MASK;
+ val = &priv->decim_cache[3];
+ break;
+ default:
+ dev_err(priv->dev, "Invalid microphone shift: %d\n", w->shift);
+ return -EINVAL;
+ }
+ } else if (cs42l43->variant_id == CS42L43B_DEVID_VAL) {
+ switch (w->shift) {
+ case CS42L43_ADC1_EN_SHIFT:
+ reg = CS42L43B_DECIM_VOL_CTRL_CH1_CH2;
+ ramp = CS42L43_DECIM1_VD_RAMP_MASK;
+ mute = CS42L43_DECIM1_MUTE_MASK;
+ val = &priv->decim_cache[0];
+ break;
+ case CS42L43_ADC2_EN_SHIFT:
+ reg = CS42L43B_DECIM_VOL_CTRL_CH1_CH2;
+ ramp = CS42L43_DECIM2_VD_RAMP_MASK;
+ mute = CS42L43_DECIM2_MUTE_MASK;
+ val = &priv->decim_cache[1];
+ break;
+ case CS42L43_PDM1_DIN_L_EN_SHIFT:
+ reg = CS42L43B_DECIM_VOL_CTRL_CH3_CH4;
+ ramp = CS42L43_DECIM3_VD_RAMP_MASK;
+ mute = CS42L43_DECIM3_MUTE_MASK;
+ val = &priv->decim_cache[2];
+ break;
+ case CS42L43_PDM1_DIN_R_EN_SHIFT:
+ reg = CS42L43B_DECIM_VOL_CTRL_CH3_CH4;
+ ramp = CS42L43_DECIM4_VD_RAMP_MASK;
+ mute = CS42L43_DECIM4_MUTE_MASK;
+ val = &priv->decim_cache[3];
+ break;
+ case CS42L43_PDM2_DIN_L_EN_SHIFT:
+ reg = CS42L43B_DECIM_VOL_CTRL_CH5_CH6;
+ ramp = CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_MASK;
+ mute = CS42L43B_DECIM5_MUTE_MASK;
+ val = &priv->decim_cache[4];
+ break;
+ case CS42L43_PDM2_DIN_R_EN_SHIFT:
+ reg = CS42L43B_DECIM_VOL_CTRL_CH5_CH6;
+ ramp = CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_MASK;
+ mute = CS42L43B_DECIM6_MUTE_MASK;
+ val = &priv->decim_cache[5];
+ break;
+ default:
+ dev_err(priv->dev, "Invalid microphone shift: %d\n", w->shift);
+ return -EINVAL;
+ }
+ } else {
return -EINVAL;
}
@@ -1722,11 +1905,6 @@ static const struct snd_soc_dapm_widget cs42l43_widgets[] = {
0, NULL, 0, cs42l43_mic_ev,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
- SND_SOC_DAPM_MUX("Decimator 1 Mode", SND_SOC_NOPM, 0, 0,
- &cs42l43_dec_mode_ctl[0]),
- SND_SOC_DAPM_MUX("Decimator 2 Mode", SND_SOC_NOPM, 0, 0,
- &cs42l43_dec_mode_ctl[1]),
-
SND_SOC_DAPM_PGA("Decimator 1", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("Decimator 2", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("Decimator 3", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -1871,53 +2049,6 @@ static const struct snd_soc_dapm_widget cs42l43_widgets[] = {
SND_SOC_DAPM_SUPPLY("Mixer Core", CS42L43_BLOCK_EN6, CS42L43_MIXER_EN_SHIFT,
0, NULL, 0),
- CS42L43_DAPM_MUX("ASPTX1", asptx1),
- CS42L43_DAPM_MUX("ASPTX2", asptx2),
- CS42L43_DAPM_MUX("ASPTX3", asptx3),
- CS42L43_DAPM_MUX("ASPTX4", asptx4),
- CS42L43_DAPM_MUX("ASPTX5", asptx5),
- CS42L43_DAPM_MUX("ASPTX6", asptx6),
-
- CS42L43_DAPM_MUX("DP1TX1", dp1tx1),
- CS42L43_DAPM_MUX("DP1TX2", dp1tx2),
- CS42L43_DAPM_MUX("DP1TX3", dp1tx3),
- CS42L43_DAPM_MUX("DP1TX4", dp1tx4),
- CS42L43_DAPM_MUX("DP2TX1", dp2tx1),
- CS42L43_DAPM_MUX("DP2TX2", dp2tx2),
- CS42L43_DAPM_MUX("DP3TX1", dp3tx1),
- CS42L43_DAPM_MUX("DP3TX2", dp3tx2),
- CS42L43_DAPM_MUX("DP4TX1", dp4tx1),
- CS42L43_DAPM_MUX("DP4TX2", dp4tx2),
-
- CS42L43_DAPM_MUX("ASRC INT1", asrcint1),
- CS42L43_DAPM_MUX("ASRC INT2", asrcint2),
- CS42L43_DAPM_MUX("ASRC INT3", asrcint3),
- CS42L43_DAPM_MUX("ASRC INT4", asrcint4),
- CS42L43_DAPM_MUX("ASRC DEC1", asrcdec1),
- CS42L43_DAPM_MUX("ASRC DEC2", asrcdec2),
- CS42L43_DAPM_MUX("ASRC DEC3", asrcdec3),
- CS42L43_DAPM_MUX("ASRC DEC4", asrcdec4),
-
- CS42L43_DAPM_MUX("ISRC1INT1", isrc1int1),
- CS42L43_DAPM_MUX("ISRC1INT2", isrc1int2),
- CS42L43_DAPM_MUX("ISRC1DEC1", isrc1dec1),
- CS42L43_DAPM_MUX("ISRC1DEC2", isrc1dec2),
- CS42L43_DAPM_MUX("ISRC2INT1", isrc2int1),
- CS42L43_DAPM_MUX("ISRC2INT2", isrc2int2),
- CS42L43_DAPM_MUX("ISRC2DEC1", isrc2dec1),
- CS42L43_DAPM_MUX("ISRC2DEC2", isrc2dec2),
-
- CS42L43_DAPM_MUX("SPDIF1", spdif1),
- CS42L43_DAPM_MUX("SPDIF2", spdif2),
-
- CS42L43_DAPM_MIXER("EQ1", eq1),
- CS42L43_DAPM_MIXER("EQ2", eq2),
-
- CS42L43_DAPM_MIXER("Speaker L", amp1),
- CS42L43_DAPM_MIXER("Speaker R", amp2),
-
- CS42L43_DAPM_MIXER("Headphone L", amp3),
- CS42L43_DAPM_MIXER("Headphone R", amp4),
};
static const struct snd_soc_dapm_route cs42l43_routes[] = {
@@ -1963,16 +2094,6 @@ static const struct snd_soc_dapm_route cs42l43_routes[] = {
{ "PDM2L", NULL, "PDM2_DIN" },
{ "PDM2R", NULL, "PDM2_DIN" },
- { "Decimator 1 Mode", "PDM", "PDM1L" },
- { "Decimator 1 Mode", "ADC", "ADC1" },
- { "Decimator 2 Mode", "PDM", "PDM1R" },
- { "Decimator 2 Mode", "ADC", "ADC2" },
-
- { "Decimator 1", NULL, "Decimator 1 Mode" },
- { "Decimator 2", NULL, "Decimator 2 Mode" },
- { "Decimator 3", NULL, "PDM2L" },
- { "Decimator 4", NULL, "PDM2R" },
-
{ "ASP Capture", NULL, "ASPTX1" },
{ "ASP Capture", NULL, "ASPTX2" },
{ "ASP Capture", NULL, "ASPTX3" },
@@ -2060,6 +2181,261 @@ static const struct snd_soc_dapm_route cs42l43_routes[] = {
{ "ASRC_DEC4", NULL, "ASRC_DEC" },
{ "EQ", NULL, "EQ Clock" },
+};
+
+static const struct snd_kcontrol_new cs42l43_a_controls[] = {
+ SOC_ENUM_EXT("Decimator 1 Ramp Up", cs42l43_dec1_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 1 Ramp Down", cs42l43_dec1_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 2 Ramp Up", cs42l43_dec2_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 2 Ramp Down", cs42l43_dec2_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 3 Ramp Up", cs42l43_dec3_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 3 Ramp Down", cs42l43_dec3_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 4 Ramp Up", cs42l43_dec4_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 4 Ramp Down", cs42l43_dec4_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+
+ SOC_SINGLE_TLV("Decimator 1 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM1_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 1 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM1_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 2 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM2_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 2 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM2_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 3 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM3_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 3 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM3_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 4 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM4_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 4 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM4_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+};
+
+static const struct snd_kcontrol_new cs42l43_b_controls[] = {
+ SOC_SINGLE_TLV("Decimator 1 Volume", CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM1_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 1 Switch", CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM1_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 2 Volume", CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM2_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 2 Switch", CS42L43B_DECIM_VOL_CTRL_CH1_CH2,
+ CS42L43_DECIM2_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 3 Volume", CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM3_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 3 Switch", CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM3_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 4 Volume", CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM4_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 4 Switch", CS42L43B_DECIM_VOL_CTRL_CH3_CH4,
+ CS42L43_DECIM4_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 5 Volume", CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM5_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 5 Switch", CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM5_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+ SOC_SINGLE_TLV("Decimator 6 Volume", CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM6_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
+ SOC_SINGLE_EXT("Decimator 6 Switch", CS42L43B_DECIM_VOL_CTRL_CH5_CH6,
+ CS42L43B_DECIM6_MUTE_SHIFT, 1, 1,
+ cs42l43_decim_get, cs42l43_dapm_put_volsw),
+
+ SOC_ENUM_EXT("Decimator 1 Ramp Up", cs42l43b_dec1_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 1 Ramp Down", cs42l43b_dec1_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 2 Ramp Up", cs42l43b_dec2_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 2 Ramp Down", cs42l43b_dec2_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 3 Ramp Up", cs42l43b_dec3_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 3 Ramp Down", cs42l43b_dec3_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 4 Ramp Up", cs42l43b_dec4_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 4 Ramp Down", cs42l43b_dec4_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 5 Ramp Up", cs42l43b_dec5_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 5 Ramp Down", cs42l43b_dec5_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 6 Ramp Up", cs42l43b_dec6_ramp_up,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+ SOC_ENUM_EXT("Decimator 6 Ramp Down", cs42l43b_dec6_ramp_down,
+ cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
+
+ SOC_SINGLE("Decimator 5 WNF Switch", CS42L43B_DECIM_HPF_WNF_CTRL5,
+ CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),
+ SOC_SINGLE("Decimator 6 WNF Switch", CS42L43B_DECIM_HPF_WNF_CTRL6,
+ CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),
+
+ SOC_ENUM("Decimator 5 WNF Corner Frequency", cs42l43b_dec5_wnf_corner),
+ SOC_ENUM("Decimator 6 WNF Corner Frequency", cs42l43b_dec6_wnf_corner),
+
+ SOC_SINGLE("Decimator 5 HPF Switch", CS42L43B_DECIM_HPF_WNF_CTRL5,
+ CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),
+ SOC_SINGLE("Decimator 6 HPF Switch", CS42L43B_DECIM_HPF_WNF_CTRL6,
+ CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),
+
+ SOC_ENUM("Decimator 5 HPF Corner Frequency", cs42l43b_dec5_hpf_corner),
+ SOC_ENUM("Decimator 6 HPF Corner Frequency", cs42l43b_dec6_hpf_corner),
+};
+
+static const struct snd_soc_dapm_widget cs42l43_a_widgets[] = {
+ SND_SOC_DAPM_MUX("Decimator 1 Mode", SND_SOC_NOPM, 0, 0,
+ &cs42l43_dec_mode_ctl[0]),
+ SND_SOC_DAPM_MUX("Decimator 2 Mode", SND_SOC_NOPM, 0, 0,
+ &cs42l43_dec_mode_ctl[1]),
+ CS42L43_DAPM_MUX("ASPTX1", asptx1),
+ CS42L43_DAPM_MUX("ASPTX2", asptx2),
+ CS42L43_DAPM_MUX("ASPTX3", asptx3),
+ CS42L43_DAPM_MUX("ASPTX4", asptx4),
+ CS42L43_DAPM_MUX("ASPTX5", asptx5),
+ CS42L43_DAPM_MUX("ASPTX6", asptx6),
+
+ CS42L43_DAPM_MUX("DP1TX1", dp1tx1),
+ CS42L43_DAPM_MUX("DP1TX2", dp1tx2),
+ CS42L43_DAPM_MUX("DP1TX3", dp1tx3),
+ CS42L43_DAPM_MUX("DP1TX4", dp1tx4),
+ CS42L43_DAPM_MUX("DP2TX1", dp2tx1),
+ CS42L43_DAPM_MUX("DP2TX2", dp2tx2),
+ CS42L43_DAPM_MUX("DP3TX1", dp3tx1),
+ CS42L43_DAPM_MUX("DP3TX2", dp3tx2),
+ CS42L43_DAPM_MUX("DP4TX1", dp4tx1),
+ CS42L43_DAPM_MUX("DP4TX2", dp4tx2),
+
+ CS42L43_DAPM_MUX("ASRC INT1", asrcint1),
+ CS42L43_DAPM_MUX("ASRC INT2", asrcint2),
+ CS42L43_DAPM_MUX("ASRC INT3", asrcint3),
+ CS42L43_DAPM_MUX("ASRC INT4", asrcint4),
+ CS42L43_DAPM_MUX("ASRC DEC1", asrcdec1),
+ CS42L43_DAPM_MUX("ASRC DEC2", asrcdec2),
+ CS42L43_DAPM_MUX("ASRC DEC3", asrcdec3),
+ CS42L43_DAPM_MUX("ASRC DEC4", asrcdec4),
+
+ CS42L43_DAPM_MUX("ISRC1INT1", isrc1int1),
+ CS42L43_DAPM_MUX("ISRC1INT2", isrc1int2),
+ CS42L43_DAPM_MUX("ISRC1DEC1", isrc1dec1),
+ CS42L43_DAPM_MUX("ISRC1DEC2", isrc1dec2),
+ CS42L43_DAPM_MUX("ISRC2INT1", isrc2int1),
+ CS42L43_DAPM_MUX("ISRC2INT2", isrc2int2),
+ CS42L43_DAPM_MUX("ISRC2DEC1", isrc2dec1),
+ CS42L43_DAPM_MUX("ISRC2DEC2", isrc2dec2),
+
+ CS42L43_DAPM_MUX("SPDIF1", spdif1),
+ CS42L43_DAPM_MUX("SPDIF2", spdif2),
+
+ CS42L43_DAPM_MIXER("EQ1", eq1),
+ CS42L43_DAPM_MIXER("EQ2", eq2),
+
+ CS42L43_DAPM_MIXER("Speaker L", amp1),
+ CS42L43_DAPM_MIXER("Speaker R", amp2),
+
+ CS42L43_DAPM_MIXER("Headphone L", amp3),
+ CS42L43_DAPM_MIXER("Headphone R", amp4),
+};
+
+static const struct snd_soc_dapm_widget cs42l43_b_widgets[] = {
+ SND_SOC_DAPM_AIF_OUT("DP3TX3", NULL, 2, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("DP3TX4", NULL, 3, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("DP4TX3", NULL, 2, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("DP4TX4", NULL, 3, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_PGA("Decimator 5", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Decimator 6", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("ISRC1DEC3", CS42L43_ISRC1_CTRL,
+ CS42L43B_ISRC_DEC3_EN_SHIFT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ISRC1DEC4", CS42L43_ISRC1_CTRL,
+ CS42L43B_ISRC_DEC4_EN_SHIFT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ISRC2DEC3", CS42L43_ISRC2_CTRL,
+ CS42L43B_ISRC_DEC3_EN_SHIFT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ISRC2DEC4", CS42L43_ISRC2_CTRL,
+ CS42L43B_ISRC_DEC4_EN_SHIFT, 0, NULL, 0),
+
+ CS42L43_DAPM_MUX("ASPTX1", b_asptx1),
+ CS42L43_DAPM_MUX("ASPTX2", b_asptx2),
+ CS42L43_DAPM_MUX("ASPTX3", b_asptx3),
+ CS42L43_DAPM_MUX("ASPTX4", b_asptx4),
+ CS42L43_DAPM_MUX("ASPTX5", b_asptx5),
+ CS42L43_DAPM_MUX("ASPTX6", b_asptx6),
+
+ CS42L43_DAPM_MUX("DP1TX1", b_dp1tx1),
+ CS42L43_DAPM_MUX("DP1TX2", b_dp1tx2),
+ CS42L43_DAPM_MUX("DP1TX3", b_dp1tx3),
+ CS42L43_DAPM_MUX("DP1TX4", b_dp1tx4),
+ CS42L43_DAPM_MUX("DP2TX1", b_dp2tx1),
+ CS42L43_DAPM_MUX("DP2TX2", b_dp2tx2),
+ CS42L43_DAPM_MUX("DP3TX1", b_dp3tx1),
+ CS42L43_DAPM_MUX("DP3TX2", b_dp3tx2),
+ CS42L43_DAPM_MUX("DP3TX3", b_dp3tx3),
+ CS42L43_DAPM_MUX("DP3TX4", b_dp3tx4),
+ CS42L43_DAPM_MUX("DP4TX1", b_dp4tx1),
+ CS42L43_DAPM_MUX("DP4TX2", b_dp4tx2),
+ CS42L43_DAPM_MUX("DP4TX3", b_dp4tx3),
+ CS42L43_DAPM_MUX("DP4TX4", b_dp4tx4),
+
+ CS42L43_DAPM_MUX("ASRC INT1", b_asrcint1),
+ CS42L43_DAPM_MUX("ASRC INT2", b_asrcint2),
+ CS42L43_DAPM_MUX("ASRC INT3", b_asrcint3),
+ CS42L43_DAPM_MUX("ASRC INT4", b_asrcint4),
+ CS42L43_DAPM_MUX("ASRC DEC1", b_asrcdec1),
+ CS42L43_DAPM_MUX("ASRC DEC2", b_asrcdec2),
+ CS42L43_DAPM_MUX("ASRC DEC3", b_asrcdec3),
+ CS42L43_DAPM_MUX("ASRC DEC4", b_asrcdec4),
+
+ CS42L43_DAPM_MUX("ISRC1INT1", b_isrc1int1),
+ CS42L43_DAPM_MUX("ISRC1INT2", b_isrc1int2),
+ CS42L43_DAPM_MUX("ISRC1DEC1", b_isrc1dec1),
+ CS42L43_DAPM_MUX("ISRC1DEC2", b_isrc1dec2),
+ CS42L43_DAPM_MUX("ISRC1DEC3", b_isrc1dec3),
+ CS42L43_DAPM_MUX("ISRC1DEC4", b_isrc1dec4),
+ CS42L43_DAPM_MUX("ISRC2INT1", b_isrc2int1),
+ CS42L43_DAPM_MUX("ISRC2INT2", b_isrc2int2),
+ CS42L43_DAPM_MUX("ISRC2DEC1", b_isrc2dec1),
+ CS42L43_DAPM_MUX("ISRC2DEC2", b_isrc2dec2),
+ CS42L43_DAPM_MUX("ISRC2DEC3", b_isrc2dec3),
+ CS42L43_DAPM_MUX("ISRC2DEC4", b_isrc2dec4),
+
+ CS42L43_DAPM_MUX("SPDIF1", b_spdif1),
+ CS42L43_DAPM_MUX("SPDIF2", b_spdif2),
+
+ CS42L43_DAPM_MIXER("EQ1", b_eq1),
+ CS42L43_DAPM_MIXER("EQ2", b_eq2),
+
+ CS42L43_DAPM_MIXER("Speaker L", b_amp1),
+ CS42L43_DAPM_MIXER("Speaker R", b_amp2),
+
+ CS42L43_DAPM_MIXER("Headphone L", b_amp3),
+ CS42L43_DAPM_MIXER("Headphone R", b_amp4),
+};
+
+static const struct snd_soc_dapm_route cs42l43_a_routes[] = {
+ { "Decimator 1 Mode", "PDM", "PDM1L" },
+ { "Decimator 1 Mode", "ADC", "ADC1" },
+ { "Decimator 2 Mode", "PDM", "PDM1R" },
+ { "Decimator 2 Mode", "ADC", "ADC2" },
+
+ { "Decimator 1", NULL, "Decimator 1 Mode" },
+ { "Decimator 2", NULL, "Decimator 2 Mode" },
+ { "Decimator 3", NULL, "PDM2L" },
+ { "Decimator 4", NULL, "PDM2R" },
CS42L43_MUX_ROUTES("ASPTX1", "ASPTX1"),
CS42L43_MUX_ROUTES("ASPTX2", "ASPTX2"),
@@ -2110,6 +2486,81 @@ static const struct snd_soc_dapm_route cs42l43_routes[] = {
CS42L43_MIXER_ROUTES("Headphone R", "HP"),
};
+static const struct snd_soc_dapm_route cs42l43_b_routes[] = {
+ { "Decimator 1", NULL, "ADC1" },
+ { "Decimator 2", NULL, "ADC2" },
+ { "Decimator 3", NULL, "PDM1L" },
+ { "Decimator 4", NULL, "PDM1R" },
+ { "Decimator 5", NULL, "PDM2L" },
+ { "Decimator 6", NULL, "PDM2R" },
+
+ { "DP3 Capture", NULL, "DP3TX3" },
+ { "DP3 Capture", NULL, "DP3TX4" },
+ { "DP4 Capture", NULL, "DP4TX3" },
+ { "DP4 Capture", NULL, "DP4TX4" },
+
+ { "ISRC1DEC3", NULL, "ISRC1" },
+ { "ISRC1DEC4", NULL, "ISRC1" },
+ { "ISRC2DEC3", NULL, "ISRC2" },
+ { "ISRC2DEC4", NULL, "ISRC2" },
+
+ CS42L43B_MUX_ROUTES("ASPTX1", "ASPTX1"),
+ CS42L43B_MUX_ROUTES("ASPTX2", "ASPTX2"),
+ CS42L43B_MUX_ROUTES("ASPTX3", "ASPTX3"),
+ CS42L43B_MUX_ROUTES("ASPTX4", "ASPTX4"),
+ CS42L43B_MUX_ROUTES("ASPTX5", "ASPTX5"),
+ CS42L43B_MUX_ROUTES("ASPTX6", "ASPTX6"),
+
+ CS42L43B_MUX_ROUTES("DP1TX1", "DP1TX1"),
+ CS42L43B_MUX_ROUTES("DP1TX2", "DP1TX2"),
+ CS42L43B_MUX_ROUTES("DP1TX3", "DP1TX3"),
+ CS42L43B_MUX_ROUTES("DP1TX4", "DP1TX4"),
+ CS42L43B_MUX_ROUTES("DP2TX1", "DP2TX1"),
+ CS42L43B_MUX_ROUTES("DP2TX2", "DP2TX2"),
+ CS42L43B_MUX_ROUTES("DP3TX1", "DP3TX1"),
+ CS42L43B_MUX_ROUTES("DP3TX2", "DP3TX2"),
+ CS42L43B_MUX_ROUTES("DP3TX3", "DP3TX3"),
+ CS42L43B_MUX_ROUTES("DP3TX4", "DP3TX4"),
+ CS42L43B_MUX_ROUTES("DP4TX1", "DP4TX1"),
+ CS42L43B_MUX_ROUTES("DP4TX2", "DP4TX2"),
+ CS42L43B_MUX_ROUTES("DP4TX3", "DP4TX3"),
+ CS42L43B_MUX_ROUTES("DP4TX4", "DP4TX4"),
+
+ CS42L43B_MUX_ROUTES("ASRC INT1", "ASRC_INT1"),
+ CS42L43B_MUX_ROUTES("ASRC INT2", "ASRC_INT2"),
+ CS42L43B_MUX_ROUTES("ASRC INT3", "ASRC_INT3"),
+ CS42L43B_MUX_ROUTES("ASRC INT4", "ASRC_INT4"),
+ CS42L43B_MUX_ROUTES("ASRC DEC1", "ASRC_DEC1"),
+ CS42L43B_MUX_ROUTES("ASRC DEC2", "ASRC_DEC2"),
+ CS42L43B_MUX_ROUTES("ASRC DEC3", "ASRC_DEC3"),
+ CS42L43B_MUX_ROUTES("ASRC DEC4", "ASRC_DEC4"),
+
+ CS42L43B_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
+ CS42L43B_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
+ CS42L43B_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
+ CS42L43B_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
+ CS42L43B_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
+ CS42L43B_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
+ CS42L43B_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
+ CS42L43B_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
+ CS42L43B_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
+ CS42L43B_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
+ CS42L43B_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
+ CS42L43B_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
+
+ CS42L43B_MUX_ROUTES("SPDIF1", "SPDIF"),
+ CS42L43B_MUX_ROUTES("SPDIF2", "SPDIF"),
+
+ CS42L43B_MIXER_ROUTES("EQ1", "EQ"),
+ CS42L43B_MIXER_ROUTES("EQ2", "EQ"),
+
+ CS42L43B_MIXER_ROUTES("Speaker L", "AMP1"),
+ CS42L43B_MIXER_ROUTES("Speaker R", "AMP2"),
+
+ CS42L43B_MIXER_ROUTES("Headphone L", "HP"),
+ CS42L43B_MIXER_ROUTES("Headphone R", "HP"),
+};
+
static int cs42l43_set_sysclk(struct snd_soc_component *component, int clk_id,
int src, unsigned int freq, int dir)
{
@@ -2126,8 +2577,14 @@ static int cs42l43_set_sysclk(struct snd_soc_component *component, int clk_id,
static int cs42l43_component_probe(struct snd_soc_component *component)
{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
+ unsigned int num_controls, num_widgets, num_routes;
+ const struct snd_soc_dapm_widget *widgets;
+ const struct snd_kcontrol_new *controls;
+ const struct snd_soc_dapm_route *routes;
struct cs42l43 *cs42l43 = priv->core;
+ int ret;
snd_soc_component_init_regmap(component, cs42l43->regmap);
@@ -2139,6 +2596,39 @@ static int cs42l43_component_probe(struct snd_soc_component *component)
priv->component = component;
priv->constraint = cs42l43_constraint;
+ switch (cs42l43->variant_id) {
+ case CS42L43_DEVID_VAL:
+ controls = cs42l43_a_controls;
+ num_controls = ARRAY_SIZE(cs42l43_a_controls);
+ widgets = cs42l43_a_widgets;
+ num_widgets = ARRAY_SIZE(cs42l43_a_widgets);
+ routes = cs42l43_a_routes;
+ num_routes = ARRAY_SIZE(cs42l43_a_routes);
+ break;
+ case CS42L43B_DEVID_VAL:
+ controls = cs42l43_b_controls;
+ num_controls = ARRAY_SIZE(cs42l43_b_controls);
+ widgets = cs42l43_b_widgets;
+ num_widgets = ARRAY_SIZE(cs42l43_b_widgets);
+ routes = cs42l43_b_routes;
+ num_routes = ARRAY_SIZE(cs42l43_b_routes);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = snd_soc_add_component_controls(component, controls, num_controls);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_dapm_new_controls(dapm, widgets, num_widgets);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_dapm_add_routes(dapm, routes, num_routes);
+ if (ret)
+ return ret;
+
return 0;
}
diff --git a/sound/soc/codecs/cs42l43.h b/sound/soc/codecs/cs42l43.h
index b2fa2cd1d99f..fd50feb26ae9 100644
--- a/sound/soc/codecs/cs42l43.h
+++ b/sound/soc/codecs/cs42l43.h
@@ -61,7 +61,7 @@ struct cs42l43_codec {
unsigned int refclk_freq;
struct completion pll_ready;
- unsigned int decim_cache[4];
+ unsigned int decim_cache[6];
unsigned int adc_ena;
unsigned int hp_ena;
@@ -103,7 +103,7 @@ struct cs42l43_codec {
bool hp_ilimited;
int hp_ilimit_count;
- struct snd_kcontrol *kctl[5];
+ struct snd_kcontrol *kctl[7];
};
#if IS_REACHABLE(CONFIG_SND_SOC_CS42L43_SDW)
--
2.48.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/4] ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant
2026-01-16 15:20 ` [PATCH v2 2/4] ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant Maciej Strozek
@ 2026-01-17 11:39 ` Krzysztof Kozlowski
0 siblings, 0 replies; 7+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-17 11:39 UTC (permalink / raw)
To: Maciej Strozek
Cc: Mark Brown, Takashi Iwai, Lee Jones, Krzysztof Kozlowski,
Jaroslav Kysela, Bard Liao, Peter Ujfalusi, linux-kernel,
linux-sound, patches, devicetree
On Fri, Jan 16, 2026 at 03:20:41PM +0000, Maciej Strozek wrote:
> CS42L43B variant adds dedicated PDM interface, SoundWire Clock Gearing
> support and more decimators to ISRCs.
>
> Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
> ---
> Documentation/devicetree/bindings/sound/cirrus,cs42l43.yaml | 3 +++
> 1 file changed, 3 insertions(+)
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 3/4] mfd: cs42l43: Add support for the B variant
2026-01-16 15:20 ` [PATCH v2 3/4] mfd: cs42l43: Add support for the B variant Maciej Strozek
@ 2026-01-22 11:59 ` Lee Jones
0 siblings, 0 replies; 7+ messages in thread
From: Lee Jones @ 2026-01-22 11:59 UTC (permalink / raw)
To: Maciej Strozek
Cc: Mark Brown, Takashi Iwai, Krzysztof Kozlowski, Jaroslav Kysela,
Bard Liao, Peter Ujfalusi, linux-kernel, linux-sound, patches,
devicetree
On Fri, 16 Jan 2026, Maciej Strozek wrote:
> Introducing CS42L43B codec, a variant of CS42L43 which can be driven by
> the same driver.
>
> Changes in CS42L43 driver specific for CS42L43B:
> - Decimator 1 and 2 are dedicated to ADC, can't be selected for PDM
> - Decimators 3 and 4 are connected to PDM1
> - Added Decimator 5 and 6 for PDM2
> - Supports SoundWire Clock Gearing
> - Updated ROM requiring no patching
> - Reduced RAM space
> - Each ISRC has 4 decimators now
>
> Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
> ---
> Changes in v2:
> - Rework the mechanism to identify the new variant along with some
> error handling improvements.
> - Added some comments in cs42l43_readable_register() for clarity.
> - Add handling of the I2C path for the B variant
> ---
> drivers/mfd/cs42l43-i2c.c | 7 ++-
> drivers/mfd/cs42l43-sdw.c | 4 +-
> drivers/mfd/cs42l43.c | 93 +++++++++++++++++++++++++++-----
> drivers/mfd/cs42l43.h | 2 +-
> include/linux/mfd/cs42l43-regs.h | 76 ++++++++++++++++++++++++++
> include/linux/mfd/cs42l43.h | 1 +
> 6 files changed, 166 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/mfd/cs42l43-i2c.c b/drivers/mfd/cs42l43-i2c.c
> index a2ab001a600a..0a0ab5e549a5 100644
> --- a/drivers/mfd/cs42l43-i2c.c
> +++ b/drivers/mfd/cs42l43-i2c.c
> @@ -47,6 +47,7 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
> cs42l43->irq = i2c->irq;
> /* A device on an I2C is always attached by definition. */
> cs42l43->attached = true;
> + cs42l43->variant_id = (long)device_get_match_data(cs42l43->dev);
[...]
> diff --git a/include/linux/mfd/cs42l43.h b/include/linux/mfd/cs42l43.h
> index 2239d8585e78..8313f9e8c722 100644
> --- a/include/linux/mfd/cs42l43.h
> +++ b/include/linux/mfd/cs42l43.h
> @@ -98,6 +98,7 @@ struct cs42l43 {
> bool sdw_pll_active;
> bool attached;
> bool hw_lock;
> + int variant_id;
> };
long != int
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-01-22 11:59 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-16 15:20 [PATCH v2 0/4] Add support for CS42L43B codec to CS42L43 driver Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 1/4] ASoC: sdw_utils: Add CS42L43B codec info Maciej Strozek
2026-01-16 15:20 ` [PATCH v2 2/4] ASoC: dt-bindings: cirrus,cs42l43: Add CS42L43B variant Maciej Strozek
2026-01-17 11:39 ` Krzysztof Kozlowski
2026-01-16 15:20 ` [PATCH v2 3/4] mfd: cs42l43: Add support for the B variant Maciej Strozek
2026-01-22 11:59 ` Lee Jones
2026-01-16 15:20 ` [PATCH v2 4/4] ASoC: " Maciej Strozek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox