ASoC: hdac_hdmi: Use list to add pins and converters
[deliverable/linux.git] / sound / soc / codecs / hdac_hdmi.c
CommitLineData
18382ead
SP
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>
a657f1d0 24#include <linux/hdmi.h>
18382ead
SP
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/hdaudio_ext.h>
07f083ab 28#include <sound/hda_i915.h>
18382ead
SP
29#include "../../hda/local.h"
30
b0362adb
SP
31#define AMP_OUT_MUTE 0xb080
32#define AMP_OUT_UNMUTE 0xb000
18382ead 33#define PIN_OUT (AC_PINCTL_OUT_EN)
b0362adb 34
18382ead
SP
35#define HDA_MAX_CONNECTIONS 32
36
37struct 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
45struct hdac_hdmi_cvt {
15b91447 46 struct list_head head;
18382ead
SP
47 hda_nid_t nid;
48 struct hdac_hdmi_cvt_params params;
49};
50
51struct hdac_hdmi_pin {
15b91447 52 struct list_head head;
18382ead
SP
53 hda_nid_t nid;
54 int num_mux_nids;
55 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
56};
57
58struct hdac_hdmi_dai_pin_map {
59 int dai_id;
15b91447
SP
60 struct hdac_hdmi_pin *pin;
61 struct hdac_hdmi_cvt *cvt;
18382ead
SP
62};
63
64struct hdac_hdmi_priv {
18382ead 65 struct hdac_hdmi_dai_pin_map dai_map[3];
15b91447
SP
66 struct list_head pin_list;
67 struct list_head cvt_list;
68 int num_pin;
69 int num_cvt;
18382ead
SP
70};
71
e342ac08
SP
72static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
73{
51b2c425 74 struct hdac_device *hdac = dev_to_hdac_dev(dev);
e342ac08 75
51b2c425 76 return to_ehdac_device(hdac);
e342ac08
SP
77}
78
b0362adb
SP
79static 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
a657f1d0
SP
98static void
99hdac_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
110static 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
b0362adb
SP
152static 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 */
15b91447
SP
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,
b0362adb
SP
159 AC_VERB_SET_POWER_STATE, pwr_state);
160
161 /* Power up converter */
15b91447
SP
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,
b0362adb
SP
165 AC_VERB_SET_POWER_STATE, pwr_state);
166}
167
168static 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;
a657f1d0 175 int ret;
b0362adb
SP
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
15b91447
SP
188 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
189 dai_map->pin->nid);
a657f1d0
SP
190 if (ret < 0)
191 return ret;
192
15b91447
SP
193 return hdac_hdmi_setup_stream(hdac, dai_map->cvt->nid,
194 dai_map->pin->nid, dd->stream_tag, dd->format);
b0362adb
SP
195}
196
197static 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);
8d33ab24
SM
209 if (!dd)
210 return -ENOMEM;
b0362adb
SP
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
220static 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
15b91447 230 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
b0362adb 231 AC_VERB_SET_CHANNEL_STREAMID, 0);
15b91447 232 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
b0362adb
SP
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
243static 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
15b91447 258 val = snd_hdac_codec_read(&hdac->hdac, dai_map->pin->nid, 0,
b0362adb
SP
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
15b91447 269 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
b0362adb
SP
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
278static 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
15b91447 289 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
b0362adb
SP
290 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
291}
292
18382ead
SP
293static int
294hdac_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
313static int hdac_hdmi_query_pin_connlist(struct hdac_ext_device *hdac,
314 struct hdac_hdmi_pin *pin)
315{
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));
320 return -EINVAL;
321 }
322
323 pin->num_mux_nids = snd_hdac_get_connections(&hdac->hdac, pin->nid,
324 pin->mux_nids, HDA_MAX_CONNECTIONS);
53072460
SP
325 if (pin->num_mux_nids == 0)
326 dev_warn(&hdac->hdac.dev, "No connections found for pin: %d\n",
327 pin->nid);
328
329 dev_dbg(&hdac->hdac.dev, "num_mux_nids %d for pin: %d\n",
330 pin->num_mux_nids, pin->nid);
18382ead
SP
331
332 return pin->num_mux_nids;
333}
334
335static 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)
338{
339 w->id = id;
340 w->name = wname;
341 w->sname = stream;
342 w->reg = SND_SOC_NOPM;
343 w->shift = 0;
344 w->kcontrol_news = NULL;
345 w->num_kcontrols = 0;
346 w->priv = NULL;
347}
348
349static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
350 const char *sink, const char *control, const char *src)
351{
352 route->sink = sink;
353 route->source = src;
354 route->control = control;
355 route->connected = NULL;
356}
357
358static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,
359 struct hdac_hdmi_dai_pin_map *dai_map)
360{
361 struct snd_soc_dapm_route route[1];
362 struct snd_soc_dapm_widget widgets[2] = { {0} };
363
364 memset(&route, 0, sizeof(route));
365
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");
370
371 hdac_hdmi_fill_route(&route[0], "hif1 Output", NULL, "Coverter 1");
372
373 snd_soc_dapm_new_controls(dapm, widgets, ARRAY_SIZE(widgets));
374 snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));
375}
376
15b91447 377static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
18382ead 378{
15b91447
SP
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;
18382ead 383
15b91447
SP
384 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
385 return -EINVAL;
18382ead 386
15b91447
SP
387 /*
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
391 */
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);
394
395 dai_map->dai_id = 0;
396 dai_map->pin = pin;
18382ead 397
15b91447 398 dai_map->cvt = cvt;
18382ead
SP
399
400 /* Enable out path for this pin widget */
15b91447 401 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
18382ead
SP
402 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
403
404 /* Enable transmission */
15b91447 405 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
18382ead
SP
406 AC_VERB_SET_DIGI_CONVERT_1, 1);
407
408 /* Category Code (CC) to zero */
15b91447 409 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
18382ead
SP
410 AC_VERB_SET_DIGI_CONVERT_2, 0);
411
15b91447 412 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
18382ead
SP
413 AC_VERB_SET_CONNECT_SEL, 0);
414
15b91447
SP
415 return 0;
416}
417
418static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
419{
420 struct hdac_hdmi_priv *hdmi = edev->private_data;
421 struct hdac_hdmi_cvt *cvt;
422
423 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
424 if (!cvt)
425 return -ENOMEM;
426
427 cvt->nid = nid;
428
429 list_add_tail(&cvt->head, &hdmi->cvt_list);
430 hdmi->num_cvt++;
431
432 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
433}
434
435static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
436{
437 struct hdac_hdmi_priv *hdmi = edev->private_data;
438 struct hdac_hdmi_pin *pin;
439
440 pin = kzalloc(sizeof(*pin), GFP_KERNEL);
441 if (!pin)
442 return -ENOMEM;
443
444 pin->nid = nid;
445
446 list_add_tail(&pin->head, &hdmi->pin_list);
447 hdmi->num_pin++;
448
449 return 0;
18382ead
SP
450}
451
452/*
453 * Parse all nodes and store the cvt/pin nids in array
454 * Add one time initialization for pin and cvt widgets
455 */
456static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
457{
458 hda_nid_t nid;
3c83ac23 459 int i, num_nodes;
18382ead
SP
460 struct hdac_device *hdac = &edev->hdac;
461 struct hdac_hdmi_priv *hdmi = edev->private_data;
15b91447 462 int ret;
18382ead 463
3c83ac23 464 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
541140d4 465 if (!nid || num_nodes <= 0) {
18382ead
SP
466 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
467 return -EINVAL;
468 }
469
3c83ac23 470 hdac->num_nodes = num_nodes;
18382ead
SP
471 hdac->start_nid = nid;
472
473 for (i = 0; i < hdac->num_nodes; i++, nid++) {
474 unsigned int caps;
475 unsigned int type;
476
477 caps = get_wcaps(hdac, nid);
478 type = get_wcaps_type(caps);
479
480 if (!(caps & AC_WCAP_DIGITAL))
481 continue;
482
483 switch (type) {
484
485 case AC_WID_AUD_OUT:
15b91447
SP
486 ret = hdac_hdmi_add_cvt(edev, nid);
487 if (ret < 0)
488 return ret;
18382ead
SP
489 break;
490
491 case AC_WID_PIN:
15b91447
SP
492 ret = hdac_hdmi_add_pin(edev, nid);
493 if (ret < 0)
494 return ret;
18382ead
SP
495 break;
496 }
497 }
498
499 hdac->end_nid = nid;
500
15b91447 501 if (!hdmi->num_pin || !hdmi->num_cvt)
18382ead
SP
502 return -EIO;
503
15b91447 504 return hdac_hdmi_init_dai_map(edev);
18382ead
SP
505}
506
507static int hdmi_codec_probe(struct snd_soc_codec *codec)
508{
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);
513
514 edev->scodec = codec;
515
516 create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);
517
518 /* Imp: Store the card pointer in hda_codec */
519 edev->card = dapm->card->snd_card;
520
e342ac08
SP
521 /*
522 * hdac_device core already sets the state to active and calls
523 * get_noresume. So enable runtime and set the device to suspend.
524 */
525 pm_runtime_enable(&edev->hdac.dev);
526 pm_runtime_put(&edev->hdac.dev);
527 pm_runtime_suspend(&edev->hdac.dev);
528
529 return 0;
530}
531
532static int hdmi_codec_remove(struct snd_soc_codec *codec)
533{
534 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
535
536 pm_runtime_disable(&edev->hdac.dev);
18382ead
SP
537 return 0;
538}
539
540static struct snd_soc_codec_driver hdmi_hda_codec = {
541 .probe = hdmi_codec_probe,
e342ac08 542 .remove = hdmi_codec_remove,
18382ead
SP
543 .idle_bias_off = true,
544};
545
b0362adb
SP
546static 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,
552};
553
18382ead
SP
554static struct snd_soc_dai_driver hdmi_dais[] = {
555 { .name = "intel-hdmi-hif1",
556 .playback = {
557 .stream_name = "hif1",
558 .channels_min = 2,
559 .channels_max = 2,
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,
568
569 },
b0362adb 570 .ops = &hdmi_dai_ops,
18382ead
SP
571 },
572};
573
574static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
575{
576 struct hdac_device *codec = &edev->hdac;
577 struct hdac_hdmi_priv *hdmi_priv;
578 int ret = 0;
579
580 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
581 if (hdmi_priv == NULL)
582 return -ENOMEM;
583
584 edev->private_data = hdmi_priv;
585
586 dev_set_drvdata(&codec->dev, edev);
587
15b91447
SP
588 INIT_LIST_HEAD(&hdmi_priv->pin_list);
589 INIT_LIST_HEAD(&hdmi_priv->cvt_list);
590
18382ead
SP
591 ret = hdac_hdmi_parse_and_map_nid(edev);
592 if (ret < 0)
593 return ret;
594
595 /* ASoC specific initialization */
596 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
597 hdmi_dais, ARRAY_SIZE(hdmi_dais));
598}
599
600static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
601{
15b91447
SP
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;
605
18382ead
SP
606 snd_soc_unregister_codec(&edev->hdac.dev);
607
15b91447
SP
608 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
609 list_del(&cvt->head);
610 kfree(cvt);
611 }
612
613 list_for_each_entry_safe(pin, pin_next, &hdmi->pin_list, head) {
614 list_del(&pin->head);
615 kfree(pin);
616 }
617
18382ead
SP
618 return 0;
619}
620
e342ac08
SP
621#ifdef CONFIG_PM
622static int hdac_hdmi_runtime_suspend(struct device *dev)
623{
624 struct hdac_ext_device *edev = to_hda_ext_device(dev);
625 struct hdac_device *hdac = &edev->hdac;
07f083ab
SP
626 struct hdac_bus *bus = hdac->bus;
627 int err;
e342ac08
SP
628
629 dev_dbg(dev, "Enter: %s\n", __func__);
630
07f083ab
SP
631 /* controller may not have been initialized for the first time */
632 if (!bus)
633 return 0;
634
e342ac08
SP
635 /* Power down afg */
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);
639
07f083ab
SP
640 err = snd_hdac_display_power(bus, false);
641 if (err < 0) {
642 dev_err(bus->dev, "Cannot turn on display power on i915\n");
643 return err;
644 }
645
e342ac08
SP
646 return 0;
647}
648
649static int hdac_hdmi_runtime_resume(struct device *dev)
650{
651 struct hdac_ext_device *edev = to_hda_ext_device(dev);
652 struct hdac_device *hdac = &edev->hdac;
07f083ab
SP
653 struct hdac_bus *bus = hdac->bus;
654 int err;
e342ac08
SP
655
656 dev_dbg(dev, "Enter: %s\n", __func__);
657
07f083ab
SP
658 /* controller may not have been initialized for the first time */
659 if (!bus)
660 return 0;
661
662 err = snd_hdac_display_power(bus, true);
663 if (err < 0) {
664 dev_err(bus->dev, "Cannot turn on display power on i915\n");
665 return err;
666 }
667
e342ac08
SP
668 /* Power up afg */
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);
672
673 return 0;
674}
675#else
676#define hdac_hdmi_runtime_suspend NULL
677#define hdac_hdmi_runtime_resume NULL
678#endif
679
680static const struct dev_pm_ops hdac_hdmi_pm = {
681 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
682};
683
18382ead
SP
684static const struct hda_device_id hdmi_list[] = {
685 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
686 {}
687};
688
689MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
690
691static struct hdac_ext_driver hdmi_driver = {
692 . hdac = {
693 .driver = {
694 .name = "HDMI HDA Codec",
e342ac08 695 .pm = &hdac_hdmi_pm,
18382ead
SP
696 },
697 .id_table = hdmi_list,
698 },
699 .probe = hdac_hdmi_dev_probe,
700 .remove = hdac_hdmi_dev_remove,
701};
702
703static int __init hdmi_init(void)
704{
705 return snd_hda_ext_driver_register(&hdmi_driver);
706}
707
708static void __exit hdmi_exit(void)
709{
710 snd_hda_ext_driver_unregister(&hdmi_driver);
711}
712
713module_init(hdmi_init);
714module_exit(hdmi_exit);
715
716MODULE_LICENSE("GPL v2");
717MODULE_DESCRIPTION("HDMI HD codec");
718MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
719MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");
This page took 0.200252 seconds and 5 git commands to generate.