blob: b2e5e549b02230cf0f0ba67e0425a7f29e520841 [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. Prustyb0362ad2015-11-10 18:42:08 +053033#define AMP_OUT_MUTE 0xb080
34#define AMP_OUT_UNMUTE 0xb000
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053035#define PIN_OUT (AC_PINCTL_OUT_EN)
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +053036
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053037#define HDA_MAX_CONNECTIONS 32
38
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053039#define ELD_MAX_SIZE 256
40#define ELD_FIXED_BYTES 20
41
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053042struct hdac_hdmi_cvt_params {
43 unsigned int channels_min;
44 unsigned int channels_max;
45 u32 rates;
46 u64 formats;
47 unsigned int maxbps;
48};
49
50struct hdac_hdmi_cvt {
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053051 struct list_head head;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053052 hda_nid_t nid;
53 struct hdac_hdmi_cvt_params params;
54};
55
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053056struct hdac_hdmi_eld {
57 bool monitor_present;
58 bool eld_valid;
59 int eld_size;
60 char eld_buffer[ELD_MAX_SIZE];
61};
62
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053063struct hdac_hdmi_pin {
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053064 struct list_head head;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053065 hda_nid_t nid;
66 int num_mux_nids;
67 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053068 struct hdac_hdmi_eld eld;
69 struct hdac_ext_device *edev;
70 int repoll_count;
71 struct delayed_work work;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053072};
73
74struct hdac_hdmi_dai_pin_map {
75 int dai_id;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053076 struct hdac_hdmi_pin *pin;
77 struct hdac_hdmi_cvt *cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053078};
79
80struct hdac_hdmi_priv {
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053081 struct hdac_hdmi_dai_pin_map dai_map[3];
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053082 struct list_head pin_list;
83 struct list_head cvt_list;
84 int num_pin;
85 int num_cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053086};
87
Subhransu S. Prustye342ac02015-11-10 18:42:07 +053088static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
89{
Geliang Tang51b2c422015-12-28 22:47:13 +080090 struct hdac_device *hdac = dev_to_hdac_dev(dev);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +053091
Geliang Tang51b2c422015-12-28 22:47:13 +080092 return to_ehdac_device(hdac);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +053093}
94
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +053095static unsigned int sad_format(const u8 *sad)
96{
97 return ((sad[0] >> 0x3) & 0x1f);
98}
99
100static unsigned int sad_sample_bits_lpcm(const u8 *sad)
101{
102 return (sad[2] & 7);
103}
104
105static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,
106 void *eld)
107{
108 u64 formats = SNDRV_PCM_FMTBIT_S16;
109 int i;
110 const u8 *sad, *eld_buf = eld;
111
112 sad = drm_eld_sad(eld_buf);
113 if (!sad)
114 goto format_constraint;
115
116 for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {
117 if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */
118
119 /*
120 * the controller support 20 and 24 bits in 32 bit
121 * container so we set S32
122 */
123 if (sad_sample_bits_lpcm(sad) & 0x6)
124 formats |= SNDRV_PCM_FMTBIT_S32;
125 }
126 }
127
128format_constraint:
129 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
130 formats);
131
132}
133
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530134 /* HDMI ELD routines */
135static unsigned int hdac_hdmi_get_eld_data(struct hdac_device *codec,
136 hda_nid_t nid, int byte_index)
137{
138 unsigned int val;
139
140 val = snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_ELDD,
141 byte_index);
142
143 dev_dbg(&codec->dev, "HDMI: ELD data byte %d: 0x%x\n",
144 byte_index, val);
145
146 return val;
147}
148
149static int hdac_hdmi_get_eld_size(struct hdac_device *codec, hda_nid_t nid)
150{
151 return snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
152 AC_DIPSIZE_ELD_BUF);
153}
154
155/*
156 * This function queries the ELD size and ELD data and fills in the buffer
157 * passed by user
158 */
159static int hdac_hdmi_get_eld(struct hdac_device *codec, hda_nid_t nid,
160 unsigned char *buf, int *eld_size)
161{
162 int i, size, ret = 0;
163
164 /*
165 * ELD size is initialized to zero in caller function. If no errors and
166 * ELD is valid, actual eld_size is assigned.
167 */
168
169 size = hdac_hdmi_get_eld_size(codec, nid);
170 if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
171 dev_err(&codec->dev, "HDMI: invalid ELD buf size %d\n", size);
172 return -ERANGE;
173 }
174
175 /* set ELD buffer */
176 for (i = 0; i < size; i++) {
177 unsigned int val = hdac_hdmi_get_eld_data(codec, nid, i);
178 /*
179 * Graphics driver might be writing to ELD buffer right now.
180 * Just abort. The caller will repoll after a while.
181 */
182 if (!(val & AC_ELDD_ELD_VALID)) {
183 dev_err(&codec->dev,
184 "HDMI: invalid ELD data byte %d\n", i);
185 ret = -EINVAL;
186 goto error;
187 }
188 val &= AC_ELDD_ELD_DATA;
189 /*
190 * The first byte cannot be zero. This can happen on some DVI
191 * connections. Some Intel chips may also need some 250ms delay
192 * to return non-zero ELD data, even when the graphics driver
193 * correctly writes ELD content before setting ELD_valid bit.
194 */
195 if (!val && !i) {
196 dev_err(&codec->dev, "HDMI: 0 ELD data\n");
197 ret = -EINVAL;
198 goto error;
199 }
200 buf[i] = val;
201 }
202
203 *eld_size = size;
204error:
205 return ret;
206}
207
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530208static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
209 hda_nid_t cvt_nid, hda_nid_t pin_nid,
210 u32 stream_tag, int format)
211{
212 unsigned int val;
213
214 dev_dbg(&hdac->hdac.dev, "cvt nid %d pnid %d stream %d format 0x%x\n",
215 cvt_nid, pin_nid, stream_tag, format);
216
217 val = (stream_tag << 4);
218
219 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
220 AC_VERB_SET_CHANNEL_STREAMID, val);
221 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
222 AC_VERB_SET_STREAM_FORMAT, format);
223
224 return 0;
225}
226
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530227static void
228hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
229 int packet_index, int byte_index)
230{
231 int val;
232
233 val = (packet_index << 5) | (byte_index & 0x1f);
234
235 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
236 AC_VERB_SET_HDMI_DIP_INDEX, val);
237}
238
239static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
240 hda_nid_t cvt_nid, hda_nid_t pin_nid)
241{
242 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
243 struct hdmi_audio_infoframe frame;
244 u8 *dip = (u8 *)&frame;
245 int ret;
246 int i;
247
248 hdmi_audio_infoframe_init(&frame);
249
250 /* Default stereo for now */
251 frame.channels = 2;
252
253 /* setup channel count */
254 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
255 AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
256
257 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
258 if (ret < 0)
259 return ret;
260
261 /* stop infoframe transmission */
262 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
263 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
264 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);
265
266
267 /* Fill infoframe. Index auto-incremented */
268 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
269 for (i = 0; i < sizeof(frame); i++)
270 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
271 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
272
273 /* Start infoframe */
274 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
275 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
276 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);
277
278 return 0;
279}
280
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530281static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
282 struct hdac_hdmi_dai_pin_map *dai_map, unsigned int pwr_state)
283{
284 /* Power up pin widget */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530285 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->pin->nid,
286 pwr_state))
287 snd_hdac_codec_write(&edev->hdac, dai_map->pin->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530288 AC_VERB_SET_POWER_STATE, pwr_state);
289
290 /* Power up converter */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530291 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->cvt->nid,
292 pwr_state))
293 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530294 AC_VERB_SET_POWER_STATE, pwr_state);
295}
296
297static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
298 struct snd_soc_dai *dai)
299{
300 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
301 struct hdac_hdmi_priv *hdmi = hdac->private_data;
302 struct hdac_hdmi_dai_pin_map *dai_map;
303 struct hdac_ext_dma_params *dd;
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530304 int ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530305
306 if (dai->id > 0) {
307 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
308 return -ENODEV;
309 }
310
311 dai_map = &hdmi->dai_map[dai->id];
312
313 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
314 dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n",
315 dd->stream_tag, dd->format);
316
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530317 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
318 dai_map->pin->nid);
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530319 if (ret < 0)
320 return ret;
321
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530322 return hdac_hdmi_setup_stream(hdac, dai_map->cvt->nid,
323 dai_map->pin->nid, dd->stream_tag, dd->format);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530324}
325
326static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
327 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
328{
329 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
330 struct hdac_ext_dma_params *dd;
331
332 if (dai->id > 0) {
333 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
334 return -ENODEV;
335 }
336
337 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
Sudip Mukherjee8d33ab22015-11-23 17:45:13 +0530338 if (!dd)
339 return -ENOMEM;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530340 dd->format = snd_hdac_calc_stream_format(params_rate(hparams),
341 params_channels(hparams), params_format(hparams),
342 24, 0);
343
344 snd_soc_dai_set_dma_data(dai, substream, (void *)dd);
345
346 return 0;
347}
348
349static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream *substream,
350 struct snd_soc_dai *dai)
351{
352 struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
353 struct hdac_ext_dma_params *dd;
354 struct hdac_hdmi_priv *hdmi = edev->private_data;
355 struct hdac_hdmi_dai_pin_map *dai_map;
356
357 dai_map = &hdmi->dai_map[dai->id];
358
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530359 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530360 AC_VERB_SET_CHANNEL_STREAMID, 0);
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_STREAM_FORMAT, 0);
363
364 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
365 snd_soc_dai_set_dma_data(dai, substream, NULL);
366
367 kfree(dd);
368
369 return 0;
370}
371
372static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
373 struct snd_soc_dai *dai)
374{
375 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
376 struct hdac_hdmi_priv *hdmi = hdac->private_data;
377 struct hdac_hdmi_dai_pin_map *dai_map;
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530378 int ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530379
380 if (dai->id > 0) {
381 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
382 return -ENODEV;
383 }
384
385 dai_map = &hdmi->dai_map[dai->id];
386
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530387 if ((!dai_map->pin->eld.monitor_present) ||
388 (!dai_map->pin->eld.eld_valid)) {
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530389
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530390 dev_err(&hdac->hdac.dev,
391 "Failed: montior present? %d ELD valid?: %d\n",
392 dai_map->pin->eld.monitor_present,
393 dai_map->pin->eld.eld_valid);
394
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530395 return -ENODEV;
396 }
397
398 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
399
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530400 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530401 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
402
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530403 ret = hdac_hdmi_eld_limit_formats(substream->runtime,
404 dai_map->pin->eld.eld_buffer);
405 if (ret < 0)
406 return ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530407
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530408 return snd_pcm_hw_constraint_eld(substream->runtime,
409 dai_map->pin->eld.eld_buffer);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530410}
411
412static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
413 struct snd_soc_dai *dai)
414{
415 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
416 struct hdac_hdmi_priv *hdmi = hdac->private_data;
417 struct hdac_hdmi_dai_pin_map *dai_map;
418
419 dai_map = &hdmi->dai_map[dai->id];
420
421 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);
422
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530423 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530424 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
425}
426
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530427static int
428hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
429{
430 int err;
431
432 /* Only stereo supported as of now */
433 cvt->params.channels_min = cvt->params.channels_max = 2;
434
435 err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
436 &cvt->params.rates,
437 &cvt->params.formats,
438 &cvt->params.maxbps);
439 if (err < 0)
440 dev_err(&hdac->dev,
441 "Failed to query pcm params for nid %d: %d\n",
442 cvt->nid, err);
443
444 return err;
445}
446
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530447static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget *w,
448 enum snd_soc_dapm_type id,
449 const char *wname, const char *stream)
450{
451 w->id = id;
452 w->name = wname;
453 w->sname = stream;
454 w->reg = SND_SOC_NOPM;
455 w->shift = 0;
456 w->kcontrol_news = NULL;
457 w->num_kcontrols = 0;
458 w->priv = NULL;
459}
460
461static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
462 const char *sink, const char *control, const char *src)
463{
464 route->sink = sink;
465 route->source = src;
466 route->control = control;
467 route->connected = NULL;
468}
469
470static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,
471 struct hdac_hdmi_dai_pin_map *dai_map)
472{
473 struct snd_soc_dapm_route route[1];
474 struct snd_soc_dapm_widget widgets[2] = { {0} };
475
476 memset(&route, 0, sizeof(route));
477
478 hdac_hdmi_fill_widget_info(&widgets[0], snd_soc_dapm_output,
479 "hif1 Output", NULL);
480 hdac_hdmi_fill_widget_info(&widgets[1], snd_soc_dapm_aif_in,
481 "Coverter 1", "hif1");
482
483 hdac_hdmi_fill_route(&route[0], "hif1 Output", NULL, "Coverter 1");
484
485 snd_soc_dapm_new_controls(dapm, widgets, ARRAY_SIZE(widgets));
486 snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));
487}
488
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530489static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530490{
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530491 struct hdac_hdmi_priv *hdmi = edev->private_data;
492 struct hdac_hdmi_dai_pin_map *dai_map = &hdmi->dai_map[0];
493 struct hdac_hdmi_cvt *cvt;
494 struct hdac_hdmi_pin *pin;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530495
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530496 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
497 return -EINVAL;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530498
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530499 /*
500 * Currently on board only 1 pin and 1 converter is enabled for
501 * simplification, more will be added eventually
502 * So using fixed map for dai_id:pin:cvt
503 */
504 cvt = list_first_entry(&hdmi->cvt_list, struct hdac_hdmi_cvt, head);
505 pin = list_first_entry(&hdmi->pin_list, struct hdac_hdmi_pin, head);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530506
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530507 dai_map->dai_id = 0;
508 dai_map->pin = pin;
509
510 dai_map->cvt = cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530511
512 /* Enable out path for this pin widget */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530513 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530514 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
515
516 /* Enable transmission */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530517 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530518 AC_VERB_SET_DIGI_CONVERT_1, 1);
519
520 /* Category Code (CC) to zero */
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530521 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530522 AC_VERB_SET_DIGI_CONVERT_2, 0);
523
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530524 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530525 AC_VERB_SET_CONNECT_SEL, 0);
526
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530527 return 0;
528}
529
530static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
531{
532 struct hdac_hdmi_priv *hdmi = edev->private_data;
533 struct hdac_hdmi_cvt *cvt;
534
535 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
536 if (!cvt)
537 return -ENOMEM;
538
539 cvt->nid = nid;
540
541 list_add_tail(&cvt->head, &hdmi->cvt_list);
542 hdmi->num_cvt++;
543
544 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
545}
546
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530547static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
548{
549 struct hdac_ext_device *edev = pin->edev;
550 int val;
551
552 if (!edev)
553 return;
554
555 pin->repoll_count = repoll;
556
557 pm_runtime_get_sync(&edev->hdac.dev);
558 val = snd_hdac_codec_read(&edev->hdac, pin->nid, 0,
559 AC_VERB_GET_PIN_SENSE, 0);
560
561 dev_dbg(&edev->hdac.dev, "Pin sense val %x for pin: %d\n",
562 val, pin->nid);
563
564 pin->eld.monitor_present = !!(val & AC_PINSENSE_PRESENCE);
565 pin->eld.eld_valid = !!(val & AC_PINSENSE_ELDV);
566
567 if (!pin->eld.monitor_present || !pin->eld.eld_valid) {
568
569 dev_dbg(&edev->hdac.dev, "%s: disconnect for pin %d\n",
570 __func__, pin->nid);
571 goto put_hdac_device;
572 }
573
574 if (pin->eld.monitor_present && pin->eld.eld_valid) {
575 /* TODO: use i915 component for reading ELD later */
576 if (hdac_hdmi_get_eld(&edev->hdac, pin->nid,
577 pin->eld.eld_buffer,
578 &pin->eld.eld_size) == 0) {
579
580 print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET,
581 pin->eld.eld_buffer, pin->eld.eld_size);
582 } else {
583 pin->eld.monitor_present = false;
584 pin->eld.eld_valid = false;
585 }
586 }
587
588 /*
589 * Sometimes the pin_sense may present invalid monitor
590 * present and eld_valid. If ELD data is not valid, loop few
591 * more times to get correct pin sense and valid ELD.
592 */
593 if ((!pin->eld.monitor_present || !pin->eld.eld_valid) && repoll)
594 schedule_delayed_work(&pin->work, msecs_to_jiffies(300));
595
596put_hdac_device:
597 pm_runtime_put_sync(&edev->hdac.dev);
598}
599
600static void hdac_hdmi_repoll_eld(struct work_struct *work)
601{
602 struct hdac_hdmi_pin *pin =
603 container_of(to_delayed_work(work), struct hdac_hdmi_pin, work);
604
605 /* picked from legacy HDA driver */
606 if (pin->repoll_count++ > 6)
607 pin->repoll_count = 0;
608
609 hdac_hdmi_present_sense(pin, pin->repoll_count);
610}
611
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530612static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
613{
614 struct hdac_hdmi_priv *hdmi = edev->private_data;
615 struct hdac_hdmi_pin *pin;
616
617 pin = kzalloc(sizeof(*pin), GFP_KERNEL);
618 if (!pin)
619 return -ENOMEM;
620
621 pin->nid = nid;
622
623 list_add_tail(&pin->head, &hdmi->pin_list);
624 hdmi->num_pin++;
625
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530626 pin->edev = edev;
627 INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld);
628
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530629 return 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530630}
631
Subhransu S. Prusty211caab2016-02-12 07:46:03 +0530632#define INTEL_VENDOR_NID 0x08
633#define INTEL_GET_VENDOR_VERB 0xf81
634#define INTEL_SET_VENDOR_VERB 0x781
635#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
636#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
637
638static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
639{
640 unsigned int vendor_param;
641
642 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
643 INTEL_GET_VENDOR_VERB, 0);
644 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
645 return;
646
647 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
648 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
649 INTEL_SET_VENDOR_VERB, vendor_param);
650 if (vendor_param == -1)
651 return;
652}
653
654static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
655{
656 unsigned int vendor_param;
657
658 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
659 INTEL_GET_VENDOR_VERB, 0);
660 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
661 return;
662
663 /* enable DP1.2 mode */
664 vendor_param |= INTEL_EN_DP12;
665 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
666 INTEL_SET_VENDOR_VERB, vendor_param);
667 if (vendor_param == -1)
668 return;
669
670}
671
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530672/*
673 * Parse all nodes and store the cvt/pin nids in array
674 * Add one time initialization for pin and cvt widgets
675 */
676static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
677{
678 hda_nid_t nid;
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +0530679 int i, num_nodes;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530680 struct hdac_device *hdac = &edev->hdac;
681 struct hdac_hdmi_priv *hdmi = edev->private_data;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530682 int ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530683
Subhransu S. Prusty211caab2016-02-12 07:46:03 +0530684 hdac_hdmi_skl_enable_all_pins(hdac);
685 hdac_hdmi_skl_enable_dp12(hdac);
686
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +0530687 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
Subhransu S. Prusty541140d2015-12-09 21:46:08 +0530688 if (!nid || num_nodes <= 0) {
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530689 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
690 return -EINVAL;
691 }
692
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +0530693 hdac->num_nodes = num_nodes;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530694 hdac->start_nid = nid;
695
696 for (i = 0; i < hdac->num_nodes; i++, nid++) {
697 unsigned int caps;
698 unsigned int type;
699
700 caps = get_wcaps(hdac, nid);
701 type = get_wcaps_type(caps);
702
703 if (!(caps & AC_WCAP_DIGITAL))
704 continue;
705
706 switch (type) {
707
708 case AC_WID_AUD_OUT:
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530709 ret = hdac_hdmi_add_cvt(edev, nid);
710 if (ret < 0)
711 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530712 break;
713
714 case AC_WID_PIN:
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530715 ret = hdac_hdmi_add_pin(edev, nid);
716 if (ret < 0)
717 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530718 break;
719 }
720 }
721
722 hdac->end_nid = nid;
723
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530724 if (!hdmi->num_pin || !hdmi->num_cvt)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530725 return -EIO;
726
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530727 return hdac_hdmi_init_dai_map(edev);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530728}
729
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530730static void hdac_hdmi_eld_notify_cb(void *aptr, int port)
731{
732 struct hdac_ext_device *edev = aptr;
733 struct hdac_hdmi_priv *hdmi = edev->private_data;
734 struct hdac_hdmi_pin *pin;
735 struct snd_soc_codec *codec = edev->scodec;
736
737 /* Don't know how this mapping is derived */
738 hda_nid_t pin_nid = port + 0x04;
739
740 dev_dbg(&edev->hdac.dev, "%s: for pin: %d\n", __func__, pin_nid);
741
742 /*
743 * skip notification during system suspend (but not in runtime PM);
744 * the state will be updated at resume. Also since the ELD and
745 * connection states are updated in anyway at the end of the resume,
746 * we can skip it when received during PM process.
747 */
748 if (snd_power_get_state(codec->component.card->snd_card) !=
749 SNDRV_CTL_POWER_D0)
750 return;
751
752 if (atomic_read(&edev->hdac.in_pm))
753 return;
754
755 list_for_each_entry(pin, &hdmi->pin_list, head) {
756 if (pin->nid == pin_nid)
757 hdac_hdmi_present_sense(pin, 1);
758 }
759}
760
761static struct i915_audio_component_audio_ops aops = {
762 .pin_eld_notify = hdac_hdmi_eld_notify_cb,
763};
764
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530765static int hdmi_codec_probe(struct snd_soc_codec *codec)
766{
767 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
768 struct hdac_hdmi_priv *hdmi = edev->private_data;
769 struct snd_soc_dapm_context *dapm =
770 snd_soc_component_get_dapm(&codec->component);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530771 struct hdac_hdmi_pin *pin;
772 int ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530773
774 edev->scodec = codec;
775
776 create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);
777
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530778 aops.audio_ptr = edev;
779 ret = snd_hdac_i915_register_notifier(&aops);
780 if (ret < 0) {
781 dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n",
782 ret);
783 return ret;
784 }
785
786 list_for_each_entry(pin, &hdmi->pin_list, head)
787 hdac_hdmi_present_sense(pin, 1);
788
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530789 /* Imp: Store the card pointer in hda_codec */
790 edev->card = dapm->card->snd_card;
791
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530792 /*
793 * hdac_device core already sets the state to active and calls
794 * get_noresume. So enable runtime and set the device to suspend.
795 */
796 pm_runtime_enable(&edev->hdac.dev);
797 pm_runtime_put(&edev->hdac.dev);
798 pm_runtime_suspend(&edev->hdac.dev);
799
800 return 0;
801}
802
803static int hdmi_codec_remove(struct snd_soc_codec *codec)
804{
805 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
806
807 pm_runtime_disable(&edev->hdac.dev);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530808 return 0;
809}
810
811static struct snd_soc_codec_driver hdmi_hda_codec = {
812 .probe = hdmi_codec_probe,
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530813 .remove = hdmi_codec_remove,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530814 .idle_bias_off = true,
815};
816
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530817static struct snd_soc_dai_ops hdmi_dai_ops = {
818 .startup = hdac_hdmi_pcm_open,
819 .shutdown = hdac_hdmi_pcm_close,
820 .hw_params = hdac_hdmi_set_hw_params,
821 .prepare = hdac_hdmi_playback_prepare,
822 .hw_free = hdac_hdmi_playback_cleanup,
823};
824
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530825static struct snd_soc_dai_driver hdmi_dais[] = {
826 { .name = "intel-hdmi-hif1",
827 .playback = {
828 .stream_name = "hif1",
829 .channels_min = 2,
830 .channels_max = 2,
831 .rates = SNDRV_PCM_RATE_32000 |
832 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
833 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
834 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
835 .formats = SNDRV_PCM_FMTBIT_S16_LE |
836 SNDRV_PCM_FMTBIT_S20_3LE |
837 SNDRV_PCM_FMTBIT_S24_LE |
838 SNDRV_PCM_FMTBIT_S32_LE,
839
840 },
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530841 .ops = &hdmi_dai_ops,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530842 },
843};
844
845static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
846{
847 struct hdac_device *codec = &edev->hdac;
848 struct hdac_hdmi_priv *hdmi_priv;
849 int ret = 0;
850
851 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
852 if (hdmi_priv == NULL)
853 return -ENOMEM;
854
855 edev->private_data = hdmi_priv;
856
857 dev_set_drvdata(&codec->dev, edev);
858
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530859 INIT_LIST_HEAD(&hdmi_priv->pin_list);
860 INIT_LIST_HEAD(&hdmi_priv->cvt_list);
861
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530862 ret = hdac_hdmi_parse_and_map_nid(edev);
863 if (ret < 0)
864 return ret;
865
866 /* ASoC specific initialization */
867 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
868 hdmi_dais, ARRAY_SIZE(hdmi_dais));
869}
870
871static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
872{
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530873 struct hdac_hdmi_priv *hdmi = edev->private_data;
874 struct hdac_hdmi_pin *pin, *pin_next;
875 struct hdac_hdmi_cvt *cvt, *cvt_next;
876
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530877 snd_soc_unregister_codec(&edev->hdac.dev);
878
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530879 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
880 list_del(&cvt->head);
881 kfree(cvt);
882 }
883
884 list_for_each_entry_safe(pin, pin_next, &hdmi->pin_list, head) {
885 list_del(&pin->head);
886 kfree(pin);
887 }
888
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530889 return 0;
890}
891
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530892#ifdef CONFIG_PM
893static int hdac_hdmi_runtime_suspend(struct device *dev)
894{
895 struct hdac_ext_device *edev = to_hda_ext_device(dev);
896 struct hdac_device *hdac = &edev->hdac;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +0530897 struct hdac_bus *bus = hdac->bus;
898 int err;
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530899
900 dev_dbg(dev, "Enter: %s\n", __func__);
901
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +0530902 /* controller may not have been initialized for the first time */
903 if (!bus)
904 return 0;
905
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530906 /* Power down afg */
907 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3))
908 snd_hdac_codec_write(hdac, hdac->afg, 0,
909 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
910
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +0530911 err = snd_hdac_display_power(bus, false);
912 if (err < 0) {
913 dev_err(bus->dev, "Cannot turn on display power on i915\n");
914 return err;
915 }
916
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530917 return 0;
918}
919
920static int hdac_hdmi_runtime_resume(struct device *dev)
921{
922 struct hdac_ext_device *edev = to_hda_ext_device(dev);
923 struct hdac_device *hdac = &edev->hdac;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +0530924 struct hdac_bus *bus = hdac->bus;
925 int err;
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530926
927 dev_dbg(dev, "Enter: %s\n", __func__);
928
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +0530929 /* controller may not have been initialized for the first time */
930 if (!bus)
931 return 0;
932
933 err = snd_hdac_display_power(bus, true);
934 if (err < 0) {
935 dev_err(bus->dev, "Cannot turn on display power on i915\n");
936 return err;
937 }
938
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530939 /* Power up afg */
940 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
941 snd_hdac_codec_write(hdac, hdac->afg, 0,
942 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
943
944 return 0;
945}
946#else
947#define hdac_hdmi_runtime_suspend NULL
948#define hdac_hdmi_runtime_resume NULL
949#endif
950
951static const struct dev_pm_ops hdac_hdmi_pm = {
952 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
953};
954
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530955static const struct hda_device_id hdmi_list[] = {
956 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
957 {}
958};
959
960MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
961
962static struct hdac_ext_driver hdmi_driver = {
963 . hdac = {
964 .driver = {
965 .name = "HDMI HDA Codec",
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530966 .pm = &hdac_hdmi_pm,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530967 },
968 .id_table = hdmi_list,
969 },
970 .probe = hdac_hdmi_dev_probe,
971 .remove = hdac_hdmi_dev_remove,
972};
973
974static int __init hdmi_init(void)
975{
976 return snd_hda_ext_driver_register(&hdmi_driver);
977}
978
979static void __exit hdmi_exit(void)
980{
981 snd_hda_ext_driver_unregister(&hdmi_driver);
982}
983
984module_init(hdmi_init);
985module_exit(hdmi_exit);
986
987MODULE_LICENSE("GPL v2");
988MODULE_DESCRIPTION("HDMI HD codec");
989MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
990MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");