Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: SOF: Intel: improve and extend HDaudio-based

Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

For LunarLake, the SoundWire in-band wake detection is reported with
the HDAudio WAKE_EN/WAKE_STS registers. In the existing code, these
registers are only handled for HDaudio codecs. Now the same registers
have to be handled with care as shared resources.

The in-band wake detection mainly used for jack detection. Without
this patchset, the SoundWire headset codecs signal an event that would
be ignored and not reported.

+38 -4
+12 -3
sound/soc/sof/intel/hda-codec.c
··· 79 79 struct hdac_bus *bus = sof_to_bus(sdev); 80 80 struct hda_codec *codec; 81 81 unsigned int mask = 0; 82 + unsigned int val = 0; 82 83 83 84 if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && 84 85 sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) 85 86 return; 86 87 87 88 if (enable) { 88 - list_for_each_codec(codec, hbus) 89 + list_for_each_codec(codec, hbus) { 90 + /* only set WAKEEN when needed for HDaudio codecs */ 91 + mask |= BIT(codec->core.addr); 89 92 if (codec->jacktbl.used) 90 - mask |= BIT(codec->core.addr); 93 + val |= BIT(codec->core.addr); 94 + } 95 + } else { 96 + list_for_each_codec(codec, hbus) { 97 + /* reset WAKEEN only HDaudio codecs */ 98 + mask |= BIT(codec->core.addr); 99 + } 91 100 } 92 101 93 - snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask); 102 + snd_hdac_chip_updatew(bus, WAKEEN, mask & STATESTS_INT_MASK, val); 94 103 } 95 104 EXPORT_SYMBOL_NS_GPL(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC); 96 105
+8 -1
sound/soc/sof/intel/hda-ctrl.c
··· 184 184 struct hdac_bus *bus = sof_to_bus(sdev); 185 185 struct hdac_stream *stream; 186 186 int sd_offset, ret = 0; 187 + u32 gctl; 187 188 188 189 if (bus->chip_init) 189 190 return 0; ··· 192 191 hda_codec_set_codec_wakeup(sdev, true); 193 192 194 193 hda_dsp_ctrl_misc_clock_gating(sdev, false); 194 + 195 + /* clear WAKE_STS if not in reset */ 196 + gctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCTL); 197 + if (gctl & SOF_HDA_GCTL_RESET) 198 + snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, 199 + SOF_HDA_WAKESTS, SOF_HDA_WAKESTS_INT_MASK); 195 200 196 201 /* reset HDA controller */ 197 202 ret = hda_dsp_ctrl_link_reset(sdev, true); ··· 228 221 229 222 /* clear WAKESTS */ 230 223 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS, 231 - SOF_HDA_WAKESTS_INT_MASK); 224 + bus->codec_mask); 232 225 233 226 hda_codec_rirb_status_clear(sdev); 234 227
+18
sound/soc/sof/intel/lnl.c
··· 189 189 return mtl_enable_interrupts(sdev, false); 190 190 } 191 191 192 + static bool lnl_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) 193 + { 194 + struct hdac_bus *bus = sof_to_bus(sdev); 195 + u16 wake_sts; 196 + 197 + /* 198 + * we need to use the global HDaudio WAKEEN/STS to be able to 199 + * detect wakes in low-power modes. The link-specific information 200 + * is handled in the process_wakeen() helper, this helper only 201 + * detects a SoundWire wake without identifying the link. 202 + */ 203 + wake_sts = snd_hdac_chip_readw(bus, STATESTS); 204 + 205 + /* filter out the range of SDIs that can be set for SoundWire */ 206 + return wake_sts & GENMASK(SDW_MAX_DEVICES, SDW_INTEL_DEV_NUM_IDA_MIN); 207 + } 208 + 192 209 const struct sof_intel_dsp_desc lnl_chip_info = { 193 210 .cores_num = 5, 194 211 .init_core_mask = BIT(0), ··· 222 205 .read_sdw_lcount = hda_sdw_check_lcount_ext, 223 206 .enable_sdw_irq = lnl_enable_sdw_irq, 224 207 .check_sdw_irq = lnl_dsp_check_sdw_irq, 208 + .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, 225 209 .check_ipc_irq = mtl_dsp_check_ipc_irq, 226 210 .cl_init = mtl_dsp_cl_init, 227 211 .power_down_dsp = mtl_power_down_dsp,