mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
ASoC: Fixes for v6.7
A crop of fixes for v6.7, one core fix for a merge issue and a bunch of driver specific fixes and new IDs, mostly for x86 platforms. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmVweTwACgkQJNaLcl1U h9BJMgf8CxgAoZ0BVu6Jdzi/ZTL6030unqDcCjI4gNehXa9dDCpxvbAEItNOi6Ta OBQrXGLgf4esYw2jOjs0yO4SGIW3Wtz3EVyWL66wAZhBPzowxXSlDHQC73sgB96d 5zuXXk3juWnr4zn+c/aFT5Q0kNlrcXN20mu2aBPJV4+8lcvEIC15WHQu0fFQ7mHJ mBOPpWpVypihb5Si2M0e0/5UepotWK7fv5U23dT7wbJfvGWoDDRYsnx0Ipw2yYBt gbnOtWlpAkxZo50BdpWrW5QsKx6KFFeYtldRd6gKfXkPefawCk+JGbzLckECA0E7 v9qBHoYmubA/jLPYqou4XTH4S4sITg== =AlC1 -----END PGP SIGNATURE----- Merge tag 'asoc-fix-v6.7-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Fixes for v6.7 A crop of fixes for v6.7, one core fix for a merge issue and a bunch of driver specific fixes and new IDs, mostly for x86 platforms.
This commit is contained in:
commit
fbbc69d2bb
@ -103,6 +103,20 @@ static const struct config_entry config_table[] = {
|
||||
{}
|
||||
},
|
||||
},
|
||||
{
|
||||
.flags = FLAG_AMD_LEGACY,
|
||||
.device = ACP_PCI_DEV_ID,
|
||||
.dmi_table = (const struct dmi_system_id []) {
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "HUAWEI"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HVY-WXX9"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
},
|
||||
},
|
||||
{
|
||||
.flags = FLAG_AMD_LEGACY,
|
||||
.device = ACP_PCI_DEV_ID,
|
||||
|
@ -283,6 +283,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@ -367,6 +374,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8A3E"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8B2F"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@ -381,6 +395,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "pang12"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "System76"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "pang13"),
|
||||
}
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -578,7 +578,7 @@ static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
hi_size = bitwidth_sclk;
|
||||
frm_delay = 2;
|
||||
frm_delay = 0;
|
||||
frm_phase = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
@ -1682,7 +1682,7 @@ static ssize_t hpload_dc_r_show(struct device *dev,
|
||||
return cs43130_show_dc(dev, buf, HP_RIGHT);
|
||||
}
|
||||
|
||||
static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = {
|
||||
static const u16 cs43130_ac_freq[CS43130_AC_FREQ] = {
|
||||
24,
|
||||
43,
|
||||
93,
|
||||
@ -2362,7 +2362,7 @@ static const struct regmap_config cs43130_regmap = {
|
||||
.use_single_write = true,
|
||||
};
|
||||
|
||||
static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
|
||||
static const u16 cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
|
||||
50,
|
||||
120,
|
||||
};
|
||||
|
@ -696,7 +696,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
|
||||
aad_pdata->mic_det_thr =
|
||||
da7219_aad_fw_mic_det_thr(dev, fw_val32);
|
||||
else
|
||||
aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
|
||||
aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_200_OHMS;
|
||||
|
||||
if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
|
||||
aad_pdata->jack_ins_deb =
|
||||
|
@ -132,6 +132,9 @@ static struct snd_soc_dai_driver hdac_hda_dais[] = {
|
||||
.sig_bits = 24,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver hdac_hda_hdmi_dais[] = {
|
||||
{
|
||||
.id = HDAC_HDMI_0_DAI_ID,
|
||||
.name = "intel-hdmi-hifi1",
|
||||
@ -607,8 +610,16 @@ static const struct snd_soc_component_driver hdac_hda_codec = {
|
||||
.endianness = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver hdac_hda_hdmi_codec = {
|
||||
.probe = hdac_hda_codec_probe,
|
||||
.remove = hdac_hda_codec_remove,
|
||||
.idle_bias_on = false,
|
||||
.endianness = 1,
|
||||
};
|
||||
|
||||
static int hdac_hda_dev_probe(struct hdac_device *hdev)
|
||||
{
|
||||
struct hdac_hda_priv *hda_pvt = dev_get_drvdata(&hdev->dev);
|
||||
struct hdac_ext_link *hlink;
|
||||
int ret;
|
||||
|
||||
@ -621,9 +632,15 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev)
|
||||
snd_hdac_ext_bus_link_get(hdev->bus, hlink);
|
||||
|
||||
/* ASoC specific initialization */
|
||||
ret = devm_snd_soc_register_component(&hdev->dev,
|
||||
&hdac_hda_codec, hdac_hda_dais,
|
||||
ARRAY_SIZE(hdac_hda_dais));
|
||||
if (hda_pvt->need_display_power)
|
||||
ret = devm_snd_soc_register_component(&hdev->dev,
|
||||
&hdac_hda_hdmi_codec, hdac_hda_hdmi_dais,
|
||||
ARRAY_SIZE(hdac_hda_hdmi_dais));
|
||||
else
|
||||
ret = devm_snd_soc_register_component(&hdev->dev,
|
||||
&hdac_hda_codec, hdac_hda_dais,
|
||||
ARRAY_SIZE(hdac_hda_dais));
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&hdev->dev, "failed to register HDA codec %d\n", ret);
|
||||
return ret;
|
||||
|
@ -2021,6 +2021,11 @@ static int tx_macro_probe(struct platform_device *pdev)
|
||||
|
||||
tx->dev = dev;
|
||||
|
||||
/* Set active_decimator default value */
|
||||
tx->active_decimator[TX_MACRO_AIF1_CAP] = -1;
|
||||
tx->active_decimator[TX_MACRO_AIF2_CAP] = -1;
|
||||
tx->active_decimator[TX_MACRO_AIF3_CAP] = -1;
|
||||
|
||||
/* set MCLK and NPL rates */
|
||||
clk_set_rate(tx->mclk, MCLK_FREQ);
|
||||
clk_set_rate(tx->npl, MCLK_FREQ);
|
||||
|
@ -184,6 +184,7 @@ static int nau8822_eq_get(struct snd_kcontrol *kcontrol,
|
||||
struct soc_bytes_ext *params = (void *)kcontrol->private_value;
|
||||
int i, reg;
|
||||
u16 reg_val, *val;
|
||||
__be16 tmp;
|
||||
|
||||
val = (u16 *)ucontrol->value.bytes.data;
|
||||
reg = NAU8822_REG_EQ1;
|
||||
@ -192,8 +193,8 @@ static int nau8822_eq_get(struct snd_kcontrol *kcontrol,
|
||||
/* conversion of 16-bit integers between native CPU format
|
||||
* and big endian format
|
||||
*/
|
||||
reg_val = cpu_to_be16(reg_val);
|
||||
memcpy(val + i, ®_val, sizeof(reg_val));
|
||||
tmp = cpu_to_be16(reg_val);
|
||||
memcpy(val + i, &tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -216,6 +217,7 @@ static int nau8822_eq_put(struct snd_kcontrol *kcontrol,
|
||||
void *data;
|
||||
u16 *val, value;
|
||||
int i, reg, ret;
|
||||
__be16 *tmp;
|
||||
|
||||
data = kmemdup(ucontrol->value.bytes.data,
|
||||
params->max, GFP_KERNEL | GFP_DMA);
|
||||
@ -228,7 +230,8 @@ static int nau8822_eq_put(struct snd_kcontrol *kcontrol,
|
||||
/* conversion of 16-bit integers between native CPU format
|
||||
* and big endian format
|
||||
*/
|
||||
value = be16_to_cpu(*(val + i));
|
||||
tmp = (__be16 *)(val + i);
|
||||
value = be16_to_cpup(tmp);
|
||||
ret = snd_soc_component_write(component, reg + i, value);
|
||||
if (ret) {
|
||||
dev_err(component->dev,
|
||||
|
@ -448,6 +448,7 @@ struct rt5645_priv {
|
||||
struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
|
||||
struct rt5645_eq_param_s *eq_param;
|
||||
struct timer_list btn_check_timer;
|
||||
struct mutex jd_mutex;
|
||||
|
||||
int codec_type;
|
||||
int sysclk;
|
||||
@ -3193,6 +3194,8 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
|
||||
rt5645_enable_push_button_irq(component, true);
|
||||
}
|
||||
} else {
|
||||
if (rt5645->en_button_func)
|
||||
rt5645_enable_push_button_irq(component, false);
|
||||
snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
|
||||
snd_soc_dapm_sync(dapm);
|
||||
rt5645->jack_type = SND_JACK_HEADPHONE;
|
||||
@ -3295,6 +3298,8 @@ static void rt5645_jack_detect_work(struct work_struct *work)
|
||||
if (!rt5645->component)
|
||||
return;
|
||||
|
||||
mutex_lock(&rt5645->jd_mutex);
|
||||
|
||||
switch (rt5645->pdata.jd_mode) {
|
||||
case 0: /* Not using rt5645 JD */
|
||||
if (rt5645->gpiod_hp_det) {
|
||||
@ -3321,7 +3326,7 @@ static void rt5645_jack_detect_work(struct work_struct *work)
|
||||
|
||||
if (!val && (rt5645->jack_type == 0)) { /* jack in */
|
||||
report = rt5645_jack_detect(rt5645->component, 1);
|
||||
} else if (!val && rt5645->jack_type != 0) {
|
||||
} else if (!val && rt5645->jack_type == SND_JACK_HEADSET) {
|
||||
/* for push button and jack out */
|
||||
btn_type = 0;
|
||||
if (snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) {
|
||||
@ -3377,6 +3382,8 @@ static void rt5645_jack_detect_work(struct work_struct *work)
|
||||
rt5645_jack_detect(rt5645->component, 0);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt5645->jd_mutex);
|
||||
|
||||
snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE);
|
||||
snd_soc_jack_report(rt5645->mic_jack, report, SND_JACK_MICROPHONE);
|
||||
if (rt5645->en_button_func)
|
||||
@ -4150,6 +4157,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c)
|
||||
}
|
||||
timer_setup(&rt5645->btn_check_timer, rt5645_btn_check_callback, 0);
|
||||
|
||||
mutex_init(&rt5645->jd_mutex);
|
||||
INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
|
||||
INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
|
||||
|
||||
|
@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
|
||||
|
||||
/* Boost mixer */
|
||||
static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
|
||||
SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1),
|
||||
SOC_DAPM_SINGLE("PGA Switch", WM8974_INPPGA, 6, 1, 1),
|
||||
};
|
||||
|
||||
/* Input PGA */
|
||||
@ -246,8 +246,8 @@ static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
|
||||
|
||||
/* Boost Mixer */
|
||||
{"ADC", NULL, "Boost Mixer"},
|
||||
{"Boost Mixer", "Aux Switch", "Aux Input"},
|
||||
{"Boost Mixer", NULL, "Input PGA"},
|
||||
{"Boost Mixer", NULL, "Aux Input"},
|
||||
{"Boost Mixer", "PGA Switch", "Input PGA"},
|
||||
{"Boost Mixer", NULL, "MICP"},
|
||||
|
||||
/* Input PGA */
|
||||
|
@ -1451,12 +1451,12 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
|
||||
ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset,
|
||||
®ion->base_addr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset,
|
||||
&offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
region->cumulative_size = offset;
|
||||
|
||||
@ -1467,6 +1467,10 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
kfree(buf->regions);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf)
|
||||
|
@ -360,6 +360,7 @@ config SND_SOC_IMX_HDMI
|
||||
config SND_SOC_IMX_RPMSG
|
||||
tristate "SoC Audio support for i.MX boards with rpmsg"
|
||||
depends on RPMSG
|
||||
depends on OF && I2C
|
||||
select SND_SOC_IMX_PCM_RPMSG
|
||||
select SND_SOC_IMX_AUDIO_RPMSG
|
||||
help
|
||||
|
@ -673,6 +673,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
|
||||
FSL_SAI_CR3_TRCE_MASK,
|
||||
FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask)));
|
||||
|
||||
/*
|
||||
* When the TERE and FSD_MSTR enabled before configuring the word width
|
||||
* There will be no frame sync clock issue, because word width impact
|
||||
* the generation of frame sync clock.
|
||||
*
|
||||
* TERE enabled earlier only for i.MX8MP case for the hardware limitation,
|
||||
* We need to disable FSD_MSTR before configuring word width, then enable
|
||||
* FSD_MSTR bit for this specific case.
|
||||
*/
|
||||
if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
|
||||
!sai->is_consumer_mode)
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
|
||||
FSL_SAI_CR4_FSD_MSTR, 0);
|
||||
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
|
||||
FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
|
||||
FSL_SAI_CR4_CHMOD_MASK,
|
||||
@ -680,6 +694,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
|
||||
FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
|
||||
FSL_SAI_CR5_FBT_MASK, val_cr5);
|
||||
|
||||
/* Enable FSD_MSTR after configuring word width */
|
||||
if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
|
||||
!sai->is_consumer_mode)
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
|
||||
FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);
|
||||
|
||||
regmap_write(sai->regmap, FSL_SAI_xMR(tx),
|
||||
~0UL - ((1 << min(channels, slots)) - 1));
|
||||
|
||||
|
@ -358,7 +358,7 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq)
|
||||
struct device *dev = &xcvr->pdev->dev;
|
||||
int ret;
|
||||
|
||||
freq = xcvr->soc_data->spdif_only ? freq / 10 : freq;
|
||||
freq = xcvr->soc_data->spdif_only ? freq / 5 : freq;
|
||||
clk_disable_unprepare(xcvr->phy_clk);
|
||||
ret = clk_set_rate(xcvr->phy_clk, freq);
|
||||
if (ret < 0) {
|
||||
@ -409,11 +409,21 @@ static int fsl_xcvr_prepare(struct snd_pcm_substream *substream,
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
u32 m_ctl = 0, v_ctl = 0;
|
||||
u32 r = substream->runtime->rate, ch = substream->runtime->channels;
|
||||
u32 fout = 32 * r * ch * 10 * 2;
|
||||
u32 fout = 32 * r * ch * 10;
|
||||
int ret = 0;
|
||||
|
||||
switch (xcvr->mode) {
|
||||
case FSL_XCVR_MODE_SPDIF:
|
||||
if (xcvr->soc_data->spdif_only && tx) {
|
||||
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_TX_DPTH_CTRL_SET,
|
||||
FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM,
|
||||
FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Failed to set bypass fem: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
fallthrough;
|
||||
case FSL_XCVR_MODE_ARC:
|
||||
if (tx) {
|
||||
ret = fsl_xcvr_en_aud_pll(xcvr, fout);
|
||||
|
@ -154,6 +154,8 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
|
||||
card->dapm_widgets = skl_hda_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets);
|
||||
if (!ctx->idisp_codec) {
|
||||
card->dapm_routes = &skl_hda_map[IDISP_ROUTE_COUNT];
|
||||
num_route -= IDISP_ROUTE_COUNT;
|
||||
for (i = 0; i < IDISP_DAI_COUNT; i++) {
|
||||
skl_hda_be_dai_links[i].codecs = &snd_soc_dummy_dlc;
|
||||
skl_hda_be_dai_links[i].num_codecs = 1;
|
||||
|
@ -1546,7 +1546,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
||||
{
|
||||
struct device *dev = card->dev;
|
||||
struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
|
||||
int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0;
|
||||
int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0;
|
||||
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
|
||||
const struct snd_soc_acpi_link_adr *adr_link = mach_params->links;
|
||||
@ -1564,6 +1564,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
||||
char *codec_name, *codec_dai_name;
|
||||
int i, j, be_id = 0;
|
||||
int codec_index;
|
||||
int hdmi_num;
|
||||
int ret;
|
||||
|
||||
ret = get_dailink_info(dev, adr_link, &sdw_be_num, &codec_conf_num);
|
||||
@ -1584,14 +1585,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
||||
ssp_num = hweight_long(ssp_mask);
|
||||
}
|
||||
|
||||
if (mach_params->codec_mask & IDISP_CODEC_MASK) {
|
||||
if (mach_params->codec_mask & IDISP_CODEC_MASK)
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
|
||||
if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
|
||||
hdmi_num = SOF_TGL_HDMI_COUNT;
|
||||
else
|
||||
hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
|
||||
}
|
||||
if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
|
||||
hdmi_num = SOF_TGL_HDMI_COUNT;
|
||||
else
|
||||
hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
|
||||
|
||||
/* enable dmic01 & dmic16k */
|
||||
if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num)
|
||||
@ -1601,7 +1601,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
||||
bt_num = 1;
|
||||
|
||||
dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n",
|
||||
sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num);
|
||||
sdw_be_num, ssp_num, dmic_num,
|
||||
ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
|
||||
|
||||
/* allocate BE dailinks */
|
||||
num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num;
|
||||
|
@ -240,8 +240,10 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
|
||||
snd_pcm_set_sync(substream);
|
||||
|
||||
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
|
||||
if (!mconfig)
|
||||
if (!mconfig) {
|
||||
kfree(dma_params);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
skl_tplg_d0i3_get(skl, mconfig->d0i3_caps);
|
||||
|
||||
@ -1462,6 +1464,7 @@ int skl_platform_register(struct device *dev)
|
||||
dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
|
||||
sizeof(skl_platform_dai), GFP_KERNEL);
|
||||
if (!dais) {
|
||||
kfree(skl->dais);
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@ -1474,8 +1477,10 @@ int skl_platform_register(struct device *dev)
|
||||
|
||||
ret = devm_snd_soc_register_component(dev, &skl_component,
|
||||
skl->dais, num_dais);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
kfree(skl->dais);
|
||||
dev_err(dev, "soc component registration failed %d\n", ret);
|
||||
}
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1003,8 +1003,10 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
|
||||
|
||||
reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
|
||||
buf = krealloc(reply.data, reply.size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
if (!buf) {
|
||||
kfree(reply.data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
*payload = buf;
|
||||
*bytes = reply.size;
|
||||
|
||||
|
@ -27,6 +27,23 @@ struct sc8280xp_snd_data {
|
||||
static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
|
||||
switch (cpu_dai->id) {
|
||||
case WSA_CODEC_DMA_RX_0:
|
||||
case WSA_CODEC_DMA_RX_1:
|
||||
/*
|
||||
* set limit of 0dB on Digital Volume for Speakers,
|
||||
* this can prevent damage of speakers to some extent without
|
||||
* active speaker protection
|
||||
*/
|
||||
snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 84);
|
||||
snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 84);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
|
||||
}
|
||||
|
@ -661,7 +661,7 @@ int snd_soc_limit_volume(struct snd_soc_card *card,
|
||||
kctl = snd_soc_card_get_kcontrol(card, name);
|
||||
if (kctl) {
|
||||
struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
|
||||
if (max <= mc->max) {
|
||||
if (max <= mc->max - mc->min) {
|
||||
mc->platform_max = max;
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -704,11 +704,6 @@ static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd,
|
||||
if (snd_soc_dai_active(dai) == 0 &&
|
||||
(dai->rate || dai->channels || dai->sample_bits))
|
||||
soc_pcm_set_dai_params(dai, NULL);
|
||||
|
||||
if (snd_soc_dai_stream_active(dai, substream->stream) == 0) {
|
||||
if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger)
|
||||
snd_soc_dai_digital_mute(dai, 1, substream->stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -947,8 +942,10 @@ static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd,
|
||||
if (snd_soc_dai_active(dai) == 1)
|
||||
soc_pcm_set_dai_params(dai, NULL);
|
||||
|
||||
if (snd_soc_dai_stream_active(dai, substream->stream) == 1)
|
||||
snd_soc_dai_digital_mute(dai, 1, substream->stream);
|
||||
if (snd_soc_dai_stream_active(dai, substream->stream) == 1) {
|
||||
if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger)
|
||||
snd_soc_dai_digital_mute(dai, 1, substream->stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* run the stream event */
|
||||
|
@ -493,6 +493,7 @@ static int sof_ipc3_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
|
||||
static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
|
||||
{
|
||||
struct snd_soc_component *scomp = swidget->scomp;
|
||||
struct snd_sof_pipeline *spipe = swidget->spipe;
|
||||
struct sof_ipc_pipe_new *pipeline;
|
||||
struct snd_sof_widget *comp_swidget;
|
||||
int ret;
|
||||
@ -545,6 +546,7 @@ static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
|
||||
swidget->dynamic_pipeline_widget);
|
||||
|
||||
swidget->core = pipeline->core;
|
||||
spipe->core_mask |= BIT(pipeline->core);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -89,7 +89,7 @@ sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidge
|
||||
struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
|
||||
struct sof_ipc4_gain *gain = swidget->private;
|
||||
struct sof_ipc4_msg *msg = &cdata->msg;
|
||||
struct sof_ipc4_gain_data data;
|
||||
struct sof_ipc4_gain_params params;
|
||||
bool all_channels_equal = true;
|
||||
u32 value;
|
||||
int ret, i;
|
||||
@ -109,20 +109,20 @@ sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidge
|
||||
*/
|
||||
for (i = 0; i < scontrol->num_channels; i++) {
|
||||
if (all_channels_equal) {
|
||||
data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
|
||||
data.init_val = cdata->chanv[0].value;
|
||||
params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
|
||||
params.init_val = cdata->chanv[0].value;
|
||||
} else {
|
||||
data.channels = cdata->chanv[i].channel;
|
||||
data.init_val = cdata->chanv[i].value;
|
||||
params.channels = cdata->chanv[i].channel;
|
||||
params.init_val = cdata->chanv[i].value;
|
||||
}
|
||||
|
||||
/* set curve type and duration from topology */
|
||||
data.curve_duration_l = gain->data.curve_duration_l;
|
||||
data.curve_duration_h = gain->data.curve_duration_h;
|
||||
data.curve_type = gain->data.curve_type;
|
||||
params.curve_duration_l = gain->data.params.curve_duration_l;
|
||||
params.curve_duration_h = gain->data.params.curve_duration_h;
|
||||
params.curve_type = gain->data.params.curve_type;
|
||||
|
||||
msg->data_ptr = &data;
|
||||
msg->data_size = sizeof(data);
|
||||
msg->data_ptr = ¶ms;
|
||||
msg->data_size = sizeof(params);
|
||||
|
||||
ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock);
|
||||
msg->data_ptr = NULL;
|
||||
|
@ -130,18 +130,18 @@ static const struct sof_topology_token comp_ext_tokens[] = {
|
||||
|
||||
static const struct sof_topology_token gain_tokens[] = {
|
||||
{SOF_TKN_GAIN_RAMP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
|
||||
get_token_u32, offsetof(struct sof_ipc4_gain_data, curve_type)},
|
||||
get_token_u32, offsetof(struct sof_ipc4_gain_params, curve_type)},
|
||||
{SOF_TKN_GAIN_RAMP_DURATION,
|
||||
SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
|
||||
offsetof(struct sof_ipc4_gain_data, curve_duration_l)},
|
||||
offsetof(struct sof_ipc4_gain_params, curve_duration_l)},
|
||||
{SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD,
|
||||
get_token_u32, offsetof(struct sof_ipc4_gain_data, init_val)},
|
||||
get_token_u32, offsetof(struct sof_ipc4_gain_params, init_val)},
|
||||
};
|
||||
|
||||
/* SRC */
|
||||
static const struct sof_topology_token src_tokens[] = {
|
||||
{SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
|
||||
offsetof(struct sof_ipc4_src, sink_rate)},
|
||||
offsetof(struct sof_ipc4_src_data, sink_rate)},
|
||||
};
|
||||
|
||||
static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = {
|
||||
@ -656,6 +656,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
|
||||
{
|
||||
struct snd_soc_component *scomp = swidget->scomp;
|
||||
struct sof_ipc4_pipeline *pipeline;
|
||||
struct snd_sof_pipeline *spipe = swidget->spipe;
|
||||
int ret;
|
||||
|
||||
pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
|
||||
@ -670,6 +671,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
|
||||
}
|
||||
|
||||
swidget->core = pipeline->core_id;
|
||||
spipe->core_mask |= BIT(pipeline->core_id);
|
||||
|
||||
if (pipeline->use_chain_dma) {
|
||||
dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name);
|
||||
@ -718,15 +720,15 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
|
||||
|
||||
swidget->private = gain;
|
||||
|
||||
gain->data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
|
||||
gain->data.init_val = SOF_IPC4_VOL_ZERO_DB;
|
||||
gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
|
||||
gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB;
|
||||
|
||||
ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->base_config);
|
||||
ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = sof_update_ipc_object(scomp, &gain->data, SOF_GAIN_TOKENS, swidget->tuples,
|
||||
swidget->num_tuples, sizeof(gain->data), 1);
|
||||
ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS,
|
||||
swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1);
|
||||
if (ret) {
|
||||
dev_err(scomp->dev, "Parsing gain tokens failed\n");
|
||||
goto err;
|
||||
@ -734,8 +736,8 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
|
||||
|
||||
dev_dbg(scomp->dev,
|
||||
"pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x\n",
|
||||
swidget->widget->name, gain->data.curve_type, gain->data.curve_duration_l,
|
||||
gain->data.init_val);
|
||||
swidget->widget->name, gain->data.params.curve_type,
|
||||
gain->data.params.curve_duration_l, gain->data.params.init_val);
|
||||
|
||||
ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg);
|
||||
if (ret)
|
||||
@ -797,6 +799,7 @@ err:
|
||||
static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
|
||||
{
|
||||
struct snd_soc_component *scomp = swidget->scomp;
|
||||
struct snd_sof_pipeline *spipe = swidget->spipe;
|
||||
struct sof_ipc4_src *src;
|
||||
int ret;
|
||||
|
||||
@ -808,18 +811,21 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
|
||||
|
||||
swidget->private = src;
|
||||
|
||||
ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, &src->base_config);
|
||||
ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt,
|
||||
&src->data.base_config);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = sof_update_ipc_object(scomp, src, SOF_SRC_TOKENS, swidget->tuples,
|
||||
ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples,
|
||||
swidget->num_tuples, sizeof(*src), 1);
|
||||
if (ret) {
|
||||
dev_err(scomp->dev, "Parsing SRC tokens failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev_dbg(scomp->dev, "SRC sink rate %d\n", src->sink_rate);
|
||||
spipe->core_mask |= BIT(swidget->core);
|
||||
|
||||
dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate);
|
||||
|
||||
ret = sof_ipc4_widget_setup_msg(swidget, &src->msg);
|
||||
if (ret)
|
||||
@ -864,6 +870,7 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
|
||||
{
|
||||
struct snd_soc_component *scomp = swidget->scomp;
|
||||
struct sof_ipc4_fw_module *fw_module;
|
||||
struct snd_sof_pipeline *spipe = swidget->spipe;
|
||||
struct sof_ipc4_process *process;
|
||||
void *cfg;
|
||||
int ret;
|
||||
@ -920,6 +927,9 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
|
||||
|
||||
sof_ipc4_widget_update_kcontrol_module_id(swidget);
|
||||
|
||||
/* set pipeline core mask to keep track of the core the module is scheduled to run on */
|
||||
spipe->core_mask |= BIT(swidget->core);
|
||||
|
||||
return 0;
|
||||
free_base_cfg_ext:
|
||||
kfree(process->base_config_ext);
|
||||
@ -1816,7 +1826,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
|
||||
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
|
||||
int ret;
|
||||
|
||||
ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->base_config,
|
||||
ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config,
|
||||
pipeline_params, available_fmt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1826,7 +1836,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
|
||||
out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
|
||||
out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
|
||||
|
||||
ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt,
|
||||
ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt,
|
||||
out_ref_rate, out_ref_channels, out_ref_valid_bits);
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev, "Failed to initialize output format for %s",
|
||||
@ -1835,7 +1845,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
|
||||
}
|
||||
|
||||
/* update pipeline memory usage */
|
||||
sof_ipc4_update_resource_usage(sdev, swidget, &gain->base_config);
|
||||
sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1891,7 +1901,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
|
||||
u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
|
||||
int output_format_index, input_format_index;
|
||||
|
||||
input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->base_config,
|
||||
input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config,
|
||||
pipeline_params, available_fmt);
|
||||
if (input_format_index < 0)
|
||||
return input_format_index;
|
||||
@ -1921,7 +1931,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
|
||||
*/
|
||||
out_ref_rate = params_rate(fe_params);
|
||||
|
||||
output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->base_config,
|
||||
output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config,
|
||||
available_fmt, out_ref_rate,
|
||||
out_ref_channels, out_ref_valid_bits);
|
||||
if (output_format_index < 0) {
|
||||
@ -1931,10 +1941,10 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
|
||||
}
|
||||
|
||||
/* update pipeline memory usage */
|
||||
sof_ipc4_update_resource_usage(sdev, swidget, &src->base_config);
|
||||
sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config);
|
||||
|
||||
out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt;
|
||||
src->sink_rate = out_audio_fmt->sampling_frequency;
|
||||
src->data.sink_rate = out_audio_fmt->sampling_frequency;
|
||||
|
||||
/* update pipeline_params for sink widgets */
|
||||
return sof_ipc4_update_hw_params(sdev, pipeline_params, out_audio_fmt);
|
||||
@ -2314,9 +2324,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
|
||||
{
|
||||
struct sof_ipc4_gain *gain = swidget->private;
|
||||
|
||||
ipc_size = sizeof(struct sof_ipc4_base_module_cfg) +
|
||||
sizeof(struct sof_ipc4_gain_data);
|
||||
ipc_data = gain;
|
||||
ipc_size = sizeof(gain->data);
|
||||
ipc_data = &gain->data;
|
||||
|
||||
msg = &gain->msg;
|
||||
break;
|
||||
@ -2335,8 +2344,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
|
||||
{
|
||||
struct sof_ipc4_src *src = swidget->private;
|
||||
|
||||
ipc_size = sizeof(struct sof_ipc4_base_module_cfg) + sizeof(src->sink_rate);
|
||||
ipc_data = src;
|
||||
ipc_size = sizeof(src->data);
|
||||
ipc_data = &src->data;
|
||||
|
||||
msg = &src->msg;
|
||||
break;
|
||||
|
@ -361,7 +361,7 @@ struct sof_ipc4_control_msg_payload {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_gain_data - IPC gain blob
|
||||
* struct sof_ipc4_gain_params - IPC gain parameters
|
||||
* @channels: Channels
|
||||
* @init_val: Initial value
|
||||
* @curve_type: Curve type
|
||||
@ -369,24 +369,32 @@ struct sof_ipc4_control_msg_payload {
|
||||
* @curve_duration_l: Curve duration low part
|
||||
* @curve_duration_h: Curve duration high part
|
||||
*/
|
||||
struct sof_ipc4_gain_data {
|
||||
struct sof_ipc4_gain_params {
|
||||
uint32_t channels;
|
||||
uint32_t init_val;
|
||||
uint32_t curve_type;
|
||||
uint32_t reserved;
|
||||
uint32_t curve_duration_l;
|
||||
uint32_t curve_duration_h;
|
||||
} __aligned(8);
|
||||
} __packed __aligned(4);
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_gain_data - IPC gain init blob
|
||||
* @base_config: IPC base config data
|
||||
* @params: Initial parameters for the gain module
|
||||
*/
|
||||
struct sof_ipc4_gain_data {
|
||||
struct sof_ipc4_base_module_cfg base_config;
|
||||
struct sof_ipc4_gain_params params;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_gain - gain config data
|
||||
* @base_config: IPC base config data
|
||||
* @data: IPC gain blob
|
||||
* @available_fmt: Available audio format
|
||||
* @msg: message structure for gain
|
||||
*/
|
||||
struct sof_ipc4_gain {
|
||||
struct sof_ipc4_base_module_cfg base_config;
|
||||
struct sof_ipc4_gain_data data;
|
||||
struct sof_ipc4_available_audio_format available_fmt;
|
||||
struct sof_ipc4_msg msg;
|
||||
@ -404,16 +412,24 @@ struct sof_ipc4_mixer {
|
||||
struct sof_ipc4_msg msg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_src SRC config data
|
||||
/*
|
||||
* struct sof_ipc4_src_data - IPC data for SRC
|
||||
* @base_config: IPC base config data
|
||||
* @sink_rate: Output rate for sink module
|
||||
*/
|
||||
struct sof_ipc4_src_data {
|
||||
struct sof_ipc4_base_module_cfg base_config;
|
||||
uint32_t sink_rate;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_src - SRC config data
|
||||
* @data: IPC base config data
|
||||
* @available_fmt: Available audio format
|
||||
* @msg: IPC4 message struct containing header and data info
|
||||
*/
|
||||
struct sof_ipc4_src {
|
||||
struct sof_ipc4_base_module_cfg base_config;
|
||||
uint32_t sink_rate;
|
||||
struct sof_ipc4_src_data data;
|
||||
struct sof_ipc4_available_audio_format available_fmt;
|
||||
struct sof_ipc4_msg msg;
|
||||
};
|
||||
|
@ -597,6 +597,9 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = {
|
||||
|
||||
static struct snd_sof_of_mach sof_mt8186_machs[] = {
|
||||
{
|
||||
.compatible = "google,steelix",
|
||||
.sof_tplg_filename = "sof-mt8186-google-steelix.tplg"
|
||||
}, {
|
||||
.compatible = "mediatek,mt8186",
|
||||
.sof_tplg_filename = "sof-mt8186.tplg",
|
||||
},
|
||||
|
@ -46,6 +46,7 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
|
||||
struct snd_sof_widget *swidget)
|
||||
{
|
||||
const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
|
||||
struct snd_sof_pipeline *spipe = swidget->spipe;
|
||||
struct snd_sof_widget *pipe_widget;
|
||||
int err = 0;
|
||||
int ret;
|
||||
@ -87,15 +88,22 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
|
||||
}
|
||||
|
||||
/*
|
||||
* disable widget core. continue to route setup status and complete flag
|
||||
* even if this fails and return the appropriate error
|
||||
* decrement ref count for cores associated with all modules in the pipeline and clear
|
||||
* the complete flag
|
||||
*/
|
||||
ret = snd_sof_dsp_core_put(sdev, swidget->core);
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev, "error: failed to disable target core: %d for widget %s\n",
|
||||
swidget->core, swidget->widget->name);
|
||||
if (!err)
|
||||
err = ret;
|
||||
if (swidget->id == snd_soc_dapm_scheduler) {
|
||||
int i;
|
||||
|
||||
for_each_set_bit(i, &spipe->core_mask, sdev->num_cores) {
|
||||
ret = snd_sof_dsp_core_put(sdev, i);
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev, "failed to disable target core: %d for pipeline %s\n",
|
||||
i, swidget->widget->name);
|
||||
if (!err)
|
||||
err = ret;
|
||||
}
|
||||
}
|
||||
swidget->spipe->complete = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -108,10 +116,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
|
||||
err = ret;
|
||||
}
|
||||
|
||||
/* clear pipeline complete */
|
||||
if (swidget->id == snd_soc_dapm_scheduler)
|
||||
swidget->spipe->complete = 0;
|
||||
|
||||
if (!err)
|
||||
dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name);
|
||||
|
||||
@ -134,8 +138,10 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
|
||||
struct snd_sof_widget *swidget)
|
||||
{
|
||||
const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
|
||||
struct snd_sof_pipeline *spipe = swidget->spipe;
|
||||
bool use_count_decremented = false;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* skip if there is no private data */
|
||||
if (!swidget->private)
|
||||
@ -166,19 +172,23 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
|
||||
goto use_count_dec;
|
||||
}
|
||||
|
||||
/* enable widget core */
|
||||
ret = snd_sof_dsp_core_get(sdev, swidget->core);
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev, "error: failed to enable target core for widget %s\n",
|
||||
swidget->widget->name);
|
||||
goto pipe_widget_free;
|
||||
/* update ref count for cores associated with all modules in the pipeline */
|
||||
if (swidget->id == snd_soc_dapm_scheduler) {
|
||||
for_each_set_bit(i, &spipe->core_mask, sdev->num_cores) {
|
||||
ret = snd_sof_dsp_core_get(sdev, i);
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev, "failed to enable target core %d for pipeline %s\n",
|
||||
i, swidget->widget->name);
|
||||
goto pipe_widget_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* setup widget in the DSP */
|
||||
if (tplg_ops && tplg_ops->widget_setup) {
|
||||
ret = tplg_ops->widget_setup(sdev, swidget);
|
||||
if (ret < 0)
|
||||
goto core_put;
|
||||
goto pipe_widget_free;
|
||||
}
|
||||
|
||||
/* send config for DAI components */
|
||||
@ -208,15 +218,22 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
|
||||
return 0;
|
||||
|
||||
widget_free:
|
||||
/* widget use_count and core ref_count will both be decremented by sof_widget_free() */
|
||||
/* widget use_count will be decremented by sof_widget_free() */
|
||||
sof_widget_free_unlocked(sdev, swidget);
|
||||
use_count_decremented = true;
|
||||
core_put:
|
||||
if (!use_count_decremented)
|
||||
snd_sof_dsp_core_put(sdev, swidget->core);
|
||||
pipe_widget_free:
|
||||
if (swidget->id != snd_soc_dapm_scheduler)
|
||||
if (swidget->id != snd_soc_dapm_scheduler) {
|
||||
sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget);
|
||||
} else {
|
||||
int j;
|
||||
|
||||
/* decrement ref count for all cores that were updated previously */
|
||||
for_each_set_bit(j, &spipe->core_mask, sdev->num_cores) {
|
||||
if (j >= i)
|
||||
break;
|
||||
snd_sof_dsp_core_put(sdev, j);
|
||||
}
|
||||
}
|
||||
use_count_dec:
|
||||
if (!use_count_decremented)
|
||||
swidget->use_count--;
|
||||
|
@ -480,6 +480,7 @@ struct snd_sof_widget {
|
||||
* @paused_count: Count of number of PCM's that have started and have currently paused this
|
||||
pipeline
|
||||
* @complete: flag used to indicate that pipeline set up is complete.
|
||||
* @core_mask: Mask containing target cores for all modules in the pipeline
|
||||
* @list: List item in sdev pipeline_list
|
||||
*/
|
||||
struct snd_sof_pipeline {
|
||||
@ -487,6 +488,7 @@ struct snd_sof_pipeline {
|
||||
int started_count;
|
||||
int paused_count;
|
||||
int complete;
|
||||
unsigned long core_mask;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
|
@ -1736,8 +1736,10 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
|
||||
/* perform pcm set op */
|
||||
if (ipc_pcm_ops && ipc_pcm_ops->pcm_setup) {
|
||||
ret = ipc_pcm_ops->pcm_setup(sdev, spcm);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
kfree(spcm);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dai_drv->dobj.private = spcm;
|
||||
|
Loading…
Reference in New Issue
Block a user