blob: 17a1ad3ead2167c303bf03471483bd20d8c7fe66 [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>
Jeeja KP4a3478d2016-02-12 07:46:06 +053027#include <sound/jack.h>
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053028#include <sound/soc.h>
29#include <sound/hdaudio_ext.h>
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +053030#include <sound/hda_i915.h>
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +053031#include <sound/pcm_drm_eld.h>
Subhransu S. Prustybcced702016-04-14 10:07:30 +053032#include <sound/hda_chmap.h>
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053033#include "../../hda/local.h"
Jeeja KP4a3478d2016-02-12 07:46:06 +053034#include "hdac_hdmi.h"
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053035
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +053036#define NAME_SIZE 32
37
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +053038#define AMP_OUT_MUTE 0xb080
39#define AMP_OUT_UNMUTE 0xb000
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053040#define PIN_OUT (AC_PINCTL_OUT_EN)
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +053041
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053042#define HDA_MAX_CONNECTIONS 32
43
Subhransu S. Prusty148569f2016-02-12 07:46:07 +053044#define HDA_MAX_CVTS 3
Jeeja KP754695f2017-02-06 12:09:14 +053045#define HDA_MAX_PORTS 3
Subhransu S. Prusty148569f2016-02-12 07:46:07 +053046
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053047#define ELD_MAX_SIZE 256
48#define ELD_FIXED_BYTES 20
49
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +053050#define ELD_VER_CEA_861D 2
51#define ELD_VER_PARTIAL 31
52#define ELD_MAX_MNL 16
53
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053054struct hdac_hdmi_cvt_params {
55 unsigned int channels_min;
56 unsigned int channels_max;
57 u32 rates;
58 u64 formats;
59 unsigned int maxbps;
60};
61
62struct hdac_hdmi_cvt {
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053063 struct list_head head;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053064 hda_nid_t nid;
Jeeja KP4a3478d2016-02-12 07:46:06 +053065 const char *name;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053066 struct hdac_hdmi_cvt_params params;
67};
68
Subhransu S. Prustyb7756ed2016-04-14 10:07:28 +053069/* Currently only spk_alloc, more to be added */
70struct hdac_hdmi_parsed_eld {
71 u8 spk_alloc;
72};
73
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053074struct hdac_hdmi_eld {
75 bool monitor_present;
76 bool eld_valid;
77 int eld_size;
78 char eld_buffer[ELD_MAX_SIZE];
Subhransu S. Prustyb7756ed2016-04-14 10:07:28 +053079 struct hdac_hdmi_parsed_eld info;
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053080};
81
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053082struct hdac_hdmi_pin {
Subhransu S. Prusty15b91442015-12-09 21:46:10 +053083 struct list_head head;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053084 hda_nid_t nid;
Jeeja KP2acd8302017-02-06 12:09:18 +053085 bool mst_capable;
Jeeja KP754695f2017-02-06 12:09:14 +053086 struct hdac_hdmi_port *ports;
87 int num_ports;
88 struct hdac_ext_device *edev;
89};
90
91struct hdac_hdmi_port {
92 int id;
93 struct hdac_hdmi_pin *pin;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053094 int num_mux_nids;
95 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +053096 struct hdac_hdmi_eld eld;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +053097};
98
Jeeja KP4a3478d2016-02-12 07:46:06 +053099struct hdac_hdmi_pcm {
100 struct list_head head;
101 int pcm_id;
Jeeja KP754695f2017-02-06 12:09:14 +0530102 struct hdac_hdmi_port *port;
Jeeja KP4a3478d2016-02-12 07:46:06 +0530103 struct hdac_hdmi_cvt *cvt;
104 struct snd_jack *jack;
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530105 int stream_tag;
106 int channels;
107 int format;
Jeeja KPab1eea12017-01-24 21:49:05 +0530108 bool chmap_set;
109 unsigned char chmap[8]; /* ALSA API channel-map */
110 struct mutex lock;
Jeeja KP4a3478d2016-02-12 07:46:06 +0530111};
112
Jeeja KP754695f2017-02-06 12:09:14 +0530113struct hdac_hdmi_dai_port_map {
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530114 int dai_id;
Jeeja KP754695f2017-02-06 12:09:14 +0530115 struct hdac_hdmi_port *port;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530116 struct hdac_hdmi_cvt *cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530117};
118
119struct hdac_hdmi_priv {
Jeeja KP754695f2017-02-06 12:09:14 +0530120 struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS];
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530121 struct list_head pin_list;
122 struct list_head cvt_list;
Jeeja KP4a3478d2016-02-12 07:46:06 +0530123 struct list_head pcm_list;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530124 int num_pin;
125 int num_cvt;
Jeeja KP754695f2017-02-06 12:09:14 +0530126 int num_ports;
Jeeja KP4a3478d2016-02-12 07:46:06 +0530127 struct mutex pin_mutex;
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530128 struct hdac_chmap chmap;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530129};
130
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530131static struct hdac_hdmi_pcm *
132hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
133 struct hdac_hdmi_cvt *cvt)
134{
135 struct hdac_hdmi_pcm *pcm = NULL;
Jeeja KP1de777f2017-01-10 17:57:48 +0530136
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530137 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
138 if (pcm->cvt == cvt)
139 break;
140 }
141
142 return pcm;
143}
Jeeja KP1de777f2017-01-10 17:57:48 +0530144
Subhransu S. Prusty28890992016-04-14 10:07:34 +0530145static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi,
146 int pcm_idx)
147{
148 struct hdac_hdmi_pcm *pcm;
149
150 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
151 if (pcm->pcm_id == pcm_idx)
152 return pcm;
153 }
154
155 return NULL;
156}
157
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530158static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
159{
Geliang Tang51b2c422015-12-28 22:47:13 +0800160 struct hdac_device *hdac = dev_to_hdac_dev(dev);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530161
Geliang Tang51b2c422015-12-28 22:47:13 +0800162 return to_ehdac_device(hdac);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +0530163}
164
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530165static unsigned int sad_format(const u8 *sad)
166{
167 return ((sad[0] >> 0x3) & 0x1f);
168}
169
170static unsigned int sad_sample_bits_lpcm(const u8 *sad)
171{
172 return (sad[2] & 7);
173}
174
175static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,
176 void *eld)
177{
178 u64 formats = SNDRV_PCM_FMTBIT_S16;
179 int i;
180 const u8 *sad, *eld_buf = eld;
181
182 sad = drm_eld_sad(eld_buf);
183 if (!sad)
184 goto format_constraint;
185
186 for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {
187 if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */
188
189 /*
190 * the controller support 20 and 24 bits in 32 bit
191 * container so we set S32
192 */
193 if (sad_sample_bits_lpcm(sad) & 0x6)
194 formats |= SNDRV_PCM_FMTBIT_S32;
195 }
196 }
197
198format_constraint:
199 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
200 formats);
201
202}
203
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530204static void
205hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
206 int packet_index, int byte_index)
207{
208 int val;
209
210 val = (packet_index << 5) | (byte_index & 0x1f);
211
212 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
213 AC_VERB_SET_HDMI_DIP_INDEX, val);
214}
215
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530216struct dp_audio_infoframe {
217 u8 type; /* 0x84 */
218 u8 len; /* 0x1b */
219 u8 ver; /* 0x11 << 2 */
220
221 u8 CC02_CT47; /* match with HDMI infoframe from this on */
222 u8 SS01_SF24;
223 u8 CXT04;
224 u8 CA;
225 u8 LFEPBL01_LSV36_DM_INH7;
226};
227
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530228static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
Jeeja KP754695f2017-02-06 12:09:14 +0530229 struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port)
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530230{
231 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
232 struct hdmi_audio_infoframe frame;
Jeeja KP754695f2017-02-06 12:09:14 +0530233 struct hdac_hdmi_pin *pin = port->pin;
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530234 struct dp_audio_infoframe dp_ai;
235 struct hdac_hdmi_priv *hdmi = hdac->private_data;
Jeeja KPab1eea12017-01-24 21:49:05 +0530236 struct hdac_hdmi_cvt *cvt = pcm->cvt;
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530237 u8 *dip;
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530238 int ret;
239 int i;
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530240 const u8 *eld_buf;
241 u8 conn_type;
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530242 int channels, ca;
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530243
Jeeja KP754695f2017-02-06 12:09:14 +0530244 ca = snd_hdac_channel_allocation(&hdac->hdac, port->eld.info.spk_alloc,
Jeeja KPab1eea12017-01-24 21:49:05 +0530245 pcm->channels, pcm->chmap_set, true, pcm->chmap);
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530246
247 channels = snd_hdac_get_active_channels(ca);
Jeeja KPab1eea12017-01-24 21:49:05 +0530248 hdmi->chmap.ops.set_channel_count(&hdac->hdac, cvt->nid, channels);
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530249
250 snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca,
Jeeja KPab1eea12017-01-24 21:49:05 +0530251 pcm->channels, pcm->chmap, pcm->chmap_set);
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530252
Jeeja KP754695f2017-02-06 12:09:14 +0530253 eld_buf = port->eld.eld_buffer;
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530254 conn_type = drm_eld_get_conn_type(eld_buf);
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530255
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530256 switch (conn_type) {
257 case DRM_ELD_CONN_TYPE_HDMI:
258 hdmi_audio_infoframe_init(&frame);
259
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530260 frame.channels = channels;
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530261 frame.channel_allocation = ca;
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530262
263 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
264 if (ret < 0)
265 return ret;
266
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530267 break;
268
269 case DRM_ELD_CONN_TYPE_DP:
270 memset(&dp_ai, 0, sizeof(dp_ai));
271 dp_ai.type = 0x84;
272 dp_ai.len = 0x1b;
273 dp_ai.ver = 0x11 << 2;
274 dp_ai.CC02_CT47 = channels - 1;
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530275 dp_ai.CA = ca;
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530276
277 dip = (u8 *)&dp_ai;
278 break;
279
280 default:
281 dev_err(&hdac->hdac.dev, "Invalid connection type: %d\n",
282 conn_type);
283 return -EIO;
284 }
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530285
286 /* stop infoframe transmission */
Jeeja KPab1eea12017-01-24 21:49:05 +0530287 hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0);
288 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530289 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);
290
291
292 /* Fill infoframe. Index auto-incremented */
Jeeja KPab1eea12017-01-24 21:49:05 +0530293 hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0);
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530294 if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
Subhransu S. Prusty391005e2016-03-10 09:04:07 +0530295 for (i = 0; i < sizeof(buffer); i++)
Jeeja KPab1eea12017-01-24 21:49:05 +0530296 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
Subhransu S. Prusty391005e2016-03-10 09:04:07 +0530297 AC_VERB_SET_HDMI_DIP_DATA, buffer[i]);
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530298 } else {
299 for (i = 0; i < sizeof(dp_ai); i++)
Jeeja KPab1eea12017-01-24 21:49:05 +0530300 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
Subhransu S. Prusty478f544e2016-02-12 07:46:09 +0530301 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
302 }
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530303
304 /* Start infoframe */
Jeeja KPab1eea12017-01-24 21:49:05 +0530305 hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0);
306 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
Subhransu S. Prustya657f1d2015-11-10 18:42:09 +0530307 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);
308
309 return 0;
310}
311
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530312static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai,
313 unsigned int tx_mask, unsigned int rx_mask,
314 int slots, int slot_width)
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530315{
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530316 struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
317 struct hdac_hdmi_priv *hdmi = edev->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +0530318 struct hdac_hdmi_dai_port_map *dai_map;
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530319 struct hdac_hdmi_pcm *pcm;
320
321 dev_dbg(&edev->hdac.dev, "%s: strm_tag: %d\n", __func__, tx_mask);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530322
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530323 dai_map = &hdmi->dai_map[dai->id];
324
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530325 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530326
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530327 if (pcm)
328 pcm->stream_tag = (tx_mask << 4);
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530329
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530330 return 0;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530331}
332
333static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
334 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
335{
336 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530337 struct hdac_hdmi_priv *hdmi = hdac->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +0530338 struct hdac_hdmi_dai_port_map *dai_map;
339 struct hdac_hdmi_port *port;
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530340 struct hdac_hdmi_pcm *pcm;
341 int format;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530342
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530343 dai_map = &hdmi->dai_map[dai->id];
Jeeja KP754695f2017-02-06 12:09:14 +0530344 port = dai_map->port;
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530345
Jeeja KP754695f2017-02-06 12:09:14 +0530346 if (!port)
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530347 return -ENODEV;
348
Jeeja KP754695f2017-02-06 12:09:14 +0530349 if ((!port->eld.monitor_present) || (!port->eld.eld_valid)) {
350 dev_err(&hdac->hdac.dev,
351 "device is not configured for this pin:port%d:%d\n",
352 port->pin->nid, port->id);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530353 return -ENODEV;
354 }
355
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530356 format = snd_hdac_calc_stream_format(params_rate(hparams),
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530357 params_channels(hparams), params_format(hparams),
358 24, 0);
359
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530360 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
361 if (!pcm)
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530362 return -EIO;
363
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530364 pcm->format = format;
365 pcm->channels = params_channels(hparams);
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530366
367 return 0;
368}
369
Jeeja KP754695f2017-02-06 12:09:14 +0530370static int hdac_hdmi_query_port_connlist(struct hdac_ext_device *hdac,
371 struct hdac_hdmi_pin *pin,
372 struct hdac_hdmi_port *port)
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530373{
374 if (!(get_wcaps(&hdac->hdac, pin->nid) & AC_WCAP_CONN_LIST)) {
375 dev_warn(&hdac->hdac.dev,
376 "HDMI: pin %d wcaps %#x does not support connection list\n",
377 pin->nid, get_wcaps(&hdac->hdac, pin->nid));
378 return -EINVAL;
379 }
380
Jeeja KP754695f2017-02-06 12:09:14 +0530381 port->num_mux_nids = snd_hdac_get_connections(&hdac->hdac, pin->nid,
382 port->mux_nids, HDA_MAX_CONNECTIONS);
383 if (port->num_mux_nids == 0)
384 dev_warn(&hdac->hdac.dev,
385 "No connections found for pin:port %d:%d\n",
386 pin->nid, port->id);
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530387
Jeeja KP754695f2017-02-06 12:09:14 +0530388 dev_dbg(&hdac->hdac.dev, "num_mux_nids %d for pin:port %d:%d\n",
389 port->num_mux_nids, pin->nid, port->id);
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530390
Jeeja KP754695f2017-02-06 12:09:14 +0530391 return port->num_mux_nids;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530392}
393
394/*
Jeeja KP754695f2017-02-06 12:09:14 +0530395 * Query pcm list and return port to which stream is routed.
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530396 *
Jeeja KP754695f2017-02-06 12:09:14 +0530397 * Also query connection list of the pin, to validate the cvt to port map.
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530398 *
Jeeja KP754695f2017-02-06 12:09:14 +0530399 * Same stream rendering to multiple ports simultaneously can be done
400 * possibly, but not supported for now in driver. So return the first port
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530401 * connected.
402 */
Jeeja KP754695f2017-02-06 12:09:14 +0530403static struct hdac_hdmi_port *hdac_hdmi_get_port_from_cvt(
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530404 struct hdac_ext_device *edev,
405 struct hdac_hdmi_priv *hdmi,
406 struct hdac_hdmi_cvt *cvt)
407{
408 struct hdac_hdmi_pcm *pcm;
Jeeja KP754695f2017-02-06 12:09:14 +0530409 struct hdac_hdmi_port *port = NULL;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530410 int ret, i;
411
412 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
413 if (pcm->cvt == cvt) {
Jeeja KP754695f2017-02-06 12:09:14 +0530414 port = pcm->port;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530415 break;
416 }
417 }
418
Jeeja KP754695f2017-02-06 12:09:14 +0530419 if (port) {
420 ret = hdac_hdmi_query_port_connlist(edev, port->pin, port);
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530421 if (ret < 0)
422 return NULL;
423
Jeeja KP754695f2017-02-06 12:09:14 +0530424 for (i = 0; i < port->num_mux_nids; i++) {
425 if (port->mux_nids[i] == cvt->nid)
426 return port;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530427 }
428 }
429
430 return NULL;
431}
432
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530433/*
434 * This tries to get a valid pin and set the HW constraints based on the
435 * ELD. Even if a valid pin is not found return success so that device open
436 * doesn't fail.
437 */
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530438static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
439 struct snd_soc_dai *dai)
440{
441 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
442 struct hdac_hdmi_priv *hdmi = hdac->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +0530443 struct hdac_hdmi_dai_port_map *dai_map;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530444 struct hdac_hdmi_cvt *cvt;
Jeeja KP754695f2017-02-06 12:09:14 +0530445 struct hdac_hdmi_port *port;
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530446 int ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530447
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530448 dai_map = &hdmi->dai_map[dai->id];
449
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530450 cvt = dai_map->cvt;
Jeeja KP754695f2017-02-06 12:09:14 +0530451 port = hdac_hdmi_get_port_from_cvt(hdac, hdmi, cvt);
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530452
453 /*
454 * To make PA and other userland happy.
455 * userland scans devices so returning error does not help.
456 */
Jeeja KP754695f2017-02-06 12:09:14 +0530457 if (!port)
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530458 return 0;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530459
Jeeja KP754695f2017-02-06 12:09:14 +0530460 if ((!port->eld.monitor_present) ||
461 (!port->eld.eld_valid)) {
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530462
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530463 dev_warn(&hdac->hdac.dev,
Jeeja KP754695f2017-02-06 12:09:14 +0530464 "Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n",
465 port->eld.monitor_present, port->eld.eld_valid,
466 port->pin->nid, port->id);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +0530467
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530468 return 0;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530469 }
470
Jeeja KP754695f2017-02-06 12:09:14 +0530471 dai_map->port = port;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530472
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530473 ret = hdac_hdmi_eld_limit_formats(substream->runtime,
Jeeja KP754695f2017-02-06 12:09:14 +0530474 port->eld.eld_buffer);
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530475 if (ret < 0)
476 return ret;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530477
Subhransu S. Prusty2428bca2016-02-12 07:46:02 +0530478 return snd_pcm_hw_constraint_eld(substream->runtime,
Jeeja KP754695f2017-02-06 12:09:14 +0530479 port->eld.eld_buffer);
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530480}
481
482static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
484{
485 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
486 struct hdac_hdmi_priv *hdmi = hdac->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +0530487 struct hdac_hdmi_dai_port_map *dai_map;
Jeeja KPab1eea12017-01-24 21:49:05 +0530488 struct hdac_hdmi_pcm *pcm;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530489
490 dai_map = &hdmi->dai_map[dai->id];
491
Jeeja KPab1eea12017-01-24 21:49:05 +0530492 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530493
Jeeja KPab1eea12017-01-24 21:49:05 +0530494 if (pcm) {
495 mutex_lock(&pcm->lock);
496 pcm->chmap_set = false;
497 memset(pcm->chmap, 0, sizeof(pcm->chmap));
498 pcm->channels = 0;
499 mutex_unlock(&pcm->lock);
Subhransu S. Prusty54dfa1e2016-02-17 21:34:00 +0530500 }
Jeeja KPab1eea12017-01-24 21:49:05 +0530501
Jeeja KP754695f2017-02-06 12:09:14 +0530502 if (dai_map->port)
503 dai_map->port = NULL;
Subhransu S. Prustyb0362ad2015-11-10 18:42:08 +0530504}
505
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530506static int
507hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
508{
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530509 unsigned int chans;
510 struct hdac_ext_device *edev = to_ehdac_device(hdac);
511 struct hdac_hdmi_priv *hdmi = edev->private_data;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530512 int err;
513
Subhransu S. Prustybcced702016-04-14 10:07:30 +0530514 chans = get_wcaps(hdac, cvt->nid);
515 chans = get_wcaps_channels(chans);
516
517 cvt->params.channels_min = 2;
518
519 cvt->params.channels_max = chans;
520 if (chans > hdmi->chmap.channels_max)
521 hdmi->chmap.channels_max = chans;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530522
523 err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
524 &cvt->params.rates,
525 &cvt->params.formats,
526 &cvt->params.maxbps);
527 if (err < 0)
528 dev_err(&hdac->dev,
529 "Failed to query pcm params for nid %d: %d\n",
530 cvt->nid, err);
531
532 return err;
533}
534
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530535static int hdac_hdmi_fill_widget_info(struct device *dev,
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530536 struct snd_soc_dapm_widget *w, enum snd_soc_dapm_type id,
537 void *priv, const char *wname, const char *stream,
538 struct snd_kcontrol_new *wc, int numkc,
539 int (*event)(struct snd_soc_dapm_widget *,
540 struct snd_kcontrol *, int), unsigned short event_flags)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530541{
542 w->id = id;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530543 w->name = devm_kstrdup(dev, wname, GFP_KERNEL);
544 if (!w->name)
545 return -ENOMEM;
546
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530547 w->sname = stream;
548 w->reg = SND_SOC_NOPM;
549 w->shift = 0;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530550 w->kcontrol_news = wc;
551 w->num_kcontrols = numkc;
552 w->priv = priv;
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530553 w->event = event;
554 w->event_flags = event_flags;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530555
556 return 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530557}
558
559static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530560 const char *sink, const char *control, const char *src,
561 int (*handler)(struct snd_soc_dapm_widget *src,
562 struct snd_soc_dapm_widget *sink))
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530563{
564 route->sink = sink;
565 route->source = src;
566 route->control = control;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530567 route->connected = handler;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530568}
569
Jeeja KP4a3478d2016-02-12 07:46:06 +0530570static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
Jeeja KP754695f2017-02-06 12:09:14 +0530571 struct hdac_hdmi_port *port)
Jeeja KP4a3478d2016-02-12 07:46:06 +0530572{
573 struct hdac_hdmi_priv *hdmi = edev->private_data;
574 struct hdac_hdmi_pcm *pcm = NULL;
575
576 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +0530577 if (!pcm->port)
578 continue;
579
580 if (pcm->port == port)
Jeeja KP4a3478d2016-02-12 07:46:06 +0530581 return pcm;
582 }
583
584 return NULL;
585}
586
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530587static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
588 hda_nid_t nid, unsigned int pwr_state)
589{
590 if (get_wcaps(&edev->hdac, nid) & AC_WCAP_POWER) {
591 if (!snd_hdac_check_power_state(&edev->hdac, nid, pwr_state))
592 snd_hdac_codec_write(&edev->hdac, nid, 0,
593 AC_VERB_SET_POWER_STATE, pwr_state);
594 }
595}
596
597static void hdac_hdmi_set_amp(struct hdac_ext_device *edev,
598 hda_nid_t nid, int val)
599{
600 if (get_wcaps(&edev->hdac, nid) & AC_WCAP_OUT_AMP)
601 snd_hdac_codec_write(&edev->hdac, nid, 0,
602 AC_VERB_SET_AMP_GAIN_MUTE, val);
603}
604
605
606static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
607 struct snd_kcontrol *kc, int event)
608{
Jeeja KP754695f2017-02-06 12:09:14 +0530609 struct hdac_hdmi_port *port = w->priv;
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530610 struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev);
611 struct hdac_hdmi_pcm *pcm;
612
613 dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n",
614 __func__, w->name, event);
615
Jeeja KP754695f2017-02-06 12:09:14 +0530616 pcm = hdac_hdmi_get_pcm(edev, port);
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530617 if (!pcm)
618 return -EIO;
619
620 switch (event) {
621 case SND_SOC_DAPM_PRE_PMU:
Jeeja KP754695f2017-02-06 12:09:14 +0530622 hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D0);
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530623
624 /* Enable out path for this pin widget */
Jeeja KP754695f2017-02-06 12:09:14 +0530625 snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0,
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530626 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
627
Jeeja KP754695f2017-02-06 12:09:14 +0530628 hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_UNMUTE);
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530629
Jeeja KP754695f2017-02-06 12:09:14 +0530630 return hdac_hdmi_setup_audio_infoframe(edev, pcm, port);
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530631
632 case SND_SOC_DAPM_POST_PMD:
Jeeja KP754695f2017-02-06 12:09:14 +0530633 hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_MUTE);
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530634
635 /* Disable out path for this pin widget */
Jeeja KP754695f2017-02-06 12:09:14 +0530636 snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0,
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530637 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
638
Jeeja KP754695f2017-02-06 12:09:14 +0530639 hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D3);
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530640 break;
641
642 }
643
644 return 0;
645}
646
647static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,
648 struct snd_kcontrol *kc, int event)
649{
650 struct hdac_hdmi_cvt *cvt = w->priv;
651 struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev);
652 struct hdac_hdmi_priv *hdmi = edev->private_data;
653 struct hdac_hdmi_pcm *pcm;
654
655 dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n",
656 __func__, w->name, event);
657
658 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt);
659 if (!pcm)
660 return -EIO;
661
662 switch (event) {
663 case SND_SOC_DAPM_PRE_PMU:
664 hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D0);
665
666 /* Enable transmission */
667 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
668 AC_VERB_SET_DIGI_CONVERT_1, 1);
669
670 /* Category Code (CC) to zero */
671 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
672 AC_VERB_SET_DIGI_CONVERT_2, 0);
673
674 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
675 AC_VERB_SET_CHANNEL_STREAMID, pcm->stream_tag);
676 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
677 AC_VERB_SET_STREAM_FORMAT, pcm->format);
678 break;
679
680 case SND_SOC_DAPM_POST_PMD:
681 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
682 AC_VERB_SET_CHANNEL_STREAMID, 0);
683 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
684 AC_VERB_SET_STREAM_FORMAT, 0);
685
686 hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D3);
687 break;
688
689 }
690
691 return 0;
692}
693
694static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
695 struct snd_kcontrol *kc, int event)
696{
Jeeja KP754695f2017-02-06 12:09:14 +0530697 struct hdac_hdmi_port *port = w->priv;
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530698 struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev);
699 int mux_idx;
700
701 dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n",
702 __func__, w->name, event);
703
704 if (!kc)
705 kc = w->kcontrols[0];
706
707 mux_idx = dapm_kcontrol_get_value(kc);
708 if (mux_idx > 0) {
Jeeja KP754695f2017-02-06 12:09:14 +0530709 snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0,
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530710 AC_VERB_SET_CONNECT_SEL, (mux_idx - 1));
711 }
712
713 return 0;
714}
715
Jeeja KP4a3478d2016-02-12 07:46:06 +0530716/*
717 * Based on user selection, map the PINs with the PCMs.
718 */
Jeeja KP754695f2017-02-06 12:09:14 +0530719static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
Jeeja KP4a3478d2016-02-12 07:46:06 +0530720 struct snd_ctl_elem_value *ucontrol)
721{
722 int ret;
723 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
724 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
725 struct snd_soc_dapm_context *dapm = w->dapm;
Jeeja KP754695f2017-02-06 12:09:14 +0530726 struct hdac_hdmi_port *port = w->priv;
Jeeja KP4a3478d2016-02-12 07:46:06 +0530727 struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
728 struct hdac_hdmi_priv *hdmi = edev->private_data;
729 struct hdac_hdmi_pcm *pcm = NULL;
730 const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]];
731
732 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
733 if (ret < 0)
734 return ret;
735
Jeeja KP754695f2017-02-06 12:09:14 +0530736 if (port == NULL)
737 return -EINVAL;
738
Jeeja KP4a3478d2016-02-12 07:46:06 +0530739 mutex_lock(&hdmi->pin_mutex);
740 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +0530741 if (!pcm->port && pcm->port == port &&
742 pcm->port->id == port->id)
743 pcm->port = NULL;
Jeeja KP4a3478d2016-02-12 07:46:06 +0530744
745 /*
746 * Jack status is not reported during device probe as the
747 * PCMs are not registered by then. So report it here.
748 */
Jeeja KP754695f2017-02-06 12:09:14 +0530749 if (!strcmp(cvt_name, pcm->cvt->name) && !pcm->port) {
750 pcm->port = port;
751 if (port->eld.monitor_present && port->eld.eld_valid) {
Jeeja KP4a3478d2016-02-12 07:46:06 +0530752 dev_dbg(&edev->hdac.dev,
753 "jack report for pcm=%d\n",
754 pcm->pcm_id);
755
756 snd_jack_report(pcm->jack, SND_JACK_AVOUT);
757 }
758 mutex_unlock(&hdmi->pin_mutex);
759 return ret;
760 }
761 }
762 mutex_unlock(&hdmi->pin_mutex);
763
764 return ret;
765}
766
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530767/*
768 * Ideally the Mux inputs should be based on the num_muxs enumerated, but
769 * the display driver seem to be programming the connection list for the pin
770 * widget runtime.
771 *
772 * So programming all the possible inputs for the mux, the user has to take
773 * care of selecting the right one and leaving all other inputs selected to
774 * "NONE"
775 */
Jeeja KP754695f2017-02-06 12:09:14 +0530776static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
777 struct hdac_hdmi_port *port,
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530778 struct snd_soc_dapm_widget *widget,
779 const char *widget_name)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530780{
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530781 struct hdac_hdmi_priv *hdmi = edev->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +0530782 struct hdac_hdmi_pin *pin = port->pin;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530783 struct snd_kcontrol_new *kc;
784 struct hdac_hdmi_cvt *cvt;
785 struct soc_enum *se;
786 char kc_name[NAME_SIZE];
787 char mux_items[NAME_SIZE];
788 /* To hold inputs to the Pin mux */
789 char *items[HDA_MAX_CONNECTIONS];
790 int i = 0;
791 int num_items = hdmi->num_cvt + 1;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530792
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530793 kc = devm_kzalloc(&edev->hdac.dev, sizeof(*kc), GFP_KERNEL);
794 if (!kc)
795 return -ENOMEM;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530796
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530797 se = devm_kzalloc(&edev->hdac.dev, sizeof(*se), GFP_KERNEL);
798 if (!se)
799 return -ENOMEM;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530800
Jeeja KP754695f2017-02-06 12:09:14 +0530801 sprintf(kc_name, "Pin %d port %d Input", pin->nid, port->id);
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530802 kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL);
803 if (!kc->name)
804 return -ENOMEM;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530805
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530806 kc->private_value = (long)se;
807 kc->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
808 kc->access = 0;
809 kc->info = snd_soc_info_enum_double;
Jeeja KP754695f2017-02-06 12:09:14 +0530810 kc->put = hdac_hdmi_set_pin_port_mux;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530811 kc->get = snd_soc_dapm_get_enum_double;
812
813 se->reg = SND_SOC_NOPM;
814
815 /* enum texts: ["NONE", "cvt #", "cvt #", ...] */
816 se->items = num_items;
817 se->mask = roundup_pow_of_two(se->items) - 1;
818
819 sprintf(mux_items, "NONE");
820 items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
821 if (!items[i])
822 return -ENOMEM;
823
824 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
825 i++;
826 sprintf(mux_items, "cvt %d", cvt->nid);
827 items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
828 if (!items[i])
829 return -ENOMEM;
830 }
831
832 se->texts = devm_kmemdup(&edev->hdac.dev, items,
833 (num_items * sizeof(char *)), GFP_KERNEL);
834 if (!se->texts)
835 return -ENOMEM;
836
837 return hdac_hdmi_fill_widget_info(&edev->hdac.dev, widget,
Jeeja KP754695f2017-02-06 12:09:14 +0530838 snd_soc_dapm_mux, port, widget_name, NULL, kc, 1,
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530839 hdac_hdmi_pin_mux_widget_event,
840 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_REG);
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530841}
842
843/* Add cvt <- input <- mux route map */
844static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_ext_device *edev,
845 struct snd_soc_dapm_widget *widgets,
846 struct snd_soc_dapm_route *route, int rindex)
847{
848 struct hdac_hdmi_priv *hdmi = edev->private_data;
849 const struct snd_kcontrol_new *kc;
850 struct soc_enum *se;
Jeeja KP754695f2017-02-06 12:09:14 +0530851 int mux_index = hdmi->num_cvt + hdmi->num_ports;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530852 int i, j;
853
Jeeja KP754695f2017-02-06 12:09:14 +0530854 for (i = 0; i < hdmi->num_ports; i++) {
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530855 kc = widgets[mux_index].kcontrol_news;
856 se = (struct soc_enum *)kc->private_value;
857 for (j = 0; j < hdmi->num_cvt; j++) {
858 hdac_hdmi_fill_route(&route[rindex],
859 widgets[mux_index].name,
860 se->texts[j + 1],
861 widgets[j].name, NULL);
862
863 rindex++;
864 }
865
866 mux_index++;
867 }
868}
869
870/*
871 * Widgets are added in the below sequence
872 * Converter widgets for num converters enumerated
Jeeja KP754695f2017-02-06 12:09:14 +0530873 * Pin-port widgets for num ports for Pins enumerated
874 * Pin-port mux widgets to represent connenction list of pin widget
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530875 *
Jeeja KP754695f2017-02-06 12:09:14 +0530876 * For each port, one Mux and One output widget is added
877 * Total widgets elements = num_cvt + (num_ports * 2);
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530878 *
879 * Routes are added as below:
Jeeja KP754695f2017-02-06 12:09:14 +0530880 * pin-port mux -> pin (based on num_ports)
881 * cvt -> "Input sel control" -> pin-port_mux
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530882 *
883 * Total route elements:
Jeeja KP754695f2017-02-06 12:09:14 +0530884 * num_ports + (pin_muxes * num_cvt)
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530885 */
886static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)
887{
888 struct snd_soc_dapm_widget *widgets;
889 struct snd_soc_dapm_route *route;
890 struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
891 struct hdac_hdmi_priv *hdmi = edev->private_data;
892 struct snd_soc_dai_driver *dai_drv = dapm->component->dai_drv;
893 char widget_name[NAME_SIZE];
894 struct hdac_hdmi_cvt *cvt;
895 struct hdac_hdmi_pin *pin;
Jeeja KP754695f2017-02-06 12:09:14 +0530896 int ret, i = 0, num_routes = 0, j;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530897
898 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
899 return -EINVAL;
900
Jeeja KP754695f2017-02-06 12:09:14 +0530901 widgets = devm_kzalloc(dapm->dev, (sizeof(*widgets) *
902 ((2 * hdmi->num_ports) + hdmi->num_cvt)),
903 GFP_KERNEL);
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530904
905 if (!widgets)
906 return -ENOMEM;
907
908 /* DAPM widgets to represent each converter widget */
909 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
910 sprintf(widget_name, "Converter %d", cvt->nid);
911 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],
Jeeja KPc9bfb5d2017-01-24 21:49:03 +0530912 snd_soc_dapm_aif_in, cvt,
913 widget_name, dai_drv[i].playback.stream_name, NULL, 0,
914 hdac_hdmi_cvt_output_widget_event,
915 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD);
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530916 if (ret < 0)
917 return ret;
918 i++;
919 }
920
921 list_for_each_entry(pin, &hdmi->pin_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +0530922 for (j = 0; j < pin->num_ports; j++) {
923 sprintf(widget_name, "hif%d-%d Output",
924 pin->nid, pin->ports[j].id);
925 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],
926 snd_soc_dapm_output, &pin->ports[j],
927 widget_name, NULL, NULL, 0,
928 hdac_hdmi_pin_output_widget_event,
929 SND_SOC_DAPM_PRE_PMU |
930 SND_SOC_DAPM_POST_PMD);
931 if (ret < 0)
932 return ret;
933 i++;
934 }
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530935 }
936
937 /* DAPM widgets to represent the connection list to pin widget */
938 list_for_each_entry(pin, &hdmi->pin_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +0530939 for (j = 0; j < pin->num_ports; j++) {
940 sprintf(widget_name, "Pin%d-Port%d Mux",
941 pin->nid, pin->ports[j].id);
942 ret = hdac_hdmi_create_pin_port_muxs(edev,
943 &pin->ports[j], &widgets[i],
944 widget_name);
945 if (ret < 0)
946 return ret;
947 i++;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530948
Jeeja KP754695f2017-02-06 12:09:14 +0530949 /* For cvt to pin_mux mapping */
950 num_routes += hdmi->num_cvt;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530951
Jeeja KP754695f2017-02-06 12:09:14 +0530952 /* For pin_mux to pin mapping */
953 num_routes++;
954 }
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530955 }
956
957 route = devm_kzalloc(dapm->dev, (sizeof(*route) * num_routes),
958 GFP_KERNEL);
959 if (!route)
960 return -ENOMEM;
961
962 i = 0;
963 /* Add pin <- NULL <- mux route map */
964 list_for_each_entry(pin, &hdmi->pin_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +0530965 for (j = 0; j < pin->num_ports; j++) {
966 int sink_index = i + hdmi->num_cvt;
967 int src_index = sink_index + pin->num_ports *
968 hdmi->num_pin;
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530969
Jeeja KP754695f2017-02-06 12:09:14 +0530970 hdac_hdmi_fill_route(&route[i],
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530971 widgets[sink_index].name, NULL,
972 widgets[src_index].name, NULL);
Jeeja KP754695f2017-02-06 12:09:14 +0530973 i++;
974 }
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530975 }
976
977 hdac_hdmi_add_pinmux_cvt_route(edev, widgets, route, i);
978
979 snd_soc_dapm_new_controls(dapm, widgets,
Jeeja KP754695f2017-02-06 12:09:14 +0530980 ((2 * hdmi->num_ports) + hdmi->num_cvt));
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +0530981
982 snd_soc_dapm_add_routes(dapm, route, num_routes);
983 snd_soc_dapm_new_widgets(dapm->card);
984
985 return 0;
986
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530987}
988
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530989static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530990{
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530991 struct hdac_hdmi_priv *hdmi = edev->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +0530992 struct hdac_hdmi_dai_port_map *dai_map;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530993 struct hdac_hdmi_cvt *cvt;
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530994 int dai_id = 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530995
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530996 if (list_empty(&hdmi->cvt_list))
Subhransu S. Prusty15b91442015-12-09 21:46:10 +0530997 return -EINVAL;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +0530998
Subhransu S. Prusty148569f2016-02-12 07:46:07 +0530999 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
1000 dai_map = &hdmi->dai_map[dai_id];
1001 dai_map->dai_id = dai_id;
1002 dai_map->cvt = cvt;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301003
Subhransu S. Prusty148569f2016-02-12 07:46:07 +05301004 dai_id++;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301005
Subhransu S. Prusty148569f2016-02-12 07:46:07 +05301006 if (dai_id == HDA_MAX_CVTS) {
1007 dev_warn(&edev->hdac.dev,
1008 "Max dais supported: %d\n", dai_id);
1009 break;
1010 }
1011 }
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301012
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301013 return 0;
1014}
1015
1016static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
1017{
1018 struct hdac_hdmi_priv *hdmi = edev->private_data;
1019 struct hdac_hdmi_cvt *cvt;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301020 char name[NAME_SIZE];
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301021
1022 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
1023 if (!cvt)
1024 return -ENOMEM;
1025
1026 cvt->nid = nid;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301027 sprintf(name, "cvt %d", cvt->nid);
1028 cvt->name = kstrdup(name, GFP_KERNEL);
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301029
1030 list_add_tail(&cvt->head, &hdmi->cvt_list);
1031 hdmi->num_cvt++;
1032
1033 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
1034}
1035
Jeeja KP754695f2017-02-06 12:09:14 +05301036static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev,
1037 struct hdac_hdmi_port *port)
Subhransu S. Prustyb7756ed2016-04-14 10:07:28 +05301038{
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301039 unsigned int ver, mnl;
1040
Jeeja KP754695f2017-02-06 12:09:14 +05301041 ver = (port->eld.eld_buffer[DRM_ELD_VER] & DRM_ELD_VER_MASK)
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301042 >> DRM_ELD_VER_SHIFT;
1043
1044 if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) {
1045 dev_err(&edev->hdac.dev, "HDMI: Unknown ELD version %d\n", ver);
1046 return -EINVAL;
1047 }
1048
Jeeja KP754695f2017-02-06 12:09:14 +05301049 mnl = (port->eld.eld_buffer[DRM_ELD_CEA_EDID_VER_MNL] &
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301050 DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;
1051
1052 if (mnl > ELD_MAX_MNL) {
1053 dev_err(&edev->hdac.dev, "HDMI: MNL Invalid %d\n", mnl);
1054 return -EINVAL;
1055 }
1056
Jeeja KP754695f2017-02-06 12:09:14 +05301057 port->eld.info.spk_alloc = port->eld.eld_buffer[DRM_ELD_SPEAKER];
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301058
1059 return 0;
Subhransu S. Prustyb7756ed2016-04-14 10:07:28 +05301060}
1061
Jeeja KP754695f2017-02-06 12:09:14 +05301062static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
1063 struct hdac_hdmi_port *port)
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301064{
1065 struct hdac_ext_device *edev = pin->edev;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301066 struct hdac_hdmi_priv *hdmi = edev->private_data;
1067 struct hdac_hdmi_pcm *pcm;
Jeeja KP754695f2017-02-06 12:09:14 +05301068 int size = 0;
Jeeja KP2acd8302017-02-06 12:09:18 +05301069 int port_id = -1;
Jeeja KP754695f2017-02-06 12:09:14 +05301070
1071 if (!hdmi)
1072 return;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301073
Jeeja KP2acd8302017-02-06 12:09:18 +05301074 /*
1075 * In case of non MST pin, get_eld info API expectes port
1076 * to be -1.
1077 */
Jeeja KP4a3478d2016-02-12 07:46:06 +05301078 mutex_lock(&hdmi->pin_mutex);
Jeeja KP754695f2017-02-06 12:09:14 +05301079 port->eld.monitor_present = false;
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301080
Jeeja KP2acd8302017-02-06 12:09:18 +05301081 if (pin->mst_capable)
1082 port_id = port->id;
1083
1084 size = snd_hdac_acomp_get_eld(&edev->hdac, pin->nid, port_id,
Jeeja KP754695f2017-02-06 12:09:14 +05301085 &port->eld.monitor_present,
1086 port->eld.eld_buffer,
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301087 ELD_MAX_SIZE);
1088
1089 if (size > 0) {
1090 size = min(size, ELD_MAX_SIZE);
Jeeja KP754695f2017-02-06 12:09:14 +05301091 if (hdac_hdmi_parse_eld(edev, port) < 0)
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301092 size = -EINVAL;
1093 }
1094
1095 if (size > 0) {
Jeeja KP754695f2017-02-06 12:09:14 +05301096 port->eld.eld_valid = true;
1097 port->eld.eld_size = size;
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301098 } else {
Jeeja KP754695f2017-02-06 12:09:14 +05301099 port->eld.eld_valid = false;
1100 port->eld.eld_size = 0;
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301101 }
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301102
Jeeja KP754695f2017-02-06 12:09:14 +05301103 pcm = hdac_hdmi_get_pcm(edev, port);
Jeeja KP4a3478d2016-02-12 07:46:06 +05301104
Jeeja KP754695f2017-02-06 12:09:14 +05301105 if (!port->eld.monitor_present || !port->eld.eld_valid) {
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301106
Jeeja KP754695f2017-02-06 12:09:14 +05301107 dev_dbg(&edev->hdac.dev, "%s: disconnect for pin:port %d:%d\n",
1108 __func__, pin->nid, port->id);
Jeeja KP4a3478d2016-02-12 07:46:06 +05301109
1110 /*
1111 * PCMs are not registered during device probe, so don't
1112 * report jack here. It will be done in usermode mux
1113 * control select.
1114 */
1115 if (pcm) {
1116 dev_dbg(&edev->hdac.dev,
1117 "jack report for pcm=%d\n", pcm->pcm_id);
1118
1119 snd_jack_report(pcm->jack, 0);
1120 }
1121
1122 mutex_unlock(&hdmi->pin_mutex);
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301123 return;
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301124 }
1125
Jeeja KP754695f2017-02-06 12:09:14 +05301126 if (port->eld.monitor_present && port->eld.eld_valid) {
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301127 if (pcm) {
1128 dev_dbg(&edev->hdac.dev,
1129 "jack report for pcm=%d\n",
1130 pcm->pcm_id);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301131
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301132 snd_jack_report(pcm->jack, SND_JACK_AVOUT);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301133 }
Sandeep Tayalf6fa11a2017-01-18 21:34:41 +05301134
1135 print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
Jeeja KP754695f2017-02-06 12:09:14 +05301136 port->eld.eld_buffer, port->eld.eld_size, false);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301137
Jeeja KP754695f2017-02-06 12:09:14 +05301138 }
Jeeja KP4a3478d2016-02-12 07:46:06 +05301139 mutex_unlock(&hdmi->pin_mutex);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301140}
1141
Jeeja KP754695f2017-02-06 12:09:14 +05301142static int hdac_hdmi_add_ports(struct hdac_hdmi_priv *hdmi,
1143 struct hdac_hdmi_pin *pin)
1144{
1145 struct hdac_hdmi_port *ports;
1146 int max_ports = HDA_MAX_PORTS;
1147 int i;
1148
1149 /*
1150 * FIXME: max_port may vary for each platform, so pass this as
1151 * as driver data or query from i915 interface when this API is
1152 * implemented.
1153 */
1154
1155 ports = kcalloc(max_ports, sizeof(*ports), GFP_KERNEL);
1156 if (!ports)
1157 return -ENOMEM;
1158
1159 for (i = 0; i < max_ports; i++) {
1160 ports[i].id = i;
1161 ports[i].pin = pin;
1162 }
1163 pin->ports = ports;
1164 pin->num_ports = max_ports;
1165 return 0;
1166}
1167
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301168static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
1169{
1170 struct hdac_hdmi_priv *hdmi = edev->private_data;
1171 struct hdac_hdmi_pin *pin;
Jeeja KP754695f2017-02-06 12:09:14 +05301172 int ret;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301173
1174 pin = kzalloc(sizeof(*pin), GFP_KERNEL);
1175 if (!pin)
1176 return -ENOMEM;
1177
1178 pin->nid = nid;
Jeeja KP2acd8302017-02-06 12:09:18 +05301179 pin->mst_capable = false;
Jeeja KP754695f2017-02-06 12:09:14 +05301180 pin->edev = edev;
1181 ret = hdac_hdmi_add_ports(hdmi, pin);
1182 if (ret < 0)
1183 return ret;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301184
1185 list_add_tail(&pin->head, &hdmi->pin_list);
1186 hdmi->num_pin++;
Jeeja KP754695f2017-02-06 12:09:14 +05301187 hdmi->num_ports += pin->num_ports;
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301188
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301189 return 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301190}
1191
Subhransu S. Prusty211caab2016-02-12 07:46:03 +05301192#define INTEL_VENDOR_NID 0x08
1193#define INTEL_GET_VENDOR_VERB 0xf81
1194#define INTEL_SET_VENDOR_VERB 0x781
1195#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
1196#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
1197
1198static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
1199{
1200 unsigned int vendor_param;
1201
1202 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1203 INTEL_GET_VENDOR_VERB, 0);
1204 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
1205 return;
1206
1207 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
1208 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1209 INTEL_SET_VENDOR_VERB, vendor_param);
1210 if (vendor_param == -1)
1211 return;
1212}
1213
1214static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
1215{
1216 unsigned int vendor_param;
1217
1218 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1219 INTEL_GET_VENDOR_VERB, 0);
1220 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
1221 return;
1222
1223 /* enable DP1.2 mode */
1224 vendor_param |= INTEL_EN_DP12;
1225 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1226 INTEL_SET_VENDOR_VERB, vendor_param);
1227 if (vendor_param == -1)
1228 return;
1229
1230}
1231
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301232static struct snd_soc_dai_ops hdmi_dai_ops = {
1233 .startup = hdac_hdmi_pcm_open,
1234 .shutdown = hdac_hdmi_pcm_close,
1235 .hw_params = hdac_hdmi_set_hw_params,
Jeeja KPc9bfb5d2017-01-24 21:49:03 +05301236 .set_tdm_slot = hdac_hdmi_set_tdm_slot,
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301237};
1238
1239/*
1240 * Each converter can support a stream independently. So a dai is created
1241 * based on the number of converter queried.
1242 */
1243static int hdac_hdmi_create_dais(struct hdac_device *hdac,
1244 struct snd_soc_dai_driver **dais,
1245 struct hdac_hdmi_priv *hdmi, int num_dais)
1246{
1247 struct snd_soc_dai_driver *hdmi_dais;
1248 struct hdac_hdmi_cvt *cvt;
1249 char name[NAME_SIZE], dai_name[NAME_SIZE];
1250 int i = 0;
1251 u32 rates, bps;
1252 unsigned int rate_max = 384000, rate_min = 8000;
1253 u64 formats;
1254 int ret;
1255
1256 hdmi_dais = devm_kzalloc(&hdac->dev,
1257 (sizeof(*hdmi_dais) * num_dais),
1258 GFP_KERNEL);
1259 if (!hdmi_dais)
1260 return -ENOMEM;
1261
1262 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
1263 ret = snd_hdac_query_supported_pcm(hdac, cvt->nid,
1264 &rates, &formats, &bps);
1265 if (ret)
1266 return ret;
1267
1268 sprintf(dai_name, "intel-hdmi-hifi%d", i+1);
1269 hdmi_dais[i].name = devm_kstrdup(&hdac->dev,
1270 dai_name, GFP_KERNEL);
1271
1272 if (!hdmi_dais[i].name)
1273 return -ENOMEM;
1274
1275 snprintf(name, sizeof(name), "hifi%d", i+1);
1276 hdmi_dais[i].playback.stream_name =
1277 devm_kstrdup(&hdac->dev, name, GFP_KERNEL);
1278 if (!hdmi_dais[i].playback.stream_name)
1279 return -ENOMEM;
1280
1281 /*
1282 * Set caps based on capability queried from the converter.
1283 * It will be constrained runtime based on ELD queried.
1284 */
1285 hdmi_dais[i].playback.formats = formats;
1286 hdmi_dais[i].playback.rates = rates;
1287 hdmi_dais[i].playback.rate_max = rate_max;
1288 hdmi_dais[i].playback.rate_min = rate_min;
1289 hdmi_dais[i].playback.channels_min = 2;
1290 hdmi_dais[i].playback.channels_max = 2;
1291 hdmi_dais[i].ops = &hdmi_dai_ops;
1292
1293 i++;
1294 }
1295
1296 *dais = hdmi_dais;
1297
1298 return 0;
1299}
1300
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301301/*
1302 * Parse all nodes and store the cvt/pin nids in array
1303 * Add one time initialization for pin and cvt widgets
1304 */
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301305static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
1306 struct snd_soc_dai_driver **dais, int *num_dais)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301307{
1308 hda_nid_t nid;
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +05301309 int i, num_nodes;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301310 struct hdac_device *hdac = &edev->hdac;
1311 struct hdac_hdmi_priv *hdmi = edev->private_data;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301312 int ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301313
Subhransu S. Prusty211caab2016-02-12 07:46:03 +05301314 hdac_hdmi_skl_enable_all_pins(hdac);
1315 hdac_hdmi_skl_enable_dp12(hdac);
1316
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +05301317 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
Subhransu S. Prusty541140d2015-12-09 21:46:08 +05301318 if (!nid || num_nodes <= 0) {
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301319 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
1320 return -EINVAL;
1321 }
1322
Sudip Mukherjee3c83ac22015-12-01 14:29:35 +05301323 hdac->num_nodes = num_nodes;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301324 hdac->start_nid = nid;
1325
1326 for (i = 0; i < hdac->num_nodes; i++, nid++) {
1327 unsigned int caps;
1328 unsigned int type;
1329
1330 caps = get_wcaps(hdac, nid);
1331 type = get_wcaps_type(caps);
1332
1333 if (!(caps & AC_WCAP_DIGITAL))
1334 continue;
1335
1336 switch (type) {
1337
1338 case AC_WID_AUD_OUT:
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301339 ret = hdac_hdmi_add_cvt(edev, nid);
1340 if (ret < 0)
1341 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301342 break;
1343
1344 case AC_WID_PIN:
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301345 ret = hdac_hdmi_add_pin(edev, nid);
1346 if (ret < 0)
1347 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301348 break;
1349 }
1350 }
1351
1352 hdac->end_nid = nid;
1353
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301354 if (!hdmi->num_pin || !hdmi->num_cvt)
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301355 return -EIO;
1356
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301357 ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
1358 if (ret) {
1359 dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
1360 ret);
1361 return ret;
1362 }
1363
1364 *num_dais = hdmi->num_cvt;
1365
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301366 return hdac_hdmi_init_dai_map(edev);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301367}
1368
Pandiyan, Dhinakaranf9318942016-09-21 13:02:48 -07001369static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301370{
1371 struct hdac_ext_device *edev = aptr;
1372 struct hdac_hdmi_priv *hdmi = edev->private_data;
Jeeja KP754695f2017-02-06 12:09:14 +05301373 struct hdac_hdmi_pin *pin = NULL;
1374 struct hdac_hdmi_port *hport = NULL;
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301375 struct snd_soc_codec *codec = edev->scodec;
Jeeja KP2acd8302017-02-06 12:09:18 +05301376 int i;
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301377
1378 /* Don't know how this mapping is derived */
1379 hda_nid_t pin_nid = port + 0x04;
1380
Jeeja KP754695f2017-02-06 12:09:14 +05301381 dev_dbg(&edev->hdac.dev, "%s: for pin:%d port=%d\n", __func__,
1382 pin_nid, pipe);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301383
1384 /*
1385 * skip notification during system suspend (but not in runtime PM);
1386 * the state will be updated at resume. Also since the ELD and
1387 * connection states are updated in anyway at the end of the resume,
1388 * we can skip it when received during PM process.
1389 */
1390 if (snd_power_get_state(codec->component.card->snd_card) !=
1391 SNDRV_CTL_POWER_D0)
1392 return;
1393
1394 if (atomic_read(&edev->hdac.in_pm))
1395 return;
1396
1397 list_for_each_entry(pin, &hdmi->pin_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +05301398 if (pin->nid != pin_nid)
1399 continue;
1400
1401 /* In case of non MST pin, pipe is -1 */
1402 if (pipe == -1) {
Jeeja KP2acd8302017-02-06 12:09:18 +05301403 pin->mst_capable = false;
Jeeja KP754695f2017-02-06 12:09:14 +05301404 /* if not MST, default is port[0] */
1405 hport = &pin->ports[0];
Jeeja KP2acd8302017-02-06 12:09:18 +05301406 goto out;
1407 } else {
1408 for (i = 0; i < pin->num_ports; i++) {
1409 pin->mst_capable = true;
1410 if (pin->ports[i].id == pipe) {
1411 hport = &pin->ports[i];
1412 goto out;
1413 }
1414 }
Jeeja KP754695f2017-02-06 12:09:14 +05301415 }
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301416 }
Jeeja KP754695f2017-02-06 12:09:14 +05301417
Jeeja KP2acd8302017-02-06 12:09:18 +05301418out:
1419 if (pin && hport)
Jeeja KP754695f2017-02-06 12:09:14 +05301420 hdac_hdmi_present_sense(pin, hport);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301421}
1422
1423static struct i915_audio_component_audio_ops aops = {
1424 .pin_eld_notify = hdac_hdmi_eld_notify_cb,
1425};
1426
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301427static struct snd_pcm *hdac_hdmi_get_pcm_from_id(struct snd_soc_card *card,
1428 int device)
1429{
1430 struct snd_soc_pcm_runtime *rtd;
1431
1432 list_for_each_entry(rtd, &card->rtd_list, list) {
1433 if (rtd->pcm && (rtd->pcm->device == device))
1434 return rtd->pcm;
1435 }
1436
1437 return NULL;
1438}
1439
Jeeja KP4a3478d2016-02-12 07:46:06 +05301440int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
1441{
1442 char jack_name[NAME_SIZE];
1443 struct snd_soc_codec *codec = dai->codec;
1444 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1445 struct snd_soc_dapm_context *dapm =
1446 snd_soc_component_get_dapm(&codec->component);
1447 struct hdac_hdmi_priv *hdmi = edev->private_data;
1448 struct hdac_hdmi_pcm *pcm;
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301449 struct snd_pcm *snd_pcm;
1450 int err;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301451
1452 /*
1453 * this is a new PCM device, create new pcm and
1454 * add to the pcm list
1455 */
1456 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
1457 if (!pcm)
1458 return -ENOMEM;
1459 pcm->pcm_id = device;
1460 pcm->cvt = hdmi->dai_map[dai->id].cvt;
Jeeja KPab1eea12017-01-24 21:49:05 +05301461 mutex_init(&pcm->lock);
Jeeja KP4a3478d2016-02-12 07:46:06 +05301462
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301463 snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device);
1464 if (snd_pcm) {
1465 err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap);
1466 if (err < 0) {
1467 dev_err(&edev->hdac.dev,
1468 "chmap control add failed with err: %d for pcm: %d\n",
1469 err, device);
1470 kfree(pcm);
1471 return err;
1472 }
1473 }
1474
Jeeja KP4a3478d2016-02-12 07:46:06 +05301475 list_add_tail(&pcm->head, &hdmi->pcm_list);
1476
1477 sprintf(jack_name, "HDMI/DP, pcm=%d Jack", device);
1478
1479 return snd_jack_new(dapm->card->snd_card, jack_name,
1480 SND_JACK_AVOUT, &pcm->jack, true, false);
1481}
1482EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
1483
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301484static int hdmi_codec_probe(struct snd_soc_codec *codec)
1485{
1486 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1487 struct hdac_hdmi_priv *hdmi = edev->private_data;
1488 struct snd_soc_dapm_context *dapm =
1489 snd_soc_component_get_dapm(&codec->component);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301490 struct hdac_hdmi_pin *pin;
Vinod Koulb2047e92016-05-12 08:58:55 +05301491 struct hdac_ext_link *hlink = NULL;
Jeeja KP754695f2017-02-06 12:09:14 +05301492 int ret, i;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301493
1494 edev->scodec = codec;
1495
Vinod Koulb2047e92016-05-12 08:58:55 +05301496 /*
1497 * hold the ref while we probe, also no need to drop the ref on
1498 * exit, we call pm_runtime_suspend() so that will do for us
1499 */
1500 hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev));
Vinod Koul500e06b2016-05-31 19:09:55 +05301501 if (!hlink) {
1502 dev_err(&edev->hdac.dev, "hdac link not found\n");
1503 return -EIO;
1504 }
1505
Vinod Koulb2047e92016-05-12 08:58:55 +05301506 snd_hdac_ext_bus_link_get(edev->ebus, hlink);
1507
Subhransu S. Prusty79f4e922016-02-12 07:46:05 +05301508 ret = create_fill_widget_route_map(dapm);
1509 if (ret < 0)
1510 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301511
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301512 aops.audio_ptr = edev;
1513 ret = snd_hdac_i915_register_notifier(&aops);
1514 if (ret < 0) {
1515 dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n",
1516 ret);
1517 return ret;
1518 }
1519
1520 list_for_each_entry(pin, &hdmi->pin_list, head)
Jeeja KP754695f2017-02-06 12:09:14 +05301521 for (i = 0; i < pin->num_ports; i++)
1522 hdac_hdmi_present_sense(pin, &pin->ports[i]);
Subhransu S. Prustyb8a54542016-02-12 07:46:01 +05301523
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301524 /* Imp: Store the card pointer in hda_codec */
1525 edev->card = dapm->card->snd_card;
1526
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301527 /*
1528 * hdac_device core already sets the state to active and calls
1529 * get_noresume. So enable runtime and set the device to suspend.
1530 */
1531 pm_runtime_enable(&edev->hdac.dev);
1532 pm_runtime_put(&edev->hdac.dev);
1533 pm_runtime_suspend(&edev->hdac.dev);
1534
1535 return 0;
1536}
1537
1538static int hdmi_codec_remove(struct snd_soc_codec *codec)
1539{
1540 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1541
1542 pm_runtime_disable(&edev->hdac.dev);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301543 return 0;
1544}
1545
Jeeja KP571d5072016-02-22 07:50:33 +05301546#ifdef CONFIG_PM
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301547static int hdmi_codec_prepare(struct device *dev)
1548{
1549 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1550 struct hdac_device *hdac = &edev->hdac;
1551
1552 pm_runtime_get_sync(&edev->hdac.dev);
1553
1554 /*
1555 * Power down afg.
1556 * codec_read is preferred over codec_write to set the power state.
1557 * This way verb is send to set the power state and response
1558 * is received. So setting power state is ensured without using loop
1559 * to read the state.
1560 */
1561 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1562 AC_PWRST_D3);
1563
1564 return 0;
1565}
1566
Subhransu S. Prusty0fee1792016-04-01 13:36:25 +05301567static void hdmi_codec_complete(struct device *dev)
Jeeja KP571d5072016-02-22 07:50:33 +05301568{
Subhransu S. Prusty0fee1792016-04-01 13:36:25 +05301569 struct hdac_ext_device *edev = to_hda_ext_device(dev);
Jeeja KP571d5072016-02-22 07:50:33 +05301570 struct hdac_hdmi_priv *hdmi = edev->private_data;
1571 struct hdac_hdmi_pin *pin;
1572 struct hdac_device *hdac = &edev->hdac;
Jeeja KP754695f2017-02-06 12:09:14 +05301573 int i;
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301574
1575 /* Power up afg */
1576 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1577 AC_PWRST_D0);
Jeeja KP571d5072016-02-22 07:50:33 +05301578
1579 hdac_hdmi_skl_enable_all_pins(&edev->hdac);
1580 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1581
Jeeja KP571d5072016-02-22 07:50:33 +05301582 /*
1583 * As the ELD notify callback request is not entertained while the
1584 * device is in suspend state. Need to manually check detection of
1585 * all pins here.
1586 */
1587 list_for_each_entry(pin, &hdmi->pin_list, head)
Jeeja KP754695f2017-02-06 12:09:14 +05301588 for (i = 0; i < pin->num_ports; i++)
1589 hdac_hdmi_present_sense(pin, &pin->ports[i]);
Jeeja KP571d5072016-02-22 07:50:33 +05301590
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301591 pm_runtime_put_sync(&edev->hdac.dev);
Jeeja KP571d5072016-02-22 07:50:33 +05301592}
1593#else
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301594#define hdmi_codec_prepare NULL
Subhransu S. Prusty0fee1792016-04-01 13:36:25 +05301595#define hdmi_codec_complete NULL
Jeeja KP571d5072016-02-22 07:50:33 +05301596#endif
1597
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301598static struct snd_soc_codec_driver hdmi_hda_codec = {
1599 .probe = hdmi_codec_probe,
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301600 .remove = hdmi_codec_remove,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301601 .idle_bias_off = true,
1602};
1603
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301604static void hdac_hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
1605 unsigned char *chmap)
1606{
1607 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1608 struct hdac_hdmi_priv *hdmi = edev->private_data;
1609 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301610
Jeeja KPab1eea12017-01-24 21:49:05 +05301611 memcpy(chmap, pcm->chmap, ARRAY_SIZE(pcm->chmap));
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301612}
1613
1614static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
1615 unsigned char *chmap, int prepared)
1616{
1617 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1618 struct hdac_hdmi_priv *hdmi = edev->private_data;
1619 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
Jeeja KP754695f2017-02-06 12:09:14 +05301620 struct hdac_hdmi_port *port = pcm->port;
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301621
Jeeja KPab1eea12017-01-24 21:49:05 +05301622 mutex_lock(&pcm->lock);
1623 pcm->chmap_set = true;
1624 memcpy(pcm->chmap, chmap, ARRAY_SIZE(pcm->chmap));
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301625 if (prepared)
Jeeja KP754695f2017-02-06 12:09:14 +05301626 hdac_hdmi_setup_audio_infoframe(edev, pcm, port);
Jeeja KPab1eea12017-01-24 21:49:05 +05301627 mutex_unlock(&pcm->lock);
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301628}
1629
1630static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
1631{
1632 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1633 struct hdac_hdmi_priv *hdmi = edev->private_data;
1634 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
Jeeja KP754695f2017-02-06 12:09:14 +05301635 struct hdac_hdmi_port *port = pcm->port;
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301636
Jeeja KP754695f2017-02-06 12:09:14 +05301637 return port ? true:false;
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301638}
1639
1640static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
1641{
1642 struct hdac_ext_device *edev = to_ehdac_device(hdac);
1643 struct hdac_hdmi_priv *hdmi = edev->private_data;
1644 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
Jeeja KP754695f2017-02-06 12:09:14 +05301645 struct hdac_hdmi_port *port = pcm->port;
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301646
Jeeja KP754695f2017-02-06 12:09:14 +05301647 if (!port || !port->eld.eld_valid)
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301648 return 0;
1649
Jeeja KP754695f2017-02-06 12:09:14 +05301650 return port->eld.info.spk_alloc;
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301651}
1652
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301653static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
1654{
1655 struct hdac_device *codec = &edev->hdac;
1656 struct hdac_hdmi_priv *hdmi_priv;
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301657 struct snd_soc_dai_driver *hdmi_dais = NULL;
Vinod Koulb2047e92016-05-12 08:58:55 +05301658 struct hdac_ext_link *hlink = NULL;
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301659 int num_dais = 0;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301660 int ret = 0;
1661
Vinod Koulb2047e92016-05-12 08:58:55 +05301662 /* hold the ref while we probe */
1663 hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev));
Vinod Koul500e06b2016-05-31 19:09:55 +05301664 if (!hlink) {
1665 dev_err(&edev->hdac.dev, "hdac link not found\n");
1666 return -EIO;
1667 }
1668
Vinod Koulb2047e92016-05-12 08:58:55 +05301669 snd_hdac_ext_bus_link_get(edev->ebus, hlink);
1670
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301671 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
1672 if (hdmi_priv == NULL)
1673 return -ENOMEM;
1674
1675 edev->private_data = hdmi_priv;
Subhransu S. Prustybcced702016-04-14 10:07:30 +05301676 snd_hdac_register_chmap_ops(codec, &hdmi_priv->chmap);
Subhransu S. Prusty28890992016-04-14 10:07:34 +05301677 hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap;
1678 hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap;
1679 hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
1680 hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301681
1682 dev_set_drvdata(&codec->dev, edev);
1683
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301684 INIT_LIST_HEAD(&hdmi_priv->pin_list);
1685 INIT_LIST_HEAD(&hdmi_priv->cvt_list);
Jeeja KP4a3478d2016-02-12 07:46:06 +05301686 INIT_LIST_HEAD(&hdmi_priv->pcm_list);
1687 mutex_init(&hdmi_priv->pin_mutex);
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301688
Ramesh Babuaeaccef2016-02-17 21:34:01 +05301689 /*
1690 * Turned off in the runtime_suspend during the first explicit
1691 * pm_runtime_suspend call.
1692 */
1693 ret = snd_hdac_display_power(edev->hdac.bus, true);
1694 if (ret < 0) {
1695 dev_err(&edev->hdac.dev,
1696 "Cannot turn on display power on i915 err: %d\n",
1697 ret);
1698 return ret;
1699 }
1700
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301701 ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais);
1702 if (ret < 0) {
1703 dev_err(&codec->dev,
1704 "Failed in parse and map nid with err: %d\n", ret);
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301705 return ret;
Subhransu S. Prusty17a42c42016-02-12 07:46:04 +05301706 }
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301707
1708 /* ASoC specific initialization */
Vinod Koulb2047e92016-05-12 08:58:55 +05301709 ret = snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
1710 hdmi_dais, num_dais);
1711
1712 snd_hdac_ext_bus_link_put(edev->ebus, hlink);
1713
1714 return ret;
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301715}
1716
1717static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
1718{
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301719 struct hdac_hdmi_priv *hdmi = edev->private_data;
1720 struct hdac_hdmi_pin *pin, *pin_next;
1721 struct hdac_hdmi_cvt *cvt, *cvt_next;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301722 struct hdac_hdmi_pcm *pcm, *pcm_next;
Jeeja KP754695f2017-02-06 12:09:14 +05301723 int i;
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301724
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301725 snd_soc_unregister_codec(&edev->hdac.dev);
1726
Jeeja KP4a3478d2016-02-12 07:46:06 +05301727 list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
1728 pcm->cvt = NULL;
Jeeja KP754695f2017-02-06 12:09:14 +05301729 pcm->port = NULL;
Jeeja KP4a3478d2016-02-12 07:46:06 +05301730 list_del(&pcm->head);
1731 kfree(pcm);
1732 }
1733
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301734 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
1735 list_del(&cvt->head);
Jeeja KP4a3478d2016-02-12 07:46:06 +05301736 kfree(cvt->name);
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301737 kfree(cvt);
1738 }
1739
1740 list_for_each_entry_safe(pin, pin_next, &hdmi->pin_list, head) {
Jeeja KP754695f2017-02-06 12:09:14 +05301741 for (i = 0; i < pin->num_ports; i++)
1742 pin->ports[i].pin = NULL;
1743 kfree(pin->ports);
Subhransu S. Prusty15b91442015-12-09 21:46:10 +05301744 list_del(&pin->head);
1745 kfree(pin);
1746 }
1747
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301748 return 0;
1749}
1750
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301751#ifdef CONFIG_PM
1752static int hdac_hdmi_runtime_suspend(struct device *dev)
1753{
1754 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1755 struct hdac_device *hdac = &edev->hdac;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301756 struct hdac_bus *bus = hdac->bus;
Vinod Koulb2047e92016-05-12 08:58:55 +05301757 struct hdac_ext_bus *ebus = hbus_to_ebus(bus);
1758 struct hdac_ext_link *hlink = NULL;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301759 int err;
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301760
1761 dev_dbg(dev, "Enter: %s\n", __func__);
1762
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301763 /* controller may not have been initialized for the first time */
1764 if (!bus)
1765 return 0;
1766
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301767 /*
1768 * Power down afg.
1769 * codec_read is preferred over codec_write to set the power state.
1770 * This way verb is send to set the power state and response
1771 * is received. So setting power state is ensured without using loop
1772 * to read the state.
1773 */
1774 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1775 AC_PWRST_D3);
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301776 err = snd_hdac_display_power(bus, false);
1777 if (err < 0) {
1778 dev_err(bus->dev, "Cannot turn on display power on i915\n");
1779 return err;
1780 }
1781
Vinod Koulb2047e92016-05-12 08:58:55 +05301782 hlink = snd_hdac_ext_bus_get_link(ebus, dev_name(dev));
Vinod Koul500e06b2016-05-31 19:09:55 +05301783 if (!hlink) {
1784 dev_err(dev, "hdac link not found\n");
1785 return -EIO;
1786 }
1787
Vinod Koulb2047e92016-05-12 08:58:55 +05301788 snd_hdac_ext_bus_link_put(ebus, hlink);
1789
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301790 return 0;
1791}
1792
1793static int hdac_hdmi_runtime_resume(struct device *dev)
1794{
1795 struct hdac_ext_device *edev = to_hda_ext_device(dev);
1796 struct hdac_device *hdac = &edev->hdac;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301797 struct hdac_bus *bus = hdac->bus;
Vinod Koulb2047e92016-05-12 08:58:55 +05301798 struct hdac_ext_bus *ebus = hbus_to_ebus(bus);
1799 struct hdac_ext_link *hlink = NULL;
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301800 int err;
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301801
1802 dev_dbg(dev, "Enter: %s\n", __func__);
1803
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301804 /* controller may not have been initialized for the first time */
1805 if (!bus)
1806 return 0;
1807
Vinod Koulb2047e92016-05-12 08:58:55 +05301808 hlink = snd_hdac_ext_bus_get_link(ebus, dev_name(dev));
Vinod Koul500e06b2016-05-31 19:09:55 +05301809 if (!hlink) {
1810 dev_err(dev, "hdac link not found\n");
1811 return -EIO;
1812 }
1813
Vinod Koulb2047e92016-05-12 08:58:55 +05301814 snd_hdac_ext_bus_link_get(ebus, hlink);
1815
Subhransu S. Prusty07f083a2015-11-10 18:42:10 +05301816 err = snd_hdac_display_power(bus, true);
1817 if (err < 0) {
1818 dev_err(bus->dev, "Cannot turn on display power on i915\n");
1819 return err;
1820 }
1821
Subhransu S. Prustyab85f5b2016-02-17 21:34:02 +05301822 hdac_hdmi_skl_enable_all_pins(&edev->hdac);
1823 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1824
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301825 /* Power up afg */
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301826 snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
1827 AC_PWRST_D0);
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301828
1829 return 0;
1830}
1831#else
1832#define hdac_hdmi_runtime_suspend NULL
1833#define hdac_hdmi_runtime_resume NULL
1834#endif
1835
1836static const struct dev_pm_ops hdac_hdmi_pm = {
1837 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
Subhransu S. Prusty1b377cc2016-04-01 13:36:26 +05301838 .prepare = hdmi_codec_prepare,
Subhransu S. Prusty0fee1792016-04-01 13:36:25 +05301839 .complete = hdmi_codec_complete,
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301840};
1841
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301842static const struct hda_device_id hdmi_list[] = {
1843 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
Jeeja KPe2304802016-03-11 10:12:55 +05301844 HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0),
Shreyas NCcc216882016-07-11 22:02:09 +05301845 HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0),
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301846 {}
1847};
1848
1849MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
1850
1851static struct hdac_ext_driver hdmi_driver = {
1852 . hdac = {
1853 .driver = {
1854 .name = "HDMI HDA Codec",
Subhransu S. Prustye342ac02015-11-10 18:42:07 +05301855 .pm = &hdac_hdmi_pm,
Subhransu S. Prusty18382ea2015-11-10 18:42:06 +05301856 },
1857 .id_table = hdmi_list,
1858 },
1859 .probe = hdac_hdmi_dev_probe,
1860 .remove = hdac_hdmi_dev_remove,
1861};
1862
1863static int __init hdmi_init(void)
1864{
1865 return snd_hda_ext_driver_register(&hdmi_driver);
1866}
1867
1868static void __exit hdmi_exit(void)
1869{
1870 snd_hda_ext_driver_unregister(&hdmi_driver);
1871}
1872
1873module_init(hdmi_init);
1874module_exit(hdmi_exit);
1875
1876MODULE_LICENSE("GPL v2");
1877MODULE_DESCRIPTION("HDMI HD codec");
1878MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
1879MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");