Commit fd2cd569 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull sound fixes from Takashi Iwai:
 "A bit more commits than expected at this time, but likely it's the
  last shot before the final.

  Many of changes are device-specific fix-ups for various ASoC drivers,
  while a few usual HD-audio quirks and a FireWire fix, as well as a
  couple of ALSA / ASoC core fixes.

  All look nice and small, and nothing to scare much"

* tag 'sound-5.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: seq: Fix race of snd_seq_timer_open()
  ALSA: hda/realtek: fix mute/micmute LEDs for HP ZBook Power G8
  ALSA: hda/realtek: headphone and mic don't work on an Acer laptop
  ASoC: qcom: lpass-cpu: Fix pop noise during audio capture begin
  ALSA: firewire-lib: fix the context to call snd_pcm_stop_xrun()
  ALSA: hda/realtek: fix mute/micmute LEDs for HP EliteBook 840 Aero G8
  ALSA: hda/realtek: fix mute/micmute LEDs and speaker for HP EliteBook x360 1040 G8
  ALSA: hda/realtek: fix mute/micmute LEDs and speaker for HP Elite Dragonfly G2
  ASoC: rt5682: Fix the fast discharge for headset unplugging in soundwire mode
  ASoC: tas2562: Fix TDM_CFG0_SAMPRATE values
  ASoC: meson: gx-card: fix sound-dai dt schema
  ASoC: AMD Renoir: Remove fix for DMI entry on Lenovo 2020 platforms
  ASoC: AMD Renoir - add DMI entry for Lenovo 2020 AMD platforms
  ASoC: SOF: reset enabled_cores state at suspend
  ASoC: fsl-asoc-card: Set .owner attribute when registering card.
  ASoC: topology: Fix spelling mistake "vesion" -> "version"
  ASoC: rt5659: Fix the lost powers for the HDA header
  ASoC: core: Fix Null-point-dereference in fmt_single_name()
parents 4244b5d8 83e197a8
...@@ -57,7 +57,7 @@ patternProperties: ...@@ -57,7 +57,7 @@ patternProperties:
rate rate
sound-dai: sound-dai:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle-array
description: phandle of the CPU DAI description: phandle of the CPU DAI
patternProperties: patternProperties:
...@@ -71,7 +71,7 @@ patternProperties: ...@@ -71,7 +71,7 @@ patternProperties:
properties: properties:
sound-dai: sound-dai:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle-array
description: phandle of the codec DAI description: phandle of the codec DAI
required: required:
......
...@@ -297,8 +297,16 @@ int snd_seq_timer_open(struct snd_seq_queue *q) ...@@ -297,8 +297,16 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
return err; return err;
} }
spin_lock_irq(&tmr->lock); spin_lock_irq(&tmr->lock);
if (tmr->timeri)
err = -EBUSY;
else
tmr->timeri = t; tmr->timeri = t;
spin_unlock_irq(&tmr->lock); spin_unlock_irq(&tmr->lock);
if (err < 0) {
snd_timer_close(t);
snd_timer_instance_free(t);
return err;
}
return 0; return 0;
} }
......
...@@ -804,7 +804,7 @@ static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs, ...@@ -804,7 +804,7 @@ static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs,
static inline void cancel_stream(struct amdtp_stream *s) static inline void cancel_stream(struct amdtp_stream *s)
{ {
s->packet_index = -1; s->packet_index = -1;
if (current_work() == &s->period_work) if (in_interrupt())
amdtp_stream_pcm_abort(s); amdtp_stream_pcm_abort(s);
WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN); WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN);
} }
......
...@@ -6568,6 +6568,7 @@ enum { ...@@ -6568,6 +6568,7 @@ enum {
ALC285_FIXUP_HP_SPECTRE_X360, ALC285_FIXUP_HP_SPECTRE_X360,
ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP,
ALC623_FIXUP_LENOVO_THINKSTATION_P340, ALC623_FIXUP_LENOVO_THINKSTATION_P340,
ALC255_FIXUP_ACER_HEADPHONE_AND_MIC,
}; };
static const struct hda_fixup alc269_fixups[] = { static const struct hda_fixup alc269_fixups[] = {
...@@ -8146,6 +8147,15 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -8146,6 +8147,15 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC283_FIXUP_HEADSET_MIC, .chain_id = ALC283_FIXUP_HEADSET_MIC,
}, },
[ALC255_FIXUP_ACER_HEADPHONE_AND_MIC] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x21, 0x03211030 }, /* Change the Headphone location to Left */
{ }
},
.chained = true,
.chain_id = ALC255_FIXUP_XIAOMI_HEADSET_MIC
},
}; };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = {
...@@ -8182,6 +8192,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -8182,6 +8192,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC),
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
...@@ -8310,6 +8321,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -8310,6 +8321,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO), SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO),
SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
...@@ -8328,10 +8341,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -8328,10 +8341,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x886d, "HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x886d, "HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
...@@ -8737,6 +8752,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { ...@@ -8737,6 +8752,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"},
{.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"},
{.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"},
{.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"},
{} {}
}; };
#define ALC225_STANDARD_PINS \ #define ALC225_STANDARD_PINS \
......
...@@ -2433,13 +2433,18 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w, ...@@ -2433,13 +2433,18 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { static const struct snd_soc_dapm_widget rt5659_particular_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("LDO2", RT5659_PWR_ANLG_3, RT5659_PWR_LDO2_BIT, 0, SND_SOC_DAPM_SUPPLY("LDO2", RT5659_PWR_ANLG_3, RT5659_PWR_LDO2_BIT, 0,
NULL, 0), NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL", RT5659_PWR_ANLG_3, RT5659_PWR_PLL_BIT, 0, SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5659_PWR_ANLG_2, RT5659_PWR_MB1_BIT,
NULL, 0), 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5659_PWR_VOL, SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5659_PWR_VOL,
RT5659_PWR_MIC_DET_BIT, 0, NULL, 0), RT5659_PWR_MIC_DET_BIT, 0, NULL, 0),
};
static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL", RT5659_PWR_ANLG_3, RT5659_PWR_PLL_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("Mono Vref", RT5659_PWR_ANLG_1, SND_SOC_DAPM_SUPPLY("Mono Vref", RT5659_PWR_ANLG_1,
RT5659_PWR_VREF3_BIT, 0, NULL, 0), RT5659_PWR_VREF3_BIT, 0, NULL, 0),
...@@ -2464,8 +2469,6 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { ...@@ -2464,8 +2469,6 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
RT5659_ADC_MONO_R_ASRC_SFT, 0, NULL, 0), RT5659_ADC_MONO_R_ASRC_SFT, 0, NULL, 0),
/* Input Side */ /* Input Side */
SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5659_PWR_ANLG_2, RT5659_PWR_MB1_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5659_PWR_ANLG_2, RT5659_PWR_MB2_BIT, SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5659_PWR_ANLG_2, RT5659_PWR_MB2_BIT,
0, NULL, 0), 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MICBIAS3", RT5659_PWR_ANLG_2, RT5659_PWR_MB3_BIT, SND_SOC_DAPM_SUPPLY("MICBIAS3", RT5659_PWR_ANLG_2, RT5659_PWR_MB3_BIT,
...@@ -3660,10 +3663,23 @@ static int rt5659_set_bias_level(struct snd_soc_component *component, ...@@ -3660,10 +3663,23 @@ static int rt5659_set_bias_level(struct snd_soc_component *component,
static int rt5659_probe(struct snd_soc_component *component) static int rt5659_probe(struct snd_soc_component *component)
{ {
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component); struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
rt5659->component = component; rt5659->component = component;
switch (rt5659->pdata.jd_src) {
case RT5659_JD_HDA_HEADER:
break;
default:
snd_soc_dapm_new_controls(dapm,
rt5659_particular_dapm_widgets,
ARRAY_SIZE(rt5659_particular_dapm_widgets));
break;
}
return 0; return 0;
} }
......
...@@ -462,7 +462,8 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) ...@@ -462,7 +462,8 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_2, regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_2,
RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL);
regmap_write(rt5682->regmap, RT5682_CBJ_CTRL_1, 0xd042); regmap_write(rt5682->regmap, RT5682_CBJ_CTRL_1, 0xd142);
regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_5, 0x0700, 0x0600);
regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_3, regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_3,
RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN); RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN);
regmap_update_bits(rt5682->regmap, RT5682_SAR_IL_CMD_1, regmap_update_bits(rt5682->regmap, RT5682_SAR_IL_CMD_1,
......
...@@ -57,13 +57,13 @@ ...@@ -57,13 +57,13 @@
#define TAS2562_TDM_CFG0_RAMPRATE_MASK BIT(5) #define TAS2562_TDM_CFG0_RAMPRATE_MASK BIT(5)
#define TAS2562_TDM_CFG0_RAMPRATE_44_1 BIT(5) #define TAS2562_TDM_CFG0_RAMPRATE_44_1 BIT(5)
#define TAS2562_TDM_CFG0_SAMPRATE_MASK GENMASK(3, 1) #define TAS2562_TDM_CFG0_SAMPRATE_MASK GENMASK(3, 1)
#define TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ 0x0 #define TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ (0x0 << 1)
#define TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ 0x1 #define TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ (0x1 << 1)
#define TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ 0x2 #define TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ (0x2 << 1)
#define TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ 0x3 #define TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ (0x3 << 1)
#define TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ 0x4 #define TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ (0x4 << 1)
#define TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ 0x5 #define TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ (0x5 << 1)
#define TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ 0x6 #define TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ (0x6 << 1)
#define TAS2562_TDM_CFG2_RIGHT_JUSTIFY BIT(6) #define TAS2562_TDM_CFG2_RIGHT_JUSTIFY BIT(6)
......
...@@ -744,6 +744,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ...@@ -744,6 +744,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
/* Initialize sound card */ /* Initialize sound card */
priv->pdev = pdev; priv->pdev = pdev;
priv->card.dev = &pdev->dev; priv->card.dev = &pdev->dev;
priv->card.owner = THIS_MODULE;
ret = snd_soc_of_parse_card_name(&priv->card, "model"); ret = snd_soc_of_parse_card_name(&priv->card, "model");
if (ret) { if (ret) {
snprintf(priv->name, sizeof(priv->name), "%s-audio", snprintf(priv->name, sizeof(priv->name), "%s-audio",
......
...@@ -93,8 +93,30 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream, ...@@ -93,8 +93,30 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id;
clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]); clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
/*
* Ensure LRCLK is disabled even in device node validation.
* Will not impact if disabled in lpass_cpu_daiops_trigger()
* suspend.
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_DISABLE);
else
regmap_fields_write(i2sctl->micen, id, LPAIF_I2SCTL_MICEN_DISABLE);
/*
* BCLK may not be enabled if lpass_cpu_daiops_prepare is called before
* lpass_cpu_daiops_shutdown. It's paired with the clk_enable in
* lpass_cpu_daiops_prepare.
*/
if (drvdata->mi2s_was_prepared[dai->driver->id]) {
drvdata->mi2s_was_prepared[dai->driver->id] = false;
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
}
clk_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]); clk_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
} }
...@@ -275,6 +297,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -275,6 +297,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
/*
* Ensure lpass BCLK/LRCLK is enabled during
* device resume as lpass_cpu_daiops_prepare() is not called
* after the device resumes. We don't check mi2s_was_prepared before
* enable/disable BCLK in trigger events because:
* 1. These trigger events are paired, so the BCLK
* enable_count is balanced.
* 2. the BCLK can be shared (ex: headset and headset mic),
* we need to increase the enable_count so that we don't
* turn off the shared BCLK while other devices are using
* it.
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = regmap_fields_write(i2sctl->spken, id, ret = regmap_fields_write(i2sctl->spken, id,
LPAIF_I2SCTL_SPKEN_ENABLE); LPAIF_I2SCTL_SPKEN_ENABLE);
...@@ -296,6 +330,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -296,6 +330,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/*
* To ensure lpass BCLK/LRCLK is disabled during
* device suspend.
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = regmap_fields_write(i2sctl->spken, id, ret = regmap_fields_write(i2sctl->spken, id,
LPAIF_I2SCTL_SPKEN_DISABLE); LPAIF_I2SCTL_SPKEN_DISABLE);
...@@ -315,12 +353,53 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -315,12 +353,53 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
return ret; return ret;
} }
static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id;
int ret;
/*
* Ensure lpass BCLK/LRCLK is enabled bit before playback/capture
* data flow starts. This allows other codec to have some delay before
* the data flow.
* (ex: to drop start up pop noise before capture starts).
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_ENABLE);
else
ret = regmap_fields_write(i2sctl->micen, id, LPAIF_I2SCTL_MICEN_ENABLE);
if (ret) {
dev_err(dai->dev, "error writing to i2sctl reg: %d\n", ret);
return ret;
}
/*
* Check mi2s_was_prepared before enabling BCLK as lpass_cpu_daiops_prepare can
* be called multiple times. It's paired with the clk_disable in
* lpass_cpu_daiops_shutdown.
*/
if (!drvdata->mi2s_was_prepared[dai->driver->id]) {
ret = clk_enable(drvdata->mi2s_bit_clk[id]);
if (ret) {
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
return ret;
}
drvdata->mi2s_was_prepared[dai->driver->id] = true;
}
return 0;
}
const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = {
.set_sysclk = lpass_cpu_daiops_set_sysclk, .set_sysclk = lpass_cpu_daiops_set_sysclk,
.startup = lpass_cpu_daiops_startup, .startup = lpass_cpu_daiops_startup,
.shutdown = lpass_cpu_daiops_shutdown, .shutdown = lpass_cpu_daiops_shutdown,
.hw_params = lpass_cpu_daiops_hw_params, .hw_params = lpass_cpu_daiops_hw_params,
.trigger = lpass_cpu_daiops_trigger, .trigger = lpass_cpu_daiops_trigger,
.prepare = lpass_cpu_daiops_prepare,
}; };
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops); EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);
......
...@@ -67,6 +67,10 @@ struct lpass_data { ...@@ -67,6 +67,10 @@ struct lpass_data {
/* MI2S SD lines to use for playback/capture */ /* MI2S SD lines to use for playback/capture */
unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
/* The state of MI2S prepare dai_ops was called */
bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS];
int hdmi_port_enable; int hdmi_port_enable;
/* low-power audio interface (LPAIF) registers */ /* low-power audio interface (LPAIF) registers */
......
...@@ -2225,6 +2225,8 @@ static char *fmt_single_name(struct device *dev, int *id) ...@@ -2225,6 +2225,8 @@ static char *fmt_single_name(struct device *dev, int *id)
return NULL; return NULL;
name = devm_kstrdup(dev, devname, GFP_KERNEL); name = devm_kstrdup(dev, devname, GFP_KERNEL);
if (!name)
return NULL;
/* are we a "%s.%d" name (platform and SPI components) */ /* are we a "%s.%d" name (platform and SPI components) */
found = strstr(name, dev->driver->name); found = strstr(name, dev->driver->name);
......
...@@ -1901,7 +1901,7 @@ static void stream_caps_new_ver(struct snd_soc_tplg_stream_caps *dest, ...@@ -1901,7 +1901,7 @@ static void stream_caps_new_ver(struct snd_soc_tplg_stream_caps *dest,
* @src: older version of pcm as a source * @src: older version of pcm as a source
* @pcm: latest version of pcm created from the source * @pcm: latest version of pcm created from the source
* *
* Support from vesion 4. User should free the returned pcm manually. * Support from version 4. User should free the returned pcm manually.
*/ */
static int pcm_new_ver(struct soc_tplg *tplg, static int pcm_new_ver(struct soc_tplg *tplg,
struct snd_soc_tplg_pcm *src, struct snd_soc_tplg_pcm *src,
...@@ -2089,7 +2089,7 @@ static void set_link_hw_format(struct snd_soc_dai_link *link, ...@@ -2089,7 +2089,7 @@ static void set_link_hw_format(struct snd_soc_dai_link *link,
* @src: old version of phyical link config as a source * @src: old version of phyical link config as a source
* @link: latest version of physical link config created from the source * @link: latest version of physical link config created from the source
* *
* Support from vesion 4. User need free the returned link config manually. * Support from version 4. User need free the returned link config manually.
*/ */
static int link_new_ver(struct soc_tplg *tplg, static int link_new_ver(struct soc_tplg *tplg,
struct snd_soc_tplg_link_config *src, struct snd_soc_tplg_link_config *src,
...@@ -2400,7 +2400,7 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg, ...@@ -2400,7 +2400,7 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
* @src: old version of manifest as a source * @src: old version of manifest as a source
* @manifest: latest version of manifest created from the source * @manifest: latest version of manifest created from the source
* *
* Support from vesion 4. Users need free the returned manifest manually. * Support from version 4. Users need free the returned manifest manually.
*/ */
static int manifest_new_ver(struct soc_tplg *tplg, static int manifest_new_ver(struct soc_tplg *tplg,
struct snd_soc_tplg_manifest *src, struct snd_soc_tplg_manifest *src,
......
...@@ -256,6 +256,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) ...@@ -256,6 +256,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
/* reset FW state */ /* reset FW state */
sdev->fw_state = SOF_FW_BOOT_NOT_STARTED; sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
sdev->enabled_cores_mask = 0;
return ret; return ret;
} }
......
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