summaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/cs35l41.c26
-rw-r--r--sound/soc/codecs/cs35l56-sdw.c2
-rw-r--r--sound/soc/codecs/cs35l56-shared.c85
-rw-r--r--sound/soc/codecs/cs35l56.c39
-rw-r--r--sound/soc/codecs/da7219-aad.c6
-rw-r--r--sound/soc/codecs/rt5645.c25
-rw-r--r--sound/soc/codecs/rt715-sdca.c8
-rw-r--r--sound/soc/codecs/rt715-sdw.c1
-rw-r--r--sound/soc/codecs/rt722-sdca.c27
-rw-r--r--sound/soc/codecs/rt722-sdca.h3
-rw-r--r--sound/soc/codecs/wsa881x.c1
11 files changed, 170 insertions, 53 deletions
diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index dfb4ce53491b..f8e57a2fc3e3 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -1094,6 +1094,7 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf
static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
{
struct wm_adsp *dsp;
+ uint32_t dsp1rx5_src;
int ret;
dsp = &cs35l41->dsp;
@@ -1113,16 +1114,29 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
return ret;
}
- ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC,
- CS35L41_INPUT_SRC_VPMON);
+ switch (cs35l41->hw_cfg.bst_type) {
+ case CS35L41_INT_BOOST:
+ case CS35L41_SHD_BOOST_ACTV:
+ dsp1rx5_src = CS35L41_INPUT_SRC_VPMON;
+ break;
+ case CS35L41_EXT_BOOST:
+ case CS35L41_SHD_BOOST_PASS:
+ dsp1rx5_src = CS35L41_INPUT_SRC_VBSTMON;
+ break;
+ default:
+ dev_err(cs35l41->dev, "wm_halo_init failed - Invalid Boost Type: %d\n",
+ cs35l41->hw_cfg.bst_type);
+ goto err_dsp;
+ }
+
+ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC, dsp1rx5_src);
if (ret < 0) {
- dev_err(cs35l41->dev, "Write INPUT_SRC_VPMON failed: %d\n", ret);
+ dev_err(cs35l41->dev, "Write DSP1RX5_SRC: %d failed: %d\n", dsp1rx5_src, ret);
goto err_dsp;
}
- ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC,
- CS35L41_INPUT_SRC_CLASSH);
+ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC, CS35L41_INPUT_SRC_VBSTMON);
if (ret < 0) {
- dev_err(cs35l41->dev, "Write INPUT_SRC_CLASSH failed: %d\n", ret);
+ dev_err(cs35l41->dev, "Write CS35L41_INPUT_SRC_VBSTMON failed: %d\n", ret);
goto err_dsp;
}
ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC,
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
index 14a5f86019aa..70ff55c1517f 100644
--- a/sound/soc/codecs/cs35l56-sdw.c
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -188,8 +188,6 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral)
goto out;
}
- regcache_cache_only(cs35l56->base.regmap, false);
-
ret = cs35l56_init(cs35l56);
if (ret < 0) {
regcache_cache_only(cs35l56->base.regmap, true);
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index 08cac58e3ab2..fd02b621da52 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -40,16 +40,11 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED);
static const struct reg_default cs35l56_reg_defaults[] = {
/* no defaults for OTP_MEM - first read populates cache */
- { CS35L56_ASP1_ENABLES1, 0x00000000 },
- { CS35L56_ASP1_CONTROL1, 0x00000028 },
- { CS35L56_ASP1_CONTROL2, 0x18180200 },
- { CS35L56_ASP1_CONTROL3, 0x00000002 },
- { CS35L56_ASP1_FRAME_CONTROL1, 0x03020100 },
- { CS35L56_ASP1_FRAME_CONTROL5, 0x00020100 },
- { CS35L56_ASP1_DATA_CONTROL1, 0x00000018 },
- { CS35L56_ASP1_DATA_CONTROL5, 0x00000018 },
-
- /* no defaults for ASP1TX mixer */
+ /*
+ * No defaults for ASP1 control or ASP1TX mixer. See
+ * cs35l56_populate_asp1_register_defaults() and
+ * cs35l56_sync_asp1_mixer_widgets_with_firmware().
+ */
{ CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 },
{ CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
@@ -210,6 +205,36 @@ static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
}
}
+static const struct reg_sequence cs35l56_asp1_defaults[] = {
+ REG_SEQ0(CS35L56_ASP1_ENABLES1, 0x00000000),
+ REG_SEQ0(CS35L56_ASP1_CONTROL1, 0x00000028),
+ REG_SEQ0(CS35L56_ASP1_CONTROL2, 0x18180200),
+ REG_SEQ0(CS35L56_ASP1_CONTROL3, 0x00000002),
+ REG_SEQ0(CS35L56_ASP1_FRAME_CONTROL1, 0x03020100),
+ REG_SEQ0(CS35L56_ASP1_FRAME_CONTROL5, 0x00020100),
+ REG_SEQ0(CS35L56_ASP1_DATA_CONTROL1, 0x00000018),
+ REG_SEQ0(CS35L56_ASP1_DATA_CONTROL5, 0x00000018),
+};
+
+/*
+ * The firmware can have control of the ASP so we don't provide regmap
+ * with defaults for these registers, to prevent a regcache_sync() from
+ * overwriting the firmware settings. But if the machine driver hooks up
+ * the ASP it means the driver is taking control of the ASP, so then the
+ * registers are populated with the defaults.
+ */
+int cs35l56_init_asp1_regs_for_driver_control(struct cs35l56_base *cs35l56_base)
+{
+ if (!cs35l56_base->fw_owns_asp1)
+ return 0;
+
+ cs35l56_base->fw_owns_asp1 = false;
+
+ return regmap_multi_reg_write(cs35l56_base->regmap, cs35l56_asp1_defaults,
+ ARRAY_SIZE(cs35l56_asp1_defaults));
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_init_asp1_regs_for_driver_control, SND_SOC_CS35L56_SHARED);
+
/*
* The firmware boot sequence can overwrite the ASP1 config registers so that
* they don't match regmap's view of their values. Rewrite the values from the
@@ -217,19 +242,15 @@ static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
*/
int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base *cs35l56_base)
{
- struct reg_sequence asp1_regs[] = {
- { .reg = CS35L56_ASP1_ENABLES1 },
- { .reg = CS35L56_ASP1_CONTROL1 },
- { .reg = CS35L56_ASP1_CONTROL2 },
- { .reg = CS35L56_ASP1_CONTROL3 },
- { .reg = CS35L56_ASP1_FRAME_CONTROL1 },
- { .reg = CS35L56_ASP1_FRAME_CONTROL5 },
- { .reg = CS35L56_ASP1_DATA_CONTROL1 },
- { .reg = CS35L56_ASP1_DATA_CONTROL5 },
- };
+ struct reg_sequence asp1_regs[ARRAY_SIZE(cs35l56_asp1_defaults)];
int i, ret;
- /* Read values from regmap cache into a write sequence */
+ if (cs35l56_base->fw_owns_asp1)
+ return 0;
+
+ memcpy(asp1_regs, cs35l56_asp1_defaults, sizeof(asp1_regs));
+
+ /* Read current values from regmap cache into the write sequence */
for (i = 0; i < ARRAY_SIZE(asp1_regs); ++i) {
ret = regmap_read(cs35l56_base->regmap, asp1_regs[i].reg, &asp1_regs[i].def);
if (ret)
@@ -307,10 +328,10 @@ int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
reg = CS35L56_DSP1_HALO_STATE;
/*
- * This can't be a regmap_read_poll_timeout() because cs35l56 will NAK
- * I2C until it has booted which would terminate the poll
+ * The regmap must remain in cache-only until the chip has
+ * booted, so use a bypassed read of the status register.
*/
- poll_ret = read_poll_timeout(regmap_read, read_ret,
+ poll_ret = read_poll_timeout(regmap_read_bypassed, read_ret,
(val < 0xFFFF) && (val >= CS35L56_HALO_STATE_BOOT_DONE),
CS35L56_HALO_STATE_POLL_US,
CS35L56_HALO_STATE_TIMEOUT_US,
@@ -362,7 +383,8 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
return;
cs35l56_wait_control_port_ready();
- regcache_cache_only(cs35l56_base->regmap, false);
+
+ /* Leave in cache-only. This will be revoked when the chip has rebooted. */
}
EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, SND_SOC_CS35L56_SHARED);
@@ -577,14 +599,14 @@ int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_sou
cs35l56_issue_wake_event(cs35l56_base);
out_sync:
- regcache_cache_only(cs35l56_base->regmap, false);
-
ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
if (ret) {
dev_err(cs35l56_base->dev, "Hibernate wake failed: %d\n", ret);
goto err;
}
+ regcache_cache_only(cs35l56_base->regmap, false);
+
ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
if (ret)
goto err;
@@ -684,7 +706,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, SND_SOC_CS35L56_SHARED);
int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base)
{
- u64 silicon_uid;
+ u64 silicon_uid = 0;
int ret;
/* Driver can't apply calibration to a secured part, so skip */
@@ -757,7 +779,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
* devices so the REVID needs to be determined before waiting for the
* firmware to boot.
*/
- ret = regmap_read(cs35l56_base->regmap, CS35L56_REVID, &revid);
+ ret = regmap_read_bypassed(cs35l56_base->regmap, CS35L56_REVID, &revid);
if (ret < 0) {
dev_err(cs35l56_base->dev, "Get Revision ID failed\n");
return ret;
@@ -768,7 +790,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
if (ret)
return ret;
- ret = regmap_read(cs35l56_base->regmap, CS35L56_DEVID, &devid);
+ ret = regmap_read_bypassed(cs35l56_base->regmap, CS35L56_DEVID, &devid);
if (ret < 0) {
dev_err(cs35l56_base->dev, "Get Device ID failed\n");
return ret;
@@ -787,6 +809,9 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
cs35l56_base->type = devid & 0xFF;
+ /* Silicon is now identified and booted so exit cache-only */
+ regcache_cache_only(cs35l56_base->regmap, false);
+
ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP_RESTRICT_STS1, &secured);
if (ret) {
dev_err(cs35l56_base->dev, "Get Secure status failed\n");
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 8d2f021fb362..4986e78105da 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -454,9 +454,14 @@ static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int f
{
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component);
unsigned int val;
+ int ret;
dev_dbg(cs35l56->base.dev, "%s: %#x\n", __func__, fmt);
+ ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+ if (ret)
+ return ret;
+
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
case SND_SOC_DAIFMT_CBC_CFC:
break;
@@ -530,6 +535,11 @@ static int cs35l56_asp_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx
unsigned int rx_mask, int slots, int slot_width)
{
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ int ret;
+
+ ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+ if (ret)
+ return ret;
if ((slots == 0) || (slot_width == 0)) {
dev_dbg(cs35l56->base.dev, "tdm config cleared\n");
@@ -578,6 +588,11 @@ static int cs35l56_asp_dai_hw_params(struct snd_pcm_substream *substream,
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
unsigned int rate = params_rate(params);
u8 asp_width, asp_wl;
+ int ret;
+
+ ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+ if (ret)
+ return ret;
asp_wl = params_width(params);
if (cs35l56->asp_slot_width)
@@ -634,7 +649,11 @@ static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
- int freq_id;
+ int freq_id, ret;
+
+ ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+ if (ret)
+ return ret;
if (freq == 0) {
cs35l56->sysclk_set = false;
@@ -1341,6 +1360,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
"spk-id-gpios", ACPI_TYPE_PACKAGE, &obj);
if (ret) {
dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret);
+ fwnode_handle_put(af01_fwnode);
return -ENOENT;
}
@@ -1348,6 +1368,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
if (obj->package.count != 4) {
dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n",
obj->package.count);
+ fwnode_handle_put(af01_fwnode);
return -ENOENT;
}
@@ -1362,6 +1383,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
*/
ret = acpi_dev_add_driver_gpios(adev, cs35l56_af01_spkid_gpios_mapping);
if (ret) {
+ fwnode_handle_put(af01_fwnode);
return dev_err_probe(cs35l56->base.dev, ret,
"Failed to add gpio mapping to AF01\n");
}
@@ -1369,14 +1391,17 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
ret = devm_add_action_or_reset(cs35l56->base.dev,
cs35l56_acpi_dev_release_driver_gpios,
adev);
- if (ret)
+ if (ret) {
+ fwnode_handle_put(af01_fwnode);
return ret;
+ }
dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n");
}
desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL);
if (IS_ERR(desc)) {
+ fwnode_handle_put(af01_fwnode);
ret = PTR_ERR(desc);
return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n");
}
@@ -1385,9 +1410,12 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
gpiod_put(desc);
if (ret < 0) {
+ fwnode_handle_put(af01_fwnode);
dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n");
return ret;
- }
+ }
+
+ fwnode_handle_put(af01_fwnode);
dev_info(cs35l56->base.dev, "Got spk-id from AF01\n");
@@ -1403,6 +1431,9 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
cs35l56->base.cal_index = -1;
cs35l56->speaker_id = -ENOENT;
+ /* Assume that the firmware owns ASP1 until we know different */
+ cs35l56->base.fw_owns_asp1 = true;
+
dev_set_drvdata(cs35l56->base.dev, cs35l56);
cs35l56_fill_supply_names(cs35l56->supplies);
@@ -1531,6 +1562,8 @@ post_soft_reset:
return ret;
dev_dbg(cs35l56->base.dev, "Firmware rebooted after soft reset\n");
+
+ regcache_cache_only(cs35l56->base.regmap, false);
}
/* Disable auto-hibernate so that runtime_pm has control */
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
index 6bc068cdcbe2..15e5e3eb592b 100644
--- a/sound/soc/codecs/da7219-aad.c
+++ b/sound/soc/codecs/da7219-aad.c
@@ -671,8 +671,10 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
return NULL;
aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
- if (!aad_pdata)
+ if (!aad_pdata) {
+ fwnode_handle_put(aad_np);
return NULL;
+ }
aad_pdata->irq = i2c->irq;
@@ -753,6 +755,8 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
else
aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
+ fwnode_handle_put(aad_np);
+
return aad_pdata;
}
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index e3ba04484813..d0d24a53df74 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -444,6 +444,7 @@ struct rt5645_priv {
struct regmap *regmap;
struct i2c_client *i2c;
struct gpio_desc *gpiod_hp_det;
+ struct gpio_desc *gpiod_cbj_sleeve;
struct snd_soc_jack *hp_jack;
struct snd_soc_jack *mic_jack;
struct snd_soc_jack *btn_jack;
@@ -3186,6 +3187,9 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
RT5645_CBJ_MN_JD, 0);
+ if (rt5645->gpiod_cbj_sleeve)
+ gpiod_set_value(rt5645->gpiod_cbj_sleeve, 1);
+
msleep(600);
regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val);
val &= 0x7;
@@ -3202,6 +3206,8 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
snd_soc_dapm_sync(dapm);
rt5645->jack_type = SND_JACK_HEADPHONE;
+ if (rt5645->gpiod_cbj_sleeve)
+ gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
}
if (rt5645->pdata.level_trigger_irq)
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
@@ -3229,6 +3235,9 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
if (rt5645->pdata.level_trigger_irq)
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
+
+ if (rt5645->gpiod_cbj_sleeve)
+ gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
}
return rt5645->jack_type;
@@ -4012,6 +4021,16 @@ static int rt5645_i2c_probe(struct i2c_client *i2c)
return ret;
}
+ rt5645->gpiod_cbj_sleeve = devm_gpiod_get_optional(&i2c->dev, "cbj-sleeve",
+ GPIOD_OUT_LOW);
+
+ if (IS_ERR(rt5645->gpiod_cbj_sleeve)) {
+ ret = PTR_ERR(rt5645->gpiod_cbj_sleeve);
+ dev_info(&i2c->dev, "failed to initialize gpiod, ret=%d\n", ret);
+ if (ret != -ENOENT)
+ return ret;
+ }
+
for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
rt5645->supplies[i].supply = rt5645_supply_names[i];
@@ -4259,6 +4278,9 @@ static void rt5645_i2c_remove(struct i2c_client *i2c)
cancel_delayed_work_sync(&rt5645->jack_detect_work);
cancel_delayed_work_sync(&rt5645->rcclock_work);
+ if (rt5645->gpiod_cbj_sleeve)
+ gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
+
regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
}
@@ -4274,6 +4296,9 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
0);
msleep(20);
regmap_write(rt5645->regmap, RT5645_RESET, 0);
+
+ if (rt5645->gpiod_cbj_sleeve)
+ gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
}
static int __maybe_unused rt5645_sys_suspend(struct device *dev)
diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c
index 3fb7b9adb61d..bc3579203c7a 100644
--- a/sound/soc/codecs/rt715-sdca.c
+++ b/sound/soc/codecs/rt715-sdca.c
@@ -316,7 +316,7 @@ static int rt715_sdca_set_amp_gain_8ch_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);
static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol,
@@ -477,7 +477,7 @@ static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = {
RT715_SDCA_FU_VOL_CTRL, CH_01),
SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_02),
- 0x2f, 0x7f, 0,
+ 0x2f, 0x3f, 0,
rt715_sdca_set_amp_gain_get, rt715_sdca_set_amp_gain_put,
in_vol_tlv),
RT715_SDCA_EXT_TLV("FU02 Capture Volume",
@@ -485,13 +485,13 @@ static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = {
RT715_SDCA_FU_VOL_CTRL, CH_01),
rt715_sdca_set_amp_gain_4ch_get,
rt715_sdca_set_amp_gain_4ch_put,
- in_vol_tlv, 4, 0x7f),
+ in_vol_tlv, 4, 0x3f),
RT715_SDCA_EXT_TLV("FU06 Capture Volume",
SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_01),
rt715_sdca_set_amp_gain_4ch_get,
rt715_sdca_set_amp_gain_4ch_put,
- in_vol_tlv, 4, 0x7f),
+ in_vol_tlv, 4, 0x3f),
/* MIC Boost Control */
RT715_SDCA_BOOST_EXT_TLV("FU0E Boost",
SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c
index 7e13868ff99f..f012fe0ded6d 100644
--- a/sound/soc/codecs/rt715-sdw.c
+++ b/sound/soc/codecs/rt715-sdw.c
@@ -111,6 +111,7 @@ static bool rt715_readable_register(struct device *dev, unsigned int reg)
case 0x839d:
case 0x83a7:
case 0x83a9:
+ case 0x752001:
case 0x752039:
return true;
default:
diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c
index e0ea3a23f7cc..e5bd9ef812de 100644
--- a/sound/soc/codecs/rt722-sdca.c
+++ b/sound/soc/codecs/rt722-sdca.c
@@ -1330,7 +1330,7 @@ static struct snd_soc_dai_driver rt722_sdca_dai[] = {
.capture = {
.stream_name = "DP6 DMic Capture",
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 4,
.rates = RT722_STEREO_RATES,
.formats = RT722_FORMATS,
},
@@ -1439,9 +1439,12 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)
int loop_check, chk_cnt = 100, ret;
unsigned int calib_status = 0;
- /* Read eFuse */
- rt722_sdca_index_write(rt722, RT722_VENDOR_SPK_EFUSE, RT722_DC_CALIB_CTRL,
- 0x4808);
+ /* Config analog bias */
+ rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_ANALOG_BIAS_CTL3,
+ 0xa081);
+ /* GE related settings */
+ rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_GE_RELATED_CTL2,
+ 0xa009);
/* Button A, B, C, D bypass mode */
rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_UMP_HID_CTL4,
0xcf00);
@@ -1475,9 +1478,6 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)
if ((calib_status & 0x0040) == 0x0)
break;
}
- /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */
- rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_DIGITAL_MISC_CTRL4,
- 0x0010);
/* Set ADC09 power entity floating control */
rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ADC0A_08_PDE_FLOAT_CTL,
0x2a12);
@@ -1490,8 +1490,21 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)
/* Set DAC03 and HP power entity floating control */
rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_DAC03_HP_PDE_FLOAT_CTL,
0x4040);
+ rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ENT_FLOAT_CTRL_1,
+ 0x4141);
+ rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_FLOAT_CTRL_1,
+ 0x0101);
/* Fine tune PDE40 latency */
regmap_write(rt722->regmap, 0x2f58, 0x07);
+ regmap_write(rt722->regmap, 0x2f03, 0x06);
+ /* MIC VRefo */
+ rt722_sdca_index_update_bits(rt722, RT722_VENDOR_REG,
+ RT722_COMBO_JACK_AUTO_CTL1, 0x0200, 0x0200);
+ rt722_sdca_index_update_bits(rt722, RT722_VENDOR_REG,
+ RT722_VREFO_GAT, 0x4000, 0x4000);
+ /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */
+ rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_DIGITAL_MISC_CTRL4,
+ 0x0010);
}
int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave)
diff --git a/sound/soc/codecs/rt722-sdca.h b/sound/soc/codecs/rt722-sdca.h
index 44af8901352e..2464361a7958 100644
--- a/sound/soc/codecs/rt722-sdca.h
+++ b/sound/soc/codecs/rt722-sdca.h
@@ -69,6 +69,7 @@ struct rt722_sdca_dmic_kctrl_priv {
#define RT722_COMBO_JACK_AUTO_CTL2 0x46
#define RT722_COMBO_JACK_AUTO_CTL3 0x47
#define RT722_DIGITAL_MISC_CTRL4 0x4a
+#define RT722_VREFO_GAT 0x63
#define RT722_FSM_CTL 0x67
#define RT722_SDCA_INTR_REC 0x82
#define RT722_SW_CONFIG1 0x8a
@@ -127,6 +128,8 @@ struct rt722_sdca_dmic_kctrl_priv {
#define RT722_UMP_HID_CTL6 0x66
#define RT722_UMP_HID_CTL7 0x67
#define RT722_UMP_HID_CTL8 0x68
+#define RT722_FLOAT_CTRL_1 0x70
+#define RT722_ENT_FLOAT_CTRL_1 0x76
/* Parameter & Verb control 01 (0x1a)(NID:20h) */
#define RT722_HIDDEN_REG_SW_RESET (0x1 << 14)
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index 3c025dabaf7a..1253695bebd8 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -1155,6 +1155,7 @@ static int wsa881x_probe(struct sdw_slave *pdev,
pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS, 0);
pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
+ pdev->prop.clk_stop_mode1 = true;
gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config);