^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // This file is provided under a dual BSD/GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright(c) 2018 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Authors: Keyon Jie <yang.jie@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/hdaudio_ext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "../sof-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "../sof-audio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "hda.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct hda_pipe_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) u8 host_dma_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u8 link_dma_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u32 ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u32 s_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u32 s_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u8 linktype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) snd_pcm_format_t format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int link_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int host_bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned int link_bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * This function checks if the host dma channel corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * to the link DMA stream_tag argument is assigned to one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * of the FEs connected to the BE DAI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static bool hda_check_fes(struct snd_soc_pcm_runtime *rtd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int dir, int stream_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct snd_pcm_substream *fe_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct hdac_stream *fe_hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct snd_soc_dpcm *dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) for_each_dpcm_fe(rtd, dir, dpcm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) fe_hstream = fe_substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (fe_hstream->stream_tag == stream_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct hdac_ext_stream *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) hda_link_stream_assign(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct hdac_ext_stream *res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct hdac_stream *stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int stream_dir = substream->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!bus->ppcap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dev_err(bus->dev, "stream type not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) spin_lock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) list_for_each_entry(stream, &bus->stream_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct hdac_ext_stream *hstream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) stream_to_hdac_ext_stream(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (stream->direction != substream->stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) hda_stream = hstream_to_sof_hda_stream(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* check if link is available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!hstream->link_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (stream->opened) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * check if the stream tag matches the stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * tag of one of the connected FEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (hda_check_fes(rtd, stream_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) stream->stream_tag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) res = hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) res = hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * This must be a hostless stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * So reserve the host DMA channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) hda_stream->host_reserved = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Decouple host and link DMA. The decoupled flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * is updated in snd_hdac_ext_stream_decouple().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!res->decoupled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) snd_hdac_ext_stream_decouple_locked(bus, res, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) res->link_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) res->link_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spin_unlock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int hda_link_dma_params(struct hdac_ext_stream *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct hda_pipe_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct hdac_stream *hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned char stream_tag = hstream->stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct hdac_bus *bus = hstream->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct hdac_ext_link *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int format_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) snd_hdac_ext_stream_decouple(bus, stream, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) snd_hdac_ext_link_stream_reset(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) params->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) params->link_bps, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_dbg(bus->dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) format_val, params->s_freq, params->ch, params->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) snd_hdac_ext_link_stream_setup(stream, format_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) list_for_each_entry(link, &bus->hlink_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (link->index == params->link_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) snd_hdac_ext_link_set_stream_id(link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) stream_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) stream->link_prepared = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Send DAI_CONFIG IPC to the DAI that matches the dai_name and direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int hda_link_config_ipc(struct sof_intel_hda_stream *hda_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) const char *dai_name, int channel, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct sof_ipc_dai_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct snd_sof_dai *sof_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct sof_ipc_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) list_for_each_entry(sof_dai, &hda_stream->sdev->dai_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!sof_dai->cpu_dai_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!strcmp(dai_name, sof_dai->cpu_dai_name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dir == sof_dai->comp_dai.direction) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) config = sof_dai->dai_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (!config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dev_err(hda_stream->sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "error: no config for DAI %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) sof_dai->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* update config with stream tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) config->hda.link_dma_ch = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* send IPC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ret = sof_ipc_tx_message(hda_stream->sdev->ipc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) config->hdr.cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) config->hdr.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) &reply, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_err(hda_stream->sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "error: failed to set dai config for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) sof_dai->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int hda_link_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct hdac_stream *hstream = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct hdac_bus *bus = hstream->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct hdac_ext_stream *link_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct hda_pipe_params p_params = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct hdac_ext_link *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* get stored dma data if resuming from system suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) link_dev = snd_soc_dai_get_dma_data(dai, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!link_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) link_dev = hda_link_stream_assign(bus, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!link_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) stream_tag = hdac_stream(link_dev)->stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) hda_stream = hstream_to_sof_hda_stream(link_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* update the DSP with the new tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = hda_link_config_ipc(hda_stream, dai->name, stream_tag - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* set the stream tag in the codec dai dma params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) snd_soc_dai_set_tdm_slot(codec_dai, stream_tag, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) snd_soc_dai_set_tdm_slot(codec_dai, 0, stream_tag, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) p_params.s_fmt = snd_pcm_format_width(params_format(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) p_params.ch = params_channels(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) p_params.s_freq = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) p_params.stream = substream->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) p_params.link_dma_id = stream_tag - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) p_params.link_index = link->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) p_params.format = params_format(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) p_params.link_bps = codec_dai->driver->playback.sig_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) p_params.link_bps = codec_dai->driver->capture.sig_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return hda_link_dma_params(link_dev, &p_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct hdac_ext_stream *link_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) snd_soc_dai_get_dma_data(dai, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct snd_sof_dev *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) snd_soc_component_get_drvdata(dai->component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int stream = substream->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (link_dev->link_prepared)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev_dbg(sdev->dev, "hda: prepare stream dir %d\n", substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return hda_link_hw_params(substream, &rtd->dpcm[stream].hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int cmd, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct hdac_ext_stream *link_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) snd_soc_dai_get_dma_data(dai, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct snd_soc_pcm_runtime *rtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct hdac_ext_link *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct hdac_stream *hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct hdac_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) hstream = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) bus = hstream->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (!link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) hda_stream = hstream_to_sof_hda_stream(link_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* set up hw_params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = hda_link_pcm_prepare(substream, dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev_err(dai->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) "error: setting up hw_params during resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) snd_hdac_ext_link_stream_start(link_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * clear link DMA channel. It will be assigned when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * hw_params is set up again after resume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ret = hda_link_config_ipc(hda_stream, dai->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) DMA_CHAN_INVALID, substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) stream_tag = hdac_stream(link_dev)->stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) snd_hdac_ext_link_clear_stream_id(link, stream_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) link_dev->link_prepared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) snd_hdac_ext_link_stream_clear(link_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int hda_link_hw_free(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct hdac_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct hdac_ext_link *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct hdac_stream *hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct snd_soc_pcm_runtime *rtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct hdac_ext_stream *link_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) hstream = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) bus = hstream->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) link_dev = snd_soc_dai_get_dma_data(dai, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!link_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev_dbg(dai->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) "%s: link_dev is not assigned\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) hda_stream = hstream_to_sof_hda_stream(link_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* free the link DMA channel in the FW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = hda_link_config_ipc(hda_stream, dai->name, DMA_CHAN_INVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) substream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (!link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) stream_tag = hdac_stream(link_dev)->stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) snd_hdac_ext_link_clear_stream_id(link, stream_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) snd_soc_dai_set_dma_data(dai, substream, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) link_dev->link_prepared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* free the host DMA channel reserved by hostless streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) hda_stream->host_reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static const struct snd_soc_dai_ops hda_link_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .hw_params = hda_link_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .hw_free = hda_link_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .trigger = hda_link_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .prepare = hda_link_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #include "../compress.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static struct snd_soc_cdai_ops sof_probe_compr_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .startup = sof_probe_compr_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .shutdown = sof_probe_compr_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .set_params = sof_probe_compr_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .trigger = sof_probe_compr_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .pointer = sof_probe_compr_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * common dai driver for skl+ platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * some products who use this DAI array only physically have a subset of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * the DAIs, but no harm is done here by adding the whole set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct snd_soc_dai_driver skl_dai[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .name = "SSP0 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .name = "SSP1 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .name = "SSP2 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .name = "SSP3 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .name = "SSP4 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .name = "SSP5 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .name = "DMIC01 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .channels_max = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .name = "DMIC16k Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .channels_max = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .name = "iDisp1 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .name = "iDisp2 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .name = "iDisp3 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .name = "iDisp4 Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .name = "Analog CPU DAI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .channels_max = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .channels_max = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .name = "Digital CPU DAI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .channels_max = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .channels_max = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .name = "Alt Analog CPU DAI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .ops = &hda_link_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .channels_max = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .channels_max = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .name = "Probe Extraction CPU DAI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .compress_new = snd_soc_new_compress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .cops = &sof_probe_compr_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .stream_name = "Probe Extraction",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .rates = SNDRV_PCM_RATE_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .rate_min = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) };