aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-05-13 09:27:16 -0400
committerMark Brown <broonie@kernel.org>2016-05-13 09:27:16 -0400
commit515511a7920c69aebf7f5fef0cb8e1df6767f34c (patch)
tree2cd9ac2853bb11aa2eeb766bb18c0b1846d8d941
parent180bc41ad11b9a7ec5b420fbcef6570163d09204 (diff)
parent8f658815da156a9239b98b34e5ba1d3db71a2f6e (diff)
Merge remote-tracking branch 'asoc/topic/hdmi' into asoc-next
-rw-r--r--include/sound/hdmi-codec.h100
-rw-r--r--include/sound/pcm_iec958.h2
-rw-r--r--sound/core/pcm_iec958.c65
-rw-r--r--sound/hda/local.h10
-rw-r--r--sound/soc/codecs/Kconfig6
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/hdac_hdmi.c163
-rw-r--r--sound/soc/codecs/hdmi-codec.c432
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c74
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c73
-rw-r--r--sound/soc/intel/boards/skl_rt286.c48
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c14
-rw-r--r--sound/soc/intel/skylake/skl-topology.c21
13 files changed, 969 insertions, 41 deletions
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
new file mode 100644
index 000000000000..fc3a481ad91e
--- /dev/null
+++ b/include/sound/hdmi-codec.h
@@ -0,0 +1,100 @@
1/*
2 * hdmi-codec.h - HDMI Codec driver API
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Author: Jyri Sarha <jsarha@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __HDMI_CODEC_H__
19#define __HDMI_CODEC_H__
20
21#include <linux/hdmi.h>
22#include <drm/drm_edid.h>
23#include <sound/asoundef.h>
24#include <uapi/sound/asound.h>
25
26/*
27 * Protocol between ASoC cpu-dai and HDMI-encoder
28 */
29struct hdmi_codec_daifmt {
30 enum {
31 HDMI_I2S,
32 HDMI_RIGHT_J,
33 HDMI_LEFT_J,
34 HDMI_DSP_A,
35 HDMI_DSP_B,
36 HDMI_AC97,
37 HDMI_SPDIF,
38 } fmt;
39 int bit_clk_inv:1;
40 int frame_clk_inv:1;
41 int bit_clk_master:1;
42 int frame_clk_master:1;
43};
44
45/*
46 * HDMI audio parameters
47 */
48struct hdmi_codec_params {
49 struct hdmi_audio_infoframe cea;
50 struct snd_aes_iec958 iec;
51 int sample_rate;
52 int sample_width;
53 int channels;
54};
55
56struct hdmi_codec_ops {
57 /*
58 * Called when ASoC starts an audio stream setup.
59 * Optional
60 */
61 int (*audio_startup)(struct device *dev);
62
63 /*
64 * Configures HDMI-encoder for audio stream.
65 * Mandatory
66 */
67 int (*hw_params)(struct device *dev,
68 struct hdmi_codec_daifmt *fmt,
69 struct hdmi_codec_params *hparms);
70
71 /*
72 * Shuts down the audio stream.
73 * Mandatory
74 */
75 void (*audio_shutdown)(struct device *dev);
76
77 /*
78 * Mute/unmute HDMI audio stream.
79 * Optional
80 */
81 int (*digital_mute)(struct device *dev, bool enable);
82
83 /*
84 * Provides EDID-Like-Data from connected HDMI device.
85 * Optional
86 */
87 int (*get_eld)(struct device *dev, uint8_t *buf, size_t len);
88};
89
90/* HDMI codec initalization data */
91struct hdmi_codec_pdata {
92 const struct hdmi_codec_ops *ops;
93 uint i2s:1;
94 uint spdif:1;
95 int max_i2s_channels;
96};
97
98#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
99
100#endif /* __HDMI_CODEC_H__ */
diff --git a/include/sound/pcm_iec958.h b/include/sound/pcm_iec958.h
index 0eed397aca8e..36f023acb201 100644
--- a/include/sound/pcm_iec958.h
+++ b/include/sound/pcm_iec958.h
@@ -6,4 +6,6 @@
6int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, 6int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
7 size_t len); 7 size_t len);
8 8
9int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
10 u8 *cs, size_t len);
9#endif 11#endif
diff --git a/sound/core/pcm_iec958.c b/sound/core/pcm_iec958.c
index 36b2d7aca1bd..5e6aed64f451 100644
--- a/sound/core/pcm_iec958.c
+++ b/sound/core/pcm_iec958.c
@@ -9,30 +9,18 @@
9#include <linux/types.h> 9#include <linux/types.h>
10#include <sound/asoundef.h> 10#include <sound/asoundef.h>
11#include <sound/pcm.h> 11#include <sound/pcm.h>
12#include <sound/pcm_params.h>
12#include <sound/pcm_iec958.h> 13#include <sound/pcm_iec958.h>
13 14
14/** 15static int create_iec958_consumer(uint rate, uint sample_width,
15 * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status 16 u8 *cs, size_t len)
16 * @runtime: pcm runtime structure with ->rate filled in
17 * @cs: channel status buffer, at least four bytes
18 * @len: length of channel status buffer
19 *
20 * Create the consumer format channel status data in @cs of maximum size
21 * @len corresponding to the parameters of the PCM runtime @runtime.
22 *
23 * Drivers may wish to tweak the contents of the buffer after creation.
24 *
25 * Returns: length of buffer, or negative error code if something failed.
26 */
27int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
28 size_t len)
29{ 17{
30 unsigned int fs, ws; 18 unsigned int fs, ws;
31 19
32 if (len < 4) 20 if (len < 4)
33 return -EINVAL; 21 return -EINVAL;
34 22
35 switch (runtime->rate) { 23 switch (rate) {
36 case 32000: 24 case 32000:
37 fs = IEC958_AES3_CON_FS_32000; 25 fs = IEC958_AES3_CON_FS_32000;
38 break; 26 break;
@@ -59,7 +47,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
59 } 47 }
60 48
61 if (len > 4) { 49 if (len > 4) {
62 switch (snd_pcm_format_width(runtime->format)) { 50 switch (sample_width) {
63 case 16: 51 case 16:
64 ws = IEC958_AES4_CON_WORDLEN_20_16; 52 ws = IEC958_AES4_CON_WORDLEN_20_16;
65 break; 53 break;
@@ -71,6 +59,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
71 IEC958_AES4_CON_MAX_WORDLEN_24; 59 IEC958_AES4_CON_MAX_WORDLEN_24;
72 break; 60 break;
73 case 24: 61 case 24:
62 case 32: /* Assume 24-bit width for 32-bit samples. */
74 ws = IEC958_AES4_CON_WORDLEN_24_20 | 63 ws = IEC958_AES4_CON_WORDLEN_24_20 |
75 IEC958_AES4_CON_MAX_WORDLEN_24; 64 IEC958_AES4_CON_MAX_WORDLEN_24;
76 break; 65 break;
@@ -92,4 +81,46 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
92 81
93 return len; 82 return len;
94} 83}
84
85/**
86 * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
87 * @runtime: pcm runtime structure with ->rate filled in
88 * @cs: channel status buffer, at least four bytes
89 * @len: length of channel status buffer
90 *
91 * Create the consumer format channel status data in @cs of maximum size
92 * @len corresponding to the parameters of the PCM runtime @runtime.
93 *
94 * Drivers may wish to tweak the contents of the buffer after creation.
95 *
96 * Returns: length of buffer, or negative error code if something failed.
97 */
98int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
99 size_t len)
100{
101 return create_iec958_consumer(runtime->rate,
102 snd_pcm_format_width(runtime->format),
103 cs, len);
104}
95EXPORT_SYMBOL(snd_pcm_create_iec958_consumer); 105EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
106
107/**
108 * snd_pcm_create_iec958_consumer_hw_params - create IEC958 channel status
109 * @hw_params: the hw_params instance for extracting rate and sample format
110 * @cs: channel status buffer, at least four bytes
111 * @len: length of channel status buffer
112 *
113 * Create the consumer format channel status data in @cs of maximum size
114 * @len corresponding to the parameters of the PCM runtime @runtime.
115 *
116 * Drivers may wish to tweak the contents of the buffer after creation.
117 *
118 * Returns: length of buffer, or negative error code if something failed.
119 */
120int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
121 u8 *cs, size_t len)
122{
123 return create_iec958_consumer(params_rate(params), params_width(params),
124 cs, len);
125}
126EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);
diff --git a/sound/hda/local.h b/sound/hda/local.h
index d692f417ddc0..0d5bb159d538 100644
--- a/sound/hda/local.h
+++ b/sound/hda/local.h
@@ -16,6 +16,16 @@ static inline int get_wcaps_type(unsigned int wcaps)
16 return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 16 return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
17} 17}
18 18
19static inline unsigned int get_wcaps_channels(u32 wcaps)
20{
21 unsigned int chans;
22
23 chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
24 chans = (chans + 1) * 2;
25
26 return chans;
27}
28
19extern const struct attribute_group *hdac_dev_attr_groups[]; 29extern const struct attribute_group *hdac_dev_attr_groups[];
20int hda_widget_sysfs_init(struct hdac_device *codec); 30int hda_widget_sysfs_init(struct hdac_device *codec);
21void hda_widget_sysfs_exit(struct hdac_device *codec); 31void hda_widget_sysfs_exit(struct hdac_device *codec);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 26ae0b5d3e16..b3afae990e39 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -88,6 +88,7 @@ config SND_SOC_ALL_CODECS
88 select SND_SOC_MC13783 if MFD_MC13XXX 88 select SND_SOC_MC13783 if MFD_MC13XXX
89 select SND_SOC_ML26124 if I2C 89 select SND_SOC_ML26124 if I2C
90 select SND_SOC_NAU8825 if I2C 90 select SND_SOC_NAU8825 if I2C
91 select SND_SOC_HDMI_CODEC
91 select SND_SOC_PCM1681 if I2C 92 select SND_SOC_PCM1681 if I2C
92 select SND_SOC_PCM179X_I2C if I2C 93 select SND_SOC_PCM179X_I2C if I2C
93 select SND_SOC_PCM179X_SPI if SPI_MASTER 94 select SND_SOC_PCM179X_SPI if SPI_MASTER
@@ -478,6 +479,11 @@ config SND_SOC_BT_SCO
478config SND_SOC_DMIC 479config SND_SOC_DMIC
479 tristate 480 tristate
480 481
482config SND_SOC_HDMI_CODEC
483 tristate
484 select SND_PCM_ELD
485 select SND_PCM_IEC958
486
481config SND_SOC_ES8328 487config SND_SOC_ES8328
482 tristate "Everest Semi ES8328 CODEC" 488 tristate "Everest Semi ES8328 CODEC"
483 489
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4532a743b5f8..b7b99416537f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -81,6 +81,7 @@ snd-soc-max9850-objs := max9850.o
81snd-soc-mc13783-objs := mc13783.o 81snd-soc-mc13783-objs := mc13783.o
82snd-soc-ml26124-objs := ml26124.o 82snd-soc-ml26124-objs := ml26124.o
83snd-soc-nau8825-objs := nau8825.o 83snd-soc-nau8825-objs := nau8825.o
84snd-soc-hdmi-codec-objs := hdmi-codec.o
84snd-soc-pcm1681-objs := pcm1681.o 85snd-soc-pcm1681-objs := pcm1681.o
85snd-soc-pcm179x-codec-objs := pcm179x.o 86snd-soc-pcm179x-codec-objs := pcm179x.o
86snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o 87snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o
@@ -291,6 +292,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
291obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 292obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
292obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 293obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
293obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 294obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
295obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
294obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 296obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
295obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o 297obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o
296obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o 298obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 13002f33384e..37332976ccbb 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -29,6 +29,7 @@
29#include <sound/hdaudio_ext.h> 29#include <sound/hdaudio_ext.h>
30#include <sound/hda_i915.h> 30#include <sound/hda_i915.h>
31#include <sound/pcm_drm_eld.h> 31#include <sound/pcm_drm_eld.h>
32#include <sound/hda_chmap.h>
32#include "../../hda/local.h" 33#include "../../hda/local.h"
33#include "hdac_hdmi.h" 34#include "hdac_hdmi.h"
34 35
@@ -60,11 +61,17 @@ struct hdac_hdmi_cvt {
60 struct hdac_hdmi_cvt_params params; 61 struct hdac_hdmi_cvt_params params;
61}; 62};
62 63
64/* Currently only spk_alloc, more to be added */
65struct hdac_hdmi_parsed_eld {
66 u8 spk_alloc;
67};
68
63struct hdac_hdmi_eld { 69struct hdac_hdmi_eld {
64 bool monitor_present; 70 bool monitor_present;
65 bool eld_valid; 71 bool eld_valid;
66 int eld_size; 72 int eld_size;
67 char eld_buffer[ELD_MAX_SIZE]; 73 char eld_buffer[ELD_MAX_SIZE];
74 struct hdac_hdmi_parsed_eld info;
68}; 75};
69 76
70struct hdac_hdmi_pin { 77struct hdac_hdmi_pin {
@@ -76,6 +83,10 @@ struct hdac_hdmi_pin {
76 struct hdac_ext_device *edev; 83 struct hdac_ext_device *edev;
77 int repoll_count; 84 int repoll_count;
78 struct delayed_work work; 85 struct delayed_work work;
86 struct mutex lock;
87 bool chmap_set;
88 unsigned char chmap[8]; /* ALSA API channel-map */
89 int channels; /* current number of channels */
79}; 90};
80 91
81struct hdac_hdmi_pcm { 92struct hdac_hdmi_pcm {
@@ -100,8 +111,22 @@ struct hdac_hdmi_priv {
100 int num_pin; 111 int num_pin;
101 int num_cvt; 112 int num_cvt;
102 struct mutex pin_mutex; 113 struct mutex pin_mutex;
114 struct hdac_chmap chmap;
103}; 115};
104 116
117static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi,
118 int pcm_idx)
119{
120 struct hdac_hdmi_pcm *pcm;
121
122 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
123 if (pcm->pcm_id == pcm_idx)
124 return pcm;
125 }
126
127 return NULL;
128}
129
105static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev) 130static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
106{ 131{
107 struct hdac_device *hdac = dev_to_hdac_dev(dev); 132 struct hdac_device *hdac = dev_to_hdac_dev(dev);
@@ -278,26 +303,31 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
278 int i; 303 int i;
279 const u8 *eld_buf; 304 const u8 *eld_buf;
280 u8 conn_type; 305 u8 conn_type;
281 int channels = 2; 306 int channels, ca;
282 307
283 list_for_each_entry(pin, &hdmi->pin_list, head) { 308 list_for_each_entry(pin, &hdmi->pin_list, head) {
284 if (pin->nid == pin_nid) 309 if (pin->nid == pin_nid)
285 break; 310 break;
286 } 311 }
287 312
313 ca = snd_hdac_channel_allocation(&hdac->hdac, pin->eld.info.spk_alloc,
314 pin->channels, pin->chmap_set, true, pin->chmap);
315
316 channels = snd_hdac_get_active_channels(ca);
317 hdmi->chmap.ops.set_channel_count(&hdac->hdac, cvt_nid, channels);
318
319 snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca,
320 pin->channels, pin->chmap, pin->chmap_set);
321
288 eld_buf = pin->eld.eld_buffer; 322 eld_buf = pin->eld.eld_buffer;
289 conn_type = drm_eld_get_conn_type(eld_buf); 323 conn_type = drm_eld_get_conn_type(eld_buf);
290 324
291 /* setup channel count */
292 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
293 AC_VERB_SET_CVT_CHAN_COUNT, channels - 1);
294
295 switch (conn_type) { 325 switch (conn_type) {
296 case DRM_ELD_CONN_TYPE_HDMI: 326 case DRM_ELD_CONN_TYPE_HDMI:
297 hdmi_audio_infoframe_init(&frame); 327 hdmi_audio_infoframe_init(&frame);
298 328
299 /* Default stereo for now */
300 frame.channels = channels; 329 frame.channels = channels;
330 frame.channel_allocation = ca;
301 331
302 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); 332 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
303 if (ret < 0) 333 if (ret < 0)
@@ -311,7 +341,7 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
311 dp_ai.len = 0x1b; 341 dp_ai.len = 0x1b;
312 dp_ai.ver = 0x11 << 2; 342 dp_ai.ver = 0x11 << 2;
313 dp_ai.CC02_CT47 = channels - 1; 343 dp_ai.CC02_CT47 = channels - 1;
314 dp_ai.CA = 0; 344 dp_ai.CA = ca;
315 345
316 dip = (u8 *)&dp_ai; 346 dip = (u8 *)&dp_ai;
317 break; 347 break;
@@ -370,17 +400,23 @@ static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
370 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai); 400 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
371 struct hdac_hdmi_priv *hdmi = hdac->private_data; 401 struct hdac_hdmi_priv *hdmi = hdac->private_data;
372 struct hdac_hdmi_dai_pin_map *dai_map; 402 struct hdac_hdmi_dai_pin_map *dai_map;
403 struct hdac_hdmi_pin *pin;
373 struct hdac_ext_dma_params *dd; 404 struct hdac_ext_dma_params *dd;
374 int ret; 405 int ret;
375 406
376 dai_map = &hdmi->dai_map[dai->id]; 407 dai_map = &hdmi->dai_map[dai->id];
408 pin = dai_map->pin;
377 409
378 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream); 410 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
379 dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n", 411 dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n",
380 dd->stream_tag, dd->format); 412 dd->stream_tag, dd->format);
381 413
414 mutex_lock(&pin->lock);
415 pin->channels = substream->runtime->channels;
416
382 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid, 417 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
383 dai_map->pin->nid); 418 dai_map->pin->nid);
419 mutex_unlock(&pin->lock);
384 if (ret < 0) 420 if (ret < 0)
385 return ret; 421 return ret;
386 422
@@ -640,6 +676,12 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
640 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0, 676 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
641 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 677 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
642 678
679 mutex_lock(&dai_map->pin->lock);
680 dai_map->pin->chmap_set = false;
681 memset(dai_map->pin->chmap, 0, sizeof(dai_map->pin->chmap));
682 dai_map->pin->channels = 0;
683 mutex_unlock(&dai_map->pin->lock);
684
643 dai_map->pin = NULL; 685 dai_map->pin = NULL;
644 } 686 }
645} 687}
@@ -647,10 +689,19 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
647static int 689static int
648hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt) 690hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
649{ 691{
692 unsigned int chans;
693 struct hdac_ext_device *edev = to_ehdac_device(hdac);
694 struct hdac_hdmi_priv *hdmi = edev->private_data;
650 int err; 695 int err;
651 696
652 /* Only stereo supported as of now */ 697 chans = get_wcaps(hdac, cvt->nid);
653 cvt->params.channels_min = cvt->params.channels_max = 2; 698 chans = get_wcaps_channels(chans);
699
700 cvt->params.channels_min = 2;
701
702 cvt->params.channels_max = chans;
703 if (chans > hdmi->chmap.channels_max)
704 hdmi->chmap.channels_max = chans;
654 705
655 err = snd_hdac_query_supported_pcm(hdac, cvt->nid, 706 err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
656 &cvt->params.rates, 707 &cvt->params.rates,
@@ -1008,6 +1059,12 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
1008 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt); 1059 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
1009} 1060}
1010 1061
1062static void hdac_hdmi_parse_eld(struct hdac_ext_device *edev,
1063 struct hdac_hdmi_pin *pin)
1064{
1065 pin->eld.info.spk_alloc = pin->eld.eld_buffer[DRM_ELD_SPEAKER];
1066}
1067
1011static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll) 1068static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
1012{ 1069{
1013 struct hdac_ext_device *edev = pin->edev; 1070 struct hdac_ext_device *edev = pin->edev;
@@ -1065,6 +1122,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
1065 1122
1066 snd_jack_report(pcm->jack, SND_JACK_AVOUT); 1123 snd_jack_report(pcm->jack, SND_JACK_AVOUT);
1067 } 1124 }
1125 hdac_hdmi_parse_eld(edev, pin);
1068 1126
1069 print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET, 1127 print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET,
1070 pin->eld.eld_buffer, pin->eld.eld_size); 1128 pin->eld.eld_buffer, pin->eld.eld_size);
@@ -1123,6 +1181,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
1123 hdmi->num_pin++; 1181 hdmi->num_pin++;
1124 1182
1125 pin->edev = edev; 1183 pin->edev = edev;
1184 mutex_init(&pin->lock);
1126 INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld); 1185 INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld);
1127 1186
1128 return 0; 1187 return 0;
@@ -1342,6 +1401,19 @@ static struct i915_audio_component_audio_ops aops = {
1342 .pin_eld_notify = hdac_hdmi_eld_notify_cb, 1401 .pin_eld_notify = hdac_hdmi_eld_notify_cb,
1343}; 1402};
1344 1403
1404static struct snd_pcm *hdac_hdmi_get_pcm_from_id(struct snd_soc_card *card,
1405 int device)
1406{
1407 struct snd_soc_pcm_runtime *rtd;
1408
1409 list_for_each_entry(rtd, &card->rtd_list, list) {
1410 if (rtd->pcm && (rtd->pcm->device == device))
1411 return rtd->pcm;
1412 }
1413
1414 return NULL;
1415}
1416
1345int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device) 1417int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
1346{ 1418{
1347 char jack_name[NAME_SIZE]; 1419 char jack_name[NAME_SIZE];
@@ -1351,6 +1423,8 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
1351 snd_soc_component_get_dapm(&codec->component); 1423 snd_soc_component_get_dapm(&codec->component);
1352 struct hdac_hdmi_priv *hdmi = edev->private_data; 1424 struct hdac_hdmi_priv *hdmi = edev->private_data;
1353 struct hdac_hdmi_pcm *pcm; 1425 struct hdac_hdmi_pcm *pcm;
1426 struct snd_pcm *snd_pcm;
1427 int err;
1354 1428
1355 /* 1429 /*
1356 * this is a new PCM device, create new pcm and 1430 * this is a new PCM device, create new pcm and
@@ -1362,6 +1436,18 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
1362 pcm->pcm_id = device; 1436 pcm->pcm_id = device;
1363 pcm->cvt = hdmi->dai_map[dai->id].cvt; 1437 pcm->cvt = hdmi->dai_map[dai->id].cvt;
1364 1438
1439 snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device);
1440 if (snd_pcm) {
1441 err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap);
1442 if (err < 0) {
1443 dev_err(&edev->hdac.dev,
1444 "chmap control add failed with err: %d for pcm: %d\n",
1445 err, device);
1446 kfree(pcm);
1447 return err;
1448 }
1449 }
1450
1365 list_add_tail(&pcm->head, &hdmi->pcm_list); 1451 list_add_tail(&pcm->head, &hdmi->pcm_list);
1366 1452
1367 sprintf(jack_name, "HDMI/DP, pcm=%d Jack", device); 1453 sprintf(jack_name, "HDMI/DP, pcm=%d Jack", device);
@@ -1483,6 +1569,60 @@ static struct snd_soc_codec_driver hdmi_hda_codec = {
1483 .idle_bias_off = true, 1569 .idle_bias_off = true,
1484}; 1570};
1485 1571
1572static void hdac_hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
1573 unsigned char *chmap)
1574{
1575 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1576 struct hdac_hdmi_priv *hdmi = edev->private_data;
1577 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
1578 struct hdac_hdmi_pin *pin = pcm->pin;
1579
1580 /* chmap is already set to 0 in caller */
1581 if (!pin)
1582 return;
1583
1584 memcpy(chmap, pin->chmap, ARRAY_SIZE(pin->chmap));
1585}
1586
1587static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
1588 unsigned char *chmap, int prepared)
1589{
1590 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1591 struct hdac_hdmi_priv *hdmi = edev->private_data;
1592 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
1593 struct hdac_hdmi_pin *pin = pcm->pin;
1594
1595 mutex_lock(&pin->lock);
1596 pin->chmap_set = true;
1597 memcpy(pin->chmap, chmap, ARRAY_SIZE(pin->chmap));
1598 if (prepared)
1599 hdac_hdmi_setup_audio_infoframe(edev, pcm->cvt->nid, pin->nid);
1600 mutex_unlock(&pin->lock);
1601}
1602
1603static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
1604{
1605 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1606 struct hdac_hdmi_priv *hdmi = edev->private_data;
1607 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
1608 struct hdac_hdmi_pin *pin = pcm->pin;
1609
1610 return pin ? true:false;
1611}
1612
1613static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
1614{
1615 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1616 struct hdac_hdmi_priv *hdmi = edev->private_data;
1617 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
1618 struct hdac_hdmi_pin *pin = pcm->pin;
1619
1620 if (!pin || !pin->eld.eld_valid)
1621 return 0;
1622
1623 return pin->eld.info.spk_alloc;
1624}
1625
1486static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) 1626static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
1487{ 1627{
1488 struct hdac_device *codec = &edev->hdac; 1628 struct hdac_device *codec = &edev->hdac;
@@ -1501,6 +1641,11 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
1501 return -ENOMEM; 1641 return -ENOMEM;
1502 1642
1503 edev->private_data = hdmi_priv; 1643 edev->private_data = hdmi_priv;
1644 snd_hdac_register_chmap_ops(codec, &hdmi_priv->chmap);
1645 hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap;
1646 hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap;
1647 hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
1648 hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;
1504 1649
1505 dev_set_drvdata(&codec->dev, edev); 1650 dev_set_drvdata(&codec->dev, edev);
1506 1651
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
new file mode 100644
index 000000000000..8e36e883e453
--- /dev/null
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -0,0 +1,432 @@
1/*
2 * ALSA SoC codec for HDMI encoder drivers
3 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Jyri Sarha <jsarha@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15#include <linux/module.h>
16#include <linux/string.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/pcm_drm_eld.h>
22#include <sound/hdmi-codec.h>
23#include <sound/pcm_iec958.h>
24
25#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
26
27struct hdmi_codec_priv {
28 struct hdmi_codec_pdata hcd;
29 struct snd_soc_dai_driver *daidrv;
30 struct hdmi_codec_daifmt daifmt[2];
31 struct mutex current_stream_lock;
32 struct snd_pcm_substream *current_stream;
33 struct snd_pcm_hw_constraint_list ratec;
34 uint8_t eld[MAX_ELD_BYTES];
35};
36
37static const struct snd_soc_dapm_widget hdmi_widgets[] = {
38 SND_SOC_DAPM_OUTPUT("TX"),
39};
40
41static const struct snd_soc_dapm_route hdmi_routes[] = {
42 { "TX", NULL, "Playback" },
43};
44
45enum {
46 DAI_ID_I2S = 0,
47 DAI_ID_SPDIF,
48};
49
50static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
51 struct snd_ctl_elem_info *uinfo)
52{
53 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
54 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
55
56 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
57 uinfo->count = sizeof(hcp->eld);
58
59 return 0;
60}
61
62static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
63 struct snd_ctl_elem_value *ucontrol)
64{
65 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
66 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
67
68 memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld));
69
70 return 0;
71}
72
73static const struct snd_kcontrol_new hdmi_controls[] = {
74 {
75 .access = SNDRV_CTL_ELEM_ACCESS_READ |
76 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
77 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
78 .name = "ELD",
79 .info = hdmi_eld_ctl_info,
80 .get = hdmi_eld_ctl_get,
81 },
82};
83
84static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
85 struct snd_soc_dai *dai)
86{
87 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
88 int ret = 0;
89
90 mutex_lock(&hcp->current_stream_lock);
91 if (!hcp->current_stream) {
92 hcp->current_stream = substream;
93 } else if (hcp->current_stream != substream) {
94 dev_err(dai->dev, "Only one simultaneous stream supported!\n");
95 ret = -EINVAL;
96 }
97 mutex_unlock(&hcp->current_stream_lock);
98
99 return ret;
100}
101
102static int hdmi_codec_startup(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai)
104{
105 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
106 int ret = 0;
107
108 dev_dbg(dai->dev, "%s()\n", __func__);
109
110 ret = hdmi_codec_new_stream(substream, dai);
111 if (ret)
112 return ret;
113
114 if (hcp->hcd.ops->audio_startup) {
115 ret = hcp->hcd.ops->audio_startup(dai->dev->parent);
116 if (ret) {
117 mutex_lock(&hcp->current_stream_lock);
118 hcp->current_stream = NULL;
119 mutex_unlock(&hcp->current_stream_lock);
120 return ret;
121 }
122 }
123
124 if (hcp->hcd.ops->get_eld) {
125 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->eld,
126 sizeof(hcp->eld));
127
128 if (!ret) {
129 ret = snd_pcm_hw_constraint_eld(substream->runtime,
130 hcp->eld);
131 if (ret)
132 return ret;
133 }
134 }
135 return 0;
136}
137
138static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
139 struct snd_soc_dai *dai)
140{
141 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
142
143 dev_dbg(dai->dev, "%s()\n", __func__);
144
145 WARN_ON(hcp->current_stream != substream);
146
147 hcp->hcd.ops->audio_shutdown(dai->dev->parent);
148
149 mutex_lock(&hcp->current_stream_lock);
150 hcp->current_stream = NULL;
151 mutex_unlock(&hcp->current_stream_lock);
152}
153
154static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
155 struct snd_pcm_hw_params *params,
156 struct snd_soc_dai *dai)
157{
158 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
159 struct hdmi_codec_params hp = {
160 .iec = {
161 .status = { 0 },
162 .subcode = { 0 },
163 .pad = 0,
164 .dig_subframe = { 0 },
165 }
166 };
167 int ret;
168
169 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
170 params_width(params), params_rate(params),
171 params_channels(params));
172
173 if (params_width(params) > 24)
174 params->msbits = 24;
175
176 ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
177 sizeof(hp.iec.status));
178 if (ret < 0) {
179 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
180 ret);
181 return ret;
182 }
183
184 ret = hdmi_codec_new_stream(substream, dai);
185 if (ret)
186 return ret;
187
188 hdmi_audio_infoframe_init(&hp.cea);
189 hp.cea.channels = params_channels(params);
190 hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
191 hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
192 hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
193
194 hp.sample_width = params_width(params);
195 hp.sample_rate = params_rate(params);
196 hp.channels = params_channels(params);
197
198 return hcp->hcd.ops->hw_params(dai->dev->parent, &hcp->daifmt[dai->id],
199 &hp);
200}
201
202static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
203 unsigned int fmt)
204{
205 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
206 struct hdmi_codec_daifmt cf = { 0 };
207 int ret = 0;
208
209 dev_dbg(dai->dev, "%s()\n", __func__);
210
211 if (dai->id == DAI_ID_SPDIF) {
212 cf.fmt = HDMI_SPDIF;
213 } else {
214 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
215 case SND_SOC_DAIFMT_CBM_CFM:
216 cf.bit_clk_master = 1;
217 cf.frame_clk_master = 1;
218 break;
219 case SND_SOC_DAIFMT_CBS_CFM:
220 cf.frame_clk_master = 1;
221 break;
222 case SND_SOC_DAIFMT_CBM_CFS:
223 cf.bit_clk_master = 1;
224 break;
225 case SND_SOC_DAIFMT_CBS_CFS:
226 break;
227 default:
228 return -EINVAL;
229 }
230
231 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
232 case SND_SOC_DAIFMT_NB_NF:
233 break;
234 case SND_SOC_DAIFMT_NB_IF:
235 cf.frame_clk_inv = 1;
236 break;
237 case SND_SOC_DAIFMT_IB_NF:
238 cf.bit_clk_inv = 1;
239 break;
240 case SND_SOC_DAIFMT_IB_IF:
241 cf.frame_clk_inv = 1;
242 cf.bit_clk_inv = 1;
243 break;
244 }
245
246 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
247 case SND_SOC_DAIFMT_I2S:
248 cf.fmt = HDMI_I2S;
249 break;
250 case SND_SOC_DAIFMT_DSP_A:
251 cf.fmt = HDMI_DSP_A;
252 break;
253 case SND_SOC_DAIFMT_DSP_B:
254 cf.fmt = HDMI_DSP_B;
255 break;
256 case SND_SOC_DAIFMT_RIGHT_J:
257 cf.fmt = HDMI_RIGHT_J;
258 break;
259 case SND_SOC_DAIFMT_LEFT_J:
260 cf.fmt = HDMI_LEFT_J;
261 break;
262 case SND_SOC_DAIFMT_AC97:
263 cf.fmt = HDMI_AC97;
264 break;
265 default:
266 dev_err(dai->dev, "Invalid DAI interface format\n");
267 return -EINVAL;
268 }
269 }
270
271 hcp->daifmt[dai->id] = cf;
272
273 return ret;
274}
275
276static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
277{
278 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
279
280 dev_dbg(dai->dev, "%s()\n", __func__);
281
282 if (hcp->hcd.ops->digital_mute)
283 return hcp->hcd.ops->digital_mute(dai->dev->parent, mute);
284
285 return 0;
286}
287
288static const struct snd_soc_dai_ops hdmi_dai_ops = {
289 .startup = hdmi_codec_startup,
290 .shutdown = hdmi_codec_shutdown,
291 .hw_params = hdmi_codec_hw_params,
292 .set_fmt = hdmi_codec_set_fmt,
293 .digital_mute = hdmi_codec_digital_mute,
294};
295
296
297#define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
298 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
299 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
300 SNDRV_PCM_RATE_192000)
301
302#define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
303 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
304 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
305 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
306
307/*
308 * This list is only for formats allowed on the I2S bus. So there is
309 * some formats listed that are not supported by HDMI interface. For
310 * instance allowing the 32-bit formats enables 24-precision with CPU
311 * DAIs that do not support 24-bit formats. If the extra formats cause
312 * problems, we should add the video side driver an option to disable
313 * them.
314 */
315#define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
316 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
317 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
318 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
319 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
320
321static struct snd_soc_dai_driver hdmi_i2s_dai = {
322 .name = "i2s-hifi",
323 .id = DAI_ID_I2S,
324 .playback = {
325 .stream_name = "Playback",
326 .channels_min = 2,
327 .channels_max = 8,
328 .rates = HDMI_RATES,
329 .formats = I2S_FORMATS,
330 .sig_bits = 24,
331 },
332 .ops = &hdmi_dai_ops,
333};
334
335static const struct snd_soc_dai_driver hdmi_spdif_dai = {
336 .name = "spdif-hifi",
337 .id = DAI_ID_SPDIF,
338 .playback = {
339 .stream_name = "Playback",
340 .channels_min = 2,
341 .channels_max = 2,
342 .rates = HDMI_RATES,
343 .formats = SPDIF_FORMATS,
344 },
345 .ops = &hdmi_dai_ops,
346};
347
348static struct snd_soc_codec_driver hdmi_codec = {
349 .controls = hdmi_controls,
350 .num_controls = ARRAY_SIZE(hdmi_controls),
351 .dapm_widgets = hdmi_widgets,
352 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
353 .dapm_routes = hdmi_routes,
354 .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
355};
356
357static int hdmi_codec_probe(struct platform_device *pdev)
358{
359 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
360 struct device *dev = &pdev->dev;
361 struct hdmi_codec_priv *hcp;
362 int dai_count, i = 0;
363 int ret;
364
365 dev_dbg(dev, "%s()\n", __func__);
366
367 if (!hcd) {
368 dev_err(dev, "%s: No plalform data\n", __func__);
369 return -EINVAL;
370 }
371
372 dai_count = hcd->i2s + hcd->spdif;
373 if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params ||
374 !hcd->ops->audio_shutdown) {
375 dev_err(dev, "%s: Invalid parameters\n", __func__);
376 return -EINVAL;
377 }
378
379 hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL);
380 if (!hcp)
381 return -ENOMEM;
382
383 hcp->hcd = *hcd;
384 mutex_init(&hcp->current_stream_lock);
385
386 hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv),
387 GFP_KERNEL);
388 if (!hcp->daidrv)
389 return -ENOMEM;
390
391 if (hcd->i2s) {
392 hcp->daidrv[i] = hdmi_i2s_dai;
393 hcp->daidrv[i].playback.channels_max =
394 hcd->max_i2s_channels;
395 i++;
396 }
397
398 if (hcd->spdif)
399 hcp->daidrv[i] = hdmi_spdif_dai;
400
401 ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
402 dai_count);
403 if (ret) {
404 dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n",
405 __func__, ret);
406 return ret;
407 }
408
409 dev_set_drvdata(dev, hcp);
410 return 0;
411}
412
413static int hdmi_codec_remove(struct platform_device *pdev)
414{
415 snd_soc_unregister_codec(&pdev->dev);
416 return 0;
417}
418
419static struct platform_driver hdmi_codec_driver = {
420 .driver = {
421 .name = HDMI_CODEC_DRV_NAME,
422 },
423 .probe = hdmi_codec_probe,
424 .remove = hdmi_codec_remove,
425};
426
427module_platform_driver(hdmi_codec_driver);
428
429MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
430MODULE_DESCRIPTION("HDMI Audio Codec Driver");
431MODULE_LICENSE("GPL");
432MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME);
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index 7cc725153422..d2808652b974 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -30,6 +30,16 @@
30static struct snd_soc_jack skylake_headset; 30static struct snd_soc_jack skylake_headset;
31static struct snd_soc_card skylake_audio_card; 31static struct snd_soc_card skylake_audio_card;
32 32
33struct skl_hdmi_pcm {
34 struct list_head head;
35 struct snd_soc_dai *codec_dai;
36 int device;
37};
38
39struct skl_nau8825_private {
40 struct list_head hdmi_pcm_list;
41};
42
33enum { 43enum {
34 SKL_DPCM_AUDIO_PB = 0, 44 SKL_DPCM_AUDIO_PB = 0,
35 SKL_DPCM_AUDIO_CP, 45 SKL_DPCM_AUDIO_CP,
@@ -192,23 +202,56 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
192 202
193static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 203static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
194{ 204{
205 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card);
195 struct snd_soc_dai *dai = rtd->codec_dai; 206 struct snd_soc_dai *dai = rtd->codec_dai;
207 struct skl_hdmi_pcm *pcm;
208
209 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
210 if (!pcm)
211 return -ENOMEM;
212
213 pcm->device = SKL_DPCM_AUDIO_HDMI1_PB;
214 pcm->codec_dai = dai;
196 215
197 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB); 216 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
217
218 return 0;
198} 219}
199 220
200static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 221static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
201{ 222{
223 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card);
202 struct snd_soc_dai *dai = rtd->codec_dai; 224 struct snd_soc_dai *dai = rtd->codec_dai;
225 struct skl_hdmi_pcm *pcm;
226
227 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
228 if (!pcm)
229 return -ENOMEM;
203 230
204 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB); 231 pcm->device = SKL_DPCM_AUDIO_HDMI2_PB;
232 pcm->codec_dai = dai;
233
234 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
235
236 return 0;
205} 237}
206 238
207static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 239static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
208{ 240{
241 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card);
209 struct snd_soc_dai *dai = rtd->codec_dai; 242 struct snd_soc_dai *dai = rtd->codec_dai;
243 struct skl_hdmi_pcm *pcm;
210 244
211 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB); 245 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
246 if (!pcm)
247 return -ENOMEM;
248
249 pcm->device = SKL_DPCM_AUDIO_HDMI3_PB;
250 pcm->codec_dai = dai;
251
252 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
253
254 return 0;
212} 255}
213 256
214static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 257static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
@@ -533,6 +576,21 @@ static struct snd_soc_dai_link skylake_dais[] = {
533 }, 576 },
534}; 577};
535 578
579static int skylake_card_late_probe(struct snd_soc_card *card)
580{
581 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
582 struct skl_hdmi_pcm *pcm;
583 int err;
584
585 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
586 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device);
587 if (err < 0)
588 return err;
589 }
590
591 return 0;
592}
593
536/* skylake audio machine driver for SPT + NAU88L25 */ 594/* skylake audio machine driver for SPT + NAU88L25 */
537static struct snd_soc_card skylake_audio_card = { 595static struct snd_soc_card skylake_audio_card = {
538 .name = "sklnau8825max", 596 .name = "sklnau8825max",
@@ -546,11 +604,21 @@ static struct snd_soc_card skylake_audio_card = {
546 .dapm_routes = skylake_map, 604 .dapm_routes = skylake_map,
547 .num_dapm_routes = ARRAY_SIZE(skylake_map), 605 .num_dapm_routes = ARRAY_SIZE(skylake_map),
548 .fully_routed = true, 606 .fully_routed = true,
607 .late_probe = skylake_card_late_probe,
549}; 608};
550 609
551static int skylake_audio_probe(struct platform_device *pdev) 610static int skylake_audio_probe(struct platform_device *pdev)
552{ 611{
612 struct skl_nau8825_private *ctx;
613
614 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
615 if (!ctx)
616 return -ENOMEM;
617
618 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
619
553 skylake_audio_card.dev = &pdev->dev; 620 skylake_audio_card.dev = &pdev->dev;
621 snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
554 622
555 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 623 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
556} 624}
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index 73cbddb640c6..e19aa99c4f72 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -34,6 +34,15 @@
34static struct snd_soc_jack skylake_headset; 34static struct snd_soc_jack skylake_headset;
35static struct snd_soc_card skylake_audio_card; 35static struct snd_soc_card skylake_audio_card;
36 36
37struct skl_hdmi_pcm {
38 struct list_head head;
39 struct snd_soc_dai *codec_dai;
40 int device;
41};
42
43struct skl_nau88125_private {
44 struct list_head hdmi_pcm_list;
45};
37enum { 46enum {
38 SKL_DPCM_AUDIO_PB = 0, 47 SKL_DPCM_AUDIO_PB = 0,
39 SKL_DPCM_AUDIO_CP, 48 SKL_DPCM_AUDIO_CP,
@@ -222,24 +231,57 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
222 231
223static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 232static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
224{ 233{
234 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card);
225 struct snd_soc_dai *dai = rtd->codec_dai; 235 struct snd_soc_dai *dai = rtd->codec_dai;
236 struct skl_hdmi_pcm *pcm;
237
238 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
239 if (!pcm)
240 return -ENOMEM;
241
242 pcm->device = SKL_DPCM_AUDIO_HDMI1_PB;
243 pcm->codec_dai = dai;
244
245 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
226 246
227 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB); 247 return 0;
228} 248}
229 249
230static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 250static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
231{ 251{
252 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card);
232 struct snd_soc_dai *dai = rtd->codec_dai; 253 struct snd_soc_dai *dai = rtd->codec_dai;
254 struct skl_hdmi_pcm *pcm;
255
256 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
257 if (!pcm)
258 return -ENOMEM;
259
260 pcm->device = SKL_DPCM_AUDIO_HDMI2_PB;
261 pcm->codec_dai = dai;
233 262
234 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB); 263 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
264
265 return 0;
235} 266}
236 267
237 268
238static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 269static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
239{ 270{
271 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card);
240 struct snd_soc_dai *dai = rtd->codec_dai; 272 struct snd_soc_dai *dai = rtd->codec_dai;
273 struct skl_hdmi_pcm *pcm;
274
275 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
276 if (!pcm)
277 return -ENOMEM;
241 278
242 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB); 279 pcm->device = SKL_DPCM_AUDIO_HDMI3_PB;
280 pcm->codec_dai = dai;
281
282 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
283
284 return 0;
243} 285}
244 286
245static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 287static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
@@ -584,6 +626,21 @@ static struct snd_soc_dai_link skylake_dais[] = {
584 }, 626 },
585}; 627};
586 628
629static int skylake_card_late_probe(struct snd_soc_card *card)
630{
631 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
632 struct skl_hdmi_pcm *pcm;
633 int err;
634
635 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
636 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device);
637 if (err < 0)
638 return err;
639 }
640
641 return 0;
642}
643
587/* skylake audio machine driver for SPT + NAU88L25 */ 644/* skylake audio machine driver for SPT + NAU88L25 */
588static struct snd_soc_card skylake_audio_card = { 645static struct snd_soc_card skylake_audio_card = {
589 .name = "sklnau8825adi", 646 .name = "sklnau8825adi",
@@ -599,11 +656,21 @@ static struct snd_soc_card skylake_audio_card = {
599 .codec_conf = ssm4567_codec_conf, 656 .codec_conf = ssm4567_codec_conf,
600 .num_configs = ARRAY_SIZE(ssm4567_codec_conf), 657 .num_configs = ARRAY_SIZE(ssm4567_codec_conf),
601 .fully_routed = true, 658 .fully_routed = true,
659 .late_probe = skylake_card_late_probe,
602}; 660};
603 661
604static int skylake_audio_probe(struct platform_device *pdev) 662static int skylake_audio_probe(struct platform_device *pdev)
605{ 663{
664 struct skl_nau88125_private *ctx;
665
666 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
667 if (!ctx)
668 return -ENOMEM;
669
670 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
671
606 skylake_audio_card.dev = &pdev->dev; 672 skylake_audio_card.dev = &pdev->dev;
673 snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
607 674
608 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 675 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
609} 676}
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index d4cdb949f733..426b48233fdb 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -30,6 +30,16 @@
30 30
31static struct snd_soc_jack skylake_headset; 31static struct snd_soc_jack skylake_headset;
32 32
33struct skl_hdmi_pcm {
34 struct list_head head;
35 struct snd_soc_dai *codec_dai;
36 int device;
37};
38
39struct skl_rt286_private {
40 struct list_head hdmi_pcm_list;
41};
42
33enum { 43enum {
34 SKL_DPCM_AUDIO_PB = 0, 44 SKL_DPCM_AUDIO_PB = 0,
35 SKL_DPCM_AUDIO_CP, 45 SKL_DPCM_AUDIO_CP,
@@ -142,9 +152,20 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
142 152
143static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) 153static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd)
144{ 154{
155 struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card);
145 struct snd_soc_dai *dai = rtd->codec_dai; 156 struct snd_soc_dai *dai = rtd->codec_dai;
157 struct skl_hdmi_pcm *pcm;
158
159 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
160 if (!pcm)
161 return -ENOMEM;
146 162
147 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB + dai->id); 163 pcm->device = SKL_DPCM_AUDIO_HDMI1_PB + dai->id;
164 pcm->codec_dai = dai;
165
166 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
167
168 return 0;
148} 169}
149 170
150static unsigned int rates[] = { 171static unsigned int rates[] = {
@@ -437,6 +458,21 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
437 }, 458 },
438}; 459};
439 460
461static int skylake_card_late_probe(struct snd_soc_card *card)
462{
463 struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
464 struct skl_hdmi_pcm *pcm;
465 int err;
466
467 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
468 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device);
469 if (err < 0)
470 return err;
471 }
472
473 return 0;
474}
475
440/* skylake audio machine driver for SPT + RT286S */ 476/* skylake audio machine driver for SPT + RT286S */
441static struct snd_soc_card skylake_rt286 = { 477static struct snd_soc_card skylake_rt286 = {
442 .name = "skylake-rt286", 478 .name = "skylake-rt286",
@@ -450,11 +486,21 @@ static struct snd_soc_card skylake_rt286 = {
450 .dapm_routes = skylake_rt286_map, 486 .dapm_routes = skylake_rt286_map,
451 .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map), 487 .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map),
452 .fully_routed = true, 488 .fully_routed = true,
489 .late_probe = skylake_card_late_probe,
453}; 490};
454 491
455static int skylake_audio_probe(struct platform_device *pdev) 492static int skylake_audio_probe(struct platform_device *pdev)
456{ 493{
494 struct skl_rt286_private *ctx;
495
496 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
497 if (!ctx)
498 return -ENOMEM;
499
500 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
501
457 skylake_rt286.dev = &pdev->dev; 502 skylake_rt286.dev = &pdev->dev;
503 snd_soc_card_set_drvdata(&skylake_rt286, ctx);
458 504
459 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286); 505 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286);
460} 506}
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 15480234b20b..7c81b31748ff 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -51,7 +51,7 @@ static struct snd_pcm_hardware azx_pcm_hw = {
51 .rate_min = 8000, 51 .rate_min = 8000,
52 .rate_max = 48000, 52 .rate_max = 48000,
53 .channels_min = 1, 53 .channels_min = 1,
54 .channels_max = HDA_QUAD, 54 .channels_max = 8,
55 .buffer_bytes_max = AZX_MAX_BUF_SIZE, 55 .buffer_bytes_max = AZX_MAX_BUF_SIZE,
56 .period_bytes_min = 128, 56 .period_bytes_min = 128,
57 .period_bytes_max = AZX_MAX_BUF_SIZE / 2, 57 .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
@@ -691,7 +691,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
691 .playback = { 691 .playback = {
692 .stream_name = "HDMI1 Playback", 692 .stream_name = "HDMI1 Playback",
693 .channels_min = HDA_STEREO, 693 .channels_min = HDA_STEREO,
694 .channels_max = HDA_STEREO, 694 .channels_max = 8,
695 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 695 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
696 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 696 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
697 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | 697 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
@@ -706,7 +706,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
706 .playback = { 706 .playback = {
707 .stream_name = "HDMI2 Playback", 707 .stream_name = "HDMI2 Playback",
708 .channels_min = HDA_STEREO, 708 .channels_min = HDA_STEREO,
709 .channels_max = HDA_STEREO, 709 .channels_max = 8,
710 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 710 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
711 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 711 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
712 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | 712 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
@@ -721,7 +721,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
721 .playback = { 721 .playback = {
722 .stream_name = "HDMI3 Playback", 722 .stream_name = "HDMI3 Playback",
723 .channels_min = HDA_STEREO, 723 .channels_min = HDA_STEREO,
724 .channels_max = HDA_STEREO, 724 .channels_max = 8,
725 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 725 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
726 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 726 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
727 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | 727 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
@@ -846,7 +846,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
846 .playback = { 846 .playback = {
847 .stream_name = "iDisp1 Tx", 847 .stream_name = "iDisp1 Tx",
848 .channels_min = HDA_STEREO, 848 .channels_min = HDA_STEREO,
849 .channels_max = HDA_STEREO, 849 .channels_max = 8,
850 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000, 850 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
851 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 851 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
852 SNDRV_PCM_FMTBIT_S24_LE, 852 SNDRV_PCM_FMTBIT_S24_LE,
@@ -858,7 +858,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
858 .playback = { 858 .playback = {
859 .stream_name = "iDisp2 Tx", 859 .stream_name = "iDisp2 Tx",
860 .channels_min = HDA_STEREO, 860 .channels_min = HDA_STEREO,
861 .channels_max = HDA_STEREO, 861 .channels_max = 8,
862 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000| 862 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
863 SNDRV_PCM_RATE_48000, 863 SNDRV_PCM_RATE_48000,
864 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 864 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
@@ -871,7 +871,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
871 .playback = { 871 .playback = {
872 .stream_name = "iDisp3 Tx", 872 .stream_name = "iDisp3 Tx",
873 .channels_min = HDA_STEREO, 873 .channels_min = HDA_STEREO,
874 .channels_max = HDA_STEREO, 874 .channels_max = 8,
875 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000| 875 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
876 SNDRV_PCM_RATE_48000, 876 SNDRV_PCM_RATE_48000,
877 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 877 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index a1f4478fabcb..3e036b0349b9 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -154,13 +154,32 @@ static void skl_dump_mconfig(struct skl_sst *ctx,
154 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg); 154 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg);
155} 155}
156 156
157static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs)
158{
159 int slot_map = 0xFFFFFFFF;
160 int start_slot = 0;
161 int i;
162
163 for (i = 0; i < chs; i++) {
164 /*
165 * For 2 channels with starting slot as 0, slot map will
166 * look like 0xFFFFFF10.
167 */
168 slot_map &= (~(0xF << (4 * i)) | (start_slot << (4 * i)));
169 start_slot++;
170 }
171 fmt->ch_map = slot_map;
172}
173
157static void skl_tplg_update_params(struct skl_module_fmt *fmt, 174static void skl_tplg_update_params(struct skl_module_fmt *fmt,
158 struct skl_pipe_params *params, int fixup) 175 struct skl_pipe_params *params, int fixup)
159{ 176{
160 if (fixup & SKL_RATE_FIXUP_MASK) 177 if (fixup & SKL_RATE_FIXUP_MASK)
161 fmt->s_freq = params->s_freq; 178 fmt->s_freq = params->s_freq;
162 if (fixup & SKL_CH_FIXUP_MASK) 179 if (fixup & SKL_CH_FIXUP_MASK) {
163 fmt->channels = params->ch; 180 fmt->channels = params->ch;
181 skl_tplg_update_chmap(fmt, fmt->channels);
182 }
164 if (fixup & SKL_FMT_FIXUP_MASK) { 183 if (fixup & SKL_FMT_FIXUP_MASK) {
165 fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt); 184 fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
166 185