2 * hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms
4 * Copyright (C) 2014-2015 Intel Corp
5 * Author: Samreen Nilofer <samreen.nilofer@intel.com>
6 * Subhransu S. Prusty <subhransu.s.prusty@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 #include <linux/init.h>
21 #include <linux/delay.h>
22 #include <linux/module.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/hdmi.h>
25 #include <sound/pcm_params.h>
26 #include <sound/soc.h>
27 #include <sound/hdaudio_ext.h>
28 #include <sound/hda_i915.h>
29 #include "../../hda/local.h"
31 #define AMP_OUT_MUTE 0xb080
32 #define AMP_OUT_UNMUTE 0xb000
33 #define PIN_OUT (AC_PINCTL_OUT_EN)
35 #define HDA_MAX_CONNECTIONS 32
37 struct hdac_hdmi_cvt_params
{
38 unsigned int channels_min
;
39 unsigned int channels_max
;
45 struct hdac_hdmi_cvt
{
46 struct list_head head
;
48 struct hdac_hdmi_cvt_params params
;
51 struct hdac_hdmi_pin
{
52 struct list_head head
;
55 hda_nid_t mux_nids
[HDA_MAX_CONNECTIONS
];
58 struct hdac_hdmi_dai_pin_map
{
60 struct hdac_hdmi_pin
*pin
;
61 struct hdac_hdmi_cvt
*cvt
;
64 struct hdac_hdmi_priv
{
65 struct hdac_hdmi_dai_pin_map dai_map
[3];
66 struct list_head pin_list
;
67 struct list_head cvt_list
;
72 static inline struct hdac_ext_device
*to_hda_ext_device(struct device
*dev
)
74 struct hdac_device
*hdac
= dev_to_hdac_dev(dev
);
76 return to_ehdac_device(hdac
);
79 static int hdac_hdmi_setup_stream(struct hdac_ext_device
*hdac
,
80 hda_nid_t cvt_nid
, hda_nid_t pin_nid
,
81 u32 stream_tag
, int format
)
85 dev_dbg(&hdac
->hdac
.dev
, "cvt nid %d pnid %d stream %d format 0x%x\n",
86 cvt_nid
, pin_nid
, stream_tag
, format
);
88 val
= (stream_tag
<< 4);
90 snd_hdac_codec_write(&hdac
->hdac
, cvt_nid
, 0,
91 AC_VERB_SET_CHANNEL_STREAMID
, val
);
92 snd_hdac_codec_write(&hdac
->hdac
, cvt_nid
, 0,
93 AC_VERB_SET_STREAM_FORMAT
, format
);
99 hdac_hdmi_set_dip_index(struct hdac_ext_device
*hdac
, hda_nid_t pin_nid
,
100 int packet_index
, int byte_index
)
104 val
= (packet_index
<< 5) | (byte_index
& 0x1f);
106 snd_hdac_codec_write(&hdac
->hdac
, pin_nid
, 0,
107 AC_VERB_SET_HDMI_DIP_INDEX
, val
);
110 static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device
*hdac
,
111 hda_nid_t cvt_nid
, hda_nid_t pin_nid
)
113 uint8_t buffer
[HDMI_INFOFRAME_HEADER_SIZE
+ HDMI_AUDIO_INFOFRAME_SIZE
];
114 struct hdmi_audio_infoframe frame
;
115 u8
*dip
= (u8
*)&frame
;
119 hdmi_audio_infoframe_init(&frame
);
121 /* Default stereo for now */
124 /* setup channel count */
125 snd_hdac_codec_write(&hdac
->hdac
, cvt_nid
, 0,
126 AC_VERB_SET_CVT_CHAN_COUNT
, frame
.channels
- 1);
128 ret
= hdmi_audio_infoframe_pack(&frame
, buffer
, sizeof(buffer
));
132 /* stop infoframe transmission */
133 hdac_hdmi_set_dip_index(hdac
, pin_nid
, 0x0, 0x0);
134 snd_hdac_codec_write(&hdac
->hdac
, pin_nid
, 0,
135 AC_VERB_SET_HDMI_DIP_XMIT
, AC_DIPXMIT_DISABLE
);
138 /* Fill infoframe. Index auto-incremented */
139 hdac_hdmi_set_dip_index(hdac
, pin_nid
, 0x0, 0x0);
140 for (i
= 0; i
< sizeof(frame
); i
++)
141 snd_hdac_codec_write(&hdac
->hdac
, pin_nid
, 0,
142 AC_VERB_SET_HDMI_DIP_DATA
, dip
[i
]);
144 /* Start infoframe */
145 hdac_hdmi_set_dip_index(hdac
, pin_nid
, 0x0, 0x0);
146 snd_hdac_codec_write(&hdac
->hdac
, pin_nid
, 0,
147 AC_VERB_SET_HDMI_DIP_XMIT
, AC_DIPXMIT_BEST
);
152 static void hdac_hdmi_set_power_state(struct hdac_ext_device
*edev
,
153 struct hdac_hdmi_dai_pin_map
*dai_map
, unsigned int pwr_state
)
155 /* Power up pin widget */
156 if (!snd_hdac_check_power_state(&edev
->hdac
, dai_map
->pin
->nid
,
158 snd_hdac_codec_write(&edev
->hdac
, dai_map
->pin
->nid
, 0,
159 AC_VERB_SET_POWER_STATE
, pwr_state
);
161 /* Power up converter */
162 if (!snd_hdac_check_power_state(&edev
->hdac
, dai_map
->cvt
->nid
,
164 snd_hdac_codec_write(&edev
->hdac
, dai_map
->cvt
->nid
, 0,
165 AC_VERB_SET_POWER_STATE
, pwr_state
);
168 static int hdac_hdmi_playback_prepare(struct snd_pcm_substream
*substream
,
169 struct snd_soc_dai
*dai
)
171 struct hdac_ext_device
*hdac
= snd_soc_dai_get_drvdata(dai
);
172 struct hdac_hdmi_priv
*hdmi
= hdac
->private_data
;
173 struct hdac_hdmi_dai_pin_map
*dai_map
;
174 struct hdac_ext_dma_params
*dd
;
178 dev_err(&hdac
->hdac
.dev
, "Only one dai supported as of now\n");
182 dai_map
= &hdmi
->dai_map
[dai
->id
];
184 dd
= (struct hdac_ext_dma_params
*)snd_soc_dai_get_dma_data(dai
, substream
);
185 dev_dbg(&hdac
->hdac
.dev
, "stream tag from cpu dai %d format in cvt 0x%x\n",
186 dd
->stream_tag
, dd
->format
);
188 ret
= hdac_hdmi_setup_audio_infoframe(hdac
, dai_map
->cvt
->nid
,
193 return hdac_hdmi_setup_stream(hdac
, dai_map
->cvt
->nid
,
194 dai_map
->pin
->nid
, dd
->stream_tag
, dd
->format
);
197 static int hdac_hdmi_set_hw_params(struct snd_pcm_substream
*substream
,
198 struct snd_pcm_hw_params
*hparams
, struct snd_soc_dai
*dai
)
200 struct hdac_ext_device
*hdac
= snd_soc_dai_get_drvdata(dai
);
201 struct hdac_ext_dma_params
*dd
;
204 dev_err(&hdac
->hdac
.dev
, "Only one dai supported as of now\n");
208 dd
= kzalloc(sizeof(*dd
), GFP_KERNEL
);
211 dd
->format
= snd_hdac_calc_stream_format(params_rate(hparams
),
212 params_channels(hparams
), params_format(hparams
),
215 snd_soc_dai_set_dma_data(dai
, substream
, (void *)dd
);
220 static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream
*substream
,
221 struct snd_soc_dai
*dai
)
223 struct hdac_ext_device
*edev
= snd_soc_dai_get_drvdata(dai
);
224 struct hdac_ext_dma_params
*dd
;
225 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
226 struct hdac_hdmi_dai_pin_map
*dai_map
;
228 dai_map
= &hdmi
->dai_map
[dai
->id
];
230 snd_hdac_codec_write(&edev
->hdac
, dai_map
->cvt
->nid
, 0,
231 AC_VERB_SET_CHANNEL_STREAMID
, 0);
232 snd_hdac_codec_write(&edev
->hdac
, dai_map
->cvt
->nid
, 0,
233 AC_VERB_SET_STREAM_FORMAT
, 0);
235 dd
= (struct hdac_ext_dma_params
*)snd_soc_dai_get_dma_data(dai
, substream
);
236 snd_soc_dai_set_dma_data(dai
, substream
, NULL
);
243 static int hdac_hdmi_pcm_open(struct snd_pcm_substream
*substream
,
244 struct snd_soc_dai
*dai
)
246 struct hdac_ext_device
*hdac
= snd_soc_dai_get_drvdata(dai
);
247 struct hdac_hdmi_priv
*hdmi
= hdac
->private_data
;
248 struct hdac_hdmi_dai_pin_map
*dai_map
;
252 dev_err(&hdac
->hdac
.dev
, "Only one dai supported as of now\n");
256 dai_map
= &hdmi
->dai_map
[dai
->id
];
258 val
= snd_hdac_codec_read(&hdac
->hdac
, dai_map
->pin
->nid
, 0,
259 AC_VERB_GET_PIN_SENSE
, 0);
260 dev_info(&hdac
->hdac
.dev
, "Val for AC_VERB_GET_PIN_SENSE: %x\n", val
);
262 if ((!(val
& AC_PINSENSE_PRESENCE
)) || (!(val
& AC_PINSENSE_ELDV
))) {
263 dev_err(&hdac
->hdac
.dev
, "Monitor presence invalid with val: %x\n", val
);
267 hdac_hdmi_set_power_state(hdac
, dai_map
, AC_PWRST_D0
);
269 snd_hdac_codec_write(&hdac
->hdac
, dai_map
->pin
->nid
, 0,
270 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
);
272 snd_pcm_hw_constraint_step(substream
->runtime
, 0,
273 SNDRV_PCM_HW_PARAM_CHANNELS
, 2);
278 static void hdac_hdmi_pcm_close(struct snd_pcm_substream
*substream
,
279 struct snd_soc_dai
*dai
)
281 struct hdac_ext_device
*hdac
= snd_soc_dai_get_drvdata(dai
);
282 struct hdac_hdmi_priv
*hdmi
= hdac
->private_data
;
283 struct hdac_hdmi_dai_pin_map
*dai_map
;
285 dai_map
= &hdmi
->dai_map
[dai
->id
];
287 hdac_hdmi_set_power_state(hdac
, dai_map
, AC_PWRST_D3
);
289 snd_hdac_codec_write(&hdac
->hdac
, dai_map
->pin
->nid
, 0,
290 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
);
294 hdac_hdmi_query_cvt_params(struct hdac_device
*hdac
, struct hdac_hdmi_cvt
*cvt
)
298 /* Only stereo supported as of now */
299 cvt
->params
.channels_min
= cvt
->params
.channels_max
= 2;
301 err
= snd_hdac_query_supported_pcm(hdac
, cvt
->nid
,
303 &cvt
->params
.formats
,
304 &cvt
->params
.maxbps
);
307 "Failed to query pcm params for nid %d: %d\n",
313 static int hdac_hdmi_query_pin_connlist(struct hdac_ext_device
*hdac
,
314 struct hdac_hdmi_pin
*pin
)
316 if (!(get_wcaps(&hdac
->hdac
, pin
->nid
) & AC_WCAP_CONN_LIST
)) {
317 dev_warn(&hdac
->hdac
.dev
,
318 "HDMI: pin %d wcaps %#x does not support connection list\n",
319 pin
->nid
, get_wcaps(&hdac
->hdac
, pin
->nid
));
323 pin
->num_mux_nids
= snd_hdac_get_connections(&hdac
->hdac
, pin
->nid
,
324 pin
->mux_nids
, HDA_MAX_CONNECTIONS
);
325 if (pin
->num_mux_nids
== 0)
326 dev_warn(&hdac
->hdac
.dev
, "No connections found for pin: %d\n",
329 dev_dbg(&hdac
->hdac
.dev
, "num_mux_nids %d for pin: %d\n",
330 pin
->num_mux_nids
, pin
->nid
);
332 return pin
->num_mux_nids
;
335 static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget
*w
,
336 enum snd_soc_dapm_type id
,
337 const char *wname
, const char *stream
)
342 w
->reg
= SND_SOC_NOPM
;
344 w
->kcontrol_news
= NULL
;
345 w
->num_kcontrols
= 0;
349 static void hdac_hdmi_fill_route(struct snd_soc_dapm_route
*route
,
350 const char *sink
, const char *control
, const char *src
)
354 route
->control
= control
;
355 route
->connected
= NULL
;
358 static void create_fill_widget_route_map(struct snd_soc_dapm_context
*dapm
,
359 struct hdac_hdmi_dai_pin_map
*dai_map
)
361 struct snd_soc_dapm_route route
[1];
362 struct snd_soc_dapm_widget widgets
[2] = { {0} };
364 memset(&route
, 0, sizeof(route
));
366 hdac_hdmi_fill_widget_info(&widgets
[0], snd_soc_dapm_output
,
367 "hif1 Output", NULL
);
368 hdac_hdmi_fill_widget_info(&widgets
[1], snd_soc_dapm_aif_in
,
369 "Coverter 1", "hif1");
371 hdac_hdmi_fill_route(&route
[0], "hif1 Output", NULL
, "Coverter 1");
373 snd_soc_dapm_new_controls(dapm
, widgets
, ARRAY_SIZE(widgets
));
374 snd_soc_dapm_add_routes(dapm
, route
, ARRAY_SIZE(route
));
377 static int hdac_hdmi_init_dai_map(struct hdac_ext_device
*edev
)
379 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
380 struct hdac_hdmi_dai_pin_map
*dai_map
= &hdmi
->dai_map
[0];
381 struct hdac_hdmi_cvt
*cvt
;
382 struct hdac_hdmi_pin
*pin
;
384 if (list_empty(&hdmi
->cvt_list
) || list_empty(&hdmi
->pin_list
))
388 * Currently on board only 1 pin and 1 converter is enabled for
389 * simplification, more will be added eventually
390 * So using fixed map for dai_id:pin:cvt
392 cvt
= list_first_entry(&hdmi
->cvt_list
, struct hdac_hdmi_cvt
, head
);
393 pin
= list_first_entry(&hdmi
->pin_list
, struct hdac_hdmi_pin
, head
);
400 /* Enable out path for this pin widget */
401 snd_hdac_codec_write(&edev
->hdac
, pin
->nid
, 0,
402 AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
);
404 /* Enable transmission */
405 snd_hdac_codec_write(&edev
->hdac
, cvt
->nid
, 0,
406 AC_VERB_SET_DIGI_CONVERT_1
, 1);
408 /* Category Code (CC) to zero */
409 snd_hdac_codec_write(&edev
->hdac
, cvt
->nid
, 0,
410 AC_VERB_SET_DIGI_CONVERT_2
, 0);
412 snd_hdac_codec_write(&edev
->hdac
, pin
->nid
, 0,
413 AC_VERB_SET_CONNECT_SEL
, 0);
418 static int hdac_hdmi_add_cvt(struct hdac_ext_device
*edev
, hda_nid_t nid
)
420 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
421 struct hdac_hdmi_cvt
*cvt
;
423 cvt
= kzalloc(sizeof(*cvt
), GFP_KERNEL
);
429 list_add_tail(&cvt
->head
, &hdmi
->cvt_list
);
432 return hdac_hdmi_query_cvt_params(&edev
->hdac
, cvt
);
435 static int hdac_hdmi_add_pin(struct hdac_ext_device
*edev
, hda_nid_t nid
)
437 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
438 struct hdac_hdmi_pin
*pin
;
440 pin
= kzalloc(sizeof(*pin
), GFP_KERNEL
);
446 list_add_tail(&pin
->head
, &hdmi
->pin_list
);
453 * Parse all nodes and store the cvt/pin nids in array
454 * Add one time initialization for pin and cvt widgets
456 static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device
*edev
)
460 struct hdac_device
*hdac
= &edev
->hdac
;
461 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
464 num_nodes
= snd_hdac_get_sub_nodes(hdac
, hdac
->afg
, &nid
);
465 if (!nid
|| num_nodes
<= 0) {
466 dev_warn(&hdac
->dev
, "HDMI: failed to get afg sub nodes\n");
470 hdac
->num_nodes
= num_nodes
;
471 hdac
->start_nid
= nid
;
473 for (i
= 0; i
< hdac
->num_nodes
; i
++, nid
++) {
477 caps
= get_wcaps(hdac
, nid
);
478 type
= get_wcaps_type(caps
);
480 if (!(caps
& AC_WCAP_DIGITAL
))
486 ret
= hdac_hdmi_add_cvt(edev
, nid
);
492 ret
= hdac_hdmi_add_pin(edev
, nid
);
501 if (!hdmi
->num_pin
|| !hdmi
->num_cvt
)
504 return hdac_hdmi_init_dai_map(edev
);
507 static int hdmi_codec_probe(struct snd_soc_codec
*codec
)
509 struct hdac_ext_device
*edev
= snd_soc_codec_get_drvdata(codec
);
510 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
511 struct snd_soc_dapm_context
*dapm
=
512 snd_soc_component_get_dapm(&codec
->component
);
514 edev
->scodec
= codec
;
516 create_fill_widget_route_map(dapm
, &hdmi
->dai_map
[0]);
518 /* Imp: Store the card pointer in hda_codec */
519 edev
->card
= dapm
->card
->snd_card
;
522 * hdac_device core already sets the state to active and calls
523 * get_noresume. So enable runtime and set the device to suspend.
525 pm_runtime_enable(&edev
->hdac
.dev
);
526 pm_runtime_put(&edev
->hdac
.dev
);
527 pm_runtime_suspend(&edev
->hdac
.dev
);
532 static int hdmi_codec_remove(struct snd_soc_codec
*codec
)
534 struct hdac_ext_device
*edev
= snd_soc_codec_get_drvdata(codec
);
536 pm_runtime_disable(&edev
->hdac
.dev
);
540 static struct snd_soc_codec_driver hdmi_hda_codec
= {
541 .probe
= hdmi_codec_probe
,
542 .remove
= hdmi_codec_remove
,
543 .idle_bias_off
= true,
546 static struct snd_soc_dai_ops hdmi_dai_ops
= {
547 .startup
= hdac_hdmi_pcm_open
,
548 .shutdown
= hdac_hdmi_pcm_close
,
549 .hw_params
= hdac_hdmi_set_hw_params
,
550 .prepare
= hdac_hdmi_playback_prepare
,
551 .hw_free
= hdac_hdmi_playback_cleanup
,
554 static struct snd_soc_dai_driver hdmi_dais
[] = {
555 { .name
= "intel-hdmi-hif1",
557 .stream_name
= "hif1",
560 .rates
= SNDRV_PCM_RATE_32000
|
561 SNDRV_PCM_RATE_44100
| SNDRV_PCM_RATE_48000
|
562 SNDRV_PCM_RATE_88200
| SNDRV_PCM_RATE_96000
|
563 SNDRV_PCM_RATE_176400
| SNDRV_PCM_RATE_192000
,
564 .formats
= SNDRV_PCM_FMTBIT_S16_LE
|
565 SNDRV_PCM_FMTBIT_S20_3LE
|
566 SNDRV_PCM_FMTBIT_S24_LE
|
567 SNDRV_PCM_FMTBIT_S32_LE
,
570 .ops
= &hdmi_dai_ops
,
574 static int hdac_hdmi_dev_probe(struct hdac_ext_device
*edev
)
576 struct hdac_device
*codec
= &edev
->hdac
;
577 struct hdac_hdmi_priv
*hdmi_priv
;
580 hdmi_priv
= devm_kzalloc(&codec
->dev
, sizeof(*hdmi_priv
), GFP_KERNEL
);
581 if (hdmi_priv
== NULL
)
584 edev
->private_data
= hdmi_priv
;
586 dev_set_drvdata(&codec
->dev
, edev
);
588 INIT_LIST_HEAD(&hdmi_priv
->pin_list
);
589 INIT_LIST_HEAD(&hdmi_priv
->cvt_list
);
591 ret
= hdac_hdmi_parse_and_map_nid(edev
);
595 /* ASoC specific initialization */
596 return snd_soc_register_codec(&codec
->dev
, &hdmi_hda_codec
,
597 hdmi_dais
, ARRAY_SIZE(hdmi_dais
));
600 static int hdac_hdmi_dev_remove(struct hdac_ext_device
*edev
)
602 struct hdac_hdmi_priv
*hdmi
= edev
->private_data
;
603 struct hdac_hdmi_pin
*pin
, *pin_next
;
604 struct hdac_hdmi_cvt
*cvt
, *cvt_next
;
606 snd_soc_unregister_codec(&edev
->hdac
.dev
);
608 list_for_each_entry_safe(cvt
, cvt_next
, &hdmi
->cvt_list
, head
) {
609 list_del(&cvt
->head
);
613 list_for_each_entry_safe(pin
, pin_next
, &hdmi
->pin_list
, head
) {
614 list_del(&pin
->head
);
622 static int hdac_hdmi_runtime_suspend(struct device
*dev
)
624 struct hdac_ext_device
*edev
= to_hda_ext_device(dev
);
625 struct hdac_device
*hdac
= &edev
->hdac
;
626 struct hdac_bus
*bus
= hdac
->bus
;
629 dev_dbg(dev
, "Enter: %s\n", __func__
);
631 /* controller may not have been initialized for the first time */
636 if (!snd_hdac_check_power_state(hdac
, hdac
->afg
, AC_PWRST_D3
))
637 snd_hdac_codec_write(hdac
, hdac
->afg
, 0,
638 AC_VERB_SET_POWER_STATE
, AC_PWRST_D3
);
640 err
= snd_hdac_display_power(bus
, false);
642 dev_err(bus
->dev
, "Cannot turn on display power on i915\n");
649 static int hdac_hdmi_runtime_resume(struct device
*dev
)
651 struct hdac_ext_device
*edev
= to_hda_ext_device(dev
);
652 struct hdac_device
*hdac
= &edev
->hdac
;
653 struct hdac_bus
*bus
= hdac
->bus
;
656 dev_dbg(dev
, "Enter: %s\n", __func__
);
658 /* controller may not have been initialized for the first time */
662 err
= snd_hdac_display_power(bus
, true);
664 dev_err(bus
->dev
, "Cannot turn on display power on i915\n");
669 if (!snd_hdac_check_power_state(hdac
, hdac
->afg
, AC_PWRST_D0
))
670 snd_hdac_codec_write(hdac
, hdac
->afg
, 0,
671 AC_VERB_SET_POWER_STATE
, AC_PWRST_D0
);
676 #define hdac_hdmi_runtime_suspend NULL
677 #define hdac_hdmi_runtime_resume NULL
680 static const struct dev_pm_ops hdac_hdmi_pm
= {
681 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend
, hdac_hdmi_runtime_resume
, NULL
)
684 static const struct hda_device_id hdmi_list
[] = {
685 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
689 MODULE_DEVICE_TABLE(hdaudio
, hdmi_list
);
691 static struct hdac_ext_driver hdmi_driver
= {
694 .name
= "HDMI HDA Codec",
697 .id_table
= hdmi_list
,
699 .probe
= hdac_hdmi_dev_probe
,
700 .remove
= hdac_hdmi_dev_remove
,
703 static int __init
hdmi_init(void)
705 return snd_hda_ext_driver_register(&hdmi_driver
);
708 static void __exit
hdmi_exit(void)
710 snd_hda_ext_driver_unregister(&hdmi_driver
);
713 module_init(hdmi_init
);
714 module_exit(hdmi_exit
);
716 MODULE_LICENSE("GPL v2");
717 MODULE_DESCRIPTION("HDMI HD codec");
718 MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
719 MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");