blob: 6fb44c4cc8c780a1b8c400c291bc43f40c0ce418 [file] [log] [blame]
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301/*
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>
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +053024#include <linux/hdmi.h>
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +053025#include <drm/drm_edid.h>
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053026#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/hdaudio_ext.h>
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +053029#include <sound/hda_i915.h>
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +053030#include <sound/pcm_drm_eld.h>
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053031#include "../../hda/local.h"
32
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +053033#define NAME_SIZE 32
34
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +053035#define AMP_OUT_MUTE 0xb080
36#define AMP_OUT_UNMUTE 0xb000
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053037#define PIN_OUT (AC_PINCTL_OUT_EN)
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +053038
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053039#define HDA_MAX_CONNECTIONS 32
40
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053041#define ELD_MAX_SIZE 256
42#define ELD_FIXED_BYTES 20
43
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053044struct hdac_hdmi_cvt_params {
45 unsigned int channels_min;
46 unsigned int channels_max;
47 u32 rates;
48 u64 formats;
49 unsigned int maxbps;
50};
51
52struct hdac_hdmi_cvt {
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053053 struct list_head head;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053054 hda_nid_t nid;
55 struct hdac_hdmi_cvt_params params;
56};
57
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053058struct hdac_hdmi_eld {
59 bool monitor_present;
60 bool eld_valid;
61 int eld_size;
62 char eld_buffer[ELD_MAX_SIZE];
63};
64
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053065struct hdac_hdmi_pin {
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053066 struct list_head head;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053067 hda_nid_t nid;
68 int num_mux_nids;
69 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053070 struct hdac_hdmi_eld eld;
71 struct hdac_ext_device *edev;
72 int repoll_count;
73 struct delayed_work work;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053074};
75
76struct hdac_hdmi_dai_pin_map {
77 int dai_id;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053078 struct hdac_hdmi_pin *pin;
79 struct hdac_hdmi_cvt *cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053080};
81
82struct hdac_hdmi_priv {
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053083 struct hdac_hdmi_dai_pin_map dai_map[3];
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053084 struct list_head pin_list;
85 struct list_head cvt_list;
86 int num_pin;
87 int num_cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053088};
89
Subhransu S. Prustye342ac02015-11-10 18:42:07 +053090static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
91{
Geliang Tang51b2c422015-12-28 22:47:13 +080092 struct hdac_device *hdac = dev_to_hdac_dev(dev);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +053093
Geliang Tang51b2c422015-12-28 22:47:13 +080094 return to_ehdac_device(hdac);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +053095}
96
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +053097static unsigned int sad_format(const u8 *sad)
98{
99 return ((sad[0] >> 0x3) & 0x1f);
100}
101
102static unsigned int sad_sample_bits_lpcm(const u8 *sad)
103{
104 return (sad[2] & 7);
105}
106
107static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,
108 void *eld)
109{
110 u64 formats = SNDRV_PCM_FMTBIT_S16;
111 int i;
112 const u8 *sad, *eld_buf = eld;
113
114 sad = drm_eld_sad(eld_buf);
115 if (!sad)
116 goto format_constraint;
117
118 for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {
119 if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */
120
121 /*
122 * the controller support 20 and 24 bits in 32 bit
123 * container so we set S32
124 */
125 if (sad_sample_bits_lpcm(sad) & 0x6)
126 formats |= SNDRV_PCM_FMTBIT_S32;
127 }
128 }
129
130format_constraint:
131 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
132 formats);
133
134}
135
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530136 /* HDMI ELD routines */
137static unsigned int hdac_hdmi_get_eld_data(struct hdac_device *codec,
138 hda_nid_t nid, int byte_index)
139{
140 unsigned int val;
141
142 val = snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_ELDD,
143 byte_index);
144
145 dev_dbg(&codec->dev, "HDMI: ELD data byte %d: 0x%x\n",
146 byte_index, val);
147
148 return val;
149}
150
151static int hdac_hdmi_get_eld_size(struct hdac_device *codec, hda_nid_t nid)
152{
153 return snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
154 AC_DIPSIZE_ELD_BUF);
155}
156
157/*
158 * This function queries the ELD size and ELD data and fills in the buffer
159 * passed by user
160 */
161static int hdac_hdmi_get_eld(struct hdac_device *codec, hda_nid_t nid,
162 unsigned char *buf, int *eld_size)
163{
164 int i, size, ret = 0;
165
166 /*
167 * ELD size is initialized to zero in caller function. If no errors and
168 * ELD is valid, actual eld_size is assigned.
169 */
170
171 size = hdac_hdmi_get_eld_size(codec, nid);
172 if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
173 dev_err(&codec->dev, "HDMI: invalid ELD buf size %d\n", size);
174 return -ERANGE;
175 }
176
177 /* set ELD buffer */
178 for (i = 0; i < size; i++) {
179 unsigned int val = hdac_hdmi_get_eld_data(codec, nid, i);
180 /*
181 * Graphics driver might be writing to ELD buffer right now.
182 * Just abort. The caller will repoll after a while.
183 */
184 if (!(val & AC_ELDD_ELD_VALID)) {
185 dev_err(&codec->dev,
186 "HDMI: invalid ELD data byte %d\n", i);
187 ret = -EINVAL;
188 goto error;
189 }
190 val &= AC_ELDD_ELD_DATA;
191 /*
192 * The first byte cannot be zero. This can happen on some DVI
193 * connections. Some Intel chips may also need some 250ms delay
194 * to return non-zero ELD data, even when the graphics driver
195 * correctly writes ELD content before setting ELD_valid bit.
196 */
197 if (!val && !i) {
198 dev_err(&codec->dev, "HDMI: 0 ELD data\n");
199 ret = -EINVAL;
200 goto error;
201 }
202 buf[i] = val;
203 }
204
205 *eld_size = size;
206error:
207 return ret;
208}
209
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530210static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
211 hda_nid_t cvt_nid, hda_nid_t pin_nid,
212 u32 stream_tag, int format)
213{
214 unsigned int val;
215
216 dev_dbg(&hdac->hdac.dev, "cvt nid %d pnid %d stream %d format 0x%x\n",
217 cvt_nid, pin_nid, stream_tag, format);
218
219 val = (stream_tag << 4);
220
221 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
222 AC_VERB_SET_CHANNEL_STREAMID, val);
223 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
224 AC_VERB_SET_STREAM_FORMAT, format);
225
226 return 0;
227}
228
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530229static void
230hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
231 int packet_index, int byte_index)
232{
233 int val;
234
235 val = (packet_index << 5) | (byte_index & 0x1f);
236
237 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
238 AC_VERB_SET_HDMI_DIP_INDEX, val);
239}
240
241static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
242 hda_nid_t cvt_nid, hda_nid_t pin_nid)
243{
244 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
245 struct hdmi_audio_infoframe frame;
246 u8 *dip = (u8 *)&frame;
247 int ret;
248 int i;
249
250 hdmi_audio_infoframe_init(&frame);
251
252 /* Default stereo for now */
253 frame.channels = 2;
254
255 /* setup channel count */
256 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
257 AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
258
259 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
260 if (ret < 0)
261 return ret;
262
263 /* stop infoframe transmission */
264 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
265 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
266 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);
267
268
269 /* Fill infoframe. Index auto-incremented */
270 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
271 for (i = 0; i < sizeof(frame); i++)
272 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
273 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
274
275 /* Start infoframe */
276 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
277 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
278 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);
279
280 return 0;
281}
282
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530283static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
284 struct hdac_hdmi_dai_pin_map *dai_map, unsigned int pwr_state)
285{
286 /* Power up pin widget */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530287 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->pin->nid,
288 pwr_state))
289 snd_hdac_codec_write(&edev->hdac, dai_map->pin->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530290 AC_VERB_SET_POWER_STATE, pwr_state);
291
292 /* Power up converter */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530293 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->cvt->nid,
294 pwr_state))
295 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530296 AC_VERB_SET_POWER_STATE, pwr_state);
297}
298
299static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
300 struct snd_soc_dai *dai)
301{
302 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
303 struct hdac_hdmi_priv *hdmi = hdac->private_data;
304 struct hdac_hdmi_dai_pin_map *dai_map;
305 struct hdac_ext_dma_params *dd;
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530306 int ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530307
308 if (dai->id > 0) {
309 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
310 return -ENODEV;
311 }
312
313 dai_map = &hdmi->dai_map[dai->id];
314
315 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
316 dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n",
317 dd->stream_tag, dd->format);
318
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530319 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
320 dai_map->pin->nid);
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530321 if (ret < 0)
322 return ret;
323
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530324 return hdac_hdmi_setup_stream(hdac, dai_map->cvt->nid,
325 dai_map->pin->nid, dd->stream_tag, dd->format);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530326}
327
328static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
330{
331 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
332 struct hdac_ext_dma_params *dd;
333
334 if (dai->id > 0) {
335 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
336 return -ENODEV;
337 }
338
339 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
Sudip Mukherjee8d33ab22015-11-23 17:45:13 +0530340 if (!dd)
341 return -ENOMEM;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530342 dd->format = snd_hdac_calc_stream_format(params_rate(hparams),
343 params_channels(hparams), params_format(hparams),
344 24, 0);
345
346 snd_soc_dai_set_dma_data(dai, substream, (void *)dd);
347
348 return 0;
349}
350
351static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream *substream,
352 struct snd_soc_dai *dai)
353{
354 struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
355 struct hdac_ext_dma_params *dd;
356 struct hdac_hdmi_priv *hdmi = edev->private_data;
357 struct hdac_hdmi_dai_pin_map *dai_map;
358
359 dai_map = &hdmi->dai_map[dai->id];
360
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530361 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530362 AC_VERB_SET_CHANNEL_STREAMID, 0);
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530363 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530364 AC_VERB_SET_STREAM_FORMAT, 0);
365
366 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
367 snd_soc_dai_set_dma_data(dai, substream, NULL);
368
369 kfree(dd);
370
371 return 0;
372}
373
374static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
375 struct snd_soc_dai *dai)
376{
377 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
378 struct hdac_hdmi_priv *hdmi = hdac->private_data;
379 struct hdac_hdmi_dai_pin_map *dai_map;
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530380 int ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530381
382 if (dai->id > 0) {
383 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
384 return -ENODEV;
385 }
386
387 dai_map = &hdmi->dai_map[dai->id];
388
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530389 if ((!dai_map->pin->eld.monitor_present) ||
390 (!dai_map->pin->eld.eld_valid)) {
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530391
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530392 dev_err(&hdac->hdac.dev,
393 "Failed: montior present? %d ELD valid?: %d\n",
394 dai_map->pin->eld.monitor_present,
395 dai_map->pin->eld.eld_valid);
396
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530397 return -ENODEV;
398 }
399
400 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
401
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530402 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530403 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
404
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530405 ret = hdac_hdmi_eld_limit_formats(substream->runtime,
406 dai_map->pin->eld.eld_buffer);
407 if (ret < 0)
408 return ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530409
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530410 return snd_pcm_hw_constraint_eld(substream->runtime,
411 dai_map->pin->eld.eld_buffer);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530412}
413
414static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
415 struct snd_soc_dai *dai)
416{
417 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
418 struct hdac_hdmi_priv *hdmi = hdac->private_data;
419 struct hdac_hdmi_dai_pin_map *dai_map;
420
421 dai_map = &hdmi->dai_map[dai->id];
422
423 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);
424
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530425 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530426 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
427}
428
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530429static int
430hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
431{
432 int err;
433
434 /* Only stereo supported as of now */
435 cvt->params.channels_min = cvt->params.channels_max = 2;
436
437 err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
438 &cvt->params.rates,
439 &cvt->params.formats,
440 &cvt->params.maxbps);
441 if (err < 0)
442 dev_err(&hdac->dev,
443 "Failed to query pcm params for nid %d: %d\n",
444 cvt->nid, err);
445
446 return err;
447}
448
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530449static int hdac_hdmi_fill_widget_info(struct device *dev,
450 struct snd_soc_dapm_widget *w,
451 enum snd_soc_dapm_type id, void *priv,
452 const char *wname, const char *stream,
453 struct snd_kcontrol_new *wc, int numkc)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530454{
455 w->id = id;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530456 w->name = devm_kstrdup(dev, wname, GFP_KERNEL);
457 if (!w->name)
458 return -ENOMEM;
459
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530460 w->sname = stream;
461 w->reg = SND_SOC_NOPM;
462 w->shift = 0;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530463 w->kcontrol_news = wc;
464 w->num_kcontrols = numkc;
465 w->priv = priv;
466
467 return 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530468}
469
470static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530471 const char *sink, const char *control, const char *src,
472 int (*handler)(struct snd_soc_dapm_widget *src,
473 struct snd_soc_dapm_widget *sink))
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530474{
475 route->sink = sink;
476 route->source = src;
477 route->control = control;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530478 route->connected = handler;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530479}
480
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530481/*
482 * Ideally the Mux inputs should be based on the num_muxs enumerated, but
483 * the display driver seem to be programming the connection list for the pin
484 * widget runtime.
485 *
486 * So programming all the possible inputs for the mux, the user has to take
487 * care of selecting the right one and leaving all other inputs selected to
488 * "NONE"
489 */
490static int hdac_hdmi_create_pin_muxs(struct hdac_ext_device *edev,
491 struct hdac_hdmi_pin *pin,
492 struct snd_soc_dapm_widget *widget,
493 const char *widget_name)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530494{
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530495 struct hdac_hdmi_priv *hdmi = edev->private_data;
496 struct snd_kcontrol_new *kc;
497 struct hdac_hdmi_cvt *cvt;
498 struct soc_enum *se;
499 char kc_name[NAME_SIZE];
500 char mux_items[NAME_SIZE];
501 /* To hold inputs to the Pin mux */
502 char *items[HDA_MAX_CONNECTIONS];
503 int i = 0;
504 int num_items = hdmi->num_cvt + 1;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530505
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530506 kc = devm_kzalloc(&edev->hdac.dev, sizeof(*kc), GFP_KERNEL);
507 if (!kc)
508 return -ENOMEM;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530509
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530510 se = devm_kzalloc(&edev->hdac.dev, sizeof(*se), GFP_KERNEL);
511 if (!se)
512 return -ENOMEM;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530513
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530514 sprintf(kc_name, "Pin %d Input", pin->nid);
515 kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL);
516 if (!kc->name)
517 return -ENOMEM;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530518
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530519 kc->private_value = (long)se;
520 kc->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
521 kc->access = 0;
522 kc->info = snd_soc_info_enum_double;
523 kc->put = snd_soc_dapm_put_enum_double;
524 kc->get = snd_soc_dapm_get_enum_double;
525
526 se->reg = SND_SOC_NOPM;
527
528 /* enum texts: ["NONE", "cvt #", "cvt #", ...] */
529 se->items = num_items;
530 se->mask = roundup_pow_of_two(se->items) - 1;
531
532 sprintf(mux_items, "NONE");
533 items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
534 if (!items[i])
535 return -ENOMEM;
536
537 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
538 i++;
539 sprintf(mux_items, "cvt %d", cvt->nid);
540 items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
541 if (!items[i])
542 return -ENOMEM;
543 }
544
545 se->texts = devm_kmemdup(&edev->hdac.dev, items,
546 (num_items * sizeof(char *)), GFP_KERNEL);
547 if (!se->texts)
548 return -ENOMEM;
549
550 return hdac_hdmi_fill_widget_info(&edev->hdac.dev, widget,
551 snd_soc_dapm_mux, &pin->nid, widget_name,
552 NULL, kc, 1);
553}
554
555/* Add cvt <- input <- mux route map */
556static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_ext_device *edev,
557 struct snd_soc_dapm_widget *widgets,
558 struct snd_soc_dapm_route *route, int rindex)
559{
560 struct hdac_hdmi_priv *hdmi = edev->private_data;
561 const struct snd_kcontrol_new *kc;
562 struct soc_enum *se;
563 int mux_index = hdmi->num_cvt + hdmi->num_pin;
564 int i, j;
565
566 for (i = 0; i < hdmi->num_pin; i++) {
567 kc = widgets[mux_index].kcontrol_news;
568 se = (struct soc_enum *)kc->private_value;
569 for (j = 0; j < hdmi->num_cvt; j++) {
570 hdac_hdmi_fill_route(&route[rindex],
571 widgets[mux_index].name,
572 se->texts[j + 1],
573 widgets[j].name, NULL);
574
575 rindex++;
576 }
577
578 mux_index++;
579 }
580}
581
582/*
583 * Widgets are added in the below sequence
584 * Converter widgets for num converters enumerated
585 * Pin widgets for num pins enumerated
586 * Pin mux widgets to represent connenction list of pin widget
587 *
588 * Total widgets elements = num_cvt + num_pin + num_pin;
589 *
590 * Routes are added as below:
591 * pin mux -> pin (based on num_pins)
592 * cvt -> "Input sel control" -> pin_mux
593 *
594 * Total route elements:
595 * num_pins + (pin_muxes * num_cvt)
596 */
597static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)
598{
599 struct snd_soc_dapm_widget *widgets;
600 struct snd_soc_dapm_route *route;
601 struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
602 struct hdac_hdmi_priv *hdmi = edev->private_data;
603 struct snd_soc_dai_driver *dai_drv = dapm->component->dai_drv;
604 char widget_name[NAME_SIZE];
605 struct hdac_hdmi_cvt *cvt;
606 struct hdac_hdmi_pin *pin;
607 int ret, i = 0, num_routes = 0;
608
609 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
610 return -EINVAL;
611
612 widgets = devm_kzalloc(dapm->dev,
613 (sizeof(*widgets) * ((2 * hdmi->num_pin) + hdmi->num_cvt)),
614 GFP_KERNEL);
615
616 if (!widgets)
617 return -ENOMEM;
618
619 /* DAPM widgets to represent each converter widget */
620 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
621 sprintf(widget_name, "Converter %d", cvt->nid);
622 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],
623 snd_soc_dapm_aif_in, &cvt->nid,
624 widget_name, dai_drv[i].playback.stream_name, NULL, 0);
625 if (ret < 0)
626 return ret;
627 i++;
628 }
629
630 list_for_each_entry(pin, &hdmi->pin_list, head) {
631 sprintf(widget_name, "hif%d Output", pin->nid);
632 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],
633 snd_soc_dapm_output, &pin->nid,
634 widget_name, NULL, NULL, 0);
635 if (ret < 0)
636 return ret;
637 i++;
638 }
639
640 /* DAPM widgets to represent the connection list to pin widget */
641 list_for_each_entry(pin, &hdmi->pin_list, head) {
642 sprintf(widget_name, "Pin %d Mux", pin->nid);
643 ret = hdac_hdmi_create_pin_muxs(edev, pin, &widgets[i],
644 widget_name);
645 if (ret < 0)
646 return ret;
647 i++;
648
649 /* For cvt to pin_mux mapping */
650 num_routes += hdmi->num_cvt;
651
652 /* For pin_mux to pin mapping */
653 num_routes++;
654 }
655
656 route = devm_kzalloc(dapm->dev, (sizeof(*route) * num_routes),
657 GFP_KERNEL);
658 if (!route)
659 return -ENOMEM;
660
661 i = 0;
662 /* Add pin <- NULL <- mux route map */
663 list_for_each_entry(pin, &hdmi->pin_list, head) {
664 int sink_index = i + hdmi->num_cvt;
665 int src_index = sink_index + hdmi->num_pin;
666
667 hdac_hdmi_fill_route(&route[i],
668 widgets[sink_index].name, NULL,
669 widgets[src_index].name, NULL);
670 i++;
671
672 }
673
674 hdac_hdmi_add_pinmux_cvt_route(edev, widgets, route, i);
675
676 snd_soc_dapm_new_controls(dapm, widgets,
677 ((2 * hdmi->num_pin) + hdmi->num_cvt));
678
679 snd_soc_dapm_add_routes(dapm, route, num_routes);
680 snd_soc_dapm_new_widgets(dapm->card);
681
682 return 0;
683
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530684}
685
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530686static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530687{
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530688 struct hdac_hdmi_priv *hdmi = edev->private_data;
689 struct hdac_hdmi_dai_pin_map *dai_map = &hdmi->dai_map[0];
690 struct hdac_hdmi_cvt *cvt;
691 struct hdac_hdmi_pin *pin;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530692
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530693 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
694 return -EINVAL;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530695
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530696 /*
697 * Currently on board only 1 pin and 1 converter is enabled for
698 * simplification, more will be added eventually
699 * So using fixed map for dai_id:pin:cvt
700 */
701 cvt = list_first_entry(&hdmi->cvt_list, struct hdac_hdmi_cvt, head);
702 pin = list_first_entry(&hdmi->pin_list, struct hdac_hdmi_pin, head);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530703
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530704 dai_map->dai_id = 0;
705 dai_map->pin = pin;
706
707 dai_map->cvt = cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530708
709 /* Enable out path for this pin widget */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530710 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530711 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
712
713 /* Enable transmission */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530714 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530715 AC_VERB_SET_DIGI_CONVERT_1, 1);
716
717 /* Category Code (CC) to zero */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530718 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530719 AC_VERB_SET_DIGI_CONVERT_2, 0);
720
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530721 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530722 AC_VERB_SET_CONNECT_SEL, 0);
723
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530724 return 0;
725}
726
727static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
728{
729 struct hdac_hdmi_priv *hdmi = edev->private_data;
730 struct hdac_hdmi_cvt *cvt;
731
732 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
733 if (!cvt)
734 return -ENOMEM;
735
736 cvt->nid = nid;
737
738 list_add_tail(&cvt->head, &hdmi->cvt_list);
739 hdmi->num_cvt++;
740
741 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
742}
743
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530744static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
745{
746 struct hdac_ext_device *edev = pin->edev;
747 int val;
748
749 if (!edev)
750 return;
751
752 pin->repoll_count = repoll;
753
754 pm_runtime_get_sync(&edev->hdac.dev);
755 val = snd_hdac_codec_read(&edev->hdac, pin->nid, 0,
756 AC_VERB_GET_PIN_SENSE, 0);
757
758 dev_dbg(&edev->hdac.dev, "Pin sense val %x for pin: %d\n",
759 val, pin->nid);
760
761 pin->eld.monitor_present = !!(val & AC_PINSENSE_PRESENCE);
762 pin->eld.eld_valid = !!(val & AC_PINSENSE_ELDV);
763
764 if (!pin->eld.monitor_present || !pin->eld.eld_valid) {
765
766 dev_dbg(&edev->hdac.dev, "%s: disconnect for pin %d\n",
767 __func__, pin->nid);
768 goto put_hdac_device;
769 }
770
771 if (pin->eld.monitor_present && pin->eld.eld_valid) {
772 /* TODO: use i915 component for reading ELD later */
773 if (hdac_hdmi_get_eld(&edev->hdac, pin->nid,
774 pin->eld.eld_buffer,
775 &pin->eld.eld_size) == 0) {
776
777 print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET,
778 pin->eld.eld_buffer, pin->eld.eld_size);
779 } else {
780 pin->eld.monitor_present = false;
781 pin->eld.eld_valid = false;
782 }
783 }
784
785 /*
786 * Sometimes the pin_sense may present invalid monitor
787 * present and eld_valid. If ELD data is not valid, loop few
788 * more times to get correct pin sense and valid ELD.
789 */
790 if ((!pin->eld.monitor_present || !pin->eld.eld_valid) && repoll)
791 schedule_delayed_work(&pin->work, msecs_to_jiffies(300));
792
793put_hdac_device:
794 pm_runtime_put_sync(&edev->hdac.dev);
795}
796
797static void hdac_hdmi_repoll_eld(struct work_struct *work)
798{
799 struct hdac_hdmi_pin *pin =
800 container_of(to_delayed_work(work), struct hdac_hdmi_pin, work);
801
802 /* picked from legacy HDA driver */
803 if (pin->repoll_count++ > 6)
804 pin->repoll_count = 0;
805
806 hdac_hdmi_present_sense(pin, pin->repoll_count);
807}
808
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530809static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
810{
811 struct hdac_hdmi_priv *hdmi = edev->private_data;
812 struct hdac_hdmi_pin *pin;
813
814 pin = kzalloc(sizeof(*pin), GFP_KERNEL);
815 if (!pin)
816 return -ENOMEM;
817
818 pin->nid = nid;
819
820 list_add_tail(&pin->head, &hdmi->pin_list);
821 hdmi->num_pin++;
822
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530823 pin->edev = edev;
824 INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld);
825
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530826 return 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530827}
828
Subhransu S. Prusty211caab2016-02-12 07:46:03 +0530829#define INTEL_VENDOR_NID 0x08
830#define INTEL_GET_VENDOR_VERB 0xf81
831#define INTEL_SET_VENDOR_VERB 0x781
832#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
833#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
834
835static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
836{
837 unsigned int vendor_param;
838
839 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
840 INTEL_GET_VENDOR_VERB, 0);
841 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
842 return;
843
844 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
845 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
846 INTEL_SET_VENDOR_VERB, vendor_param);
847 if (vendor_param == -1)
848 return;
849}
850
851static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
852{
853 unsigned int vendor_param;
854
855 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
856 INTEL_GET_VENDOR_VERB, 0);
857 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
858 return;
859
860 /* enable DP1.2 mode */
861 vendor_param |= INTEL_EN_DP12;
862 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
863 INTEL_SET_VENDOR_VERB, vendor_param);
864 if (vendor_param == -1)
865 return;
866
867}
868
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +0530869static struct snd_soc_dai_ops hdmi_dai_ops = {
870 .startup = hdac_hdmi_pcm_open,
871 .shutdown = hdac_hdmi_pcm_close,
872 .hw_params = hdac_hdmi_set_hw_params,
873 .prepare = hdac_hdmi_playback_prepare,
874 .hw_free = hdac_hdmi_playback_cleanup,
875};
876
877/*
878 * Each converter can support a stream independently. So a dai is created
879 * based on the number of converter queried.
880 */
881static int hdac_hdmi_create_dais(struct hdac_device *hdac,
882 struct snd_soc_dai_driver **dais,
883 struct hdac_hdmi_priv *hdmi, int num_dais)
884{
885 struct snd_soc_dai_driver *hdmi_dais;
886 struct hdac_hdmi_cvt *cvt;
887 char name[NAME_SIZE], dai_name[NAME_SIZE];
888 int i = 0;
889 u32 rates, bps;
890 unsigned int rate_max = 384000, rate_min = 8000;
891 u64 formats;
892 int ret;
893
894 hdmi_dais = devm_kzalloc(&hdac->dev,
895 (sizeof(*hdmi_dais) * num_dais),
896 GFP_KERNEL);
897 if (!hdmi_dais)
898 return -ENOMEM;
899
900 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
901 ret = snd_hdac_query_supported_pcm(hdac, cvt->nid,
902 &rates, &formats, &bps);
903 if (ret)
904 return ret;
905
906 sprintf(dai_name, "intel-hdmi-hifi%d", i+1);
907 hdmi_dais[i].name = devm_kstrdup(&hdac->dev,
908 dai_name, GFP_KERNEL);
909
910 if (!hdmi_dais[i].name)
911 return -ENOMEM;
912
913 snprintf(name, sizeof(name), "hifi%d", i+1);
914 hdmi_dais[i].playback.stream_name =
915 devm_kstrdup(&hdac->dev, name, GFP_KERNEL);
916 if (!hdmi_dais[i].playback.stream_name)
917 return -ENOMEM;
918
919 /*
920 * Set caps based on capability queried from the converter.
921 * It will be constrained runtime based on ELD queried.
922 */
923 hdmi_dais[i].playback.formats = formats;
924 hdmi_dais[i].playback.rates = rates;
925 hdmi_dais[i].playback.rate_max = rate_max;
926 hdmi_dais[i].playback.rate_min = rate_min;
927 hdmi_dais[i].playback.channels_min = 2;
928 hdmi_dais[i].playback.channels_max = 2;
929 hdmi_dais[i].ops = &hdmi_dai_ops;
930
931 i++;
932 }
933
934 *dais = hdmi_dais;
935
936 return 0;
937}
938
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530939/*
940 * Parse all nodes and store the cvt/pin nids in array
941 * Add one time initialization for pin and cvt widgets
942 */
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +0530943static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
944 struct snd_soc_dai_driver **dais, int *num_dais)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530945{
946 hda_nid_t nid;
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +0530947 int i, num_nodes;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530948 struct hdac_device *hdac = &edev->hdac;
949 struct hdac_hdmi_priv *hdmi = edev->private_data;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530950 int ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530951
Subhransu S. Prusty211caab2016-02-12 07:46:03 +0530952 hdac_hdmi_skl_enable_all_pins(hdac);
953 hdac_hdmi_skl_enable_dp12(hdac);
954
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +0530955 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
Subhransu S. Prusty541140d2015-12-09 21:46:08 +0530956 if (!nid || num_nodes <= 0) {
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530957 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
958 return -EINVAL;
959 }
960
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +0530961 hdac->num_nodes = num_nodes;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530962 hdac->start_nid = nid;
963
964 for (i = 0; i < hdac->num_nodes; i++, nid++) {
965 unsigned int caps;
966 unsigned int type;
967
968 caps = get_wcaps(hdac, nid);
969 type = get_wcaps_type(caps);
970
971 if (!(caps & AC_WCAP_DIGITAL))
972 continue;
973
974 switch (type) {
975
976 case AC_WID_AUD_OUT:
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530977 ret = hdac_hdmi_add_cvt(edev, nid);
978 if (ret < 0)
979 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530980 break;
981
982 case AC_WID_PIN:
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530983 ret = hdac_hdmi_add_pin(edev, nid);
984 if (ret < 0)
985 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530986 break;
987 }
988 }
989
990 hdac->end_nid = nid;
991
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530992 if (!hdmi->num_pin || !hdmi->num_cvt)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530993 return -EIO;
994
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +0530995 ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
996 if (ret) {
997 dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
998 ret);
999 return ret;
1000 }
1001
1002 *num_dais = hdmi->num_cvt;
1003
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301004 return hdac_hdmi_init_dai_map(edev);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301005}
1006
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301007static void hdac_hdmi_eld_notify_cb(void *aptr, int port)
1008{
1009 struct hdac_ext_device *edev = aptr;
1010 struct hdac_hdmi_priv *hdmi = edev->private_data;
1011 struct hdac_hdmi_pin *pin;
1012 struct snd_soc_codec *codec = edev->scodec;
1013
1014 /* Don't know how this mapping is derived */
1015 hda_nid_t pin_nid = port + 0x04;
1016
1017 dev_dbg(&edev->hdac.dev, "%s: for pin: %d\n", __func__, pin_nid);
1018
1019 /*
1020 * skip notification during system suspend (but not in runtime PM);
1021 * the state will be updated at resume. Also since the ELD and
1022 * connection states are updated in anyway at the end of the resume,
1023 * we can skip it when received during PM process.
1024 */
1025 if (snd_power_get_state(codec->component.card->snd_card) !=
1026 SNDRV_CTL_POWER_D0)
1027 return;
1028
1029 if (atomic_read(&edev->hdac.in_pm))
1030 return;
1031
1032 list_for_each_entry(pin, &hdmi->pin_list, head) {
1033 if (pin->nid == pin_nid)
1034 hdac_hdmi_present_sense(pin, 1);
1035 }
1036}
1037
1038static struct i915_audio_component_audio_ops aops = {
1039 .pin_eld_notify = hdac_hdmi_eld_notify_cb,
1040};
1041
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301042static int hdmi_codec_probe(struct snd_soc_codec *codec)
1043{
1044 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1045 struct hdac_hdmi_priv *hdmi = edev->private_data;
1046 struct snd_soc_dapm_context *dapm =
1047 snd_soc_component_get_dapm(&codec->component);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301048 struct hdac_hdmi_pin *pin;
1049 int ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301050
1051 edev->scodec = codec;
1052
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +05301053 ret = create_fill_widget_route_map(dapm);
1054 if (ret < 0)
1055 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301056
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301057 aops.audio_ptr = edev;
1058 ret = snd_hdac_i915_register_notifier(&aops);
1059 if (ret < 0) {
1060 dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n",
1061 ret);
1062 return ret;
1063 }
1064
1065 list_for_each_entry(pin, &hdmi->pin_list, head)
1066 hdac_hdmi_present_sense(pin, 1);
1067
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301068 /* Imp: Store the card pointer in hda_codec */
1069 edev->card = dapm->card->snd_card;
1070
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301071 /*
1072 * hdac_device core already sets the state to active and calls
1073 * get_noresume. So enable runtime and set the device to suspend.
1074 */
1075 pm_runtime_enable(&edev->hdac.dev);
1076 pm_runtime_put(&edev->hdac.dev);
1077 pm_runtime_suspend(&edev->hdac.dev);
1078
1079 return 0;
1080}
1081
1082static int hdmi_codec_remove(struct snd_soc_codec *codec)
1083{
1084 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1085
1086 pm_runtime_disable(&edev->hdac.dev);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301087 return 0;
1088}
1089
1090static struct snd_soc_codec_driver hdmi_hda_codec = {
1091 .probe = hdmi_codec_probe,
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301092 .remove = hdmi_codec_remove,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301093 .idle_bias_off = true,
1094};
1095
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301096static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
1097{
1098 struct hdac_device *codec = &edev->hdac;
1099 struct hdac_hdmi_priv *hdmi_priv;
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301100 struct snd_soc_dai_driver *hdmi_dais = NULL;
1101 int num_dais = 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301102 int ret = 0;
1103
1104 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
1105 if (hdmi_priv == NULL)
1106 return -ENOMEM;
1107
1108 edev->private_data = hdmi_priv;
1109
1110 dev_set_drvdata(&codec->dev, edev);
1111
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301112 INIT_LIST_HEAD(&hdmi_priv->pin_list);
1113 INIT_LIST_HEAD(&hdmi_priv->cvt_list);
1114
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301115 ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais);
1116 if (ret < 0) {
1117 dev_err(&codec->dev,
1118 "Failed in parse and map nid with err: %d\n", ret);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301119 return ret;
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301120 }
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301121
1122 /* ASoC specific initialization */
1123 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301124 hdmi_dais, num_dais);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301125}
1126
1127static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
1128{
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301129 struct hdac_hdmi_priv *hdmi = edev->private_data;
1130 struct hdac_hdmi_pin *pin, *pin_next;
1131 struct hdac_hdmi_cvt *cvt, *cvt_next;
1132
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301133 snd_soc_unregister_codec(&edev->hdac.dev);
1134
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301135 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
1136 list_del(&cvt->head);
1137 kfree(cvt);
1138 }
1139
1140 list_for_each_entry_safe(pin, pin_next, &hdmi->pin_list, head) {
1141 list_del(&pin->head);
1142 kfree(pin);
1143 }
1144
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301145 return 0;
1146}
1147
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301148#ifdef CONFIG_PM
1149static int hdac_hdmi_runtime_suspend(struct device *dev)
1150{
1151 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1152 struct hdac_device *hdac = &edev->hdac;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301153 struct hdac_bus *bus = hdac->bus;
1154 int err;
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301155
1156 dev_dbg(dev, "Enter: %s\n", __func__);
1157
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301158 /* controller may not have been initialized for the first time */
1159 if (!bus)
1160 return 0;
1161
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301162 /* Power down afg */
1163 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3))
1164 snd_hdac_codec_write(hdac, hdac->afg, 0,
1165 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1166
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301167 err = snd_hdac_display_power(bus, false);
1168 if (err < 0) {
1169 dev_err(bus->dev, "Cannot turn on display power on i915\n");
1170 return err;
1171 }
1172
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301173 return 0;
1174}
1175
1176static int hdac_hdmi_runtime_resume(struct device *dev)
1177{
1178 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1179 struct hdac_device *hdac = &edev->hdac;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301180 struct hdac_bus *bus = hdac->bus;
1181 int err;
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301182
1183 dev_dbg(dev, "Enter: %s\n", __func__);
1184
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301185 /* controller may not have been initialized for the first time */
1186 if (!bus)
1187 return 0;
1188
1189 err = snd_hdac_display_power(bus, true);
1190 if (err < 0) {
1191 dev_err(bus->dev, "Cannot turn on display power on i915\n");
1192 return err;
1193 }
1194
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301195 /* Power up afg */
1196 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
1197 snd_hdac_codec_write(hdac, hdac->afg, 0,
1198 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1199
1200 return 0;
1201}
1202#else
1203#define hdac_hdmi_runtime_suspend NULL
1204#define hdac_hdmi_runtime_resume NULL
1205#endif
1206
1207static const struct dev_pm_ops hdac_hdmi_pm = {
1208 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
1209};
1210
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301211static const struct hda_device_id hdmi_list[] = {
1212 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
1213 {}
1214};
1215
1216MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
1217
1218static struct hdac_ext_driver hdmi_driver = {
1219 . hdac = {
1220 .driver = {
1221 .name = "HDMI HDA Codec",
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301222 .pm = &hdac_hdmi_pm,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301223 },
1224 .id_table = hdmi_list,
1225 },
1226 .probe = hdac_hdmi_dev_probe,
1227 .remove = hdac_hdmi_dev_remove,
1228};
1229
1230static int __init hdmi_init(void)
1231{
1232 return snd_hda_ext_driver_register(&hdmi_driver);
1233}
1234
1235static void __exit hdmi_exit(void)
1236{
1237 snd_hda_ext_driver_unregister(&hdmi_driver);
1238}
1239
1240module_init(hdmi_init);
1241module_exit(hdmi_exit);
1242
1243MODULE_LICENSE("GPL v2");
1244MODULE_DESCRIPTION("HDMI HD codec");
1245MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
1246MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");