diff options
Diffstat (limited to 'sound/soc')
42 files changed, 544 insertions, 245 deletions
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index d8f554f369a8..e6386de20ac7 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -342,11 +342,34 @@ static int acp3x_dma_close(struct snd_soc_component *component, { struct snd_soc_pcm_runtime *prtd; struct i2s_dev_data *adata; + struct i2s_stream_instance *ins; prtd = substream->private_data; component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); adata = dev_get_drvdata(component->dev); + ins = substream->runtime->private_data; + if (!ins) + return -EINVAL; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (ins->i2s_instance) { + case I2S_BT_INSTANCE: + adata->play_stream = NULL; + break; + case I2S_SP_INSTANCE: + default: + adata->i2ssp_play_stream = NULL; + } + } else { + switch (ins->i2s_instance) { + case I2S_BT_INSTANCE: + adata->capture_stream = NULL; + break; + case I2S_SP_INSTANCE: + default: + adata->i2ssp_capture_stream = NULL; + } + } /* Disable ACP irq, when the current stream is being closed and * another stream is also not active. @@ -354,13 +377,6 @@ static int acp3x_dma_close(struct snd_soc_component *component, if (!adata->play_stream && !adata->capture_stream && !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - adata->play_stream = NULL; - adata->i2ssp_play_stream = NULL; - } else { - adata->capture_stream = NULL; - adata->i2ssp_capture_stream = NULL; - } return 0; } diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c index f25ce50f1a90..ebf4388b6262 100644 --- a/sound/soc/amd/raven/pci-acp3x.c +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -232,9 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci, } pm_runtime_set_autosuspend_delay(&pci->dev, 2000); pm_runtime_use_autosuspend(&pci->dev); - pm_runtime_set_active(&pci->dev); pm_runtime_put_noidle(&pci->dev); - pm_runtime_enable(&pci->dev); pm_runtime_allow(&pci->dev); return 0; @@ -303,7 +301,7 @@ static void snd_acp3x_remove(struct pci_dev *pci) ret = acp3x_deinit(adata->acp3x_base); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); - pm_runtime_disable(&pci->dev); + pm_runtime_forbid(&pci->dev); pm_runtime_get_noresume(&pci->dev); pci_disable_msi(pci); pci_release_regions(pci); diff --git a/sound/soc/amd/renoir/Makefile b/sound/soc/amd/renoir/Makefile index e4371932a55a..4a82690aec16 100644 --- a/sound/soc/amd/renoir/Makefile +++ b/sound/soc/amd/renoir/Makefile @@ -2,6 +2,7 @@ # Renoir platform Support snd-rn-pci-acp3x-objs := rn-pci-acp3x.o snd-acp3x-pdm-dma-objs := acp3x-pdm-dma.o -obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-rn-pci-acp3x.o -obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-acp3x-pdm-dma.o -obj-$(CONFIG_SND_SOC_AMD_RENOIR_MACH) += acp3x-rn.o +snd-acp3x-rn-objs := acp3x-rn.o +obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-rn-pci-acp3x.o +obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-acp3x-pdm-dma.o +obj-$(CONFIG_SND_SOC_AMD_RENOIR_MACH) += snd-acp3x-rn.o diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index de003acb1951..473efe9ef998 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -441,13 +441,13 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) ret = snd_hda_codec_set_name(hcodec, hcodec->preset->name); if (ret < 0) { dev_err(&hdev->dev, "name failed %s\n", hcodec->preset->name); - goto error; + goto error_pm; } ret = snd_hdac_regmap_init(&hcodec->core); if (ret < 0) { dev_err(&hdev->dev, "regmap init failed\n"); - goto error; + goto error_pm; } patch = (hda_codec_patch_t)hcodec->preset->driver_data; @@ -455,7 +455,7 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) ret = patch(hcodec); if (ret < 0) { dev_err(&hdev->dev, "patch failed %d\n", ret); - goto error; + goto error_regmap; } } else { dev_dbg(&hdev->dev, "no patch file found\n"); @@ -467,7 +467,7 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) ret = snd_hda_codec_parse_pcms(hcodec); if (ret < 0) { dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret); - goto error; + goto error_regmap; } /* HDMI controls need to be created in machine drivers */ @@ -476,7 +476,7 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) if (ret < 0) { dev_err(&hdev->dev, "unable to create controls %d\n", ret); - goto error; + goto error_regmap; } } @@ -496,7 +496,9 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) return 0; -error: +error_regmap: + snd_hdac_regmap_exit(hdev); +error_pm: pm_runtime_put(&hdev->dev); error_no_pm: snd_hdac_ext_bus_link_put(hdev->bus, hlink); @@ -518,6 +520,8 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component) pm_runtime_disable(&hdev->dev); snd_hdac_ext_bus_link_put(hdev->bus, hlink); + + snd_hdac_regmap_exit(hdev); } static const struct snd_soc_dapm_route hdac_hda_dapm_routes[] = { diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index 96718e3a1ad0..d87402a86c88 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -779,13 +779,6 @@ static int max98373_probe(struct snd_soc_component *component) regmap_write(max98373->regmap, MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, 0x1); - /* Set inital volume (0dB) */ - regmap_write(max98373->regmap, - MAX98373_R203D_AMP_DIG_VOL_CTRL, - 0x00); - regmap_write(max98373->regmap, - MAX98373_R203E_AMP_PATH_GAIN, - 0x00); /* Enable DC blocker */ regmap_write(max98373->regmap, MAX98373_R203F_AMP_DSP_CFG, @@ -869,7 +862,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98373 = { .num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets), .dapm_routes = max98373_audio_map, .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), - .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, .non_legacy_dai_naming = 1, diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 0d63ebfbff2f..e6613b52bd78 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -700,8 +700,8 @@ static bool max98390_readable_register(struct device *dev, unsigned int reg) case MAX98390_IRQ_CTRL ... MAX98390_WDOG_CTRL: case MAX98390_MEAS_ADC_THERM_WARN_THRESH ... MAX98390_BROWNOUT_INFINITE_HOLD: - case MAX98390_BROWNOUT_LVL_HOLD ... THERMAL_COILTEMP_RD_BACK_BYTE0: - case DSMIG_DEBUZZER_THRESHOLD ... MAX98390_R24FF_REV_ID: + case MAX98390_BROWNOUT_LVL_HOLD ... DSMIG_DEBUZZER_THRESHOLD: + case DSM_VOL_ENA ... MAX98390_R24FF_REV_ID: return true; default: return false; @@ -717,7 +717,7 @@ static bool max98390_volatile_reg(struct device *dev, unsigned int reg) case MAX98390_BROWNOUT_LOWEST_STATUS: case MAX98390_ENV_TRACK_BOOST_VOUT_READ: case DSM_STBASS_HPF_B0_BYTE0 ... DSM_DEBUZZER_ATTACK_TIME_BYTE2: - case THERMAL_RDC_RD_BACK_BYTE1 ... THERMAL_COILTEMP_RD_BACK_BYTE0: + case THERMAL_RDC_RD_BACK_BYTE1 ... DSMIG_DEBUZZER_THRESHOLD: case DSM_THERMAL_GAIN ... DSM_WBDRC_GAIN: return true; default: diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 67e2e944d21b..2cccb310fa96 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -34,30 +34,32 @@ static const struct reg_default rt1015_reg[] = { { 0x0000, 0x0000 }, { 0x0004, 0xa000 }, { 0x0006, 0x0003 }, - { 0x000a, 0x0802 }, - { 0x000c, 0x0020 }, + { 0x000a, 0x081e }, + { 0x000c, 0x0006 }, { 0x000e, 0x0000 }, { 0x0010, 0x0000 }, { 0x0012, 0x0000 }, + { 0x0014, 0x0000 }, + { 0x0016, 0x0000 }, + { 0x0018, 0x0000 }, { 0x0020, 0x8000 }, - { 0x0022, 0x471b }, - { 0x006a, 0x0000 }, - { 0x006c, 0x4020 }, + { 0x0022, 0x8043 }, { 0x0076, 0x0000 }, { 0x0078, 0x0000 }, - { 0x007a, 0x0000 }, + { 0x007a, 0x0002 }, { 0x007c, 0x10ec }, { 0x007d, 0x1015 }, { 0x00f0, 0x5000 }, - { 0x00f2, 0x0774 }, - { 0x00f3, 0x8400 }, + { 0x00f2, 0x004c }, + { 0x00f3, 0xecfe }, { 0x00f4, 0x0000 }, + { 0x00f6, 0x0400 }, { 0x0100, 0x0028 }, { 0x0102, 0xff02 }, - { 0x0104, 0x8232 }, + { 0x0104, 0xa213 }, { 0x0106, 0x200c }, - { 0x010c, 0x002f }, - { 0x010e, 0xc000 }, + { 0x010c, 0x0000 }, + { 0x010e, 0x0058 }, { 0x0111, 0x0200 }, { 0x0112, 0x0400 }, { 0x0114, 0x0022 }, @@ -65,38 +67,46 @@ static const struct reg_default rt1015_reg[] = { { 0x0118, 0x0000 }, { 0x011a, 0x0123 }, { 0x011c, 0x4567 }, - { 0x0300, 0xdddd }, - { 0x0302, 0x0000 }, - { 0x0311, 0x9330 }, - { 0x0313, 0x0000 }, - { 0x0314, 0x0000 }, + { 0x0300, 0x203d }, + { 0x0302, 0x001e }, + { 0x0311, 0x0000 }, + { 0x0313, 0x6014 }, + { 0x0314, 0x00a2 }, { 0x031a, 0x00a0 }, { 0x031c, 0x001f }, { 0x031d, 0xffff }, { 0x031e, 0x0000 }, { 0x031f, 0x0000 }, + { 0x0320, 0x0000 }, { 0x0321, 0x0000 }, - { 0x0322, 0x0000 }, - { 0x0328, 0x0000 }, - { 0x0329, 0x0000 }, - { 0x032a, 0x0000 }, - { 0x032b, 0x0000 }, - { 0x032c, 0x0000 }, - { 0x032d, 0x0000 }, - { 0x032e, 0x030e }, - { 0x0330, 0x0080 }, + { 0x0322, 0xd7df }, + { 0x0328, 0x10b2 }, + { 0x0329, 0x0175 }, + { 0x032a, 0x36ad }, + { 0x032b, 0x7e55 }, + { 0x032c, 0x0520 }, + { 0x032d, 0xaa00 }, + { 0x032e, 0x570e }, + { 0x0330, 0xe180 }, { 0x0332, 0x0034 }, - { 0x0334, 0x0000 }, - { 0x0336, 0x0000 }, + { 0x0334, 0x0001 }, + { 0x0336, 0x0010 }, + { 0x0338, 0x0000 }, + { 0x04fa, 0x0030 }, + { 0x04fc, 0x35c8 }, + { 0x04fe, 0x0800 }, + { 0x0500, 0x0400 }, + { 0x0502, 0x1000 }, + { 0x0504, 0x0000 }, { 0x0506, 0x04ff }, - { 0x0508, 0x0030 }, - { 0x050a, 0x0018 }, - { 0x0519, 0x307f }, - { 0x051a, 0xffff }, - { 0x051b, 0x4000 }, + { 0x0508, 0x0010 }, + { 0x050a, 0x001a }, + { 0x0519, 0x1c68 }, + { 0x051a, 0x0ccc }, + { 0x051b, 0x0666 }, { 0x051d, 0x0000 }, { 0x051f, 0x0000 }, - { 0x0536, 0x1000 }, + { 0x0536, 0x061c }, { 0x0538, 0x0000 }, { 0x053a, 0x0000 }, { 0x053c, 0x0000 }, @@ -110,19 +120,18 @@ static const struct reg_default rt1015_reg[] = { { 0x0544, 0x0000 }, { 0x0568, 0x0000 }, { 0x056a, 0x0000 }, - { 0x1000, 0x0000 }, - { 0x1002, 0x6505 }, + { 0x1000, 0x0040 }, + { 0x1002, 0x5405 }, { 0x1006, 0x5515 }, - { 0x1007, 0x003f }, - { 0x1009, 0x770f }, - { 0x100a, 0x01ff }, - { 0x100c, 0x0000 }, + { 0x1007, 0x05f7 }, + { 0x1009, 0x0b0a }, + { 0x100a, 0x00ef }, { 0x100d, 0x0003 }, { 0x1010, 0xa433 }, { 0x1020, 0x0000 }, - { 0x1200, 0x3d02 }, - { 0x1202, 0x0813 }, - { 0x1204, 0x0211 }, + { 0x1200, 0x5a01 }, + { 0x1202, 0x6524 }, + { 0x1204, 0x1f00 }, { 0x1206, 0x0000 }, { 0x1208, 0x0000 }, { 0x120a, 0x0000 }, @@ -130,16 +139,16 @@ static const struct reg_default rt1015_reg[] = { { 0x120e, 0x0000 }, { 0x1210, 0x0000 }, { 0x1212, 0x0000 }, - { 0x1300, 0x0701 }, - { 0x1302, 0x12f9 }, - { 0x1304, 0x3405 }, + { 0x1300, 0x10a1 }, + { 0x1302, 0x12ff }, + { 0x1304, 0x0400 }, { 0x1305, 0x0844 }, - { 0x1306, 0x1611 }, + { 0x1306, 0x4611 }, { 0x1308, 0x555e }, { 0x130a, 0x0000 }, - { 0x130c, 0x2400}, - { 0x130e, 0x7700 }, - { 0x130f, 0x0000 }, + { 0x130c, 0x2000 }, + { 0x130e, 0x0100 }, + { 0x130f, 0x0001 }, { 0x1310, 0x0000 }, { 0x1312, 0x0000 }, { 0x1314, 0x0000 }, @@ -209,6 +218,9 @@ static bool rt1015_volatile_register(struct device *dev, unsigned int reg) case RT1015_DC_CALIB_CLSD7: case RT1015_DC_CALIB_CLSD8: case RT1015_S_BST_TIMING_INTER1: + case RT1015_OSCK_STA: + case RT1015_MONO_DYNA_CTRL1: + case RT1015_MONO_DYNA_CTRL5: return true; default: @@ -224,6 +236,12 @@ static bool rt1015_readable_register(struct device *dev, unsigned int reg) case RT1015_CLK3: case RT1015_PLL1: case RT1015_PLL2: + case RT1015_DUM_RW1: + case RT1015_DUM_RW2: + case RT1015_DUM_RW3: + case RT1015_DUM_RW4: + case RT1015_DUM_RW5: + case RT1015_DUM_RW6: case RT1015_CLK_DET: case RT1015_SIL_DET: case RT1015_CUSTOMER_ID: @@ -235,6 +253,7 @@ static bool rt1015_readable_register(struct device *dev, unsigned int reg) case RT1015_PAD_DRV2: case RT1015_GAT_BOOST: case RT1015_PRO_ALT: + case RT1015_OSCK_STA: case RT1015_MAN_I2C: case RT1015_DAC1: case RT1015_DAC2: @@ -272,6 +291,13 @@ static bool rt1015_readable_register(struct device *dev, unsigned int reg) case RT1015_SMART_BST_CTRL2: case RT1015_ANA_CTRL1: case RT1015_ANA_CTRL2: + case RT1015_PWR_STATE_CTRL: + case RT1015_MONO_DYNA_CTRL: + case RT1015_MONO_DYNA_CTRL1: + case RT1015_MONO_DYNA_CTRL2: + case RT1015_MONO_DYNA_CTRL3: + case RT1015_MONO_DYNA_CTRL4: + case RT1015_MONO_DYNA_CTRL5: case RT1015_SPK_VOL: case RT1015_SHORT_DETTOP1: case RT1015_SHORT_DETTOP2: diff --git a/sound/soc/codecs/rt1015.h b/sound/soc/codecs/rt1015.h index 6fbe802082c4..8169962935a5 100644 --- a/sound/soc/codecs/rt1015.h +++ b/sound/soc/codecs/rt1015.h @@ -21,6 +21,12 @@ #define RT1015_CLK3 0x0006 #define RT1015_PLL1 0x000a #define RT1015_PLL2 0x000c +#define RT1015_DUM_RW1 0x000e +#define RT1015_DUM_RW2 0x0010 +#define RT1015_DUM_RW3 0x0012 +#define RT1015_DUM_RW4 0x0014 +#define RT1015_DUM_RW5 0x0016 +#define RT1015_DUM_RW6 0x0018 #define RT1015_CLK_DET 0x0020 #define RT1015_SIL_DET 0x0022 #define RT1015_CUSTOMER_ID 0x0076 @@ -32,6 +38,7 @@ #define RT1015_PAD_DRV2 0x00f2 #define RT1015_GAT_BOOST 0x00f3 #define RT1015_PRO_ALT 0x00f4 +#define RT1015_OSCK_STA 0x00f6 #define RT1015_MAN_I2C 0x0100 #define RT1015_DAC1 0x0102 #define RT1015_DAC2 0x0104 @@ -70,7 +77,13 @@ #define RT1015_ANA_CTRL1 0x0334 #define RT1015_ANA_CTRL2 0x0336 #define RT1015_PWR_STATE_CTRL 0x0338 -#define RT1015_SPK_VOL 0x0506 +#define RT1015_MONO_DYNA_CTRL 0x04fa +#define RT1015_MONO_DYNA_CTRL1 0x04fc +#define RT1015_MONO_DYNA_CTRL2 0x04fe +#define RT1015_MONO_DYNA_CTRL3 0x0500 +#define RT1015_MONO_DYNA_CTRL4 0x0502 +#define RT1015_MONO_DYNA_CTRL5 0x0504 +#define RT1015_SPK_VOL 0x0506 #define RT1015_SHORT_DETTOP1 0x0508 #define RT1015_SHORT_DETTOP2 0x050a #define RT1015_SPK_DC_DETECT1 0x0519 diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 9593a9a27bf8..e8d14eefc41b 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -272,13 +272,13 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf); *mic = buf & 0x80000000; } - if (!*mic) { + + if (!*hp) { snd_soc_dapm_disable_pin(dapm, "HV"); snd_soc_dapm_disable_pin(dapm, "VREF"); - } - if (!*hp) snd_soc_dapm_disable_pin(dapm, "LDO1"); - snd_soc_dapm_sync(dapm); + snd_soc_dapm_sync(dapm); + } return 0; } diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 70fee6849ab0..dfbc0ca38ff7 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -31,18 +31,19 @@ #include "rt5670.h" #include "rt5670-dsp.h" -#define RT5670_DEV_GPIO BIT(0) -#define RT5670_IN2_DIFF BIT(1) -#define RT5670_DMIC_EN BIT(2) -#define RT5670_DMIC1_IN2P BIT(3) -#define RT5670_DMIC1_GPIO6 BIT(4) -#define RT5670_DMIC1_GPIO7 BIT(5) -#define RT5670_DMIC2_INR BIT(6) -#define RT5670_DMIC2_GPIO8 BIT(7) -#define RT5670_DMIC3_GPIO5 BIT(8) -#define RT5670_JD_MODE1 BIT(9) -#define RT5670_JD_MODE2 BIT(10) -#define RT5670_JD_MODE3 BIT(11) +#define RT5670_DEV_GPIO BIT(0) +#define RT5670_IN2_DIFF BIT(1) +#define RT5670_DMIC_EN BIT(2) +#define RT5670_DMIC1_IN2P BIT(3) +#define RT5670_DMIC1_GPIO6 BIT(4) +#define RT5670_DMIC1_GPIO7 BIT(5) +#define RT5670_DMIC2_INR BIT(6) +#define RT5670_DMIC2_GPIO8 BIT(7) +#define RT5670_DMIC3_GPIO5 BIT(8) +#define RT5670_JD_MODE1 BIT(9) +#define RT5670_JD_MODE2 BIT(10) +#define RT5670_JD_MODE3 BIT(11) +#define RT5670_GPIO1_IS_EXT_SPK_EN BIT(12) static unsigned long rt5670_quirk; static unsigned int quirk_override; @@ -602,9 +603,9 @@ int rt5670_set_jack_detect(struct snd_soc_component *component, EXPORT_SYMBOL_GPL(rt5670_set_jack_detect); static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); +static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); +static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000); static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ @@ -1447,6 +1448,33 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt5670_spk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + + if (!rt5670->pdata.gpio1_is_ext_spk_en) + return 0; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, + RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_HI); + break; + + case SND_SOC_DAPM_PRE_PMD: + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, + RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_LO); + break; + + default: + return 0; + } + + return 0; +} + static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1860,7 +1888,9 @@ static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = { }; static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = { - SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA_E("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0, + rt5670_spk_event, SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_OUTPUT("SPOLP"), SND_SOC_DAPM_OUTPUT("SPOLN"), SND_SOC_DAPM_OUTPUT("SPORP"), @@ -2857,14 +2887,14 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, { .callback = rt5670_quirk_cb, - .ident = "Lenovo Thinkpad Tablet 10", + .ident = "Lenovo Miix 2 10", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"), }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_EXT_SPK_EN | RT5670_JD_MODE2), }, { @@ -2924,6 +2954,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, rt5670->pdata.dev_gpio = true; dev_info(&i2c->dev, "quirk dev_gpio\n"); } + if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) { + rt5670->pdata.gpio1_is_ext_spk_en = true; + dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n"); + } if (rt5670_quirk & RT5670_IN2_DIFF) { rt5670->pdata.in2_diff = true; dev_info(&i2c->dev, "quirk IN2_DIFF\n"); @@ -3023,6 +3057,13 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); } + if (rt5670->pdata.gpio1_is_ext_spk_en) { + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, + RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1); + regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, + RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); + } + if (rt5670->pdata.jd_mode) { regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h index a8c3e44770b8..de0203369b7c 100644 --- a/sound/soc/codecs/rt5670.h +++ b/sound/soc/codecs/rt5670.h @@ -757,7 +757,7 @@ #define RT5670_PWR_VREF2_BIT 4 #define RT5670_PWR_FV2 (0x1 << 3) #define RT5670_PWR_FV2_BIT 3 -#define RT5670_LDO_SEL_MASK (0x3) +#define RT5670_LDO_SEL_MASK (0x7) #define RT5670_LDO_SEL_SFT 0 /* Power Management for Analog 2 (0x64) */ diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index d3245123101d..d503b5bef4ba 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -932,7 +932,9 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2); snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, RT5682_PWR_CBJ, RT5682_PWR_CBJ); - + snd_soc_component_update_bits(component, + RT5682_HP_CHARGE_PUMP_1, + RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, 0); snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH); @@ -956,17 +958,21 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) rt5682->jack_type = SND_JACK_HEADPHONE; break; } + + snd_soc_component_update_bits(component, + RT5682_HP_CHARGE_PUMP_1, + RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, + RT5682_OSW_L_EN | RT5682_OSW_R_EN); } else { rt5682_enable_push_button_irq(component, false); snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); - if (snd_soc_dapm_get_pin_status(dapm, "MICBIAS")) + if (!snd_soc_dapm_get_pin_status(dapm, "MICBIAS")) snd_soc_component_update_bits(component, - RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0); - else + RT5682_PWR_ANLG_1, RT5682_PWR_MB, 0); + if (!snd_soc_dapm_get_pin_status(dapm, "Vref2")) snd_soc_component_update_bits(component, - RT5682_PWR_ANLG_1, - RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); + RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0); snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, RT5682_PWR_CBJ, 0); @@ -985,16 +991,17 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, rt5682->hs_jack = hs_jack; - if (!rt5682->is_sdw) { - if (!hs_jack) { - regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, - RT5682_JD1_EN_MASK, RT5682_JD1_DIS); - regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, - RT5682_POW_JDH | RT5682_POW_JDL, 0); - cancel_delayed_work_sync(&rt5682->jack_detect_work); - return 0; - } + if (!hs_jack) { + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, + RT5682_JD1_EN_MASK, RT5682_JD1_DIS); + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, + RT5682_POW_JDH | RT5682_POW_JDL, 0); + cancel_delayed_work_sync(&rt5682->jack_detect_work); + + return 0; + } + if (!rt5682->is_sdw) { switch (rt5682->pdata.jd_src) { case RT5682_JD1: snd_soc_component_update_bits(component, @@ -1075,7 +1082,8 @@ void rt5682_jack_detect_handler(struct work_struct *work) /* jack was out, report jack type */ rt5682->jack_type = rt5682_headset_detect(rt5682->component, 1); - } else { + } else if ((rt5682->jack_type & SND_JACK_HEADSET) == + SND_JACK_HEADSET) { /* jack is already in, report button event */ rt5682->jack_type = SND_JACK_HEADSET; btn_type = rt5682_button_detect(rt5682->component); @@ -1601,8 +1609,7 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { 0, set_filter_clk, SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, rt5682_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, - NULL, 0), + SND_SOC_DAPM_SUPPLY("Vref2", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, NULL, 0), /* ASRC */ @@ -2485,6 +2492,15 @@ static int rt5682_wclk_prepare(struct clk_hw *hw) snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, RT5682_PWR_MB, RT5682_PWR_MB); + + snd_soc_dapm_force_enable_pin_unlocked(dapm, "Vref2"); + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, + RT5682_PWR_VREF2 | RT5682_PWR_FV2, + RT5682_PWR_VREF2); + usleep_range(55000, 60000); + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, + RT5682_PWR_FV2, RT5682_PWR_FV2); + snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1"); snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2F"); snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2B"); @@ -2510,9 +2526,12 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw) snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); + snd_soc_dapm_disable_pin_unlocked(dapm, "Vref2"); if (!rt5682->jack_type) snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, + RT5682_PWR_VREF2 | RT5682_PWR_FV2 | RT5682_PWR_MB, 0); + snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1"); snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2F"); snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2B"); @@ -2829,12 +2848,13 @@ static int rt5682_probe(struct snd_soc_component *component) return ret; } rt5682->mclk = NULL; - } else { - /* Register CCF DAI clock control */ - ret = rt5682_register_dai_clks(component); - if (ret) - return ret; } + + /* Register CCF DAI clock control */ + ret = rt5682_register_dai_clks(component); + if (ret) + return ret; + /* Initial setup for CCF */ rt5682->lrck[RT5682_AIF1] = CLK_48; #endif diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 06ba36595ddd..7cfc89602fc3 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -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, 0), +SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1), }; /* Input PGA */ @@ -474,6 +474,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, iface |= 0x0008; break; case SND_SOC_DAIFMT_DSP_A: + if ((fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_IB_IF || + (fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_NB_IF) { + return -EINVAL; + } iface |= 0x00018; break; default: diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h index 77665b15c8db..7e1c13ca37f1 100644 --- a/sound/soc/fsl/fsl_asrc_common.h +++ b/sound/soc/fsl/fsl_asrc_common.h @@ -32,6 +32,7 @@ enum asrc_pair_index { * @dma_chan: inputer and output DMA channels * @dma_data: private dma data * @pos: hardware pointer position + * @req_dma_chan: flag to release dev_to_dev chan * @private: pair private area */ struct fsl_asrc_pair { @@ -45,6 +46,7 @@ struct fsl_asrc_pair { struct dma_chan *dma_chan[2]; struct imx_dma_data dma_data; unsigned int pos; + bool req_dma_chan; void *private; }; diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index d6a3fc5f87e5..5f01a58f422a 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -135,6 +135,8 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, struct snd_dmaengine_dai_dma_data *dma_params_be = NULL; struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_asrc_pair *pair = runtime->private_data; + struct dma_chan *tmp_chan = NULL, *be_chan = NULL; + struct snd_soc_component *component_be = NULL; struct fsl_asrc *asrc = pair->asrc; struct dma_slave_config config_fe, config_be; enum asrc_pair_index index = pair->index; @@ -142,7 +144,6 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, int stream = substream->stream; struct imx_dma_data *tmp_data; struct snd_soc_dpcm *dpcm; - struct dma_chan *tmp_chan; struct device *dev_be; u8 dir = tx ? OUT : IN; dma_cap_mask_t mask; @@ -198,17 +199,29 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, dma_cap_set(DMA_CYCLIC, mask); /* + * The Back-End device might have already requested a DMA channel, + * so try to reuse it first, and then request a new one upon NULL. + */ + component_be = snd_soc_lookup_component_nolocked(dev_be, SND_DMAENGINE_PCM_DRV_NAME); + if (component_be) { + be_chan = soc_component_to_pcm(component_be)->chan[substream->stream]; + tmp_chan = be_chan; + } + if (!tmp_chan) + tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx"); + + /* * An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each * peripheral, unlike SDMA channel that is allocated dynamically. So no - * need to configure dma_request and dma_request2, but get dma_chan via - * dma_request_slave_channel directly with dma name of Front-End device + * need to configure dma_request and dma_request2, but get dma_chan of + * Back-End device directly via dma_request_slave_channel. */ if (!asrc->use_edma) { /* Get DMA request of Back-End */ - tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx"); tmp_data = tmp_chan->private; pair->dma_data.dma_request = tmp_data->dma_request; - dma_release_channel(tmp_chan); + if (!be_chan) + dma_release_channel(tmp_chan); /* Get DMA request of Front-End */ tmp_chan = asrc->get_dma_channel(pair, dir); @@ -220,9 +233,11 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, pair->dma_chan[dir] = dma_request_channel(mask, filter, &pair->dma_data); + pair->req_dma_chan = true; } else { - pair->dma_chan[dir] = - asrc->get_dma_channel(pair, dir); + pair->dma_chan[dir] = tmp_chan; + /* Do not flag to release if we are reusing the Back-End one */ + pair->req_dma_chan = !be_chan; } if (!pair->dma_chan[dir]) { @@ -261,7 +276,8 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ret = dmaengine_slave_config(pair->dma_chan[dir], &config_be); if (ret) { dev_err(dev, "failed to config DMA channel for Back-End\n"); - dma_release_channel(pair->dma_chan[dir]); + if (pair->req_dma_chan) + dma_release_channel(pair->dma_chan[dir]); return ret; } @@ -273,19 +289,22 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, static int fsl_asrc_dma_hw_free(struct snd_soc_component *component, struct snd_pcm_substream *substream) { + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_asrc_pair *pair = runtime->private_data; + u8 dir = tx ? OUT : IN; snd_pcm_set_runtime_buffer(substream, NULL); - if (pair->dma_chan[IN]) - dma_release_channel(pair->dma_chan[IN]); + if (pair->dma_chan[!dir]) + dma_release_channel(pair->dma_chan[!dir]); - if (pair->dma_chan[OUT]) - dma_release_channel(pair->dma_chan[OUT]); + /* release dev_to_dev chan if we aren't reusing the Back-End one */ + if (pair->dma_chan[dir] && pair->req_dma_chan) + dma_release_channel(pair->dma_chan[dir]); - pair->dma_chan[IN] = NULL; - pair->dma_chan[OUT] = NULL; + pair->dma_chan[!dir] = NULL; + pair->dma_chan[dir] = NULL; return 0; } diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index 0c813a45bba7..69aeb0e71844 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -265,12 +265,20 @@ static int fsl_mqs_remove(struct platform_device *pdev) static int fsl_mqs_runtime_resume(struct device *dev) { struct fsl_mqs *mqs_priv = dev_get_drvdata(dev); + int ret; - if (mqs_priv->ipg) - clk_prepare_enable(mqs_priv->ipg); + ret = clk_prepare_enable(mqs_priv->ipg); + if (ret) { + dev_err(dev, "failed to enable ipg clock\n"); + return ret; + } - if (mqs_priv->mclk) - clk_prepare_enable(mqs_priv->mclk); + ret = clk_prepare_enable(mqs_priv->mclk); + if (ret) { + dev_err(dev, "failed to enable mclk clock\n"); + clk_disable_unprepare(mqs_priv->ipg); + return ret; + } if (mqs_priv->use_gpr) regmap_write(mqs_priv->regmap, IOMUXC_GPR2, @@ -292,11 +300,8 @@ static int fsl_mqs_runtime_suspend(struct device *dev) regmap_read(mqs_priv->regmap, REG_MQS_CTRL, &mqs_priv->reg_mqs_ctrl); - if (mqs_priv->mclk) - clk_disable_unprepare(mqs_priv->mclk); - - if (mqs_priv->ipg) - clk_disable_unprepare(mqs_priv->ipg); + clk_disable_unprepare(mqs_priv->mclk); + clk_disable_unprepare(mqs_priv->ipg); return 0; } diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index bad89b0d129e..1a2fa7f18142 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -678,8 +678,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, struct regmap *regs = ssi->regs; u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; unsigned long clkrate, baudrate, tmprate; - unsigned int slots = params_channels(hw_params); - unsigned int slot_width = 32; + unsigned int channels = params_channels(hw_params); + unsigned int slot_width = params_width(hw_params); + unsigned int slots = 2; u64 sub, savesub = 100000; unsigned int freq; bool baudclk_is_used; @@ -688,10 +689,14 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, /* Override slots and slot_width if being specifically set... */ if (ssi->slots) slots = ssi->slots; - /* ...but keep 32 bits if slots is 2 -- I2S Master mode */ - if (ssi->slot_width && slots != 2) + if (ssi->slot_width) slot_width = ssi->slot_width; + /* ...but force 32 bits for stereo audio using I2S Master Mode */ + if (channels == 2 && + (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) == SSI_SCR_I2S_MODE_MASTER) + slot_width = 32; + /* Generate bit clock based on the slot number and slot width */ freq = slots * slot_width * params_rate(hw_params); diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 9ad35d9940fe..97b4f5480a31 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -317,8 +317,8 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, if (ret < 0) goto out_put_node; - dai_link->dpcm_playback = 1; - dai_link->dpcm_capture = 1; + snd_soc_dai_link_set_capabilities(dai_link); + dai_link->ops = &graph_ops; dai_link->init = asoc_simple_dai_init; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 55e9f8800b3e..04d4d28ed511 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -231,8 +231,8 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, if (ret < 0) goto out_put_node; - dai_link->dpcm_playback = 1; - dai_link->dpcm_capture = 1; + snd_soc_dai_link_set_capabilities(dai_link); + dai_link->ops = &simple_ops; dai_link->init = asoc_simple_dai_init; diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index a2a5798c9139..5dc489a79454 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -492,7 +492,7 @@ config SND_SOC_INTEL_SOF_PCM512x_MACH endif ## SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL -if (SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK) +if (SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK) config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH tristate "CML_LP with DA7219 and MAX98357A in I2S Mode" @@ -520,7 +520,7 @@ config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH Say Y if you have such a device. If unsure select "N". -endif ## SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK +endif ## SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK if SND_SOC_SOF_JASPERLAKE diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index 5f96d7ac0a22..bed4d5f73d9c 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -354,6 +354,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { { .name = "Codec DSP", .stream_name = "Wake on Voice", + .capture_only = 1, .ops = &bdw_rt5677_dsp_ops, SND_SOC_DAILINK_REG(dsp), }, diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 9e5fc9430628..ecbc58e8a37f 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -543,8 +543,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) if (cnt) { ret = device_add_properties(codec_dev, props); - if (ret) + if (ret) { + put_device(codec_dev); return ret; + } } devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios); diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index 7a43c70a1378..22e432768edb 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -253,21 +253,20 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); /* - * Default mode for SSP configuration is TDM 4 slot + * Default mode for SSP configuration is TDM 4 slot. One board/design, + * the Lenovo Miix 2 10 uses not 1 but 2 codecs connected to SSP2. The + * second piggy-backed, output-only codec is inside the keyboard-dock + * (which has extra speakers). Unlike the main rt5672 codec, we cannot + * configure this codec, it is hard coded to use 2 channel 24 bit I2S. + * Since we only support 2 channels anyways, there is no need for TDM + * on any cht-bsw-rt5672 designs. So we simply use I2S 2ch everywhere. */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), - SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_IB_NF | + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) { - dev_err(rtd->dev, "can't set format to TDM %d\n", ret); - return ret; - } - - /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); - if (ret < 0) { - dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); + dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); return ret; } diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index f51b28d1b94d..92f51d0e9fe2 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -72,7 +72,7 @@ config SND_SOC_QDSP6_ASM_DAI config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" - depends on QCOM_APR && HAS_DMA + depends on QCOM_APR select SND_SOC_QDSP6_COMMON select SND_SOC_QDSP6_CORE select SND_SOC_QDSP6_AFE diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c index 6c20bdd850f3..8ada4ecba847 100644 --- a/sound/soc/qcom/common.c +++ b/sound/soc/qcom/common.c @@ -4,6 +4,7 @@ #include <linux/module.h> #include "common.h" +#include "qdsp6/q6afe.h" int qcom_snd_parse_of(struct snd_soc_card *card) { @@ -101,6 +102,15 @@ int qcom_snd_parse_of(struct snd_soc_card *card) } link->no_pcm = 1; link->ignore_pmdown_time = 1; + + if (q6afe_is_rx_port(link->id)) { + link->dpcm_playback = 1; + link->dpcm_capture = 0; + } else { + link->dpcm_playback = 0; + link->dpcm_capture = 1; + } + } else { dlc = devm_kzalloc(dev, sizeof(*dlc), GFP_KERNEL); if (!dlc) @@ -113,12 +123,12 @@ int qcom_snd_parse_of(struct snd_soc_card *card) link->codecs->dai_name = "snd-soc-dummy-dai"; link->codecs->name = "snd-soc-dummy"; link->dynamic = 1; + link->dpcm_playback = 1; + link->dpcm_capture = 1; } link->ignore_suspend = 1; link->nonatomic = 1; - link->dpcm_playback = 1; - link->dpcm_capture = 1; link->stream_name = link->name; link++; diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index e0945f7a58c8..0ce4eb60f984 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -800,6 +800,14 @@ int q6afe_get_port_id(int index) } EXPORT_SYMBOL_GPL(q6afe_get_port_id); +int q6afe_is_rx_port(int index) +{ + if (index < 0 || index >= AFE_PORT_MAX) + return -EINVAL; + + return port_maps[index].is_rx; +} +EXPORT_SYMBOL_GPL(q6afe_is_rx_port); static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt, struct q6afe_port *port) { diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h index c7ed5422baff..1a0f80a14afe 100644 --- a/sound/soc/qcom/qdsp6/q6afe.h +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -198,6 +198,7 @@ int q6afe_port_start(struct q6afe_port *port); int q6afe_port_stop(struct q6afe_port *port); void q6afe_port_put(struct q6afe_port *port); int q6afe_get_port_id(int index); +int q6afe_is_rx_port(int index); void q6afe_hdmi_port_prepare(struct q6afe_port *port, struct q6afe_hdmi_cfg *cfg); void q6afe_slim_port_prepare(struct q6afe_port *port, diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index 0e0e8f7a460a..ae4b2cabdf2d 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -25,6 +25,7 @@ #define ASM_STREAM_CMD_FLUSH 0x00010BCE #define ASM_SESSION_CMD_PAUSE 0x00010BD3 #define ASM_DATA_CMD_EOS 0x00010BDB +#define ASM_DATA_EVENT_RENDERED_EOS 0x00010C1C #define ASM_NULL_POPP_TOPOLOGY 0x00010C68 #define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 #define ASM_STREAM_CMD_SET_ENCDEC_PARAM 0x00010C10 @@ -622,9 +623,6 @@ static int32_t q6asm_stream_callback(struct apr_device *adev, case ASM_SESSION_CMD_SUSPEND: client_event = ASM_CLIENT_EVENT_CMD_SUSPEND_DONE; break; - case ASM_DATA_CMD_EOS: - client_event = ASM_CLIENT_EVENT_CMD_EOS_DONE; - break; case ASM_STREAM_CMD_FLUSH: client_event = ASM_CLIENT_EVENT_CMD_FLUSH_DONE; break; @@ -728,6 +726,9 @@ static int32_t q6asm_stream_callback(struct apr_device *adev, } break; + case ASM_DATA_EVENT_RENDERED_EOS: + client_event = ASM_CLIENT_EVENT_CMD_EOS_DONE; + break; } if (ac->cb) diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index f45e5aaa4b30..9539b0d024fe 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -219,19 +219,32 @@ static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, return 0; } +static int rockchip_sound_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; + return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, + 8000, 96000); +} + static const struct snd_soc_ops rockchip_sound_max98357a_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_max98357a_hw_params, }; static const struct snd_soc_ops rockchip_sound_rt5514_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_rt5514_hw_params, }; static const struct snd_soc_ops rockchip_sound_da7219_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_da7219_hw_params, }; static const struct snd_soc_ops rockchip_sound_dmic_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_dmic_hw_params, }; diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index 7cd42fcfcf38..1707414cfa92 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -590,8 +590,10 @@ static int rockchip_pdm_resume(struct device *dev) int ret; ret = pm_runtime_get_sync(dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put(dev); return ret; + } ret = regcache_sync(pdm->regmap); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 7b387202c5db..2b8abf88ec60 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -310,7 +310,7 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, } EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup); -static struct snd_soc_component +struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev, const char *driver_name) { struct snd_soc_component *component; @@ -329,6 +329,7 @@ static struct snd_soc_component return found_component; } +EXPORT_SYMBOL_GPL(snd_soc_lookup_component_nolocked); struct snd_soc_component *snd_soc_lookup_component(struct device *dev, const char *driver_name) @@ -2572,6 +2573,33 @@ int snd_soc_register_component(struct device *dev, EXPORT_SYMBOL_GPL(snd_soc_register_component); /** + * snd_soc_unregister_component_by_driver - Unregister component using a given driver + * from the ASoC core + * + * @dev: The device to unregister + * @component_driver: The component driver to unregister + */ +void snd_soc_unregister_component_by_driver(struct device *dev, + const struct snd_soc_component_driver *component_driver) +{ + struct snd_soc_component *component; + + if (!component_driver) + return; + + mutex_lock(&client_mutex); + component = snd_soc_lookup_component_nolocked(dev, component_driver->name); + if (!component) + goto out; + + snd_soc_del_component_unlocked(component); + +out: + mutex_unlock(&client_mutex); +} +EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver); + +/** * snd_soc_unregister_component - Unregister all related component * from the ASoC core * diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index b05e18b63a1c..457159975b01 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -391,6 +391,44 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir) return stream->channels_min; } +/* + * snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs + */ +void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link) +{ + struct snd_soc_dai_link_component *cpu; + struct snd_soc_dai_link_component *codec; + struct snd_soc_dai *dai; + bool supported[SNDRV_PCM_STREAM_LAST + 1]; + int direction; + int i; + + for_each_pcm_streams(direction) { + supported[direction] = true; + + for_each_link_cpus(dai_link, i, cpu) { + dai = snd_soc_find_dai(cpu); + if (!dai || !snd_soc_dai_stream_valid(dai, direction)) { + supported[direction] = false; + break; + } + } + if (!supported[direction]) + continue; + for_each_link_codecs(dai_link, i, codec) { + dai = snd_soc_find_dai(codec); + if (!dai || !snd_soc_dai_stream_valid(dai, direction)) { + supported[direction] = false; + break; + } + } + } + + dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK]; + dai_link->dpcm_capture = supported[SNDRV_PCM_STREAM_CAPTURE]; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities); + void snd_soc_dai_action(struct snd_soc_dai *dai, int stream, int action) { diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index a9ea172a66a7..4534a1c03e8e 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -9,9 +9,48 @@ #include <sound/soc.h> #include <sound/dmaengine_pcm.h> +static void devm_dai_release(struct device *dev, void *res) +{ + snd_soc_unregister_dai(*(struct snd_soc_dai **)res); +} + +/** + * devm_snd_soc_register_dai - resource-managed dai registration + * @dev: Device used to manage component + * @component: The component the DAIs are registered for + * @dai_drv: DAI driver to use for the DAI + * @legacy_dai_naming: if %true, use legacy single-name format; + * if %false, use multiple-name format; + */ +struct snd_soc_dai *devm_snd_soc_register_dai(struct device *dev, + struct snd_soc_component *component, + struct snd_soc_dai_driver *dai_drv, + bool legacy_dai_naming) +{ + struct snd_soc_dai **ptr; + struct snd_soc_dai *dai; + + ptr = devres_alloc(devm_dai_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + dai = snd_soc_register_dai(component, dai_drv, legacy_dai_naming); + if (dai) { + *ptr = dai; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return dai; +} +EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai); + static void devm_component_release(struct device *dev, void *res) { - snd_soc_unregister_component(*(struct device **)res); + const struct snd_soc_component_driver **cmpnt_drv = res; + + snd_soc_unregister_component_by_driver(dev, *cmpnt_drv); } /** @@ -28,7 +67,7 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai) { - struct device **ptr; + const struct snd_soc_component_driver **ptr; int ret; ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); @@ -37,7 +76,7 @@ int devm_snd_soc_register_component(struct device *dev, ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); if (ret == 0) { - *ptr = dev; + *ptr = cmpnt_drv; devres_add(dev, ptr); } else { devres_free(ptr); diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index f728309a0833..61844403f181 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -21,18 +21,6 @@ */ #define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(31) -struct dmaengine_pcm { - struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1]; - const struct snd_dmaengine_pcm_config *config; - struct snd_soc_component component; - unsigned int flags; -}; - -static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p) -{ - return container_of(p, struct dmaengine_pcm, component); -} - static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm, struct snd_pcm_substream *substream) { @@ -490,7 +478,7 @@ void snd_dmaengine_pcm_unregister(struct device *dev) pcm = soc_component_to_pcm(component); - snd_soc_unregister_component(dev); + snd_soc_unregister_component_by_driver(dev, component->driver); dmaengine_pcm_release_chan(pcm); kfree(pcm); } diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2c114b4542ce..c517064f5391 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2630,15 +2630,15 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new) int count, paths; int ret; + if (!fe->dai_link->dynamic) + return 0; + if (fe->num_cpus > 1) { dev_err(fe->dev, "%s doesn't support Multi CPU yet\n", __func__); return -EINVAL; } - if (!fe->dai_link->dynamic) - return 0; - /* only check active links */ if (!snd_soc_dai_active(asoc_rtd_to_cpu(fe, 0))) return 0; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 9e89633676b7..6eaa00c21011 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1261,17 +1261,29 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list); ret = soc_tplg_add_route(tplg, routes[i]); - if (ret < 0) + if (ret < 0) { + /* + * this route was added to the list, it will + * be freed in remove_route() so increment the + * counter to skip it in the error handling + * below. + */ + i++; break; + } /* add route, but keep going if some fail */ snd_soc_dapm_add_routes(dapm, routes[i], 1); } - /* free memory allocated for all dapm routes in case of error */ - if (ret < 0) - for (i = 0; i < count ; i++) - kfree(routes[i]); + /* + * free memory allocated for all dapm routes not added to the + * list in case of error + */ + if (ret < 0) { + while (i < count) + kfree(routes[i++]); + } /* * free pointer to array of dapm routes as this is no longer needed. @@ -1359,7 +1371,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( if (err < 0) { dev_err(tplg->dev, "ASoC: failed to init %s\n", mc->hdr.name); - soc_tplg_free_tlv(tplg, &kc[i]); goto err_sm; } } @@ -1367,6 +1378,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( err_sm: for (; i >= 0; i--) { + soc_tplg_free_tlv(tplg, &kc[i]); sm = (struct soc_mixer_control *)kc[i].private_value; kfree(sm); kfree(kc[i].name); @@ -1851,7 +1863,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list); /* register the DAI to the component */ - dai = snd_soc_register_dai(tplg->comp, dai_drv, false); + dai = devm_snd_soc_register_dai(tplg->comp->dev, tplg->comp, dai_drv, false); if (!dai) return -ENOMEM; @@ -1859,7 +1871,6 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, ret = snd_soc_dapm_new_dai_widgets(dapm, dai); if (ret != 0) { dev_err(dai->dev, "Failed to create DAI widgets %d\n", ret); - snd_soc_unregister_dai(dai); return ret; } diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 339c4930b0c0..adc7c37145d6 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -345,15 +345,15 @@ int snd_sof_device_remove(struct device *dev) struct snd_sof_pdata *pdata = sdev->pdata; int ret; - ret = snd_sof_dsp_power_down_notify(sdev); - if (ret < 0) - dev_warn(dev, "error: %d failed to prepare DSP for device removal", - ret); - if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) cancel_work_sync(&sdev->probe_work); if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { + ret = snd_sof_dsp_power_down_notify(sdev); + if (ret < 0) + dev_warn(dev, "error: %d failed to prepare DSP for device removal", + ret); + snd_sof_fw_unload(sdev); snd_sof_ipc_free(sdev); snd_sof_free_debug(sdev); diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 63f9c20a1bac..a4fa8451d8cb 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -375,6 +375,14 @@ static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev, static struct snd_soc_dai_driver imx8_dai[] = { { .name = "esai-port", + .playback = { + .channels_min = 1, + .channels_max = 8, + }, + .capture = { + .channels_min = 1, + .channels_max = 8, + }, }, }; diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index fa86a9e2990f..287114a37688 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -240,6 +240,14 @@ static int imx8m_ipc_pcm_params(struct snd_sof_dev *sdev, static struct snd_soc_dai_driver imx8m_dai[] = { { .name = "sai-port", + .playback = { + .channels_min = 1, + .channels_max = 32, + }, + .capture = { + .channels_min = 1, + .channels_max = 32, + }, }, }; diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index c9a2bee4b55c..3aaf25e4f766 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -25,8 +25,7 @@ config SND_SOC_SOF_INTEL_PCI select SND_SOC_SOF_CANNONLAKE if SND_SOC_SOF_CANNONLAKE_SUPPORT select SND_SOC_SOF_COFFEELAKE if SND_SOC_SOF_COFFEELAKE_SUPPORT select SND_SOC_SOF_ICELAKE if SND_SOC_SOF_ICELAKE_SUPPORT - select SND_SOC_SOF_COMETLAKE_LP if SND_SOC_SOF_COMETLAKE_LP_SUPPORT - select SND_SOC_SOF_COMETLAKE_H if SND_SOC_SOF_COMETLAKE_H_SUPPORT + select SND_SOC_SOF_COMETLAKE if SND_SOC_SOF_COMETLAKE_SUPPORT select SND_SOC_SOF_TIGERLAKE if SND_SOC_SOF_TIGERLAKE_SUPPORT select SND_SOC_SOF_ELKHARTLAKE if SND_SOC_SOF_ELKHARTLAKE_SUPPORT select SND_SOC_SOF_JASPERLAKE if SND_SOC_SOF_JASPERLAKE_SUPPORT @@ -201,34 +200,22 @@ config SND_SOC_SOF_ICELAKE This option is not user-selectable but automagically handled by 'select' statements at a higher level -config SND_SOC_SOF_COMETLAKE_LP +config SND_SOC_SOF_COMETLAKE tristate select SND_SOC_SOF_HDA_COMMON help This option is not user-selectable but automagically handled by 'select' statements at a higher level -config SND_SOC_SOF_COMETLAKE_LP_SUPPORT - bool "SOF support for CometLake-LP" - help - This adds support for Sound Open Firmware for Intel(R) platforms - using the Cometlake-LP processors. - Say Y if you have such a device. - If unsure select "N". +config SND_SOC_SOF_COMETLAKE_SUPPORT + bool -config SND_SOC_SOF_COMETLAKE_H - tristate - select SND_SOC_SOF_HDA_COMMON - help - This option is not user-selectable but automagically handled by - 'select' statements at a higher level - -config SND_SOC_SOF_COMETLAKE_H_SUPPORT - bool "SOF support for CometLake-H" +config SND_SOC_SOF_COMETLAKE_LP_SUPPORT + bool "SOF support for CometLake" + select SND_SOC_SOF_COMETLAKE_SUPPORT help This adds support for Sound Open Firmware for Intel(R) platforms - using the Cometlake-H processors. - Say Y if you have such a device. + using the Cometlake processors. If unsure select "N". config SND_SOC_SOF_TIGERLAKE_SUPPORT diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 7f65dcc95811..1bda14c3590c 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -653,11 +653,16 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context) if (status & AZX_INT_CTRL_EN) { rirb_status = snd_hdac_chip_readb(bus, RIRBSTS); if (rirb_status & RIRB_INT_MASK) { + /* + * Clearing the interrupt status here ensures + * that no interrupt gets masked after the RIRB + * wp is read in snd_hdac_bus_update_rirb. + */ + snd_hdac_chip_writeb(bus, RIRBSTS, + RIRB_INT_MASK); active = true; if (rirb_status & RIRB_INT_RESPONSE) snd_hdac_bus_update_rirb(bus); - snd_hdac_chip_writeb(bus, RIRBSTS, - RIRB_INT_MASK); } } #endif diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index b13697dab7c0..aa3532ba1434 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -151,9 +151,7 @@ static const struct sof_dev_desc cfl_desc = { }; #endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP) || \ - IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_H) - +#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) static const struct sof_dev_desc cml_desc = { .machines = snd_soc_acpi_intel_cml_machines, .alt_machines = snd_soc_acpi_intel_cml_sdw_machines, @@ -411,8 +409,11 @@ static const struct pci_device_id sof_pci_ids[] = { .driver_data = (unsigned long)&cfl_desc}, #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) - { PCI_DEVICE(0x8086, 0x34C8), + { PCI_DEVICE(0x8086, 0x34C8), /* ICL-LP */ + .driver_data = (unsigned long)&icl_desc}, + { PCI_DEVICE(0x8086, 0x3dc8), /* ICL-H */ .driver_data = (unsigned long)&icl_desc}, + #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) { PCI_DEVICE(0x8086, 0x38c8), @@ -420,17 +421,20 @@ static const struct pci_device_id sof_pci_ids[] = { { PCI_DEVICE(0x8086, 0x4dc8), .driver_data = (unsigned long)&jsl_desc}, #endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP) - { PCI_DEVICE(0x8086, 0x02c8), +#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) + { PCI_DEVICE(0x8086, 0x02c8), /* CML-LP */ .driver_data = (unsigned long)&cml_desc}, -#endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_H) - { PCI_DEVICE(0x8086, 0x06c8), + { PCI_DEVICE(0x8086, 0x06c8), /* CML-H */ + .driver_data = (unsigned long)&cml_desc}, + { PCI_DEVICE(0x8086, 0xa3f0), /* CML-S */ .driver_data = (unsigned long)&cml_desc}, #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) - { PCI_DEVICE(0x8086, 0xa0c8), + { PCI_DEVICE(0x8086, 0xa0c8), /* TGL-LP */ + .driver_data = (unsigned long)&tgl_desc}, + { PCI_DEVICE(0x8086, 0x43c8), /* TGL-H */ .driver_data = (unsigned long)&tgl_desc}, + #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) { PCI_DEVICE(0x8086, 0x4b55), |