xref: /linux/sound/soc/codecs/hdac_hdmi.c (revision a8fe58cec351c25e09c393bf46117c0c47b5a17c)
1 /*
2  *  hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms
3  *
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  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
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.
12  *
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.
17  *
18  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19  */
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"
30 
31 #define AMP_OUT_MUTE		0xb080
32 #define AMP_OUT_UNMUTE		0xb000
33 #define PIN_OUT			(AC_PINCTL_OUT_EN)
34 
35 #define HDA_MAX_CONNECTIONS     32
36 
37 struct hdac_hdmi_cvt_params {
38 	unsigned int channels_min;
39 	unsigned int channels_max;
40 	u32 rates;
41 	u64 formats;
42 	unsigned int maxbps;
43 };
44 
45 struct hdac_hdmi_cvt {
46 	struct list_head head;
47 	hda_nid_t nid;
48 	struct hdac_hdmi_cvt_params params;
49 };
50 
51 struct hdac_hdmi_pin {
52 	struct list_head head;
53 	hda_nid_t nid;
54 	int num_mux_nids;
55 	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
56 };
57 
58 struct hdac_hdmi_dai_pin_map {
59 	int dai_id;
60 	struct hdac_hdmi_pin *pin;
61 	struct hdac_hdmi_cvt *cvt;
62 };
63 
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;
68 	int num_pin;
69 	int num_cvt;
70 };
71 
72 static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
73 {
74 	struct hdac_device *hdac = dev_to_hdac_dev(dev);
75 
76 	return to_ehdac_device(hdac);
77 }
78 
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)
82 {
83 	unsigned int val;
84 
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);
87 
88 	val = (stream_tag << 4);
89 
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);
94 
95 	return 0;
96 }
97 
98 static void
99 hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
100 				int packet_index, int byte_index)
101 {
102 	int val;
103 
104 	val = (packet_index << 5) | (byte_index & 0x1f);
105 
106 	snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
107 				AC_VERB_SET_HDMI_DIP_INDEX, val);
108 }
109 
110 static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
111 				hda_nid_t cvt_nid, hda_nid_t pin_nid)
112 {
113 	uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
114 	struct hdmi_audio_infoframe frame;
115 	u8 *dip = (u8 *)&frame;
116 	int ret;
117 	int i;
118 
119 	hdmi_audio_infoframe_init(&frame);
120 
121 	/* Default stereo for now */
122 	frame.channels = 2;
123 
124 	/* setup channel count */
125 	snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
126 			    AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
127 
128 	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
129 	if (ret < 0)
130 		return ret;
131 
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);
136 
137 
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]);
143 
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);
148 
149 	return 0;
150 }
151 
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)
154 {
155 	/* Power up pin widget */
156 	if (!snd_hdac_check_power_state(&edev->hdac, dai_map->pin->nid,
157 						pwr_state))
158 		snd_hdac_codec_write(&edev->hdac, dai_map->pin->nid, 0,
159 			AC_VERB_SET_POWER_STATE, pwr_state);
160 
161 	/* Power up converter */
162 	if (!snd_hdac_check_power_state(&edev->hdac, dai_map->cvt->nid,
163 						pwr_state))
164 		snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
165 			AC_VERB_SET_POWER_STATE, pwr_state);
166 }
167 
168 static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
169 				struct snd_soc_dai *dai)
170 {
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;
175 	int ret;
176 
177 	if (dai->id > 0) {
178 		dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
179 		return -ENODEV;
180 	}
181 
182 	dai_map = &hdmi->dai_map[dai->id];
183 
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);
187 
188 	ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
189 						dai_map->pin->nid);
190 	if (ret < 0)
191 		return ret;
192 
193 	return hdac_hdmi_setup_stream(hdac, dai_map->cvt->nid,
194 			dai_map->pin->nid, dd->stream_tag, dd->format);
195 }
196 
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)
199 {
200 	struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
201 	struct hdac_ext_dma_params *dd;
202 
203 	if (dai->id > 0) {
204 		dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
205 		return -ENODEV;
206 	}
207 
208 	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
209 	if (!dd)
210 		return -ENOMEM;
211 	dd->format = snd_hdac_calc_stream_format(params_rate(hparams),
212 			params_channels(hparams), params_format(hparams),
213 			24, 0);
214 
215 	snd_soc_dai_set_dma_data(dai, substream, (void *)dd);
216 
217 	return 0;
218 }
219 
220 static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream *substream,
221 		struct snd_soc_dai *dai)
222 {
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;
227 
228 	dai_map = &hdmi->dai_map[dai->id];
229 
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);
234 
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);
237 
238 	kfree(dd);
239 
240 	return 0;
241 }
242 
243 static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
244 			struct snd_soc_dai *dai)
245 {
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;
249 	int val;
250 
251 	if (dai->id > 0) {
252 		dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
253 		return -ENODEV;
254 	}
255 
256 	dai_map = &hdmi->dai_map[dai->id];
257 
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);
261 
262 	if ((!(val & AC_PINSENSE_PRESENCE)) || (!(val & AC_PINSENSE_ELDV))) {
263 		dev_err(&hdac->hdac.dev, "Monitor presence invalid with val: %x\n", val);
264 		return -ENODEV;
265 	}
266 
267 	hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
268 
269 	snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
270 			AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
271 
272 	snd_pcm_hw_constraint_step(substream->runtime, 0,
273 				   SNDRV_PCM_HW_PARAM_CHANNELS, 2);
274 
275 	return 0;
276 }
277 
278 static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
279 		struct snd_soc_dai *dai)
280 {
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;
284 
285 	dai_map = &hdmi->dai_map[dai->id];
286 
287 	hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);
288 
289 	snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
290 			AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
291 }
292 
293 static int
294 hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
295 {
296 	int err;
297 
298 	/* Only stereo supported as of now */
299 	cvt->params.channels_min = cvt->params.channels_max = 2;
300 
301 	err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
302 			&cvt->params.rates,
303 			&cvt->params.formats,
304 			&cvt->params.maxbps);
305 	if (err < 0)
306 		dev_err(&hdac->dev,
307 			"Failed to query pcm params for nid %d: %d\n",
308 			cvt->nid, err);
309 
310 	return err;
311 }
312 
313 static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget *w,
314 				enum snd_soc_dapm_type id,
315 				const char *wname, const char *stream)
316 {
317 	w->id = id;
318 	w->name = wname;
319 	w->sname = stream;
320 	w->reg = SND_SOC_NOPM;
321 	w->shift = 0;
322 	w->kcontrol_news = NULL;
323 	w->num_kcontrols = 0;
324 	w->priv = NULL;
325 }
326 
327 static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
328 		const char *sink, const char *control, const char *src)
329 {
330 	route->sink = sink;
331 	route->source = src;
332 	route->control = control;
333 	route->connected = NULL;
334 }
335 
336 static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,
337 					struct hdac_hdmi_dai_pin_map *dai_map)
338 {
339 	struct snd_soc_dapm_route route[1];
340 	struct snd_soc_dapm_widget widgets[2] = { {0} };
341 
342 	memset(&route, 0, sizeof(route));
343 
344 	hdac_hdmi_fill_widget_info(&widgets[0], snd_soc_dapm_output,
345 			"hif1 Output", NULL);
346 	hdac_hdmi_fill_widget_info(&widgets[1], snd_soc_dapm_aif_in,
347 			"Coverter 1", "hif1");
348 
349 	hdac_hdmi_fill_route(&route[0], "hif1 Output", NULL, "Coverter 1");
350 
351 	snd_soc_dapm_new_controls(dapm, widgets, ARRAY_SIZE(widgets));
352 	snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));
353 }
354 
355 static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
356 {
357 	struct hdac_hdmi_priv *hdmi = edev->private_data;
358 	struct hdac_hdmi_dai_pin_map *dai_map = &hdmi->dai_map[0];
359 	struct hdac_hdmi_cvt *cvt;
360 	struct hdac_hdmi_pin *pin;
361 
362 	if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
363 		return -EINVAL;
364 
365 	/*
366 	 * Currently on board only 1 pin and 1 converter is enabled for
367 	 * simplification, more will be added eventually
368 	 * So using fixed map for dai_id:pin:cvt
369 	 */
370 	cvt = list_first_entry(&hdmi->cvt_list, struct hdac_hdmi_cvt, head);
371 	pin = list_first_entry(&hdmi->pin_list, struct hdac_hdmi_pin, head);
372 
373 	dai_map->dai_id = 0;
374 	dai_map->pin = pin;
375 
376 	dai_map->cvt = cvt;
377 
378 	/* Enable out path for this pin widget */
379 	snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
380 			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
381 
382 	/* Enable transmission */
383 	snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
384 			AC_VERB_SET_DIGI_CONVERT_1, 1);
385 
386 	/* Category Code (CC) to zero */
387 	snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
388 			AC_VERB_SET_DIGI_CONVERT_2, 0);
389 
390 	snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
391 			AC_VERB_SET_CONNECT_SEL, 0);
392 
393 	return 0;
394 }
395 
396 static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
397 {
398 	struct hdac_hdmi_priv *hdmi = edev->private_data;
399 	struct hdac_hdmi_cvt *cvt;
400 
401 	cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
402 	if (!cvt)
403 		return -ENOMEM;
404 
405 	cvt->nid = nid;
406 
407 	list_add_tail(&cvt->head, &hdmi->cvt_list);
408 	hdmi->num_cvt++;
409 
410 	return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
411 }
412 
413 static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
414 {
415 	struct hdac_hdmi_priv *hdmi = edev->private_data;
416 	struct hdac_hdmi_pin *pin;
417 
418 	pin = kzalloc(sizeof(*pin), GFP_KERNEL);
419 	if (!pin)
420 		return -ENOMEM;
421 
422 	pin->nid = nid;
423 
424 	list_add_tail(&pin->head, &hdmi->pin_list);
425 	hdmi->num_pin++;
426 
427 	return 0;
428 }
429 
430 /*
431  * Parse all nodes and store the cvt/pin nids in array
432  * Add one time initialization for pin and cvt widgets
433  */
434 static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
435 {
436 	hda_nid_t nid;
437 	int i, num_nodes;
438 	struct hdac_device *hdac = &edev->hdac;
439 	struct hdac_hdmi_priv *hdmi = edev->private_data;
440 	int ret;
441 
442 	num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
443 	if (!nid || num_nodes <= 0) {
444 		dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
445 		return -EINVAL;
446 	}
447 
448 	hdac->num_nodes = num_nodes;
449 	hdac->start_nid = nid;
450 
451 	for (i = 0; i < hdac->num_nodes; i++, nid++) {
452 		unsigned int caps;
453 		unsigned int type;
454 
455 		caps = get_wcaps(hdac, nid);
456 		type = get_wcaps_type(caps);
457 
458 		if (!(caps & AC_WCAP_DIGITAL))
459 			continue;
460 
461 		switch (type) {
462 
463 		case AC_WID_AUD_OUT:
464 			ret = hdac_hdmi_add_cvt(edev, nid);
465 			if (ret < 0)
466 				return ret;
467 			break;
468 
469 		case AC_WID_PIN:
470 			ret = hdac_hdmi_add_pin(edev, nid);
471 			if (ret < 0)
472 				return ret;
473 			break;
474 		}
475 	}
476 
477 	hdac->end_nid = nid;
478 
479 	if (!hdmi->num_pin || !hdmi->num_cvt)
480 		return -EIO;
481 
482 	return hdac_hdmi_init_dai_map(edev);
483 }
484 
485 static int hdmi_codec_probe(struct snd_soc_codec *codec)
486 {
487 	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
488 	struct hdac_hdmi_priv *hdmi = edev->private_data;
489 	struct snd_soc_dapm_context *dapm =
490 		snd_soc_component_get_dapm(&codec->component);
491 
492 	edev->scodec = codec;
493 
494 	create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);
495 
496 	/* Imp: Store the card pointer in hda_codec */
497 	edev->card = dapm->card->snd_card;
498 
499 	/*
500 	 * hdac_device core already sets the state to active and calls
501 	 * get_noresume. So enable runtime and set the device to suspend.
502 	 */
503 	pm_runtime_enable(&edev->hdac.dev);
504 	pm_runtime_put(&edev->hdac.dev);
505 	pm_runtime_suspend(&edev->hdac.dev);
506 
507 	return 0;
508 }
509 
510 static int hdmi_codec_remove(struct snd_soc_codec *codec)
511 {
512 	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
513 
514 	pm_runtime_disable(&edev->hdac.dev);
515 	return 0;
516 }
517 
518 static struct snd_soc_codec_driver hdmi_hda_codec = {
519 	.probe		= hdmi_codec_probe,
520 	.remove		= hdmi_codec_remove,
521 	.idle_bias_off	= true,
522 };
523 
524 static struct snd_soc_dai_ops hdmi_dai_ops = {
525 	.startup = hdac_hdmi_pcm_open,
526 	.shutdown = hdac_hdmi_pcm_close,
527 	.hw_params = hdac_hdmi_set_hw_params,
528 	.prepare = hdac_hdmi_playback_prepare,
529 	.hw_free = hdac_hdmi_playback_cleanup,
530 };
531 
532 static struct snd_soc_dai_driver hdmi_dais[] = {
533 	{	.name = "intel-hdmi-hif1",
534 		.playback = {
535 			.stream_name = "hif1",
536 			.channels_min = 2,
537 			.channels_max = 2,
538 			.rates = SNDRV_PCM_RATE_32000 |
539 				SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
540 				SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
541 				SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
542 			.formats = SNDRV_PCM_FMTBIT_S16_LE |
543 				SNDRV_PCM_FMTBIT_S20_3LE |
544 				SNDRV_PCM_FMTBIT_S24_LE |
545 				SNDRV_PCM_FMTBIT_S32_LE,
546 
547 		},
548 		.ops = &hdmi_dai_ops,
549 	},
550 };
551 
552 static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
553 {
554 	struct hdac_device *codec = &edev->hdac;
555 	struct hdac_hdmi_priv *hdmi_priv;
556 	int ret = 0;
557 
558 	hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
559 	if (hdmi_priv == NULL)
560 		return -ENOMEM;
561 
562 	edev->private_data = hdmi_priv;
563 
564 	dev_set_drvdata(&codec->dev, edev);
565 
566 	INIT_LIST_HEAD(&hdmi_priv->pin_list);
567 	INIT_LIST_HEAD(&hdmi_priv->cvt_list);
568 
569 	ret = hdac_hdmi_parse_and_map_nid(edev);
570 	if (ret < 0)
571 		return ret;
572 
573 	/* ASoC specific initialization */
574 	return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
575 			hdmi_dais, ARRAY_SIZE(hdmi_dais));
576 }
577 
578 static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
579 {
580 	struct hdac_hdmi_priv *hdmi = edev->private_data;
581 	struct hdac_hdmi_pin *pin, *pin_next;
582 	struct hdac_hdmi_cvt *cvt, *cvt_next;
583 
584 	snd_soc_unregister_codec(&edev->hdac.dev);
585 
586 	list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
587 		list_del(&cvt->head);
588 		kfree(cvt);
589 	}
590 
591 	list_for_each_entry_safe(pin, pin_next, &hdmi->pin_list, head) {
592 		list_del(&pin->head);
593 		kfree(pin);
594 	}
595 
596 	return 0;
597 }
598 
599 #ifdef CONFIG_PM
600 static int hdac_hdmi_runtime_suspend(struct device *dev)
601 {
602 	struct hdac_ext_device *edev = to_hda_ext_device(dev);
603 	struct hdac_device *hdac = &edev->hdac;
604 	struct hdac_bus *bus = hdac->bus;
605 	int err;
606 
607 	dev_dbg(dev, "Enter: %s\n", __func__);
608 
609 	/* controller may not have been initialized for the first time */
610 	if (!bus)
611 		return 0;
612 
613 	/* Power down afg */
614 	if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3))
615 		snd_hdac_codec_write(hdac, hdac->afg, 0,
616 			AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
617 
618 	err = snd_hdac_display_power(bus, false);
619 	if (err < 0) {
620 		dev_err(bus->dev, "Cannot turn on display power on i915\n");
621 		return err;
622 	}
623 
624 	return 0;
625 }
626 
627 static int hdac_hdmi_runtime_resume(struct device *dev)
628 {
629 	struct hdac_ext_device *edev = to_hda_ext_device(dev);
630 	struct hdac_device *hdac = &edev->hdac;
631 	struct hdac_bus *bus = hdac->bus;
632 	int err;
633 
634 	dev_dbg(dev, "Enter: %s\n", __func__);
635 
636 	/* controller may not have been initialized for the first time */
637 	if (!bus)
638 		return 0;
639 
640 	err = snd_hdac_display_power(bus, true);
641 	if (err < 0) {
642 		dev_err(bus->dev, "Cannot turn on display power on i915\n");
643 		return err;
644 	}
645 
646 	/* Power up afg */
647 	if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
648 		snd_hdac_codec_write(hdac, hdac->afg, 0,
649 			AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
650 
651 	return 0;
652 }
653 #else
654 #define hdac_hdmi_runtime_suspend NULL
655 #define hdac_hdmi_runtime_resume NULL
656 #endif
657 
658 static const struct dev_pm_ops hdac_hdmi_pm = {
659 	SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
660 };
661 
662 static const struct hda_device_id hdmi_list[] = {
663 	HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
664 	{}
665 };
666 
667 MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
668 
669 static struct hdac_ext_driver hdmi_driver = {
670 	. hdac = {
671 		.driver = {
672 			.name   = "HDMI HDA Codec",
673 			.pm = &hdac_hdmi_pm,
674 		},
675 		.id_table       = hdmi_list,
676 	},
677 	.probe          = hdac_hdmi_dev_probe,
678 	.remove         = hdac_hdmi_dev_remove,
679 };
680 
681 static int __init hdmi_init(void)
682 {
683 	return snd_hda_ext_driver_register(&hdmi_driver);
684 }
685 
686 static void __exit hdmi_exit(void)
687 {
688 	snd_hda_ext_driver_unregister(&hdmi_driver);
689 }
690 
691 module_init(hdmi_init);
692 module_exit(hdmi_exit);
693 
694 MODULE_LICENSE("GPL v2");
695 MODULE_DESCRIPTION("HDMI HD codec");
696 MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
697 MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");
698