Commit 2a28a8b3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-6.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "The majority of changes here are various fixes for Intel drivers,
  and there is a change in ASoC PCM core for the format constraints.

  In addition, a workaround for HD-audio HDMI regressions and usual
  HD-audio quirks are found"

* tag 'sound-6.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/hdmi: Preserve the previous PCM device upon re-enablement
  ALSA: hda/realtek: Add quirk for Clevo X370SNW
  ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
  ASoC: SOF: avoid a NULL dereference with unsupported widgets
  ASoC: da7213.c: add missing pm_runtime_disable()
  ASoC: hdac_hdmi: use set_stream() instead of set_tdm_slots()
  ASoC: codecs: lpass: fix the order or clks turn off during suspend
  ASoC: Intel: bytcr_rt5640: Add quirk for the Acer Iconia One 7 B1-750
  ASoC: SOF: ipc4: Ensure DSP is in D0I0 during sof_ipc4_set_get_data()
  ASoC: amd: yc: Add DMI entries to support Victus by HP Laptop 16-e1xxx (8A22)
  ASoC: soc-pcm: fix hw->formats cleared by soc_pcm_hw_init() for dpcm
  ASoC: Intel: soc-acpi: add table for Intel 'Rooks County' NUC M15
  ASOC: Intel: sof_sdw: add quirk for Intel 'Rooks County' NUC M15
parents 8dfab523 f785f5ee
...@@ -81,6 +81,7 @@ struct hdmi_spec_per_pin { ...@@ -81,6 +81,7 @@ struct hdmi_spec_per_pin {
struct delayed_work work; struct delayed_work work;
struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/ struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */ int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
int prev_pcm_idx; /* previously assigned pcm index */
int repoll_count; int repoll_count;
bool setup; /* the stream has been set up by prepare callback */ bool setup; /* the stream has been set up by prepare callback */
bool silent_stream; bool silent_stream;
...@@ -1380,9 +1381,17 @@ static void hdmi_attach_hda_pcm(struct hdmi_spec *spec, ...@@ -1380,9 +1381,17 @@ static void hdmi_attach_hda_pcm(struct hdmi_spec *spec,
/* pcm already be attached to the pin */ /* pcm already be attached to the pin */
if (per_pin->pcm) if (per_pin->pcm)
return; return;
/* try the previously used slot at first */
idx = per_pin->prev_pcm_idx;
if (idx >= 0) {
if (!test_bit(idx, &spec->pcm_bitmap))
goto found;
per_pin->prev_pcm_idx = -1; /* no longer valid, clear it */
}
idx = hdmi_find_pcm_slot(spec, per_pin); idx = hdmi_find_pcm_slot(spec, per_pin);
if (idx == -EBUSY) if (idx == -EBUSY)
return; return;
found:
per_pin->pcm_idx = idx; per_pin->pcm_idx = idx;
per_pin->pcm = get_hdmi_pcm(spec, idx); per_pin->pcm = get_hdmi_pcm(spec, idx);
set_bit(idx, &spec->pcm_bitmap); set_bit(idx, &spec->pcm_bitmap);
...@@ -1398,6 +1407,7 @@ static void hdmi_detach_hda_pcm(struct hdmi_spec *spec, ...@@ -1398,6 +1407,7 @@ static void hdmi_detach_hda_pcm(struct hdmi_spec *spec,
return; return;
idx = per_pin->pcm_idx; idx = per_pin->pcm_idx;
per_pin->pcm_idx = -1; per_pin->pcm_idx = -1;
per_pin->prev_pcm_idx = idx; /* remember the previous index */
per_pin->pcm = NULL; per_pin->pcm = NULL;
if (idx >= 0 && idx < spec->pcm_used) if (idx >= 0 && idx < spec->pcm_used)
clear_bit(idx, &spec->pcm_bitmap); clear_bit(idx, &spec->pcm_bitmap);
...@@ -1924,6 +1934,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) ...@@ -1924,6 +1934,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
per_pin->pcm = NULL; per_pin->pcm = NULL;
per_pin->pcm_idx = -1; per_pin->pcm_idx = -1;
per_pin->prev_pcm_idx = -1;
per_pin->pin_nid = pin_nid; per_pin->pin_nid = pin_nid;
per_pin->pin_nid_idx = spec->num_nids; per_pin->pin_nid_idx = spec->num_nids;
per_pin->dev_id = i; per_pin->dev_id = i;
......
...@@ -2624,6 +2624,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ...@@ -2624,6 +2624,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
SND_PCI_QUIRK(0x1558, 0x3702, "Clevo X370SN[VW]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
...@@ -9443,6 +9444,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -9443,6 +9444,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8b66, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8b7a, "HP", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8b7a, "HP", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8b7d, "HP", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8b7d, "HP", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8b87, "HP", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8b87, "HP", ALC236_FIXUP_HP_GPIO_LED),
......
...@@ -269,6 +269,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -269,6 +269,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "8A43"), DMI_MATCH(DMI_BOARD_NAME, "8A43"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
DMI_MATCH(DMI_BOARD_NAME, "8A22"),
}
},
{} {}
}; };
......
...@@ -2022,6 +2022,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c) ...@@ -2022,6 +2022,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c)
return ret; return ret;
} }
static void da7213_i2c_remove(struct i2c_client *i2c)
{
pm_runtime_disable(&i2c->dev);
}
static int __maybe_unused da7213_runtime_suspend(struct device *dev) static int __maybe_unused da7213_runtime_suspend(struct device *dev)
{ {
struct da7213_priv *da7213 = dev_get_drvdata(dev); struct da7213_priv *da7213 = dev_get_drvdata(dev);
...@@ -2065,6 +2070,7 @@ static struct i2c_driver da7213_i2c_driver = { ...@@ -2065,6 +2070,7 @@ static struct i2c_driver da7213_i2c_driver = {
.pm = &da7213_pm, .pm = &da7213_pm,
}, },
.probe_new = da7213_i2c_probe, .probe_new = da7213_i2c_probe,
.remove = da7213_i2c_remove,
.id_table = da7213_i2c_id, .id_table = da7213_i2c_id,
}; };
......
...@@ -436,23 +436,28 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_device *hdev, ...@@ -436,23 +436,28 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_device *hdev,
return 0; return 0;
} }
static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai, static int hdac_hdmi_set_stream(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, void *stream, int direction)
int slots, int slot_width)
{ {
struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai); struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
struct hdac_device *hdev = hdmi->hdev; struct hdac_device *hdev = hdmi->hdev;
struct hdac_hdmi_dai_port_map *dai_map; struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_pcm *pcm; struct hdac_hdmi_pcm *pcm;
struct hdac_stream *hstream;
dev_dbg(&hdev->dev, "%s: strm_tag: %d\n", __func__, tx_mask); if (!stream)
return -EINVAL;
hstream = (struct hdac_stream *)stream;
dev_dbg(&hdev->dev, "%s: strm_tag: %d\n", __func__, hstream->stream_tag);
dai_map = &hdmi->dai_map[dai->id]; dai_map = &hdmi->dai_map[dai->id];
pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt); pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
if (pcm) if (pcm)
pcm->stream_tag = (tx_mask << 4); pcm->stream_tag = (hstream->stream_tag << 4);
return 0; return 0;
} }
...@@ -1544,7 +1549,7 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { ...@@ -1544,7 +1549,7 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
.startup = hdac_hdmi_pcm_open, .startup = hdac_hdmi_pcm_open,
.shutdown = hdac_hdmi_pcm_close, .shutdown = hdac_hdmi_pcm_close,
.hw_params = hdac_hdmi_set_hw_params, .hw_params = hdac_hdmi_set_hw_params,
.set_tdm_slot = hdac_hdmi_set_tdm_slot, .set_stream = hdac_hdmi_set_stream,
}; };
/* /*
......
...@@ -3670,9 +3670,9 @@ static int __maybe_unused rx_macro_runtime_suspend(struct device *dev) ...@@ -3670,9 +3670,9 @@ static int __maybe_unused rx_macro_runtime_suspend(struct device *dev)
regcache_cache_only(rx->regmap, true); regcache_cache_only(rx->regmap, true);
regcache_mark_dirty(rx->regmap); regcache_mark_dirty(rx->regmap);
clk_disable_unprepare(rx->mclk);
clk_disable_unprepare(rx->npl);
clk_disable_unprepare(rx->fsgen); clk_disable_unprepare(rx->fsgen);
clk_disable_unprepare(rx->npl);
clk_disable_unprepare(rx->mclk);
return 0; return 0;
} }
......
...@@ -2098,9 +2098,9 @@ static int __maybe_unused tx_macro_runtime_suspend(struct device *dev) ...@@ -2098,9 +2098,9 @@ static int __maybe_unused tx_macro_runtime_suspend(struct device *dev)
regcache_cache_only(tx->regmap, true); regcache_cache_only(tx->regmap, true);
regcache_mark_dirty(tx->regmap); regcache_mark_dirty(tx->regmap);
clk_disable_unprepare(tx->mclk);
clk_disable_unprepare(tx->npl);
clk_disable_unprepare(tx->fsgen); clk_disable_unprepare(tx->fsgen);
clk_disable_unprepare(tx->npl);
clk_disable_unprepare(tx->mclk);
return 0; return 0;
} }
......
...@@ -2506,9 +2506,9 @@ static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev) ...@@ -2506,9 +2506,9 @@ static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev)
regcache_cache_only(wsa->regmap, true); regcache_cache_only(wsa->regmap, true);
regcache_mark_dirty(wsa->regmap); regcache_mark_dirty(wsa->regmap);
clk_disable_unprepare(wsa->mclk);
clk_disable_unprepare(wsa->npl);
clk_disable_unprepare(wsa->fsgen); clk_disable_unprepare(wsa->fsgen);
clk_disable_unprepare(wsa->npl);
clk_disable_unprepare(wsa->mclk);
return 0; return 0;
} }
......
...@@ -533,6 +533,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, ...@@ -533,6 +533,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
/* Please keep this list alphabetically sorted */ /* Please keep this list alphabetically sorted */
static const struct dmi_system_id byt_rt5640_quirk_table[] = { static const struct dmi_system_id byt_rt5640_quirk_table[] = {
{ /* Acer Iconia One 7 B1-750 */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
},
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
BYT_RT5640_JD_SRC_JD1_IN4P |
BYT_RT5640_OVCD_TH_1500UA |
BYT_RT5640_OVCD_SF_0P75 |
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN),
},
{ /* Acer Iconia Tab 8 W1-810 */ { /* Acer Iconia Tab 8 W1-810 */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
......
...@@ -213,6 +213,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { ...@@ -213,6 +213,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
SOF_SDW_PCH_DMIC | SOF_SDW_PCH_DMIC |
RT711_JD1), RT711_JD1),
}, },
{
/* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_SDW_PCH_DMIC |
RT711_JD2_100K),
},
/* TigerLake-SDCA devices */ /* TigerLake-SDCA devices */
{ {
.callback = sof_sdw_quirk_cb, .callback = sof_sdw_quirk_cb,
......
...@@ -354,6 +354,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link3[] = { ...@@ -354,6 +354,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link3[] = {
{} {}
}; };
static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link2[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
.adr_d = rt711_sdca_0_adr,
},
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(rt1316_2_single_adr),
.adr_d = rt1316_2_single_adr,
},
{}
};
static const struct snd_soc_acpi_adr_device mx8373_2_adr[] = { static const struct snd_soc_acpi_adr_device mx8373_2_adr[] = {
{ {
.adr = 0x000223019F837300ull, .adr = 0x000223019F837300ull,
...@@ -624,6 +638,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { ...@@ -624,6 +638,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
.drv_name = "sof_sdw", .drv_name = "sof_sdw",
.sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l3.tplg", .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l3.tplg",
}, },
{
.link_mask = 0x5, /* 2 active links required */
.links = adl_sdw_rt711_link0_rt1316_link2,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l2.tplg",
},
{ {
.link_mask = 0x1, /* link0 required */ .link_mask = 0x1, /* link0 required */
.links = adl_rvp, .links = adl_rvp,
......
...@@ -1661,10 +1661,14 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream) ...@@ -1661,10 +1661,14 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
struct snd_pcm_hardware *hw = &runtime->hw; struct snd_pcm_hardware *hw = &runtime->hw;
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
int stream = substream->stream; int stream = substream->stream;
u64 formats = hw->formats;
int i; int i;
soc_pcm_hw_init(hw); soc_pcm_hw_init(hw);
if (formats)
hw->formats &= formats;
for_each_rtd_cpu_dais(fe, i, dai) { for_each_rtd_cpu_dais(fe, i, dai) {
struct snd_soc_pcm_stream *cpu_stream; struct snd_soc_pcm_stream *cpu_stream;
......
...@@ -1805,6 +1805,14 @@ static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route * ...@@ -1805,6 +1805,14 @@ static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *
u32 header, extension; u32 header, extension;
int ret; int ret;
if (!src_fw_module || !sink_fw_module) {
/* The NULL module will print as "(efault)" */
dev_err(sdev->dev, "source %s or sink %s widget weren't set up properly\n",
src_fw_module->man4_module_entry.name,
sink_fw_module->man4_module_entry.name);
return -ENODEV;
}
sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
SOF_PIN_TYPE_SOURCE); SOF_PIN_TYPE_SOURCE);
if (sroute->src_queue_id < 0) { if (sroute->src_queue_id < 0) {
......
...@@ -405,6 +405,9 @@ static int sof_ipc4_tx_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_ ...@@ -405,6 +405,9 @@ static int sof_ipc4_tx_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_
static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data, static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
size_t payload_bytes, bool set) size_t payload_bytes, bool set)
{ {
const struct sof_dsp_power_state target_state = {
.state = SOF_DSP_PM_D0,
};
size_t payload_limit = sdev->ipc->max_payload_size; size_t payload_limit = sdev->ipc->max_payload_size;
struct sof_ipc4_msg *ipc4_msg = data; struct sof_ipc4_msg *ipc4_msg = data;
struct sof_ipc4_msg tx = {{ 0 }}; struct sof_ipc4_msg tx = {{ 0 }};
...@@ -435,6 +438,11 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data, ...@@ -435,6 +438,11 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
tx.extension |= SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK(1); tx.extension |= SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK(1);
/* ensure the DSP is in D0i0 before sending IPC */
ret = snd_sof_dsp_set_power_state(sdev, &target_state);
if (ret < 0)
return ret;
/* Serialise IPC TX */ /* Serialise IPC TX */
mutex_lock(&sdev->ipc->tx_mutex); mutex_lock(&sdev->ipc->tx_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment