Add support for CS42L43B codec to CS42L43 driver

Merge series from Maciej Strozek <mstrozek@opensource.cirrus.com>:

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.
master
Mark Brown 2026-03-09 22:37:16 +00:00
commit 296bd7dd81
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
10 changed files with 848 additions and 152 deletions

View File

@ -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

View File

@ -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);

View File

@ -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 = (long)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);

View File

@ -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%06lx)\n",
devid, cs42l43->variant_id);
goto err;
}
break;
default:
dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid);

View File

@ -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;

View File

@ -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 */

View File

@ -98,6 +98,7 @@ struct cs42l43 {
bool sdw_pll_active;
bool attached;
bool hw_lock;
long variant_id;
};
#endif /* CS42L43_CORE_EXT_H */

View File

@ -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_to_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;
}

View File

@ -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)

View File

@ -723,6 +723,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",