550 lines
19 KiB
Diff
550 lines
19 KiB
Diff
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
|
|
--- a/include/sound/soc_sdw_utils.h
|
|
+++ b/include/sound/soc_sdw_utils.h
|
|
@@ -250,8 +250,6 @@ int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
|
|
struct snd_soc_dai_link *dai_links,
|
|
struct asoc_sdw_codec_info *info,
|
|
bool playback);
|
|
-int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd,
|
|
- struct snd_soc_dai *dai);
|
|
int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix);
|
|
|
|
/* MAXIM codec support */
|
|
diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c
|
|
--- a/sound/soc/amd/acp/acp-sdw-sof-mach.c
|
|
+++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c
|
|
@@ -314,7 +314,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
|
if (!sof_aux)
|
|
return -ENOMEM;
|
|
|
|
- ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_devs);
|
|
+ ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_confs);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
@@ -390,7 +390,7 @@ static int mc_probe(struct platform_device *pdev)
|
|
ctx->private = amd_ctx;
|
|
card = &ctx->card;
|
|
card->dev = &pdev->dev;
|
|
- card->name = "amd-soundwire";
|
|
+ card->name = "amd-sdw";
|
|
card->owner = THIS_MODULE;
|
|
card->late_probe = asoc_sdw_card_late_probe;
|
|
|
|
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
|
|
--- a/sound/soc/codecs/Kconfig
|
|
+++ b/sound/soc/codecs/Kconfig
|
|
@@ -524,13 +524,13 @@ config SND_SOC_ADAU1977
|
|
tristate
|
|
|
|
config SND_SOC_ADAU1977_SPI
|
|
- tristate
|
|
+ tristate "Analog Devices ADAU1977/ADAU1978/ADAU1979 CODEC - SPI"
|
|
depends on SPI_MASTER
|
|
select SND_SOC_ADAU1977
|
|
select REGMAP_SPI
|
|
|
|
config SND_SOC_ADAU1977_I2C
|
|
- tristate
|
|
+ tristate "Analog Devices ADAU1977/ADAU1978/ADAU1979 CODEC - I2C"
|
|
depends on I2C
|
|
select SND_SOC_ADAU1977
|
|
select REGMAP_I2C
|
|
diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c
|
|
--- a/sound/soc/codecs/adau1977-i2c.c
|
|
+++ b/sound/soc/codecs/adau1977-i2c.c
|
|
@@ -34,9 +34,18 @@ static const struct i2c_device_id adau1977_i2c_ids[] = {
|
|
};
|
|
MODULE_DEVICE_TABLE(i2c, adau1977_i2c_ids);
|
|
|
|
+static const struct of_device_id adau1977_i2c_of_match[] = {
|
|
+ { .compatible = "adi,adau1977" },
|
|
+ { .compatible = "adi,adau1978" },
|
|
+ { .compatible = "adi,adau1979" },
|
|
+ { },
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, adau1977_i2c_of_match);
|
|
+
|
|
static struct i2c_driver adau1977_i2c_driver = {
|
|
.driver = {
|
|
.name = "adau1977",
|
|
+ .of_match_table = adau1977_i2c_of_match,
|
|
},
|
|
.probe = adau1977_i2c_probe,
|
|
.id_table = adau1977_i2c_ids,
|
|
diff --git a/sound/soc/codecs/adau1977-spi.c b/sound/soc/codecs/adau1977-spi.c
|
|
--- a/sound/soc/codecs/adau1977-spi.c
|
|
+++ b/sound/soc/codecs/adau1977-spi.c
|
|
@@ -53,18 +53,18 @@ static const struct spi_device_id adau1977_spi_ids[] = {
|
|
};
|
|
MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
|
|
|
|
-static const struct of_device_id adau1977_spi_of_match[] __maybe_unused = {
|
|
- { .compatible = "adi,adau1977" },
|
|
- { .compatible = "adi,adau1978" },
|
|
- { .compatible = "adi,adau1979" },
|
|
- { },
|
|
+static const struct of_device_id adau1977_spi_of_match[] = {
|
|
+ { .compatible = "adi,adau1977" },
|
|
+ { .compatible = "adi,adau1978" },
|
|
+ { .compatible = "adi,adau1979" },
|
|
+ { },
|
|
};
|
|
MODULE_DEVICE_TABLE(of, adau1977_spi_of_match);
|
|
|
|
static struct spi_driver adau1977_spi_driver = {
|
|
.driver = {
|
|
.name = "adau1977",
|
|
- .of_match_table = of_match_ptr(adau1977_spi_of_match),
|
|
+ .of_match_table = adau1977_spi_of_match,
|
|
},
|
|
.probe = adau1977_spi_probe,
|
|
.id_table = adau1977_spi_ids,
|
|
diff --git a/sound/soc/codecs/rt712-sdca-sdw.c b/sound/soc/codecs/rt712-sdca-sdw.c
|
|
--- a/sound/soc/codecs/rt712-sdca-sdw.c
|
|
+++ b/sound/soc/codecs/rt712-sdca-sdw.c
|
|
@@ -18,12 +18,16 @@
|
|
static bool rt712_sdca_readable_register(struct device *dev, unsigned int reg)
|
|
{
|
|
switch (reg) {
|
|
+ case 0x004d:
|
|
case 0x201a ... 0x201f:
|
|
case 0x2029 ... 0x202a:
|
|
case 0x202d ... 0x2034:
|
|
case 0x2230 ... 0x2232:
|
|
case 0x2f01 ... 0x2f0a:
|
|
case 0x2f35 ... 0x2f36:
|
|
+ case 0x2f3a:
|
|
+ case 0x2f3d:
|
|
+ case 0x2f41:
|
|
case 0x2f50:
|
|
case 0x2f54:
|
|
case 0x2f58 ... 0x2f5d:
|
|
@@ -48,6 +52,7 @@ static bool rt712_sdca_readable_register(struct device *dev, unsigned int reg)
|
|
static bool rt712_sdca_volatile_register(struct device *dev, unsigned int reg)
|
|
{
|
|
switch (reg) {
|
|
+ case 0x004d:
|
|
case 0x201b:
|
|
case 0x201c:
|
|
case 0x201d:
|
|
@@ -56,6 +61,9 @@ static bool rt712_sdca_volatile_register(struct device *dev, unsigned int reg)
|
|
case 0x2230:
|
|
case 0x2f01:
|
|
case 0x2f35:
|
|
+ case 0x2f3a:
|
|
+ case 0x2f3d:
|
|
+ case 0x2f41:
|
|
case 0x320c:
|
|
case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0):
|
|
case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
|
|
diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c
|
|
--- a/sound/soc/codecs/rt712-sdca.c
|
|
+++ b/sound/soc/codecs/rt712-sdca.c
|
|
@@ -73,14 +73,57 @@ static int rt712_sdca_index_update_bits(struct rt712_sdca_priv *rt712,
|
|
return rt712_sdca_index_write(rt712, nid, reg, tmp);
|
|
}
|
|
|
|
+static void rt712_sdca_clk_patch(struct rt712_sdca_priv *rt712)
|
|
+{
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
|
|
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x03);
|
|
+ usleep_range(1000, 1100);
|
|
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x02);
|
|
+ usleep_range(1000, 1100);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x0080, 0x0000);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x001f, 0x0017);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF3, 0x0010, 0x0000);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF1, 0x0081, 0x0001);
|
|
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x03);
|
|
+ usleep_range(1000, 1100);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF1, 0x0081, 0x0081);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x0080, 0x0080);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x001f, 0x0000);
|
|
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF3, 0x0010, 0x0010);
|
|
+ usleep_range(1000, 1100);
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0081);
|
|
+}
|
|
+
|
|
+static void rt712_sdca_clk_patch2(struct rt712_sdca_priv *rt712)
|
|
+{
|
|
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_REG, 0x49, 0x0800,
|
|
+ 0x0000);
|
|
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_REG, 0x49, 0xf000,
|
|
+ 0x0000);
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
|
|
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_ANALOG_CTL, 0x0c, 0xc000,
|
|
+ 0xc000);
|
|
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_ANALOG_CTL, 0x00, 0xc000,
|
|
+ 0xc000);
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0081);
|
|
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x02);
|
|
+ usleep_range(1000, 1100);
|
|
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x03);
|
|
+ usleep_range(1000, 1100);
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
|
|
+}
|
|
+
|
|
static int rt712_sdca_calibration(struct rt712_sdca_priv *rt712)
|
|
{
|
|
unsigned int val, loop_rc = 0, loop_dc = 0;
|
|
struct device *dev;
|
|
struct regmap *regmap = rt712->regmap;
|
|
+ unsigned int clk_base;
|
|
int chk_cnt = 100;
|
|
int ret = 0;
|
|
|
|
+ regmap_read(rt712->regmap, RT712_SDW_ROOT_CLK, &clk_base);
|
|
+
|
|
mutex_lock(&rt712->calibrate_mutex);
|
|
dev = regmap_get_device(regmap);
|
|
|
|
@@ -109,8 +152,35 @@ static int rt712_sdca_calibration(struct rt712_sdca_priv *rt712)
|
|
if (ret < 0)
|
|
goto _cali_fail_;
|
|
}
|
|
- if (loop_dc == chk_cnt)
|
|
- dev_err(dev, "%s, calibration time-out!\n", __func__);
|
|
+
|
|
+ if (loop_dc == chk_cnt) {
|
|
+ if (clk_base == RT712_CLK_FREQ_24_576MHZ) {
|
|
+ rt712_sdca_clk_patch(rt712);
|
|
+ rt712_sdca_clk_patch2(rt712);
|
|
+ }
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_FSM_CTL, 0x4100);
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_CALI,
|
|
+ RT712_DAC_DC_CALI_CTL1, 0x7883);
|
|
+ rt712_sdca_index_write(rt712, RT712_VENDOR_CALI,
|
|
+ RT712_DAC_DC_CALI_CTL1, 0xf893);
|
|
+ rt712_sdca_index_read(rt712, RT712_VENDOR_CALI,
|
|
+ RT712_DAC_DC_CALI_CTL1, &val);
|
|
+
|
|
+ for (loop_dc = 0; loop_dc < chk_cnt &&
|
|
+ (val & RT712_DAC_DC_CALI_TRIGGER); loop_dc++) {
|
|
+ usleep_range(10000, 11000);
|
|
+ ret = rt712_sdca_index_read(rt712, RT712_VENDOR_CALI,
|
|
+ RT712_DAC_DC_CALI_CTL1, &val);
|
|
+
|
|
+ if (ret < 0)
|
|
+ goto _cali_fail_;
|
|
+ }
|
|
+
|
|
+ if (loop_dc == chk_cnt)
|
|
+ dev_err(dev, "%s, calibration time-out!\n", __func__);
|
|
+ else
|
|
+ dev_dbg(dev, "%s, calibration success!\n", __func__);
|
|
+ }
|
|
|
|
if (loop_dc == chk_cnt || loop_rc == chk_cnt)
|
|
ret = -ETIMEDOUT;
|
|
@@ -1759,9 +1829,13 @@ static void rt712_sdca_va_io_init(struct rt712_sdca_priv *rt712)
|
|
|
|
static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
|
|
{
|
|
- int ret = 0;
|
|
unsigned int jack_func_status, mic_func_status, amp_func_status;
|
|
struct device *dev = &rt712->slave->dev;
|
|
+ unsigned int clk_base;
|
|
+ int ret = 0;
|
|
+
|
|
+ regmap_read(rt712->regmap, RT712_SDW_ROOT_CLK, &clk_base);
|
|
+ dev_dbg(dev, "%s clk_base=%x", __func__, clk_base);
|
|
|
|
regmap_read(rt712->regmap,
|
|
SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0), &jack_func_status);
|
|
@@ -1773,6 +1847,12 @@ static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
|
|
__func__, jack_func_status, mic_func_status, amp_func_status);
|
|
|
|
rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_JD_CTL3, 0x7778);
|
|
+
|
|
+ if (clk_base == RT712_CLK_FREQ_24_576MHZ) {
|
|
+ rt712_sdca_clk_patch(rt712);
|
|
+ rt712_sdca_clk_patch2(rt712);
|
|
+ }
|
|
+
|
|
/* DMIC */
|
|
if ((mic_func_status & FUNCTION_NEEDS_INITIALIZATION) || (!rt712->first_hw_init)) {
|
|
rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_DMIC2_FU_IT_FLOAT_CTL, 0x1526);
|
|
diff --git a/sound/soc/codecs/rt712-sdca.h b/sound/soc/codecs/rt712-sdca.h
|
|
--- a/sound/soc/codecs/rt712-sdca.h
|
|
+++ b/sound/soc/codecs/rt712-sdca.h
|
|
@@ -162,6 +162,16 @@ struct rt712_dmic_kctrl_priv {
|
|
#define RT712_EAPD_HIGH 0x2
|
|
#define RT712_EAPD_LOW 0x0
|
|
|
|
+/* SDW clock root frequency */
|
|
+#define RT712_SDW_ROOT_CLK 0x004d
|
|
+#define RT712_SDW_SCALE_CLK0 0x0062
|
|
+#define RT712_SDW_SCALE_CLK1 0x0072
|
|
+
|
|
+/* PLL2 config */
|
|
+#define RT712_PLL2_CONF1 0x2f3a
|
|
+#define RT712_PLL2_CONF2 0x2f3d
|
|
+#define RT712_PLL2_CONF3 0x2f41
|
|
+
|
|
/* RC Calibration register */
|
|
#define RT712_RC_CAL 0x3201
|
|
|
|
@@ -254,6 +264,14 @@ enum rt712_sdca_version {
|
|
RT712_VB,
|
|
};
|
|
|
|
+enum {
|
|
+ RT712_CLK_FREQ_19_2_MHZ = 1,
|
|
+ RT712_CLK_FREQ_24MHZ = 2,
|
|
+ RT712_CLK_FREQ_24_576MHZ = 3,
|
|
+ RT712_CLK_FREQ_22_5792MHZ = 4,
|
|
+};
|
|
+
|
|
+
|
|
int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave);
|
|
int rt712_sdca_init(struct device *dev, struct regmap *regmap,
|
|
struct regmap *mbq_regmap, struct sdw_slave *slave);
|
|
diff --git a/sound/soc/codecs/rt721-sdca-sdw.c b/sound/soc/codecs/rt721-sdca-sdw.c
|
|
--- a/sound/soc/codecs/rt721-sdca-sdw.c
|
|
+++ b/sound/soc/codecs/rt721-sdca-sdw.c
|
|
@@ -70,6 +70,7 @@ static bool rt721_sdca_mbq_readable_register(struct device *dev, unsigned int re
|
|
case 0x0310100:
|
|
case 0x2000000 ... 0x2000003:
|
|
case 0x2000013:
|
|
+ case 0x2000026:
|
|
case 0x200002c:
|
|
case 0x200003c:
|
|
case 0x2000046:
|
|
@@ -142,6 +143,7 @@ static bool rt721_sdca_mbq_volatile_register(struct device *dev, unsigned int re
|
|
case 0x200000d:
|
|
case 0x2000019:
|
|
case 0x2000020:
|
|
+ case 0x2000026:
|
|
case 0x200002c:
|
|
case 0x2000030:
|
|
case 0x2000046:
|
|
@@ -155,6 +157,7 @@ static bool rt721_sdca_mbq_volatile_register(struct device *dev, unsigned int re
|
|
case 0x5810039:
|
|
case 0x5b10018:
|
|
case 0x5b10019:
|
|
+ case 0x6100006:
|
|
return true;
|
|
default:
|
|
return false;
|
|
diff --git a/sound/soc/codecs/rt721-sdca.c b/sound/soc/codecs/rt721-sdca.c
|
|
--- a/sound/soc/codecs/rt721-sdca.c
|
|
+++ b/sound/soc/codecs/rt721-sdca.c
|
|
@@ -1497,6 +1497,15 @@ int rt721_sdca_init(struct device *dev, struct regmap *regmap,
|
|
&soc_sdca_dev_rt721, rt721_sdca_dai, ARRAY_SIZE(rt721_sdca_dai));
|
|
}
|
|
|
|
+static void rt721_sdca_reset(struct rt721_sdca_priv *rt721)
|
|
+{
|
|
+ rt_sdca_index_update_bits(rt721->mbq_regmap, RT721_VENDOR_REG,
|
|
+ RT721_VD_HIDDEN_CTRL, RT721_HIDDEN_REG_SW_RESET,
|
|
+ RT721_HIDDEN_REG_SW_RESET);
|
|
+ rt_sdca_index_update_bits(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT,
|
|
+ RT721_HDA_LEGACY_RESET_CTL, 0x1, 0x1);
|
|
+}
|
|
+
|
|
int rt721_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
|
{
|
|
struct rt721_sdca_priv *rt721 = dev_get_drvdata(dev);
|
|
@@ -1530,9 +1539,17 @@ int rt721_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
|
}
|
|
|
|
pm_runtime_get_noresume(&slave->dev);
|
|
+
|
|
+ if (!rt721->first_hw_init)
|
|
+ rt721_sdca_reset(rt721);
|
|
+
|
|
rt721_sdca_dmic_preset(rt721);
|
|
rt721_sdca_amp_preset(rt721);
|
|
rt721_sdca_jack_preset(rt721);
|
|
+
|
|
+ if (rt721->hs_jack && (!rt721->first_hw_init))
|
|
+ rt721_sdca_jack_init(rt721);
|
|
+
|
|
if (rt721->first_hw_init) {
|
|
regcache_cache_bypass(rt721->regmap, false);
|
|
regcache_mark_dirty(rt721->regmap);
|
|
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
|
|
--- a/sound/soc/codecs/wm_adsp.c
|
|
+++ b/sound/soc/codecs/wm_adsp.c
|
|
@@ -775,9 +775,12 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
|
|
s++;
|
|
}
|
|
|
|
+ adsp_dbg(dsp, "Try '%s'\n", fw->filename);
|
|
ret = wm_adsp_firmware_request(&fw->firmware, fw->filename, cs_dsp->dev);
|
|
if (ret < 0) {
|
|
- adsp_dbg(dsp, "Failed to request '%s': %d\n", fw->filename, ret);
|
|
+ if (ret != -ENOENT)
|
|
+ adsp_dbg(dsp, "Failed to request '%s': %d\n", fw->filename, ret);
|
|
+
|
|
kfree(fw->filename);
|
|
fw->filename = NULL;
|
|
if (ret != -ENOENT)
|
|
diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
|
|
--- a/sound/soc/intel/boards/sof_es8336.c
|
|
+++ b/sound/soc/intel/boards/sof_es8336.c
|
|
@@ -360,6 +360,15 @@ static const struct dmi_system_id sof_es8336_quirk_table[] = {
|
|
.driver_data = (void *)(SOF_ES8336_HEADPHONE_GPIO |
|
|
SOC_ES8336_HEADSET_MIC1)
|
|
},
|
|
+ {
|
|
+ .callback = sof_es8336_quirk_cb,
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "NDZ-WXX9"),
|
|
+ },
|
|
+ .driver_data = (void *)(SOF_ES8336_HEADPHONE_GPIO |
|
|
+ SOC_ES8336_HEADSET_MIC1)
|
|
+ },
|
|
{}
|
|
};
|
|
|
|
diff --git a/sound/soc/sdw_utils/soc_sdw_cs_amp.c b/sound/soc/sdw_utils/soc_sdw_cs_amp.c
|
|
--- a/sound/soc/sdw_utils/soc_sdw_cs_amp.c
|
|
+++ b/sound/soc/sdw_utils/soc_sdw_cs_amp.c
|
|
@@ -14,7 +14,6 @@
|
|
#include <sound/soc-dai.h>
|
|
#include <sound/soc_sdw_utils.h>
|
|
|
|
-#define CS_AMP_CHANNELS_PER_AMP 4
|
|
#define CS35L56_SPK_VOLUME_0DB 400 /* 0dB Max */
|
|
|
|
int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix)
|
|
@@ -64,51 +63,6 @@ int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai
|
|
}
|
|
EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_rtd_init, "SND_SOC_SDW_UTILS");
|
|
|
|
-int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
|
|
-{
|
|
- const struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
|
- const struct snd_soc_dai_link_ch_map *ch_map;
|
|
- const struct snd_soc_dai_link_component *codec_dlc;
|
|
- struct snd_soc_dai *codec_dai;
|
|
- u8 ch_slot[8] = {};
|
|
- unsigned int amps_per_bus, ch_per_amp, mask;
|
|
- int i, ret;
|
|
-
|
|
- WARN_ON(dai_link->num_cpus > ARRAY_SIZE(ch_slot));
|
|
-
|
|
- /*
|
|
- * CS35L56 has 4 TX channels. When the capture is aggregated the
|
|
- * same bus slots will be allocated to all the amps on a bus. Only
|
|
- * one amp on that bus can be transmitting in each slot so divide
|
|
- * the available 4 slots between all the amps on a bus.
|
|
- */
|
|
- amps_per_bus = dai_link->num_codecs / dai_link->num_cpus;
|
|
- if ((amps_per_bus == 0) || (amps_per_bus > CS_AMP_CHANNELS_PER_AMP)) {
|
|
- dev_err(rtd->card->dev, "Illegal num_codecs:%u / num_cpus:%u\n",
|
|
- dai_link->num_codecs, dai_link->num_cpus);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- ch_per_amp = CS_AMP_CHANNELS_PER_AMP / amps_per_bus;
|
|
-
|
|
- for_each_rtd_ch_maps(rtd, i, ch_map) {
|
|
- codec_dlc = snd_soc_link_to_codec(rtd->dai_link, i);
|
|
- codec_dai = snd_soc_find_dai(codec_dlc);
|
|
- mask = GENMASK(ch_per_amp - 1, 0) << ch_slot[ch_map->cpu];
|
|
-
|
|
- ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, mask, 4, 32);
|
|
- if (ret < 0) {
|
|
- dev_err(rtd->card->dev, "Failed to set TDM slot:%d\n", ret);
|
|
- return ret;
|
|
- }
|
|
-
|
|
- ch_slot[ch_map->cpu] += ch_per_amp;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_feedback_rtd_init, "SND_SOC_SDW_UTILS");
|
|
-
|
|
int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
|
|
struct snd_soc_dai_link *dai_links,
|
|
struct asoc_sdw_codec_info *info,
|
|
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
|
|
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
|
|
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
|
|
@@ -811,7 +811,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
|
.dai_name = "cs35l56-sdw1c",
|
|
.dai_type = SOC_SDW_DAI_TYPE_AMP,
|
|
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
|
|
- .rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
|
|
},
|
|
},
|
|
.dai_num = 2,
|
|
@@ -840,7 +839,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
|
.dai_name = "cs35l56-sdw1c",
|
|
.dai_type = SOC_SDW_DAI_TYPE_AMP,
|
|
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
|
|
- .rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
|
|
},
|
|
},
|
|
.dai_num = 2,
|
|
@@ -869,7 +867,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
|
.dai_name = "cs35l56-sdw1c",
|
|
.dai_type = SOC_SDW_DAI_TYPE_AMP,
|
|
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
|
|
- .rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
|
|
},
|
|
},
|
|
.dai_num = 2,
|
|
@@ -898,7 +895,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
|
.dai_name = "cs35l56-sdw1c",
|
|
.dai_type = SOC_SDW_DAI_TYPE_AMP,
|
|
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
|
|
- .rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
|
|
},
|
|
},
|
|
.dai_num = 2,
|
|
@@ -1565,7 +1561,7 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
|
struct snd_soc_dai_link_ch_map *ch_maps;
|
|
int ch = params_channels(params);
|
|
- unsigned int ch_mask;
|
|
+ unsigned int cpu_ch_mask, codec_ch_mask;
|
|
int num_codecs;
|
|
int step;
|
|
int i;
|
|
@@ -1575,8 +1571,9 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
|
|
/* Identical data will be sent to all codecs in playback */
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
- ch_mask = GENMASK(ch - 1, 0);
|
|
+ cpu_ch_mask = GENMASK(ch - 1, 0);
|
|
step = 0;
|
|
+ codec_ch_mask = 0;
|
|
} else {
|
|
num_codecs = rtd->dai_link->num_codecs;
|
|
|
|
@@ -1586,17 +1583,24 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
|
|
return -EINVAL;
|
|
}
|
|
|
|
- ch_mask = GENMASK(ch / num_codecs - 1, 0);
|
|
- step = hweight_long(ch_mask);
|
|
+ cpu_ch_mask = GENMASK(ch / num_codecs - 1, 0);
|
|
+ step = hweight_long(cpu_ch_mask);
|
|
+ codec_ch_mask = cpu_ch_mask;
|
|
}
|
|
|
|
/*
|
|
* The captured data will be combined from each cpu DAI if the dai
|
|
* link has more than one codec DAIs. Set codec channel mask and
|
|
* ASoC will set the corresponding channel numbers for each cpu dai.
|
|
+ *
|
|
+ * sdw_stream_add_slave() assigns different payload offsets to each
|
|
+ * codec in a capture stream, so that the same channels on each
|
|
+ * codec map to different channels on the CPU.
|
|
*/
|
|
- for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
|
|
- ch_maps->cpu_ch_mask = ch_mask << (i * step);
|
|
+ for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
|
|
+ ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
|
|
+ ch_maps->codec_ch_mask = codec_ch_mask;
|
|
+ }
|
|
|
|
return 0;
|
|
}
|