]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - sound/soc/intel/skylake/skl-pcm.c
ASoC: Intel: Skylake: Add multichannel support for HDMI
[karo-tx-linux.git] / sound / soc / intel / skylake / skl-pcm.c
index b6e6b61d10ec22349650ee5c1db3074068a180e4..8de921272f718a1d74f489b92d532ee716b8804a 100644 (file)
@@ -51,7 +51,7 @@ static struct snd_pcm_hardware azx_pcm_hw = {
        .rate_min =             8000,
        .rate_max =             48000,
        .channels_min =         1,
-       .channels_max =         HDA_QUAD,
+       .channels_max =         8,
        .buffer_bytes_max =     AZX_MAX_BUF_SIZE,
        .period_bytes_min =     128,
        .period_bytes_max =     AZX_MAX_BUF_SIZE / 2,
@@ -206,6 +206,23 @@ static int skl_get_format(struct snd_pcm_substream *substream,
        return format_val;
 }
 
+static int skl_be_prepare(struct snd_pcm_substream *substream,
+               struct snd_soc_dai *dai)
+{
+       struct skl *skl = get_skl_ctx(dai->dev);
+       struct skl_sst *ctx = skl->skl_sst;
+       struct skl_module_cfg *mconfig;
+
+       if ((dai->playback_active > 1) || (dai->capture_active > 1))
+               return 0;
+
+       mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
+       if (mconfig == NULL)
+               return -EINVAL;
+
+       return skl_dsp_set_dma_control(ctx, mconfig);
+}
+
 static int skl_pcm_prepare(struct snd_pcm_substream *substream,
                struct snd_soc_dai *dai)
 {
@@ -458,7 +475,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
        struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
        struct hdac_ext_stream *link_dev;
        struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
-       struct skl_dma_params *dma_params;
+       struct hdac_ext_dma_params *dma_params;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct skl_pipe_params p_params = {0};
 
@@ -470,11 +487,9 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
        snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
 
        /* set the stream tag in the codec dai dma params  */
-       dma_params = (struct skl_dma_params *)
-                       snd_soc_dai_get_dma_data(codec_dai, substream);
+       dma_params = snd_soc_dai_get_dma_data(codec_dai, substream);
        if (dma_params)
                dma_params->stream_tag =  hdac_stream(link_dev)->stream_tag;
-       snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params);
 
        p_params.s_fmt = snd_pcm_format_width(params_format(params));
        p_params.ch = params_channels(params);
@@ -588,6 +603,7 @@ static struct snd_soc_dai_ops skl_dmic_dai_ops = {
 
 static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
        .hw_params = skl_be_hw_params,
+       .prepare = skl_be_prepare,
 };
 
 static struct snd_soc_dai_ops skl_link_dai_ops = {
@@ -660,6 +676,51 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
                .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
        },
 },
+{
+       .name = "HDMI1 Pin",
+       .ops = &skl_pcm_dai_ops,
+       .playback = {
+               .stream_name = "HDMI1 Playback",
+               .channels_min = HDA_STEREO,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+                       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
+                       SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
+                       SNDRV_PCM_RATE_192000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
+                       SNDRV_PCM_FMTBIT_S32_LE,
+       },
+},
+{
+       .name = "HDMI2 Pin",
+       .ops = &skl_pcm_dai_ops,
+       .playback = {
+               .stream_name = "HDMI2 Playback",
+               .channels_min = HDA_STEREO,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+                       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
+                       SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
+                       SNDRV_PCM_RATE_192000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
+                       SNDRV_PCM_FMTBIT_S32_LE,
+       },
+},
+{
+       .name = "HDMI3 Pin",
+       .ops = &skl_pcm_dai_ops,
+       .playback = {
+               .stream_name = "HDMI3 Playback",
+               .channels_min = HDA_STEREO,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+                       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
+                       SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
+                       SNDRV_PCM_RATE_192000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
+                       SNDRV_PCM_FMTBIT_S32_LE,
+       },
+},
 
 /* BE CPU  Dais */
 {
@@ -699,14 +760,41 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
        },
 },
 {
-       .name = "iDisp Pin",
+       .name = "iDisp1 Pin",
        .ops = &skl_link_dai_ops,
        .playback = {
-               .stream_name = "iDisp Tx",
+               .stream_name = "iDisp1 Tx",
                .channels_min = HDA_STEREO,
-               .channels_max = HDA_STEREO,
+               .channels_max = 8,
                .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
+                       SNDRV_PCM_FMTBIT_S24_LE,
+       },
+},
+{
+       .name = "iDisp2 Pin",
+       .ops = &skl_link_dai_ops,
+       .playback = {
+               .stream_name = "iDisp2 Tx",
+               .channels_min = HDA_STEREO,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
+                       SNDRV_PCM_RATE_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
+                       SNDRV_PCM_FMTBIT_S24_LE,
+       },
+},
+{
+       .name = "iDisp3 Pin",
+       .ops = &skl_link_dai_ops,
+       .playback = {
+               .stream_name = "iDisp3 Tx",
+               .channels_min = HDA_STEREO,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
+                       SNDRV_PCM_RATE_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
+                       SNDRV_PCM_FMTBIT_S24_LE,
        },
 },
 {
@@ -863,7 +951,9 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus,
                else
                        delay += hstream->bufsize;
        }
-       delay = (hstream->bufsize == delay) ? 0 : delay;
+
+       if (hstream->bufsize == delay)
+               delay = 0;
 
        if (delay >= hstream->period_bytes) {
                dev_info(bus->dev,