blob: e405be7929e31c3f7775a4f272e130484abc4c32 [file] [log] [blame]
Thomas Gleixner1a59d1b82019-05-27 08:55:05 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Wu Fengguang079d88c2010-03-08 10:44:23 +08002/*
3 *
4 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
5 *
6 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
Takashi Iwai84eb01b2010-09-07 12:27:25 +02007 * Copyright (c) 2006 ATI Technologies Inc.
8 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
9 * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
Anssi Hannula5a6135842013-10-24 21:10:35 +030010 * Copyright (c) 2013 Anssi Hannula <anssi.hannula@iki.fi>
Wu Fengguang079d88c2010-03-08 10:44:23 +080011 *
12 * Authors:
13 * Wu Fengguang <wfg@linux.intel.com>
14 *
15 * Maintained by:
16 * Wu Fengguang <wfg@linux.intel.com>
Wu Fengguang079d88c2010-03-08 10:44:23 +080017 */
18
Takashi Iwai84eb01b2010-09-07 12:27:25 +020019#include <linux/init.h>
20#include <linux/delay.h>
Takashi Iwaiade49db2018-07-11 18:05:52 +020021#include <linux/pci.h>
Takashi Iwai84eb01b2010-09-07 12:27:25 +020022#include <linux/slab.h>
Paul Gortmaker65a77212011-07-15 13:13:37 -040023#include <linux/module.h>
Chris Wilsonaaa23f82018-06-27 07:25:32 +010024#include <linux/pm_runtime.h>
Takashi Iwai84eb01b2010-09-07 12:27:25 +020025#include <sound/core.h>
David Henningsson07acecc2011-05-19 11:46:03 +020026#include <sound/jack.h>
Wang Xingchao433968d2012-09-06 10:02:37 +080027#include <sound/asoundef.h>
Takashi Iwaid45e6882012-07-31 11:36:00 +020028#include <sound/tlv.h>
David Henningsson25adc132015-08-19 10:48:58 +020029#include <sound/hdaudio.h>
30#include <sound/hda_i915.h>
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +053031#include <sound/hda_chmap.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050032#include <sound/hda_codec.h>
Takashi Iwai84eb01b2010-09-07 12:27:25 +020033#include "hda_local.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020034#include "hda_jack.h"
Takashi Iwaie38e4862019-12-02 08:49:47 +010035#include "hda_controller.h"
Takashi Iwai84eb01b2010-09-07 12:27:25 +020036
Takashi Iwai0ebaa242011-01-11 18:11:04 +010037static bool static_hdmi_pcm;
38module_param(static_hdmi_pcm, bool, 0644);
39MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
40
Takashi Iwaib3923502020-04-15 18:25:23 +020041static bool enable_acomp = true;
42module_param(enable_acomp, bool, 0444);
43MODULE_PARM_DESC(enable_acomp, "Enable audio component binding (default=yes)");
44
Harsha Priya951894c2020-07-06 13:53:17 -070045static bool enable_silent_stream =
46IS_ENABLED(CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM);
47module_param(enable_silent_stream, bool, 0644);
48MODULE_PARM_DESC(enable_silent_stream, "Enable Silent Stream for HDMI devices");
49
Stephen Warren384a48d2011-06-01 11:14:21 -060050struct hdmi_spec_per_cvt {
51 hda_nid_t cvt_nid;
52 int assigned;
53 unsigned int channels_min;
54 unsigned int channels_max;
55 u32 rates;
56 u64 formats;
57 unsigned int maxbps;
58};
59
Takashi Iwai4eea3092013-02-07 18:18:19 +010060/* max. connections to a widget */
61#define HDA_MAX_CONNECTIONS 32
62
Stephen Warren384a48d2011-06-01 11:14:21 -060063struct hdmi_spec_per_pin {
64 hda_nid_t pin_nid;
Libin Yang91520852017-01-12 16:04:53 +080065 int dev_id;
Libin Yanga76056f2015-12-16 16:48:15 +080066 /* pin idx, different device entries on the same pin use the same idx */
67 int pin_nid_idx;
Stephen Warren384a48d2011-06-01 11:14:21 -060068 int num_mux_nids;
69 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
Mengdong Lin2df67422014-03-20 13:01:06 +080070 int mux_idx;
Anssi Hannula1df5a062013-10-05 02:25:40 +030071 hda_nid_t cvt_nid;
Wu Fengguang744626d2011-11-16 16:29:47 +080072
73 struct hda_codec *codec;
Stephen Warren384a48d2011-06-01 11:14:21 -060074 struct hdmi_eld sink_eld;
Takashi Iwaia4e9a382013-10-17 18:21:12 +020075 struct mutex lock;
Wu Fengguang744626d2011-11-16 16:29:47 +080076 struct delayed_work work;
Libin Yang2bea2412016-01-12 11:13:26 +080077 struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
Libin Yanga76056f2015-12-16 16:48:15 +080078 int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
Wu Fengguangc6e84532011-11-18 16:59:32 -060079 int repoll_count;
Takashi Iwaib0540872013-09-02 12:33:02 +020080 bool setup; /* the stream has been set up by prepare callback */
Kai Vehmanenb1a50392020-12-10 19:44:45 +020081 bool silent_stream;
Takashi Iwaib0540872013-09-02 12:33:02 +020082 int channels; /* current number of channels */
Takashi Iwai1a6003b2012-09-06 17:42:08 +020083 bool non_pcm;
Takashi Iwaid45e6882012-07-31 11:36:00 +020084 bool chmap_set; /* channel-map override by ALSA API? */
85 unsigned char chmap[8]; /* ALSA API channel-map */
Jie Yangcd6a6502015-05-27 19:45:45 +080086#ifdef CONFIG_SND_PROC_FS
Takashi Iwaia4e9a382013-10-17 18:21:12 +020087 struct snd_info_entry *proc_entry;
88#endif
Stephen Warren384a48d2011-06-01 11:14:21 -060089};
90
Anssi Hannula307229d2013-10-24 21:10:34 +030091/* operations used by generic code that can be overridden by patches */
92struct hdmi_ops {
93 int (*pin_get_eld)(struct hda_codec *codec, hda_nid_t pin_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +053094 int dev_id, unsigned char *buf, int *eld_size);
Anssi Hannula307229d2013-10-24 21:10:34 +030095
Anssi Hannula307229d2013-10-24 21:10:34 +030096 void (*pin_setup_infoframe)(struct hda_codec *codec, hda_nid_t pin_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +053097 int dev_id,
Anssi Hannula307229d2013-10-24 21:10:34 +030098 int ca, int active_channels, int conn_type);
99
100 /* enable/disable HBR (HD passthrough) */
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530101 int (*pin_hbr_setup)(struct hda_codec *codec, hda_nid_t pin_nid,
102 int dev_id, bool hbr);
Anssi Hannula307229d2013-10-24 21:10:34 +0300103
104 int (*setup_stream)(struct hda_codec *codec, hda_nid_t cvt_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530105 hda_nid_t pin_nid, int dev_id, u32 stream_tag,
106 int format);
Anssi Hannula307229d2013-10-24 21:10:34 +0300107
Takashi Iwai4846a672016-03-21 12:56:46 +0100108 void (*pin_cvt_fixup)(struct hda_codec *codec,
109 struct hdmi_spec_per_pin *per_pin,
110 hda_nid_t cvt_nid);
Anssi Hannula307229d2013-10-24 21:10:34 +0300111};
112
Libin Yang2bea2412016-01-12 11:13:26 +0800113struct hdmi_pcm {
114 struct hda_pcm *pcm;
115 struct snd_jack *jack;
Libin Yangfb087ea2016-02-23 16:33:37 +0800116 struct snd_kcontrol *eld_ctl;
Libin Yang2bea2412016-01-12 11:13:26 +0800117};
118
Wu Fengguang079d88c2010-03-08 10:44:23 +0800119struct hdmi_spec {
Takashi Iwaiade49db2018-07-11 18:05:52 +0200120 struct hda_codec *codec;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800121 int num_cvts;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100122 struct snd_array cvts; /* struct hdmi_spec_per_cvt */
123 hda_nid_t cvt_nids[4]; /* only for haswell fix */
Stephen Warren384a48d2011-06-01 11:14:21 -0600124
Libin Yang91520852017-01-12 16:04:53 +0800125 /*
126 * num_pins is the number of virtual pins
127 * for example, there are 3 pins, and each pin
128 * has 4 device entries, then the num_pins is 12
129 */
Wu Fengguang079d88c2010-03-08 10:44:23 +0800130 int num_pins;
Libin Yang91520852017-01-12 16:04:53 +0800131 /*
132 * num_nids is the number of real pins
133 * In the above example, num_nids is 3
134 */
135 int num_nids;
136 /*
137 * dev_num is the number of device entries
138 * on each pin.
139 * In the above example, dev_num is 4
140 */
141 int dev_num;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100142 struct snd_array pins; /* struct hdmi_spec_per_pin */
Libin Yang2bea2412016-01-12 11:13:26 +0800143 struct hdmi_pcm pcm_rec[16];
Libin Yang42b29872015-12-16 13:42:42 +0800144 struct mutex pcm_lock;
Takashi Iwai302d5a82019-10-29 21:41:20 +0100145 struct mutex bind_lock; /* for audio component binding */
Libin Yanga76056f2015-12-16 16:48:15 +0800146 /* pcm_bitmap means which pcms have been assigned to pins*/
147 unsigned long pcm_bitmap;
Libin Yang2bf3c852015-12-16 13:42:43 +0800148 int pcm_used; /* counter of pcm_rec[] */
Libin Yangac983792015-12-16 16:48:16 +0800149 /* bitmap shows whether the pcm is opened in user space
150 * bit 0 means the first playback PCM (PCM3);
151 * bit 1 means the second playback PCM, and so on.
152 */
153 unsigned long pcm_in_use;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800154
David Henningsson4bd038f2013-02-19 16:11:25 +0100155 struct hdmi_eld temp_eld;
Anssi Hannula307229d2013-10-24 21:10:34 +0300156 struct hdmi_ops ops;
Stephen Warren75fae112014-01-30 11:52:16 -0700157
158 bool dyn_pin_out;
Libin Yang6590faa2015-12-16 13:42:41 +0800159 bool dyn_pcm_assign;
Takashi Iwaicb457222019-11-11 20:09:37 +0100160 bool intel_hsw_fixup; /* apply Intel platform-specific fixups */
Wu Fengguang079d88c2010-03-08 10:44:23 +0800161 /*
Anssi Hannula5a6135842013-10-24 21:10:35 +0300162 * Non-generic VIA/NVIDIA specific
Wu Fengguang079d88c2010-03-08 10:44:23 +0800163 */
164 struct hda_multi_out multiout;
Takashi Iwaid0b12522012-06-15 14:34:42 +0200165 struct hda_pcm_stream pcm_playback;
David Henningsson25adc132015-08-19 10:48:58 +0200166
Takashi Iwaiade49db2018-07-11 18:05:52 +0200167 bool use_acomp_notifier; /* use eld_notify callback for hotplug */
168 bool acomp_registered; /* audio component registered in this driver */
Kai-Heng Fengcd72c312020-08-04 23:58:34 +0800169 bool force_connect; /* force connectivity */
Takashi Iwaiae891ab2018-07-11 15:17:22 +0200170 struct drm_audio_component_audio_ops drm_audio_ops;
Takashi Iwaiade49db2018-07-11 18:05:52 +0200171 int (*port2pin)(struct hda_codec *, int); /* reverse port/pin mapping */
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +0530172
173 struct hdac_chmap chmap;
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +0530174 hda_nid_t vendor_nid;
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +0100175 const int *port_map;
176 int port_num;
Harsha Priya951894c2020-07-06 13:53:17 -0700177 bool send_silent_stream; /* Flag to enable silent stream feature */
Wu Fengguang079d88c2010-03-08 10:44:23 +0800178};
179
Takashi Iwaia57942b2018-07-11 16:23:16 +0200180#ifdef CONFIG_SND_HDA_COMPONENT
Takashi Iwai691be972016-03-18 15:10:08 +0100181static inline bool codec_has_acomp(struct hda_codec *codec)
182{
183 struct hdmi_spec *spec = codec->spec;
184 return spec->use_acomp_notifier;
185}
Takashi Iwaif4e30402015-12-10 13:01:28 +0100186#else
187#define codec_has_acomp(codec) false
188#endif
Wu Fengguang079d88c2010-03-08 10:44:23 +0800189
190struct hdmi_audio_infoframe {
191 u8 type; /* 0x84 */
192 u8 ver; /* 0x01 */
193 u8 len; /* 0x0a */
194
Wu Fengguang53d7d692010-09-21 14:25:49 +0800195 u8 checksum;
196
Wu Fengguang079d88c2010-03-08 10:44:23 +0800197 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
198 u8 SS01_SF24;
199 u8 CXT04;
200 u8 CA;
201 u8 LFEPBL01_LSV36_DM_INH7;
Wu Fengguang53d7d692010-09-21 14:25:49 +0800202};
203
204struct dp_audio_infoframe {
205 u8 type; /* 0x84 */
206 u8 len; /* 0x1b */
207 u8 ver; /* 0x11 << 2 */
208
209 u8 CC02_CT47; /* match with HDMI infoframe from this on */
210 u8 SS01_SF24;
211 u8 CXT04;
212 u8 CA;
213 u8 LFEPBL01_LSV36_DM_INH7;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800214};
215
Takashi Iwai2b203dbb2011-02-11 12:17:30 +0100216union audio_infoframe {
217 struct hdmi_audio_infoframe hdmi;
218 struct dp_audio_infoframe dp;
219 u8 bytes[0];
220};
221
Wu Fengguang079d88c2010-03-08 10:44:23 +0800222/*
Wu Fengguang079d88c2010-03-08 10:44:23 +0800223 * HDMI routines
224 */
225
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100226#define get_pin(spec, idx) \
227 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
228#define get_cvt(spec, idx) \
229 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
Libin Yang2bea2412016-01-12 11:13:26 +0800230/* obtain hdmi_pcm object assigned to idx */
231#define get_hdmi_pcm(spec, idx) (&(spec)->pcm_rec[idx])
232/* obtain hda_pcm object assigned to idx */
233#define get_pcm_rec(spec, idx) (get_hdmi_pcm(spec, idx)->pcm)
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100234
Libin Yang91520852017-01-12 16:04:53 +0800235static int pin_id_to_pin_index(struct hda_codec *codec,
236 hda_nid_t pin_nid, int dev_id)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800237{
Takashi Iwai4e76a882014-02-25 12:21:03 +0100238 struct hdmi_spec *spec = codec->spec;
Stephen Warren384a48d2011-06-01 11:14:21 -0600239 int pin_idx;
Libin Yang91520852017-01-12 16:04:53 +0800240 struct hdmi_spec_per_pin *per_pin;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800241
Libin Yang91520852017-01-12 16:04:53 +0800242 /*
243 * (dev_id == -1) means it is NON-MST pin
244 * return the first virtual pin on this port
245 */
246 if (dev_id == -1)
247 dev_id = 0;
248
249 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
250 per_pin = get_pin(spec, pin_idx);
251 if ((per_pin->pin_nid == pin_nid) &&
252 (per_pin->dev_id == dev_id))
Stephen Warren384a48d2011-06-01 11:14:21 -0600253 return pin_idx;
Libin Yang91520852017-01-12 16:04:53 +0800254 }
Wu Fengguang079d88c2010-03-08 10:44:23 +0800255
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +0200256 codec_warn(codec, "HDMI: pin NID 0x%x not registered\n", pin_nid);
Stephen Warren384a48d2011-06-01 11:14:21 -0600257 return -EINVAL;
258}
259
Libin Yang2bf3c852015-12-16 13:42:43 +0800260static int hinfo_to_pcm_index(struct hda_codec *codec,
261 struct hda_pcm_stream *hinfo)
262{
263 struct hdmi_spec *spec = codec->spec;
264 int pcm_idx;
265
266 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++)
267 if (get_pcm_rec(spec, pcm_idx)->stream == hinfo)
268 return pcm_idx;
269
Kai Vehmanen90670fd2020-07-03 18:38:18 +0300270 codec_warn(codec, "HDMI: hinfo %p not tied to a PCM\n", hinfo);
Libin Yang2bf3c852015-12-16 13:42:43 +0800271 return -EINVAL;
272}
273
Takashi Iwai4e76a882014-02-25 12:21:03 +0100274static int hinfo_to_pin_index(struct hda_codec *codec,
Stephen Warren384a48d2011-06-01 11:14:21 -0600275 struct hda_pcm_stream *hinfo)
276{
Takashi Iwai4e76a882014-02-25 12:21:03 +0100277 struct hdmi_spec *spec = codec->spec;
Libin Yang6590faa2015-12-16 13:42:41 +0800278 struct hdmi_spec_per_pin *per_pin;
Stephen Warren384a48d2011-06-01 11:14:21 -0600279 int pin_idx;
280
Libin Yang6590faa2015-12-16 13:42:41 +0800281 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
282 per_pin = get_pin(spec, pin_idx);
Libin Yang2bea2412016-01-12 11:13:26 +0800283 if (per_pin->pcm &&
284 per_pin->pcm->pcm->stream == hinfo)
Stephen Warren384a48d2011-06-01 11:14:21 -0600285 return pin_idx;
Libin Yang6590faa2015-12-16 13:42:41 +0800286 }
Stephen Warren384a48d2011-06-01 11:14:21 -0600287
Kai Vehmanen90670fd2020-07-03 18:38:18 +0300288 codec_dbg(codec, "HDMI: hinfo %p (pcm %d) not registered\n", hinfo,
289 hinfo_to_pcm_index(codec, hinfo));
Stephen Warren384a48d2011-06-01 11:14:21 -0600290 return -EINVAL;
291}
292
Libin Yang022f3442016-02-03 10:48:34 +0800293static struct hdmi_spec_per_pin *pcm_idx_to_pin(struct hdmi_spec *spec,
294 int pcm_idx)
295{
296 int i;
297 struct hdmi_spec_per_pin *per_pin;
298
299 for (i = 0; i < spec->num_pins; i++) {
300 per_pin = get_pin(spec, i);
301 if (per_pin->pcm_idx == pcm_idx)
302 return per_pin;
303 }
304 return NULL;
305}
306
Takashi Iwai4e76a882014-02-25 12:21:03 +0100307static int cvt_nid_to_cvt_index(struct hda_codec *codec, hda_nid_t cvt_nid)
Stephen Warren384a48d2011-06-01 11:14:21 -0600308{
Takashi Iwai4e76a882014-02-25 12:21:03 +0100309 struct hdmi_spec *spec = codec->spec;
Stephen Warren384a48d2011-06-01 11:14:21 -0600310 int cvt_idx;
311
312 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++)
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100313 if (get_cvt(spec, cvt_idx)->cvt_nid == cvt_nid)
Stephen Warren384a48d2011-06-01 11:14:21 -0600314 return cvt_idx;
315
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +0200316 codec_warn(codec, "HDMI: cvt NID 0x%x not registered\n", cvt_nid);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800317 return -EINVAL;
318}
319
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500320static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
321 struct snd_ctl_elem_info *uinfo)
322{
323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
David Henningsson68e03de2013-02-19 16:11:23 +0100324 struct hdmi_spec *spec = codec->spec;
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200325 struct hdmi_spec_per_pin *per_pin;
David Henningsson68e03de2013-02-19 16:11:23 +0100326 struct hdmi_eld *eld;
Libin Yangfb087ea2016-02-23 16:33:37 +0800327 int pcm_idx;
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500328
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500329 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
330
Libin Yangfb087ea2016-02-23 16:33:37 +0800331 pcm_idx = kcontrol->private_value;
332 mutex_lock(&spec->pcm_lock);
333 per_pin = pcm_idx_to_pin(spec, pcm_idx);
334 if (!per_pin) {
335 /* no pin is bound to the pcm */
336 uinfo->count = 0;
Takashi Iwaif69548f2018-07-12 23:06:51 +0200337 goto unlock;
Libin Yangfb087ea2016-02-23 16:33:37 +0800338 }
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200339 eld = &per_pin->sink_eld;
David Henningsson68e03de2013-02-19 16:11:23 +0100340 uinfo->count = eld->eld_valid ? eld->eld_size : 0;
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500341
Takashi Iwaif69548f2018-07-12 23:06:51 +0200342 unlock:
343 mutex_unlock(&spec->pcm_lock);
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500344 return 0;
345}
346
347static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
348 struct snd_ctl_elem_value *ucontrol)
349{
350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
David Henningsson68e03de2013-02-19 16:11:23 +0100351 struct hdmi_spec *spec = codec->spec;
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200352 struct hdmi_spec_per_pin *per_pin;
David Henningsson68e03de2013-02-19 16:11:23 +0100353 struct hdmi_eld *eld;
Libin Yangfb087ea2016-02-23 16:33:37 +0800354 int pcm_idx;
Takashi Iwaif69548f2018-07-12 23:06:51 +0200355 int err = 0;
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500356
Libin Yangfb087ea2016-02-23 16:33:37 +0800357 pcm_idx = kcontrol->private_value;
358 mutex_lock(&spec->pcm_lock);
359 per_pin = pcm_idx_to_pin(spec, pcm_idx);
360 if (!per_pin) {
361 /* no pin is bound to the pcm */
362 memset(ucontrol->value.bytes.data, 0,
363 ARRAY_SIZE(ucontrol->value.bytes.data));
Takashi Iwaif69548f2018-07-12 23:06:51 +0200364 goto unlock;
Libin Yangfb087ea2016-02-23 16:33:37 +0800365 }
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500366
Takashi Iwaif69548f2018-07-12 23:06:51 +0200367 eld = &per_pin->sink_eld;
David Henningsson360a8242016-02-05 09:05:41 +0100368 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
369 eld->eld_size > ELD_MAX_SIZE) {
David Henningsson68e03de2013-02-19 16:11:23 +0100370 snd_BUG();
Takashi Iwaif69548f2018-07-12 23:06:51 +0200371 err = -EINVAL;
372 goto unlock;
David Henningsson68e03de2013-02-19 16:11:23 +0100373 }
374
375 memset(ucontrol->value.bytes.data, 0,
376 ARRAY_SIZE(ucontrol->value.bytes.data));
377 if (eld->eld_valid)
378 memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
379 eld->eld_size);
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500380
Takashi Iwaif69548f2018-07-12 23:06:51 +0200381 unlock:
382 mutex_unlock(&spec->pcm_lock);
383 return err;
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500384}
385
Bhumika Goyalf3b827e2017-02-20 00:18:09 +0530386static const struct snd_kcontrol_new eld_bytes_ctl = {
Takashi Iwaifbd3eb72020-01-04 09:35:56 +0100387 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE |
388 SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK,
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500389 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
390 .name = "ELD",
391 .info = hdmi_eld_ctl_info,
392 .get = hdmi_eld_ctl_get,
393};
394
Libin Yangfb087ea2016-02-23 16:33:37 +0800395static int hdmi_create_eld_ctl(struct hda_codec *codec, int pcm_idx,
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500396 int device)
397{
398 struct snd_kcontrol *kctl;
399 struct hdmi_spec *spec = codec->spec;
400 int err;
401
402 kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
403 if (!kctl)
404 return -ENOMEM;
Libin Yangfb087ea2016-02-23 16:33:37 +0800405 kctl->private_value = pcm_idx;
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500406 kctl->id.device = device;
407
Libin Yangfb087ea2016-02-23 16:33:37 +0800408 /* no pin nid is associated with the kctl now
409 * tbd: associate pin nid to eld ctl later
410 */
411 err = snd_hda_ctl_add(codec, 0, kctl);
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500412 if (err < 0)
413 return err;
414
Libin Yangfb087ea2016-02-23 16:33:37 +0800415 get_hdmi_pcm(spec, pcm_idx)->eld_ctl = kctl;
Pierre-Louis Bossart14bc52b2011-09-30 16:35:41 -0500416 return 0;
417}
418
Wu Fengguang079d88c2010-03-08 10:44:23 +0800419#ifdef BE_PARANOID
420static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
421 int *packet_index, int *byte_index)
422{
423 int val;
424
425 val = snd_hda_codec_read(codec, pin_nid, 0,
426 AC_VERB_GET_HDMI_DIP_INDEX, 0);
427
428 *packet_index = val >> 5;
429 *byte_index = val & 0x1f;
430}
431#endif
432
433static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
434 int packet_index, int byte_index)
435{
436 int val;
437
438 val = (packet_index << 5) | (byte_index & 0x1f);
439
440 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
441}
442
443static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
444 unsigned char val)
445{
446 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
447}
448
Stephen Warren384a48d2011-06-01 11:14:21 -0600449static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800450{
Stephen Warren75fae112014-01-30 11:52:16 -0700451 struct hdmi_spec *spec = codec->spec;
452 int pin_out;
453
Wu Fengguang079d88c2010-03-08 10:44:23 +0800454 /* Unmute */
455 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
456 snd_hda_codec_write(codec, pin_nid, 0,
457 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Stephen Warren75fae112014-01-30 11:52:16 -0700458
459 if (spec->dyn_pin_out)
460 /* Disable pin out until stream is active */
461 pin_out = 0;
462 else
463 /* Enable pin out: some machines with GM965 gets broken output
464 * when the pin is disabled or changed while using with HDMI
465 */
466 pin_out = PIN_OUT;
467
Wu Fengguang079d88c2010-03-08 10:44:23 +0800468 snd_hda_codec_write(codec, pin_nid, 0,
Stephen Warren75fae112014-01-30 11:52:16 -0700469 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_out);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800470}
471
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200472/*
473 * ELD proc files
474 */
475
Jie Yangcd6a6502015-05-27 19:45:45 +0800476#ifdef CONFIG_SND_PROC_FS
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200477static void print_eld_info(struct snd_info_entry *entry,
478 struct snd_info_buffer *buffer)
479{
480 struct hdmi_spec_per_pin *per_pin = entry->private_data;
481
482 mutex_lock(&per_pin->lock);
483 snd_hdmi_print_eld_info(&per_pin->sink_eld, buffer);
484 mutex_unlock(&per_pin->lock);
485}
486
487static void write_eld_info(struct snd_info_entry *entry,
488 struct snd_info_buffer *buffer)
489{
490 struct hdmi_spec_per_pin *per_pin = entry->private_data;
491
492 mutex_lock(&per_pin->lock);
493 snd_hdmi_write_eld_info(&per_pin->sink_eld, buffer);
494 mutex_unlock(&per_pin->lock);
495}
496
497static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
498{
499 char name[32];
500 struct hda_codec *codec = per_pin->codec;
501 struct snd_info_entry *entry;
502 int err;
503
504 snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
Takashi Iwai6efdd852015-02-27 16:09:22 +0100505 err = snd_card_proc_new(codec->card, name, &entry);
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200506 if (err < 0)
507 return err;
508
509 snd_info_set_text_ops(entry, per_pin, print_eld_info);
510 entry->c.text.write = write_eld_info;
Joe Perches6a73cf42018-05-23 12:20:59 -0700511 entry->mode |= 0200;
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200512 per_pin->proc_entry = entry;
513
514 return 0;
515}
516
517static void eld_proc_free(struct hdmi_spec_per_pin *per_pin)
518{
Markus Elfring1947a112015-06-28 11:15:28 +0200519 if (!per_pin->codec->bus->shutdown) {
Takashi Iwaic560a672015-04-22 18:26:38 +0200520 snd_info_free_entry(per_pin->proc_entry);
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200521 per_pin->proc_entry = NULL;
522 }
523}
524#else
Takashi Iwaib55447a2013-10-21 16:31:45 +0200525static inline int eld_proc_new(struct hdmi_spec_per_pin *per_pin,
526 int index)
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200527{
528 return 0;
529}
Takashi Iwaib55447a2013-10-21 16:31:45 +0200530static inline void eld_proc_free(struct hdmi_spec_per_pin *per_pin)
Takashi Iwaia4e9a382013-10-17 18:21:12 +0200531{
532}
533#endif
Wu Fengguang079d88c2010-03-08 10:44:23 +0800534
535/*
Wu Fengguang079d88c2010-03-08 10:44:23 +0800536 * Audio InfoFrame routines
537 */
538
539/*
540 * Enable Audio InfoFrame Transmission
541 */
542static void hdmi_start_infoframe_trans(struct hda_codec *codec,
543 hda_nid_t pin_nid)
544{
545 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
546 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
547 AC_DIPXMIT_BEST);
548}
549
550/*
551 * Disable Audio InfoFrame Transmission
552 */
553static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
554 hda_nid_t pin_nid)
555{
556 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
557 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
558 AC_DIPXMIT_DISABLE);
559}
560
561static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
562{
563#ifdef CONFIG_SND_DEBUG_VERBOSE
564 int i;
565 int size;
566
567 size = snd_hdmi_get_eld_size(codec, pin_nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100568 codec_dbg(codec, "HDMI: ELD buf size is %d\n", size);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800569
570 for (i = 0; i < 8; i++) {
571 size = snd_hda_codec_read(codec, pin_nid, 0,
572 AC_VERB_GET_HDMI_DIP_SIZE, i);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100573 codec_dbg(codec, "HDMI: DIP GP[%d] buf size is %d\n", i, size);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800574 }
575#endif
576}
577
578static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
579{
580#ifdef BE_PARANOID
581 int i, j;
582 int size;
583 int pi, bi;
584 for (i = 0; i < 8; i++) {
585 size = snd_hda_codec_read(codec, pin_nid, 0,
586 AC_VERB_GET_HDMI_DIP_SIZE, i);
587 if (size == 0)
588 continue;
589
590 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
591 for (j = 1; j < 1000; j++) {
592 hdmi_write_dip_byte(codec, pin_nid, 0x0);
593 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
594 if (pi != i)
Takashi Iwai4e76a882014-02-25 12:21:03 +0100595 codec_dbg(codec, "dip index %d: %d != %d\n",
Wu Fengguang079d88c2010-03-08 10:44:23 +0800596 bi, pi, i);
597 if (bi == 0) /* byte index wrapped around */
598 break;
599 }
Takashi Iwai4e76a882014-02-25 12:21:03 +0100600 codec_dbg(codec,
Wu Fengguang079d88c2010-03-08 10:44:23 +0800601 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
602 i, size, j);
603 }
604#endif
605}
606
Wu Fengguang53d7d692010-09-21 14:25:49 +0800607static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *hdmi_ai)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800608{
Wu Fengguang53d7d692010-09-21 14:25:49 +0800609 u8 *bytes = (u8 *)hdmi_ai;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800610 u8 sum = 0;
611 int i;
612
Wu Fengguang53d7d692010-09-21 14:25:49 +0800613 hdmi_ai->checksum = 0;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800614
Wu Fengguang53d7d692010-09-21 14:25:49 +0800615 for (i = 0; i < sizeof(*hdmi_ai); i++)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800616 sum += bytes[i];
617
Wu Fengguang53d7d692010-09-21 14:25:49 +0800618 hdmi_ai->checksum = -sum;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800619}
620
621static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
622 hda_nid_t pin_nid,
Wu Fengguang53d7d692010-09-21 14:25:49 +0800623 u8 *dip, int size)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800624{
Wu Fengguang079d88c2010-03-08 10:44:23 +0800625 int i;
626
627 hdmi_debug_dip_size(codec, pin_nid);
628 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
629
Wu Fengguang079d88c2010-03-08 10:44:23 +0800630 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
Wu Fengguang53d7d692010-09-21 14:25:49 +0800631 for (i = 0; i < size; i++)
632 hdmi_write_dip_byte(codec, pin_nid, dip[i]);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800633}
634
635static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
Wu Fengguang53d7d692010-09-21 14:25:49 +0800636 u8 *dip, int size)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800637{
Wu Fengguang079d88c2010-03-08 10:44:23 +0800638 u8 val;
639 int i;
640
Kai Vehmanen46c3bbd2020-12-11 15:16:13 +0200641 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800642 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
643 != AC_DIPXMIT_BEST)
644 return false;
645
Wu Fengguang53d7d692010-09-21 14:25:49 +0800646 for (i = 0; i < size; i++) {
Wu Fengguang079d88c2010-03-08 10:44:23 +0800647 val = snd_hda_codec_read(codec, pin_nid, 0,
648 AC_VERB_GET_HDMI_DIP_DATA, 0);
Wu Fengguang53d7d692010-09-21 14:25:49 +0800649 if (val != dip[i])
Wu Fengguang079d88c2010-03-08 10:44:23 +0800650 return false;
651 }
652
653 return true;
654}
655
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530656static int hdmi_pin_get_eld(struct hda_codec *codec, hda_nid_t nid,
657 int dev_id, unsigned char *buf, int *eld_size)
658{
659 snd_hda_set_dev_select(codec, nid, dev_id);
660
661 return snd_hdmi_get_eld(codec, nid, buf, eld_size);
662}
663
Anssi Hannula307229d2013-10-24 21:10:34 +0300664static void hdmi_pin_setup_infoframe(struct hda_codec *codec,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530665 hda_nid_t pin_nid, int dev_id,
Anssi Hannula307229d2013-10-24 21:10:34 +0300666 int ca, int active_channels,
667 int conn_type)
668{
669 union audio_infoframe ai;
670
Mengdong Lincaaf5ef2014-03-11 17:12:52 -0400671 memset(&ai, 0, sizeof(ai));
Anssi Hannula307229d2013-10-24 21:10:34 +0300672 if (conn_type == 0) { /* HDMI */
673 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
674
675 hdmi_ai->type = 0x84;
676 hdmi_ai->ver = 0x01;
677 hdmi_ai->len = 0x0a;
678 hdmi_ai->CC02_CT47 = active_channels - 1;
679 hdmi_ai->CA = ca;
680 hdmi_checksum_audio_infoframe(hdmi_ai);
681 } else if (conn_type == 1) { /* DisplayPort */
682 struct dp_audio_infoframe *dp_ai = &ai.dp;
683
684 dp_ai->type = 0x84;
685 dp_ai->len = 0x1b;
686 dp_ai->ver = 0x11 << 2;
687 dp_ai->CC02_CT47 = active_channels - 1;
688 dp_ai->CA = ca;
689 } else {
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +0200690 codec_dbg(codec, "HDMI: unknown connection type at pin NID 0x%x\n", pin_nid);
Anssi Hannula307229d2013-10-24 21:10:34 +0300691 return;
692 }
693
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530694 snd_hda_set_dev_select(codec, pin_nid, dev_id);
695
Anssi Hannula307229d2013-10-24 21:10:34 +0300696 /*
697 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or
698 * sizeof(*dp_ai) to avoid partial match/update problems when
699 * the user switches between HDMI/DP monitors.
700 */
701 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
702 sizeof(ai))) {
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +0200703 codec_dbg(codec, "%s: pin NID=0x%x channels=%d ca=0x%02x\n",
704 __func__, pin_nid, active_channels, ca);
Anssi Hannula307229d2013-10-24 21:10:34 +0300705 hdmi_stop_infoframe_trans(codec, pin_nid);
706 hdmi_fill_audio_infoframe(codec, pin_nid,
707 ai.bytes, sizeof(ai));
708 hdmi_start_infoframe_trans(codec, pin_nid);
709 }
710}
711
Takashi Iwaib0540872013-09-02 12:33:02 +0200712static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
713 struct hdmi_spec_per_pin *per_pin,
714 bool non_pcm)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800715{
Anssi Hannula307229d2013-10-24 21:10:34 +0300716 struct hdmi_spec *spec = codec->spec;
Subhransu S. Prusty739ffee2016-03-04 19:59:49 +0530717 struct hdac_chmap *chmap = &spec->chmap;
Stephen Warren384a48d2011-06-01 11:14:21 -0600718 hda_nid_t pin_nid = per_pin->pin_nid;
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530719 int dev_id = per_pin->dev_id;
Takashi Iwaib0540872013-09-02 12:33:02 +0200720 int channels = per_pin->channels;
Anssi Hannula1df5a062013-10-05 02:25:40 +0300721 int active_channels;
Stephen Warren384a48d2011-06-01 11:14:21 -0600722 struct hdmi_eld *eld;
Subhransu S. Prusty828cb4e2016-03-04 19:59:50 +0530723 int ca;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800724
Takashi Iwaib0540872013-09-02 12:33:02 +0200725 if (!channels)
726 return;
727
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530728 snd_hda_set_dev_select(codec, pin_nid, dev_id);
729
Takashi Iwai44bb6d02016-03-21 12:36:44 +0100730 /* some HW (e.g. HSW+) needs reprogramming the amp at each time */
731 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
Mengdong Lin58f7d282013-09-04 16:37:12 -0400732 snd_hda_codec_write(codec, pin_nid, 0,
733 AC_VERB_SET_AMP_GAIN_MUTE,
734 AMP_OUT_UNMUTE);
735
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100736 eld = &per_pin->sink_eld;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800737
Subhransu S. Prustybb63f722016-03-04 19:59:52 +0530738 ca = snd_hdac_channel_allocation(&codec->core,
Subhransu S. Prusty828cb4e2016-03-04 19:59:50 +0530739 eld->info.spk_alloc, channels,
740 per_pin->chmap_set, non_pcm, per_pin->chmap);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800741
Subhransu S. Prustybb63f722016-03-04 19:59:52 +0530742 active_channels = snd_hdac_get_active_channels(ca);
Anssi Hannula1df5a062013-10-05 02:25:40 +0300743
Subhransu S. Prusty739ffee2016-03-04 19:59:49 +0530744 chmap->ops.set_channel_count(&codec->core, per_pin->cvt_nid,
745 active_channels);
Anssi Hannula1df5a062013-10-05 02:25:40 +0300746
Stephen Warren384a48d2011-06-01 11:14:21 -0600747 /*
Anssi Hannula39edac72013-10-07 19:24:52 +0300748 * always configure channel mapping, it may have been changed by the
749 * user in the meantime
750 */
Subhransu S. Prustybb63f722016-03-04 19:59:52 +0530751 snd_hdac_setup_channel_mapping(&spec->chmap,
Subhransu S. Prusty828cb4e2016-03-04 19:59:50 +0530752 pin_nid, non_pcm, ca, channels,
753 per_pin->chmap, per_pin->chmap_set);
Anssi Hannula39edac72013-10-07 19:24:52 +0300754
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530755 spec->ops.pin_setup_infoframe(codec, pin_nid, dev_id,
756 ca, active_channels, eld->info.conn_type);
Wang Xingchao433968d2012-09-06 10:02:37 +0800757
Takashi Iwai1a6003b2012-09-06 17:42:08 +0200758 per_pin->non_pcm = non_pcm;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800759}
760
Wu Fengguang079d88c2010-03-08 10:44:23 +0800761/*
762 * Unsolicited events
763 */
764
Takashi Iwaidb845402020-02-06 17:28:02 +0100765static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
Takashi Iwai38faddb2010-07-28 14:21:55 +0200766
Libin Yang91520852017-01-12 16:04:53 +0800767static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid,
768 int dev_id)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800769{
770 struct hdmi_spec *spec = codec->spec;
Libin Yang91520852017-01-12 16:04:53 +0800771 int pin_idx = pin_id_to_pin_index(codec, nid, dev_id);
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200772
David Henningsson20ce9022013-12-04 10:19:41 +0800773 if (pin_idx < 0)
774 return;
Chris Wilsonaaa23f82018-06-27 07:25:32 +0100775 mutex_lock(&spec->pcm_lock);
Takashi Iwaidb845402020-02-06 17:28:02 +0100776 hdmi_present_sense(get_pin(spec, pin_idx), 1);
Chris Wilsonaaa23f82018-06-27 07:25:32 +0100777 mutex_unlock(&spec->pcm_lock);
David Henningsson20ce9022013-12-04 10:19:41 +0800778}
779
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200780static void jack_callback(struct hda_codec *codec,
781 struct hda_jack_callback *jack)
782{
Takashi Iwaiade49db2018-07-11 18:05:52 +0200783 /* stop polling when notification is enabled */
784 if (codec_has_acomp(codec))
785 return;
786
Nikhil Mahale5204a052019-11-19 14:17:08 +0530787 check_presence_and_report(codec, jack->nid, jack->dev_id);
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200788}
789
Takashi Iwai165c0942020-02-06 17:28:01 +0100790static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res,
791 struct hda_jack_tbl *jack)
David Henningsson20ce9022013-12-04 10:19:41 +0800792{
Takashi Iwai3a938972011-10-28 01:16:55 +0200793 jack->jack_dirty = 1;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800794
Takashi Iwai4e76a882014-02-25 12:21:03 +0100795 codec_dbg(codec,
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +0200796 "HDMI hot plug event: Codec=%d NID=0x%x Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
Nikhil Mahale5204a052019-11-19 14:17:08 +0530797 codec->addr, jack->nid, jack->dev_id, !!(res & AC_UNSOL_RES_IA),
Fengguang Wufae3d882012-04-10 17:00:35 +0800798 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
Wu Fengguang079d88c2010-03-08 10:44:23 +0800799
Nikhil Mahale5204a052019-11-19 14:17:08 +0530800 check_presence_and_report(codec, jack->nid, jack->dev_id);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800801}
802
803static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
804{
805 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
806 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
807 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
808 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
809
Takashi Iwai4e76a882014-02-25 12:21:03 +0100810 codec_info(codec,
Takashi Iwaie9ea8e82012-06-21 11:41:05 +0200811 "HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
Stephen Warren384a48d2011-06-01 11:14:21 -0600812 codec->addr,
Wu Fengguang079d88c2010-03-08 10:44:23 +0800813 tag,
814 subtag,
815 cp_state,
816 cp_ready);
817
818 /* TODO */
Pierre-Louis Bossart75663c02020-01-13 15:14:05 -0600819 if (cp_state) {
Wu Fengguang079d88c2010-03-08 10:44:23 +0800820 ;
Pierre-Louis Bossart75663c02020-01-13 15:14:05 -0600821 }
822 if (cp_ready) {
Wu Fengguang079d88c2010-03-08 10:44:23 +0800823 ;
Pierre-Louis Bossart75663c02020-01-13 15:14:05 -0600824 }
Wu Fengguang079d88c2010-03-08 10:44:23 +0800825}
826
827
828static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
829{
Wu Fengguang079d88c2010-03-08 10:44:23 +0800830 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
831 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
Nikhil Mahale5204a052019-11-19 14:17:08 +0530832 struct hda_jack_tbl *jack;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800833
Takashi Iwaiade49db2018-07-11 18:05:52 +0200834 if (codec_has_acomp(codec))
835 return;
836
Nikhil Mahale5204a052019-11-19 14:17:08 +0530837 if (codec->dp_mst) {
838 int dev_entry =
839 (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
840
841 jack = snd_hda_jack_tbl_get_from_tag(codec, tag, dev_entry);
842 } else {
843 jack = snd_hda_jack_tbl_get_from_tag(codec, tag, 0);
844 }
845
846 if (!jack) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100847 codec_dbg(codec, "Unexpected HDMI event tag 0x%x\n", tag);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800848 return;
849 }
850
851 if (subtag == 0)
Takashi Iwai165c0942020-02-06 17:28:01 +0100852 hdmi_intrinsic_event(codec, res, jack);
Wu Fengguang079d88c2010-03-08 10:44:23 +0800853 else
854 hdmi_non_intrinsic_event(codec, res);
855}
856
Mengdong Lin58f7d282013-09-04 16:37:12 -0400857static void haswell_verify_D0(struct hda_codec *codec,
Wang Xingchao53b434f2013-06-18 10:41:53 +0800858 hda_nid_t cvt_nid, hda_nid_t nid)
David Henningsson83f26ad2013-04-10 12:26:07 +0200859{
Mengdong Lin58f7d282013-09-04 16:37:12 -0400860 int pwr;
David Henningsson83f26ad2013-04-10 12:26:07 +0200861
Wang Xingchao53b434f2013-06-18 10:41:53 +0800862 /* For Haswell, the converter 1/2 may keep in D3 state after bootup,
863 * thus pins could only choose converter 0 for use. Make sure the
864 * converters are in correct power state */
Takashi Iwaifd678ca2013-06-18 16:28:36 +0200865 if (!snd_hda_check_power_state(codec, cvt_nid, AC_PWRST_D0))
Wang Xingchao53b434f2013-06-18 10:41:53 +0800866 snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
867
Takashi Iwaifd678ca2013-06-18 16:28:36 +0200868 if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D0)) {
David Henningsson83f26ad2013-04-10 12:26:07 +0200869 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
870 AC_PWRST_D0);
871 msleep(40);
872 pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0);
873 pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT;
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +0200874 codec_dbg(codec, "Haswell HDMI audio: Power for NID 0x%x is now D%d\n", nid, pwr);
David Henningsson83f26ad2013-04-10 12:26:07 +0200875 }
David Henningsson83f26ad2013-04-10 12:26:07 +0200876}
877
Wu Fengguang079d88c2010-03-08 10:44:23 +0800878/*
879 * Callbacks
880 */
881
Takashi Iwai92f10b32010-08-03 14:21:00 +0200882/* HBR should be Non-PCM, 8 channels */
883#define is_hbr_format(format) \
884 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
885
Anssi Hannula307229d2013-10-24 21:10:34 +0300886static int hdmi_pin_hbr_setup(struct hda_codec *codec, hda_nid_t pin_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530887 int dev_id, bool hbr)
Wu Fengguang079d88c2010-03-08 10:44:23 +0800888{
Anssi Hannula307229d2013-10-24 21:10:34 +0300889 int pinctl, new_pinctl;
David Henningsson83f26ad2013-04-10 12:26:07 +0200890
Stephen Warren384a48d2011-06-01 11:14:21 -0600891 if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530892 snd_hda_set_dev_select(codec, pin_nid, dev_id);
Stephen Warren384a48d2011-06-01 11:14:21 -0600893 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300894 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
895
Anssi Hannula13122e62013-11-10 20:56:10 +0200896 if (pinctl < 0)
897 return hbr ? -EINVAL : 0;
898
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300899 new_pinctl = pinctl & ~AC_PINCTL_EPT;
Anssi Hannula307229d2013-10-24 21:10:34 +0300900 if (hbr)
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300901 new_pinctl |= AC_PINCTL_EPT_HBR;
902 else
903 new_pinctl |= AC_PINCTL_EPT_NATIVE;
904
Takashi Iwai4e76a882014-02-25 12:21:03 +0100905 codec_dbg(codec,
906 "hdmi_pin_hbr_setup: NID=0x%x, %spinctl=0x%x\n",
Stephen Warren384a48d2011-06-01 11:14:21 -0600907 pin_nid,
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300908 pinctl == new_pinctl ? "" : "new-",
909 new_pinctl);
910
911 if (pinctl != new_pinctl)
Stephen Warren384a48d2011-06-01 11:14:21 -0600912 snd_hda_codec_write(codec, pin_nid, 0,
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300913 AC_VERB_SET_PIN_WIDGET_CONTROL,
914 new_pinctl);
Anssi Hannula307229d2013-10-24 21:10:34 +0300915 } else if (hbr)
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300916 return -EINVAL;
Anssi Hannula307229d2013-10-24 21:10:34 +0300917
918 return 0;
919}
920
921static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530922 hda_nid_t pin_nid, int dev_id,
923 u32 stream_tag, int format)
Anssi Hannula307229d2013-10-24 21:10:34 +0300924{
925 struct hdmi_spec *spec = codec->spec;
Sriram Periyasamy5a5d7182017-09-19 17:25:05 -0500926 unsigned int param;
Anssi Hannula307229d2013-10-24 21:10:34 +0300927 int err;
928
Nikhil Mahale9c32fea2019-11-19 14:17:09 +0530929 err = spec->ops.pin_hbr_setup(codec, pin_nid, dev_id,
930 is_hbr_format(format));
Anssi Hannula307229d2013-10-24 21:10:34 +0300931
932 if (err) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100933 codec_dbg(codec, "hdmi_setup_stream: HBR is not supported\n");
Anssi Hannula307229d2013-10-24 21:10:34 +0300934 return err;
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300935 }
Wu Fengguang079d88c2010-03-08 10:44:23 +0800936
Takashi Iwaicb457222019-11-11 20:09:37 +0100937 if (spec->intel_hsw_fixup) {
Sriram Periyasamy5a5d7182017-09-19 17:25:05 -0500938
939 /*
940 * on recent platforms IEC Coding Type is required for HBR
941 * support, read current Digital Converter settings and set
942 * ICT bitfield if needed.
943 */
944 param = snd_hda_codec_read(codec, cvt_nid, 0,
945 AC_VERB_GET_DIGI_CONVERT_1, 0);
946
947 param = (param >> 16) & ~(AC_DIG3_ICT);
948
949 /* on recent platforms ICT mode is required for HBR support */
950 if (is_hbr_format(format))
951 param |= 0x1;
952
953 snd_hda_codec_write(codec, cvt_nid, 0,
954 AC_VERB_SET_DIGI_CONVERT_3, param);
955 }
956
Stephen Warren384a48d2011-06-01 11:14:21 -0600957 snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
Anssi Hannulaea87d1c2010-08-03 13:28:58 +0300958 return 0;
Wu Fengguang079d88c2010-03-08 10:44:23 +0800959}
960
Libin Yang42b29872015-12-16 13:42:42 +0800961/* Try to find an available converter
962 * If pin_idx is less then zero, just try to find an available converter.
963 * Otherwise, try to find an available converter and get the cvt mux index
964 * of the pin.
965 */
Wang Xingchao7ef166b2013-06-18 21:42:14 +0800966static int hdmi_choose_cvt(struct hda_codec *codec,
Takashi Iwai4846a672016-03-21 12:56:46 +0100967 int pin_idx, int *cvt_id)
Takashi Iwaibbbe3392010-08-13 08:45:23 +0200968{
969 struct hdmi_spec *spec = codec->spec;
Stephen Warren384a48d2011-06-01 11:14:21 -0600970 struct hdmi_spec_per_pin *per_pin;
Stephen Warren384a48d2011-06-01 11:14:21 -0600971 struct hdmi_spec_per_cvt *per_cvt = NULL;
Wang Xingchao7ef166b2013-06-18 21:42:14 +0800972 int cvt_idx, mux_idx = 0;
Takashi Iwaibbbe3392010-08-13 08:45:23 +0200973
Libin Yang42b29872015-12-16 13:42:42 +0800974 /* pin_idx < 0 means no pin will be bound to the converter */
975 if (pin_idx < 0)
976 per_pin = NULL;
977 else
978 per_pin = get_pin(spec, pin_idx);
Takashi Iwaibbbe3392010-08-13 08:45:23 +0200979
Kai Vehmanenb1a50392020-12-10 19:44:45 +0200980 if (per_pin && per_pin->silent_stream) {
981 cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
982 if (cvt_id)
983 *cvt_id = cvt_idx;
984 return 0;
985 }
986
Stephen Warren384a48d2011-06-01 11:14:21 -0600987 /* Dynamically assign converter to stream */
988 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
Takashi Iwaibce0d2a2013-03-13 14:40:31 +0100989 per_cvt = get_cvt(spec, cvt_idx);
Stephen Warren384a48d2011-06-01 11:14:21 -0600990
991 /* Must not already be assigned */
992 if (per_cvt->assigned)
993 continue;
Libin Yang42b29872015-12-16 13:42:42 +0800994 if (per_pin == NULL)
995 break;
Stephen Warren384a48d2011-06-01 11:14:21 -0600996 /* Must be in pin's mux's list of converters */
997 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
998 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)
999 break;
1000 /* Not in mux list */
1001 if (mux_idx == per_pin->num_mux_nids)
1002 continue;
1003 break;
1004 }
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001005
Stephen Warren384a48d2011-06-01 11:14:21 -06001006 /* No free converters */
1007 if (cvt_idx == spec->num_cvts)
Libin Yang42b29872015-12-16 13:42:42 +08001008 return -EBUSY;
Stephen Warren384a48d2011-06-01 11:14:21 -06001009
Libin Yang42b29872015-12-16 13:42:42 +08001010 if (per_pin != NULL)
1011 per_pin->mux_idx = mux_idx;
Mengdong Lin2df67422014-03-20 13:01:06 +08001012
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001013 if (cvt_id)
1014 *cvt_id = cvt_idx;
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001015
1016 return 0;
1017}
1018
Mengdong Lin2df67422014-03-20 13:01:06 +08001019/* Assure the pin select the right convetor */
1020static void intel_verify_pin_cvt_connect(struct hda_codec *codec,
1021 struct hdmi_spec_per_pin *per_pin)
1022{
1023 hda_nid_t pin_nid = per_pin->pin_nid;
1024 int mux_idx, curr;
1025
1026 mux_idx = per_pin->mux_idx;
1027 curr = snd_hda_codec_read(codec, pin_nid, 0,
1028 AC_VERB_GET_CONNECT_SEL, 0);
1029 if (curr != mux_idx)
1030 snd_hda_codec_write_cache(codec, pin_nid, 0,
1031 AC_VERB_SET_CONNECT_SEL,
1032 mux_idx);
1033}
1034
Libin Yang42b29872015-12-16 13:42:42 +08001035/* get the mux index for the converter of the pins
1036 * converter's mux index is the same for all pins on Intel platform
1037 */
1038static int intel_cvt_id_to_mux_idx(struct hdmi_spec *spec,
1039 hda_nid_t cvt_nid)
1040{
1041 int i;
1042
1043 for (i = 0; i < spec->num_cvts; i++)
1044 if (spec->cvt_nids[i] == cvt_nid)
1045 return i;
1046 return -EINVAL;
1047}
1048
Mengdong Lin300016b2013-11-04 01:13:13 -05001049/* Intel HDMI workaround to fix audio routing issue:
1050 * For some Intel display codecs, pins share the same connection list.
1051 * So a conveter can be selected by multiple pins and playback on any of these
1052 * pins will generate sound on the external display, because audio flows from
1053 * the same converter to the display pipeline. Also muting one pin may make
1054 * other pins have no sound output.
1055 * So this function assures that an assigned converter for a pin is not selected
1056 * by any other pins.
1057 */
1058static void intel_not_share_assigned_cvt(struct hda_codec *codec,
Libin Yang91520852017-01-12 16:04:53 +08001059 hda_nid_t pin_nid,
1060 int dev_id, int mux_idx)
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001061{
1062 struct hdmi_spec *spec = codec->spec;
Takashi Iwai7639a062015-03-03 10:07:24 +01001063 hda_nid_t nid;
Mengdong Linf82d7d12013-09-21 20:34:45 -04001064 int cvt_idx, curr;
1065 struct hdmi_spec_per_cvt *per_cvt;
Libin Yang91520852017-01-12 16:04:53 +08001066 struct hdmi_spec_per_pin *per_pin;
1067 int pin_idx;
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001068
Libin Yang91520852017-01-12 16:04:53 +08001069 /* configure the pins connections */
1070 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1071 int dev_id_saved;
1072 int dev_num;
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001073
Libin Yang91520852017-01-12 16:04:53 +08001074 per_pin = get_pin(spec, pin_idx);
1075 /*
1076 * pin not connected to monitor
1077 * no need to operate on it
1078 */
1079 if (!per_pin->pcm)
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001080 continue;
1081
Libin Yang91520852017-01-12 16:04:53 +08001082 if ((per_pin->pin_nid == pin_nid) &&
1083 (per_pin->dev_id == dev_id))
Mengdong Linf82d7d12013-09-21 20:34:45 -04001084 continue;
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001085
Libin Yang91520852017-01-12 16:04:53 +08001086 /*
1087 * if per_pin->dev_id >= dev_num,
1088 * snd_hda_get_dev_select() will fail,
1089 * and the following operation is unpredictable.
1090 * So skip this situation.
1091 */
1092 dev_num = snd_hda_get_num_devices(codec, per_pin->pin_nid) + 1;
1093 if (per_pin->dev_id >= dev_num)
1094 continue;
1095
1096 nid = per_pin->pin_nid;
1097
1098 /*
1099 * Calling this function should not impact
1100 * on the device entry selection
1101 * So let's save the dev id for each pin,
1102 * and restore it when return
1103 */
1104 dev_id_saved = snd_hda_get_dev_select(codec, nid);
1105 snd_hda_set_dev_select(codec, nid, per_pin->dev_id);
Mengdong Linf82d7d12013-09-21 20:34:45 -04001106 curr = snd_hda_codec_read(codec, nid, 0,
1107 AC_VERB_GET_CONNECT_SEL, 0);
Libin Yang91520852017-01-12 16:04:53 +08001108 if (curr != mux_idx) {
1109 snd_hda_set_dev_select(codec, nid, dev_id_saved);
Mengdong Linf82d7d12013-09-21 20:34:45 -04001110 continue;
Libin Yang91520852017-01-12 16:04:53 +08001111 }
1112
Mengdong Linf82d7d12013-09-21 20:34:45 -04001113
1114 /* choose an unassigned converter. The conveters in the
1115 * connection list are in the same order as in the codec.
1116 */
1117 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
1118 per_cvt = get_cvt(spec, cvt_idx);
1119 if (!per_cvt->assigned) {
Takashi Iwai4e76a882014-02-25 12:21:03 +01001120 codec_dbg(codec,
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +02001121 "choose cvt %d for pin NID 0x%x\n",
1122 cvt_idx, nid);
Mengdong Linf82d7d12013-09-21 20:34:45 -04001123 snd_hda_codec_write_cache(codec, nid, 0,
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001124 AC_VERB_SET_CONNECT_SEL,
Mengdong Linf82d7d12013-09-21 20:34:45 -04001125 cvt_idx);
1126 break;
1127 }
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001128 }
Libin Yang91520852017-01-12 16:04:53 +08001129 snd_hda_set_dev_select(codec, nid, dev_id_saved);
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001130 }
1131}
1132
Libin Yang42b29872015-12-16 13:42:42 +08001133/* A wrapper of intel_not_share_asigned_cvt() */
1134static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec,
Libin Yang91520852017-01-12 16:04:53 +08001135 hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid)
Libin Yang42b29872015-12-16 13:42:42 +08001136{
1137 int mux_idx;
1138 struct hdmi_spec *spec = codec->spec;
1139
Libin Yang42b29872015-12-16 13:42:42 +08001140 /* On Intel platform, the mapping of converter nid to
1141 * mux index of the pins are always the same.
1142 * The pin nid may be 0, this means all pins will not
1143 * share the converter.
1144 */
1145 mux_idx = intel_cvt_id_to_mux_idx(spec, cvt_nid);
1146 if (mux_idx >= 0)
Libin Yang91520852017-01-12 16:04:53 +08001147 intel_not_share_assigned_cvt(codec, pin_nid, dev_id, mux_idx);
Libin Yang42b29872015-12-16 13:42:42 +08001148}
1149
Takashi Iwai4846a672016-03-21 12:56:46 +01001150/* skeleton caller of pin_cvt_fixup ops */
1151static void pin_cvt_fixup(struct hda_codec *codec,
1152 struct hdmi_spec_per_pin *per_pin,
1153 hda_nid_t cvt_nid)
1154{
1155 struct hdmi_spec *spec = codec->spec;
1156
1157 if (spec->ops.pin_cvt_fixup)
1158 spec->ops.pin_cvt_fixup(codec, per_pin, cvt_nid);
1159}
1160
Libin Yang42b29872015-12-16 13:42:42 +08001161/* called in hdmi_pcm_open when no pin is assigned to the PCM
1162 * in dyn_pcm_assign mode.
1163 */
1164static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
1165 struct hda_codec *codec,
1166 struct snd_pcm_substream *substream)
1167{
1168 struct hdmi_spec *spec = codec->spec;
1169 struct snd_pcm_runtime *runtime = substream->runtime;
Libin Yangac983792015-12-16 16:48:16 +08001170 int cvt_idx, pcm_idx;
Libin Yang42b29872015-12-16 13:42:42 +08001171 struct hdmi_spec_per_cvt *per_cvt = NULL;
1172 int err;
1173
Libin Yangac983792015-12-16 16:48:16 +08001174 pcm_idx = hinfo_to_pcm_index(codec, hinfo);
1175 if (pcm_idx < 0)
1176 return -EINVAL;
1177
Takashi Iwai4846a672016-03-21 12:56:46 +01001178 err = hdmi_choose_cvt(codec, -1, &cvt_idx);
Libin Yang42b29872015-12-16 13:42:42 +08001179 if (err)
1180 return err;
1181
1182 per_cvt = get_cvt(spec, cvt_idx);
1183 per_cvt->assigned = 1;
1184 hinfo->nid = per_cvt->cvt_nid;
1185
Takashi Iwai4846a672016-03-21 12:56:46 +01001186 pin_cvt_fixup(codec, NULL, per_cvt->cvt_nid);
Libin Yang42b29872015-12-16 13:42:42 +08001187
Libin Yangac983792015-12-16 16:48:16 +08001188 set_bit(pcm_idx, &spec->pcm_in_use);
Libin Yang42b29872015-12-16 13:42:42 +08001189 /* todo: setup spdif ctls assign */
1190
1191 /* Initially set the converter's capabilities */
1192 hinfo->channels_min = per_cvt->channels_min;
1193 hinfo->channels_max = per_cvt->channels_max;
1194 hinfo->rates = per_cvt->rates;
1195 hinfo->formats = per_cvt->formats;
1196 hinfo->maxbps = per_cvt->maxbps;
1197
1198 /* Store the updated parameters */
1199 runtime->hw.channels_min = hinfo->channels_min;
1200 runtime->hw.channels_max = hinfo->channels_max;
1201 runtime->hw.formats = hinfo->formats;
1202 runtime->hw.rates = hinfo->rates;
1203
1204 snd_pcm_hw_constraint_step(substream->runtime, 0,
1205 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
1206 return 0;
1207}
1208
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001209/*
1210 * HDA PCM callbacks
1211 */
1212static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1213 struct hda_codec *codec,
1214 struct snd_pcm_substream *substream)
1215{
1216 struct hdmi_spec *spec = codec->spec;
1217 struct snd_pcm_runtime *runtime = substream->runtime;
Takashi Iwai4846a672016-03-21 12:56:46 +01001218 int pin_idx, cvt_idx, pcm_idx;
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001219 struct hdmi_spec_per_pin *per_pin;
1220 struct hdmi_eld *eld;
1221 struct hdmi_spec_per_cvt *per_cvt = NULL;
1222 int err;
1223
1224 /* Validate hinfo */
Libin Yang2bf3c852015-12-16 13:42:43 +08001225 pcm_idx = hinfo_to_pcm_index(codec, hinfo);
1226 if (pcm_idx < 0)
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001227 return -EINVAL;
Libin Yang2bf3c852015-12-16 13:42:43 +08001228
Libin Yang42b29872015-12-16 13:42:42 +08001229 mutex_lock(&spec->pcm_lock);
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001230 pin_idx = hinfo_to_pin_index(codec, hinfo);
Libin Yang42b29872015-12-16 13:42:42 +08001231 if (!spec->dyn_pcm_assign) {
1232 if (snd_BUG_ON(pin_idx < 0)) {
Takashi Iwaif69548f2018-07-12 23:06:51 +02001233 err = -EINVAL;
1234 goto unlock;
Libin Yang42b29872015-12-16 13:42:42 +08001235 }
1236 } else {
1237 /* no pin is assigned to the PCM
1238 * PA need pcm open successfully when probe
1239 */
1240 if (pin_idx < 0) {
1241 err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
Takashi Iwaif69548f2018-07-12 23:06:51 +02001242 goto unlock;
Libin Yang42b29872015-12-16 13:42:42 +08001243 }
1244 }
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001245
Takashi Iwai4846a672016-03-21 12:56:46 +01001246 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
Takashi Iwaif69548f2018-07-12 23:06:51 +02001247 if (err < 0)
1248 goto unlock;
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001249
1250 per_cvt = get_cvt(spec, cvt_idx);
Stephen Warren384a48d2011-06-01 11:14:21 -06001251 /* Claim converter */
1252 per_cvt->assigned = 1;
Libin Yang42b29872015-12-16 13:42:42 +08001253
Libin Yangac983792015-12-16 16:48:16 +08001254 set_bit(pcm_idx, &spec->pcm_in_use);
Libin Yang42b29872015-12-16 13:42:42 +08001255 per_pin = get_pin(spec, pin_idx);
Anssi Hannula1df5a062013-10-05 02:25:40 +03001256 per_pin->cvt_nid = per_cvt->cvt_nid;
Stephen Warren384a48d2011-06-01 11:14:21 -06001257 hinfo->nid = per_cvt->cvt_nid;
1258
Takashi Iwaie38e4862019-12-02 08:49:47 +01001259 /* flip stripe flag for the assigned stream if supported */
1260 if (get_wcaps(codec, per_cvt->cvt_nid) & AC_WCAP_STRIPE)
1261 azx_stream(get_azx_dev(substream))->stripe = 1;
1262
Libin Yang91520852017-01-12 16:04:53 +08001263 snd_hda_set_dev_select(codec, per_pin->pin_nid, per_pin->dev_id);
Takashi Iwaibddee962013-06-18 16:14:22 +02001264 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
Stephen Warren384a48d2011-06-01 11:14:21 -06001265 AC_VERB_SET_CONNECT_SEL,
Takashi Iwai4846a672016-03-21 12:56:46 +01001266 per_pin->mux_idx);
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001267
1268 /* configure unused pins to choose other converters */
Takashi Iwai4846a672016-03-21 12:56:46 +01001269 pin_cvt_fixup(codec, per_pin, 0);
Wang Xingchao7ef166b2013-06-18 21:42:14 +08001270
Libin Yang2bf3c852015-12-16 13:42:43 +08001271 snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid);
Takashi Iwaibbbe3392010-08-13 08:45:23 +02001272
Stephen Warren2def8172011-06-01 11:14:20 -06001273 /* Initially set the converter's capabilities */
Stephen Warren384a48d2011-06-01 11:14:21 -06001274 hinfo->channels_min = per_cvt->channels_min;
1275 hinfo->channels_max = per_cvt->channels_max;
1276 hinfo->rates = per_cvt->rates;
1277 hinfo->formats = per_cvt->formats;
1278 hinfo->maxbps = per_cvt->maxbps;
Stephen Warren2def8172011-06-01 11:14:20 -06001279
Libin Yang42b29872015-12-16 13:42:42 +08001280 eld = &per_pin->sink_eld;
Stephen Warren384a48d2011-06-01 11:14:21 -06001281 /* Restrict capabilities by ELD if this isn't disabled */
Stephen Warrenc3d52102011-06-01 11:14:16 -06001282 if (!static_hdmi_pcm && eld->eld_valid) {
David Henningsson1613d6b2013-02-19 16:11:24 +01001283 snd_hdmi_eld_update_pcm_info(&eld->info, hinfo);
Takashi Iwaibbbe3392010-08-13 08:45:23 +02001284 if (hinfo->channels_min > hinfo->channels_max ||
Takashi Iwai2ad779b2013-02-01 14:01:27 +01001285 !hinfo->rates || !hinfo->formats) {
1286 per_cvt->assigned = 0;
1287 hinfo->nid = 0;
Libin Yang2bf3c852015-12-16 13:42:43 +08001288 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
Takashi Iwaif69548f2018-07-12 23:06:51 +02001289 err = -ENODEV;
1290 goto unlock;
Takashi Iwai2ad779b2013-02-01 14:01:27 +01001291 }
Takashi Iwaibbbe3392010-08-13 08:45:23 +02001292 }
Stephen Warren2def8172011-06-01 11:14:20 -06001293
1294 /* Store the updated parameters */
Takashi Iwai639cef02011-01-14 10:30:46 +01001295 runtime->hw.channels_min = hinfo->channels_min;
1296 runtime->hw.channels_max = hinfo->channels_max;
1297 runtime->hw.formats = hinfo->formats;
1298 runtime->hw.rates = hinfo->rates;
Takashi Iwai4fe2ca12011-01-14 10:33:26 +01001299
1300 snd_pcm_hw_constraint_step(substream->runtime, 0,
1301 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
Takashi Iwaif69548f2018-07-12 23:06:51 +02001302 unlock:
1303 mutex_unlock(&spec->pcm_lock);
1304 return err;
Takashi Iwaibbbe3392010-08-13 08:45:23 +02001305}
1306
1307/*
Wu Fengguang079d88c2010-03-08 10:44:23 +08001308 * HDA/HDMI auto parsing
1309 */
Stephen Warren384a48d2011-06-01 11:14:21 -06001310static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
Wu Fengguang079d88c2010-03-08 10:44:23 +08001311{
1312 struct hdmi_spec *spec = codec->spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01001313 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
Stephen Warren384a48d2011-06-01 11:14:21 -06001314 hda_nid_t pin_nid = per_pin->pin_nid;
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05301315 int dev_id = per_pin->dev_id;
Kai Vehmanenae254882019-11-27 18:12:40 +02001316 int conns;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001317
1318 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +01001319 codec_warn(codec,
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +02001320 "HDMI: pin NID 0x%x wcaps %#x does not support connection list\n",
Wu Fengguang079d88c2010-03-08 10:44:23 +08001321 pin_nid, get_wcaps(codec, pin_nid));
1322 return -EINVAL;
1323 }
1324
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05301325 snd_hda_set_dev_select(codec, pin_nid, dev_id);
1326
Kai Vehmanenae254882019-11-27 18:12:40 +02001327 if (spec->intel_hsw_fixup) {
1328 conns = spec->num_cvts;
1329 memcpy(per_pin->mux_nids, spec->cvt_nids,
1330 sizeof(hda_nid_t) * conns);
1331 } else {
1332 conns = snd_hda_get_raw_connections(codec, pin_nid,
1333 per_pin->mux_nids,
1334 HDA_MAX_CONNECTIONS);
1335 }
1336
Libin Yang91520852017-01-12 16:04:53 +08001337 /* all the device entries on the same pin have the same conn list */
Kai Vehmanenae254882019-11-27 18:12:40 +02001338 per_pin->num_mux_nids = conns;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001339
1340 return 0;
1341}
1342
Libin Yanga76056f2015-12-16 16:48:15 +08001343static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
Nikhil Mahale5398e942019-11-19 14:17:10 +05301344 struct hdmi_spec_per_pin *per_pin)
Libin Yanga76056f2015-12-16 16:48:15 +08001345{
1346 int i;
1347
Nikhil Mahale5398e942019-11-19 14:17:10 +05301348 /*
Kai Vehmanen0c0fe9e2019-11-29 16:37:55 +02001349 * generic_hdmi_build_pcms() may allocate extra PCMs on some
1350 * platforms (with maximum of 'num_nids + dev_num - 1')
Nikhil Mahale5398e942019-11-19 14:17:10 +05301351 *
1352 * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n
1353 * if m==0. This guarantees that dynamic pcm assignments are compatible
Kai Vehmanen0c0fe9e2019-11-29 16:37:55 +02001354 * with the legacy static per_pin-pcm assignment that existed in the
Nikhil Mahale5398e942019-11-19 14:17:10 +05301355 * days before DP-MST.
1356 *
Takashi Iwai643a2cc2019-12-03 16:41:05 +01001357 * Intel DP-MST prefers this legacy behavior for compatibility, too.
1358 *
Nikhil Mahale5398e942019-11-19 14:17:10 +05301359 * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)).
1360 */
Libin Yanga76056f2015-12-16 16:48:15 +08001361
Takashi Iwai643a2cc2019-12-03 16:41:05 +01001362 if (per_pin->dev_id == 0 || spec->intel_hsw_fixup) {
Kai Vehmanen0c0fe9e2019-11-29 16:37:55 +02001363 if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
1364 return per_pin->pin_nid_idx;
1365 } else {
1366 i = spec->num_nids + (per_pin->dev_id - 1);
1367 if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap)))
1368 return i;
Nikhil Mahale5398e942019-11-19 14:17:10 +05301369 }
1370
1371 /* have a second try; check the area over num_nids */
Libin Yang91520852017-01-12 16:04:53 +08001372 for (i = spec->num_nids; i < spec->pcm_used; i++) {
Libin Yanga76056f2015-12-16 16:48:15 +08001373 if (!test_bit(i, &spec->pcm_bitmap))
1374 return i;
1375 }
1376
1377 /* the last try; check the empty slots in pins */
Libin Yang91520852017-01-12 16:04:53 +08001378 for (i = 0; i < spec->num_nids; i++) {
Libin Yanga76056f2015-12-16 16:48:15 +08001379 if (!test_bit(i, &spec->pcm_bitmap))
1380 return i;
1381 }
1382 return -EBUSY;
1383}
1384
1385static void hdmi_attach_hda_pcm(struct hdmi_spec *spec,
1386 struct hdmi_spec_per_pin *per_pin)
1387{
1388 int idx;
1389
1390 /* pcm already be attached to the pin */
1391 if (per_pin->pcm)
1392 return;
1393 idx = hdmi_find_pcm_slot(spec, per_pin);
Libin Yangd10a80d2016-03-01 15:18:26 +08001394 if (idx == -EBUSY)
Libin Yanga76056f2015-12-16 16:48:15 +08001395 return;
1396 per_pin->pcm_idx = idx;
Libin Yang2bea2412016-01-12 11:13:26 +08001397 per_pin->pcm = get_hdmi_pcm(spec, idx);
Libin Yanga76056f2015-12-16 16:48:15 +08001398 set_bit(idx, &spec->pcm_bitmap);
1399}
1400
1401static void hdmi_detach_hda_pcm(struct hdmi_spec *spec,
1402 struct hdmi_spec_per_pin *per_pin)
1403{
1404 int idx;
1405
1406 /* pcm already be detached from the pin */
1407 if (!per_pin->pcm)
1408 return;
1409 idx = per_pin->pcm_idx;
1410 per_pin->pcm_idx = -1;
1411 per_pin->pcm = NULL;
1412 if (idx >= 0 && idx < spec->pcm_used)
1413 clear_bit(idx, &spec->pcm_bitmap);
1414}
1415
Libin Yangac983792015-12-16 16:48:16 +08001416static int hdmi_get_pin_cvt_mux(struct hdmi_spec *spec,
1417 struct hdmi_spec_per_pin *per_pin, hda_nid_t cvt_nid)
1418{
1419 int mux_idx;
1420
1421 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
1422 if (per_pin->mux_nids[mux_idx] == cvt_nid)
1423 break;
1424 return mux_idx;
1425}
1426
1427static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid);
1428
1429static void hdmi_pcm_setup_pin(struct hdmi_spec *spec,
1430 struct hdmi_spec_per_pin *per_pin)
1431{
1432 struct hda_codec *codec = per_pin->codec;
1433 struct hda_pcm *pcm;
1434 struct hda_pcm_stream *hinfo;
1435 struct snd_pcm_substream *substream;
1436 int mux_idx;
1437 bool non_pcm;
1438
1439 if (per_pin->pcm_idx >= 0 && per_pin->pcm_idx < spec->pcm_used)
Libin Yang2bea2412016-01-12 11:13:26 +08001440 pcm = get_pcm_rec(spec, per_pin->pcm_idx);
Libin Yangac983792015-12-16 16:48:16 +08001441 else
1442 return;
Takashi Iwai8a7d6002018-04-25 16:19:13 +02001443 if (!pcm->pcm)
1444 return;
Libin Yangac983792015-12-16 16:48:16 +08001445 if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))
1446 return;
1447
1448 /* hdmi audio only uses playback and one substream */
1449 hinfo = pcm->stream;
1450 substream = pcm->pcm->streams[0].substream;
1451
1452 per_pin->cvt_nid = hinfo->nid;
1453
1454 mux_idx = hdmi_get_pin_cvt_mux(spec, per_pin, hinfo->nid);
Libin Yang91520852017-01-12 16:04:53 +08001455 if (mux_idx < per_pin->num_mux_nids) {
1456 snd_hda_set_dev_select(codec, per_pin->pin_nid,
1457 per_pin->dev_id);
Libin Yangac983792015-12-16 16:48:16 +08001458 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
1459 AC_VERB_SET_CONNECT_SEL,
1460 mux_idx);
Libin Yang91520852017-01-12 16:04:53 +08001461 }
Libin Yangac983792015-12-16 16:48:16 +08001462 snd_hda_spdif_ctls_assign(codec, per_pin->pcm_idx, hinfo->nid);
1463
1464 non_pcm = check_non_pcm_per_cvt(codec, hinfo->nid);
1465 if (substream->runtime)
1466 per_pin->channels = substream->runtime->channels;
1467 per_pin->setup = true;
1468 per_pin->mux_idx = mux_idx;
1469
1470 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
1471}
1472
1473static void hdmi_pcm_reset_pin(struct hdmi_spec *spec,
1474 struct hdmi_spec_per_pin *per_pin)
1475{
1476 if (per_pin->pcm_idx >= 0 && per_pin->pcm_idx < spec->pcm_used)
1477 snd_hda_spdif_ctls_unassign(per_pin->codec, per_pin->pcm_idx);
1478
1479 per_pin->chmap_set = false;
1480 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
1481
1482 per_pin->setup = false;
1483 per_pin->channels = 0;
1484}
1485
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001486static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
1487 struct hdmi_spec_per_pin *per_pin)
1488{
1489 struct hdmi_spec *spec = codec->spec;
1490
1491 if (per_pin->pcm_idx >= 0)
1492 return spec->pcm_rec[per_pin->pcm_idx].jack;
1493 else
1494 return NULL;
1495}
1496
Takashi Iwaie90247f2015-11-13 09:12:12 +01001497/* update per_pin ELD from the given new ELD;
1498 * setup info frame and notification accordingly
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001499 * also notify ELD kctl and report jack status changes
Takashi Iwaie90247f2015-11-13 09:12:12 +01001500 */
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001501static void update_eld(struct hda_codec *codec,
Takashi Iwaie90247f2015-11-13 09:12:12 +01001502 struct hdmi_spec_per_pin *per_pin,
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001503 struct hdmi_eld *eld,
1504 int repoll)
Takashi Iwaie90247f2015-11-13 09:12:12 +01001505{
1506 struct hdmi_eld *pin_eld = &per_pin->sink_eld;
Libin Yanga76056f2015-12-16 16:48:15 +08001507 struct hdmi_spec *spec = codec->spec;
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001508 struct snd_jack *pcm_jack;
Takashi Iwaie90247f2015-11-13 09:12:12 +01001509 bool old_eld_valid = pin_eld->eld_valid;
1510 bool eld_changed;
Colin Ian Kingf953e722019-09-05 16:48:26 +01001511 int pcm_idx;
Takashi Iwaie90247f2015-11-13 09:12:12 +01001512
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001513 if (eld->eld_valid) {
1514 if (eld->eld_size <= 0 ||
1515 snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
1516 eld->eld_size) < 0) {
1517 eld->eld_valid = false;
1518 if (repoll) {
1519 schedule_delayed_work(&per_pin->work,
1520 msecs_to_jiffies(300));
1521 return;
1522 }
1523 }
1524 }
1525
1526 if (!eld->eld_valid || eld->eld_size <= 0) {
1527 eld->eld_valid = false;
1528 eld->eld_size = 0;
1529 }
1530
Libin Yangfb087ea2016-02-23 16:33:37 +08001531 /* for monitor disconnection, save pcm_idx firstly */
1532 pcm_idx = per_pin->pcm_idx;
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001533
1534 /*
1535 * pcm_idx >=0 before update_eld() means it is in monitor
1536 * disconnected event. Jack must be fetched before update_eld().
1537 */
1538 pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
1539
Libin Yanga76056f2015-12-16 16:48:15 +08001540 if (spec->dyn_pcm_assign) {
Libin Yangac983792015-12-16 16:48:16 +08001541 if (eld->eld_valid) {
Libin Yanga76056f2015-12-16 16:48:15 +08001542 hdmi_attach_hda_pcm(spec, per_pin);
Libin Yangac983792015-12-16 16:48:16 +08001543 hdmi_pcm_setup_pin(spec, per_pin);
1544 } else {
1545 hdmi_pcm_reset_pin(spec, per_pin);
Libin Yanga76056f2015-12-16 16:48:15 +08001546 hdmi_detach_hda_pcm(spec, per_pin);
Libin Yangac983792015-12-16 16:48:16 +08001547 }
Libin Yanga76056f2015-12-16 16:48:15 +08001548 }
Libin Yangfb087ea2016-02-23 16:33:37 +08001549 /* if pcm_idx == -1, it means this is in monitor connection event
1550 * we can get the correct pcm_idx now.
1551 */
1552 if (pcm_idx == -1)
1553 pcm_idx = per_pin->pcm_idx;
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001554 if (!pcm_jack)
1555 pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
Libin Yanga76056f2015-12-16 16:48:15 +08001556
Takashi Iwaie90247f2015-11-13 09:12:12 +01001557 if (eld->eld_valid)
1558 snd_hdmi_show_eld(codec, &eld->info);
1559
1560 eld_changed = (pin_eld->eld_valid != eld->eld_valid);
Takashi Iwai551626e2019-07-17 14:30:23 +02001561 eld_changed |= (pin_eld->monitor_present != eld->monitor_present);
1562 if (!eld_changed && eld->eld_valid && pin_eld->eld_valid)
Takashi Iwaie90247f2015-11-13 09:12:12 +01001563 if (pin_eld->eld_size != eld->eld_size ||
1564 memcmp(pin_eld->eld_buffer, eld->eld_buffer,
1565 eld->eld_size) != 0)
1566 eld_changed = true;
1567
Takashi Iwai551626e2019-07-17 14:30:23 +02001568 if (eld_changed) {
1569 pin_eld->monitor_present = eld->monitor_present;
1570 pin_eld->eld_valid = eld->eld_valid;
1571 pin_eld->eld_size = eld->eld_size;
1572 if (eld->eld_valid)
1573 memcpy(pin_eld->eld_buffer, eld->eld_buffer,
1574 eld->eld_size);
1575 pin_eld->info = eld->info;
1576 }
Takashi Iwaie90247f2015-11-13 09:12:12 +01001577
1578 /*
1579 * Re-setup pin and infoframe. This is needed e.g. when
1580 * - sink is first plugged-in
1581 * - transcoder can change during stream playback on Haswell
1582 * and this can make HW reset converter selection on a pin.
1583 */
1584 if (eld->eld_valid && !old_eld_valid && per_pin->setup) {
Takashi Iwai4846a672016-03-21 12:56:46 +01001585 pin_cvt_fixup(codec, per_pin, 0);
Takashi Iwaie90247f2015-11-13 09:12:12 +01001586 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1587 }
1588
Libin Yangfb087ea2016-02-23 16:33:37 +08001589 if (eld_changed && pcm_idx >= 0)
Takashi Iwaie90247f2015-11-13 09:12:12 +01001590 snd_ctl_notify(codec->card,
1591 SNDRV_CTL_EVENT_MASK_VALUE |
1592 SNDRV_CTL_EVENT_MASK_INFO,
Libin Yangfb087ea2016-02-23 16:33:37 +08001593 &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
Takashi Iwaie90247f2015-11-13 09:12:12 +01001594
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001595 if (eld_changed && pcm_jack)
Takashi Iwaidb845402020-02-06 17:28:02 +01001596 snd_jack_report(pcm_jack,
1597 (eld->monitor_present && eld->eld_valid) ?
1598 SND_JACK_AVOUT : 0);
1599}
1600
Takashi Iwai788d4412015-11-12 15:36:13 +01001601/* update ELD and jack state via HD-audio verbs */
Takashi Iwaidb845402020-02-06 17:28:02 +01001602static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
Takashi Iwai788d4412015-11-12 15:36:13 +01001603 int repoll)
Wu Fengguang079d88c2010-03-08 10:44:23 +08001604{
Wu Fengguang744626d2011-11-16 16:29:47 +08001605 struct hda_codec *codec = per_pin->codec;
David Henningsson4bd038f2013-02-19 16:11:25 +01001606 struct hdmi_spec *spec = codec->spec;
1607 struct hdmi_eld *eld = &spec->temp_eld;
Wu Fengguang744626d2011-11-16 16:29:47 +08001608 hda_nid_t pin_nid = per_pin->pin_nid;
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05301609 int dev_id = per_pin->dev_id;
Stephen Warren5d44f922011-05-24 17:11:17 -06001610 /*
1611 * Always execute a GetPinSense verb here, even when called from
1612 * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited
1613 * response's PD bit is not the real PD value, but indicates that
1614 * the real PD value changed. An older version of the HD-audio
1615 * specification worked this way. Hence, we just ignore the data in
1616 * the unsolicited response to avoid custom WARs.
1617 */
David Henningssonda4a7a32013-12-18 10:46:04 +01001618 int present;
Takashi Iwaiae47e2e2020-02-06 17:28:03 +01001619 int ret;
1620
1621 ret = snd_hda_power_up_pm(codec);
1622 if (ret < 0 && pm_runtime_suspended(hda_codec_dev(codec)))
1623 goto out;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001624
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05301625 present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
David Henningssonda4a7a32013-12-18 10:46:04 +01001626
Takashi Iwaia4e9a382013-10-17 18:21:12 +02001627 mutex_lock(&per_pin->lock);
Takashi Iwaic44da622016-04-13 09:45:53 +02001628 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
1629 if (eld->monitor_present)
David Henningsson4bd038f2013-02-19 16:11:25 +01001630 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
1631 else
1632 eld->eld_valid = false;
Stephen Warren5d44f922011-05-24 17:11:17 -06001633
Takashi Iwai4e76a882014-02-25 12:21:03 +01001634 codec_dbg(codec,
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +02001635 "HDMI status: Codec=%d NID=0x%x Presence_Detect=%d ELD_Valid=%d\n",
Takashi Iwaic44da622016-04-13 09:45:53 +02001636 codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
Stephen Warren5d44f922011-05-24 17:11:17 -06001637
David Henningsson4bd038f2013-02-19 16:11:25 +01001638 if (eld->eld_valid) {
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05301639 if (spec->ops.pin_get_eld(codec, pin_nid, dev_id,
1640 eld->eld_buffer, &eld->eld_size) < 0)
David Henningsson4bd038f2013-02-19 16:11:25 +01001641 eld->eld_valid = false;
Wu Fengguang744626d2011-11-16 16:29:47 +08001642 }
David Henningsson4bd038f2013-02-19 16:11:25 +01001643
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001644 update_eld(codec, per_pin, eld, repoll);
Takashi Iwaia4e9a382013-10-17 18:21:12 +02001645 mutex_unlock(&per_pin->lock);
Takashi Iwaiae47e2e2020-02-06 17:28:03 +01001646 out:
1647 snd_hda_power_down_pm(codec);
Wu Fengguang079d88c2010-03-08 10:44:23 +08001648}
1649
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001650#define I915_SILENT_RATE 48000
1651#define I915_SILENT_CHANNELS 2
1652#define I915_SILENT_FORMAT SNDRV_PCM_FORMAT_S16_LE
1653#define I915_SILENT_FORMAT_BITS 16
1654#define I915_SILENT_FMT_MASK 0xf
Harsha Priya951894c2020-07-06 13:53:17 -07001655
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001656static void silent_stream_enable(struct hda_codec *codec,
1657 struct hdmi_spec_per_pin *per_pin)
1658{
1659 struct hdmi_spec *spec = codec->spec;
1660 struct hdmi_spec_per_cvt *per_cvt;
1661 int cvt_idx, pin_idx, err;
1662 unsigned int format;
Harsha Priya951894c2020-07-06 13:53:17 -07001663
1664 mutex_lock(&per_pin->lock);
1665
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001666 if (per_pin->setup) {
1667 codec_dbg(codec, "hdmi: PCM already open, no silent stream\n");
1668 goto unlock_out;
1669 }
Harsha Priya951894c2020-07-06 13:53:17 -07001670
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001671 pin_idx = pin_id_to_pin_index(codec, per_pin->pin_nid, per_pin->dev_id);
1672 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
1673 if (err) {
1674 codec_err(codec, "hdmi: no free converter to enable silent mode\n");
1675 goto unlock_out;
1676 }
Harsha Priya951894c2020-07-06 13:53:17 -07001677
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001678 per_cvt = get_cvt(spec, cvt_idx);
1679 per_cvt->assigned = 1;
1680 per_pin->cvt_nid = per_cvt->cvt_nid;
1681 per_pin->silent_stream = true;
1682
1683 codec_dbg(codec, "hdmi: enabling silent stream pin-NID=0x%x cvt-NID=0x%x\n",
1684 per_pin->pin_nid, per_cvt->cvt_nid);
1685
1686 snd_hda_set_dev_select(codec, per_pin->pin_nid, per_pin->dev_id);
1687 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
1688 AC_VERB_SET_CONNECT_SEL,
1689 per_pin->mux_idx);
1690
1691 /* configure unused pins to choose other converters */
1692 pin_cvt_fixup(codec, per_pin, 0);
1693
1694 snd_hdac_sync_audio_rate(&codec->core, per_pin->pin_nid,
1695 per_pin->dev_id, I915_SILENT_RATE);
1696
1697 /* trigger silent stream generation in hw */
1698 format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
1699 I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
1700 snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
1701 I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
1702 usleep_range(100, 200);
1703 snd_hda_codec_setup_stream(codec, per_pin->cvt_nid, I915_SILENT_FMT_MASK, 0, format);
1704
1705 per_pin->channels = I915_SILENT_CHANNELS;
Harsha Priya951894c2020-07-06 13:53:17 -07001706 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1707
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001708 unlock_out:
Harsha Priya951894c2020-07-06 13:53:17 -07001709 mutex_unlock(&per_pin->lock);
1710}
1711
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001712static void silent_stream_disable(struct hda_codec *codec,
1713 struct hdmi_spec_per_pin *per_pin)
1714{
1715 struct hdmi_spec *spec = codec->spec;
1716 struct hdmi_spec_per_cvt *per_cvt;
1717 int cvt_idx;
1718
1719 mutex_lock(&per_pin->lock);
1720 if (!per_pin->silent_stream)
1721 goto unlock_out;
1722
1723 codec_dbg(codec, "HDMI: disable silent stream on pin-NID=0x%x cvt-NID=0x%x\n",
1724 per_pin->pin_nid, per_pin->cvt_nid);
1725
1726 cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
1727 if (cvt_idx >= 0 && cvt_idx < spec->num_cvts) {
1728 per_cvt = get_cvt(spec, cvt_idx);
1729 per_cvt->assigned = 0;
1730 }
1731
1732 per_pin->cvt_nid = 0;
1733 per_pin->silent_stream = false;
1734
1735 unlock_out:
Takashi Iwai3d5c5fd2021-01-01 09:38:52 +01001736 mutex_unlock(&per_pin->lock);
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001737}
1738
Takashi Iwai788d4412015-11-12 15:36:13 +01001739/* update ELD and jack state via audio component */
1740static void sync_eld_via_acomp(struct hda_codec *codec,
1741 struct hdmi_spec_per_pin *per_pin)
1742{
Takashi Iwai788d4412015-11-12 15:36:13 +01001743 struct hdmi_spec *spec = codec->spec;
1744 struct hdmi_eld *eld = &spec->temp_eld;
Harsha Priya951894c2020-07-06 13:53:17 -07001745 bool monitor_prev, monitor_next;
Takashi Iwai788d4412015-11-12 15:36:13 +01001746
Takashi Iwaie2dc7d72015-12-01 12:39:38 +01001747 mutex_lock(&per_pin->lock);
Takashi Iwaic64c1432016-03-21 16:07:30 +01001748 eld->monitor_present = false;
Harsha Priya951894c2020-07-06 13:53:17 -07001749 monitor_prev = per_pin->sink_eld.monitor_present;
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001750 eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
Libin Yang91520852017-01-12 16:04:53 +08001751 per_pin->dev_id, &eld->monitor_present,
1752 eld->eld_buffer, ELD_MAX_SIZE);
Takashi Iwaiadf615a2020-02-06 17:28:04 +01001753 eld->eld_valid = (eld->eld_size > 0);
1754 update_eld(codec, per_pin, eld, 0);
Harsha Priya951894c2020-07-06 13:53:17 -07001755 monitor_next = per_pin->sink_eld.monitor_present;
Takashi Iwaie2dc7d72015-12-01 12:39:38 +01001756 mutex_unlock(&per_pin->lock);
Harsha Priya951894c2020-07-06 13:53:17 -07001757
1758 /*
1759 * Power-up will call hdmi_present_sense, so the PM calls
1760 * have to be done without mutex held.
1761 */
1762
1763 if (spec->send_silent_stream) {
1764 int pm_ret;
1765
1766 if (!monitor_prev && monitor_next) {
1767 pm_ret = snd_hda_power_up_pm(codec);
1768 if (pm_ret < 0)
1769 codec_err(codec,
1770 "Monitor plugged-in, Failed to power up codec ret=[%d]\n",
1771 pm_ret);
1772 silent_stream_enable(codec, per_pin);
1773 } else if (monitor_prev && !monitor_next) {
Kai Vehmanenb1a50392020-12-10 19:44:45 +02001774 silent_stream_disable(codec, per_pin);
Harsha Priya951894c2020-07-06 13:53:17 -07001775 pm_ret = snd_hda_power_down_pm(codec);
1776 if (pm_ret < 0)
1777 codec_err(codec,
1778 "Monitor plugged-out, Failed to power down codec ret=[%d]\n",
1779 pm_ret);
1780 }
1781 }
Takashi Iwai788d4412015-11-12 15:36:13 +01001782}
1783
Takashi Iwaidb845402020-02-06 17:28:02 +01001784static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
Takashi Iwai788d4412015-11-12 15:36:13 +01001785{
1786 struct hda_codec *codec = per_pin->codec;
1787
Takashi Iwaiae47e2e2020-02-06 17:28:03 +01001788 if (!codec_has_acomp(codec))
Takashi Iwaidb845402020-02-06 17:28:02 +01001789 hdmi_present_sense_via_verbs(per_pin, repoll);
Takashi Iwaiae47e2e2020-02-06 17:28:03 +01001790 else
Takashi Iwai788d4412015-11-12 15:36:13 +01001791 sync_eld_via_acomp(codec, per_pin);
Takashi Iwai788d4412015-11-12 15:36:13 +01001792}
1793
Wu Fengguang744626d2011-11-16 16:29:47 +08001794static void hdmi_repoll_eld(struct work_struct *work)
1795{
1796 struct hdmi_spec_per_pin *per_pin =
1797 container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
Chris Wilsonaaa23f82018-06-27 07:25:32 +01001798 struct hda_codec *codec = per_pin->codec;
1799 struct hdmi_spec *spec = codec->spec;
Hui Wang8c2e6722019-05-06 22:09:31 +08001800 struct hda_jack_tbl *jack;
1801
Nikhil Mahale5204a052019-11-19 14:17:08 +05301802 jack = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid,
1803 per_pin->dev_id);
Hui Wang8c2e6722019-05-06 22:09:31 +08001804 if (jack)
1805 jack->jack_dirty = 1;
Wu Fengguang744626d2011-11-16 16:29:47 +08001806
Wu Fengguangc6e84532011-11-18 16:59:32 -06001807 if (per_pin->repoll_count++ > 6)
1808 per_pin->repoll_count = 0;
1809
Chris Wilsonaaa23f82018-06-27 07:25:32 +01001810 mutex_lock(&spec->pcm_lock);
Takashi Iwaidb845402020-02-06 17:28:02 +01001811 hdmi_present_sense(per_pin, per_pin->repoll_count);
Chris Wilsonaaa23f82018-06-27 07:25:32 +01001812 mutex_unlock(&spec->pcm_lock);
Wu Fengguang744626d2011-11-16 16:29:47 +08001813}
1814
Wu Fengguang079d88c2010-03-08 10:44:23 +08001815static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1816{
1817 struct hdmi_spec *spec = codec->spec;
Stephen Warren384a48d2011-06-01 11:14:21 -06001818 unsigned int caps, config;
1819 int pin_idx;
1820 struct hdmi_spec_per_pin *per_pin;
David Henningsson07acecc2011-05-19 11:46:03 +02001821 int err;
Libin Yang91520852017-01-12 16:04:53 +08001822 int dev_num, i;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001823
Takashi Iwaiefc2f8de2012-11-21 14:27:37 +01001824 caps = snd_hda_query_pin_caps(codec, pin_nid);
Stephen Warren384a48d2011-06-01 11:14:21 -06001825 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
1826 return 0;
1827
Libin Yang91520852017-01-12 16:04:53 +08001828 /*
1829 * For DP MST audio, Configuration Default is the same for
1830 * all device entries on the same pin
1831 */
Takashi Iwaiefc2f8de2012-11-21 14:27:37 +01001832 config = snd_hda_codec_get_pincfg(codec, pin_nid);
Kai-Heng Fengcd72c312020-08-04 23:58:34 +08001833 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE &&
1834 !spec->force_connect)
Stephen Warren384a48d2011-06-01 11:14:21 -06001835 return 0;
1836
Libin Yang91520852017-01-12 16:04:53 +08001837 /*
1838 * To simplify the implementation, malloc all
1839 * the virtual pins in the initialization statically
1840 */
Takashi Iwaicb457222019-11-11 20:09:37 +01001841 if (spec->intel_hsw_fixup) {
Libin Yang91520852017-01-12 16:04:53 +08001842 /*
1843 * On Intel platforms, device entries number is
1844 * changed dynamically. If there is a DP MST
1845 * hub connected, the device entries number is 3.
1846 * Otherwise, it is 1.
1847 * Here we manually set dev_num to 3, so that
1848 * we can initialize all the device entries when
1849 * bootup statically.
1850 */
1851 dev_num = 3;
1852 spec->dev_num = 3;
1853 } else if (spec->dyn_pcm_assign && codec->dp_mst) {
1854 dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1;
1855 /*
1856 * spec->dev_num is the maxinum number of device entries
1857 * among all the pins
1858 */
1859 spec->dev_num = (spec->dev_num > dev_num) ?
1860 spec->dev_num : dev_num;
1861 } else {
1862 /*
1863 * If the platform doesn't support DP MST,
1864 * manually set dev_num to 1. This means
1865 * the pin has only one device entry.
1866 */
1867 dev_num = 1;
1868 spec->dev_num = 1;
Libin Yang2bea2412016-01-12 11:13:26 +08001869 }
Wu Fengguang079d88c2010-03-08 10:44:23 +08001870
Libin Yang91520852017-01-12 16:04:53 +08001871 for (i = 0; i < dev_num; i++) {
1872 pin_idx = spec->num_pins;
1873 per_pin = snd_array_new(&spec->pins);
Wu Fengguang079d88c2010-03-08 10:44:23 +08001874
Libin Yang91520852017-01-12 16:04:53 +08001875 if (!per_pin)
1876 return -ENOMEM;
1877
1878 if (spec->dyn_pcm_assign) {
1879 per_pin->pcm = NULL;
1880 per_pin->pcm_idx = -1;
1881 } else {
1882 per_pin->pcm = get_hdmi_pcm(spec, pin_idx);
1883 per_pin->pcm_idx = pin_idx;
1884 }
1885 per_pin->pin_nid = pin_nid;
1886 per_pin->pin_nid_idx = spec->num_nids;
1887 per_pin->dev_id = i;
1888 per_pin->non_pcm = false;
1889 snd_hda_set_dev_select(codec, pin_nid, i);
Libin Yang91520852017-01-12 16:04:53 +08001890 err = hdmi_read_pin_conn(codec, pin_idx);
1891 if (err < 0)
1892 return err;
1893 spec->num_pins++;
1894 }
1895 spec->num_nids++;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001896
Stephen Warren384a48d2011-06-01 11:14:21 -06001897 return 0;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001898}
1899
Stephen Warren384a48d2011-06-01 11:14:21 -06001900static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
Wu Fengguang079d88c2010-03-08 10:44:23 +08001901{
1902 struct hdmi_spec *spec = codec->spec;
Stephen Warren384a48d2011-06-01 11:14:21 -06001903 struct hdmi_spec_per_cvt *per_cvt;
1904 unsigned int chans;
1905 int err;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001906
Stephen Warren384a48d2011-06-01 11:14:21 -06001907 chans = get_wcaps(codec, cvt_nid);
1908 chans = get_wcaps_channels(chans);
1909
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01001910 per_cvt = snd_array_new(&spec->cvts);
1911 if (!per_cvt)
1912 return -ENOMEM;
Stephen Warren384a48d2011-06-01 11:14:21 -06001913
1914 per_cvt->cvt_nid = cvt_nid;
1915 per_cvt->channels_min = 2;
Takashi Iwaid45e6882012-07-31 11:36:00 +02001916 if (chans <= 16) {
Stephen Warren384a48d2011-06-01 11:14:21 -06001917 per_cvt->channels_max = chans;
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05301918 if (chans > spec->chmap.channels_max)
1919 spec->chmap.channels_max = chans;
Takashi Iwaid45e6882012-07-31 11:36:00 +02001920 }
Stephen Warren384a48d2011-06-01 11:14:21 -06001921
1922 err = snd_hda_query_supported_pcm(codec, cvt_nid,
1923 &per_cvt->rates,
1924 &per_cvt->formats,
1925 &per_cvt->maxbps);
1926 if (err < 0)
1927 return err;
1928
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01001929 if (spec->num_cvts < ARRAY_SIZE(spec->cvt_nids))
1930 spec->cvt_nids[spec->num_cvts] = cvt_nid;
1931 spec->num_cvts++;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001932
1933 return 0;
1934}
1935
Kai-Heng Fengcd72c312020-08-04 23:58:34 +08001936static const struct snd_pci_quirk force_connect_list[] = {
Kai-Heng Fengd96f27c2020-08-11 17:53:34 +08001937 SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
Kai-Heng Fengcd72c312020-08-04 23:58:34 +08001938 SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
1939 {}
1940};
1941
Wu Fengguang079d88c2010-03-08 10:44:23 +08001942static int hdmi_parse_codec(struct hda_codec *codec)
1943{
Kai-Heng Fengcd72c312020-08-04 23:58:34 +08001944 struct hdmi_spec *spec = codec->spec;
Kai Vehmanen56275032020-07-03 18:38:17 +03001945 hda_nid_t start_nid;
1946 unsigned int caps;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001947 int i, nodes;
Kai-Heng Fengcd72c312020-08-04 23:58:34 +08001948 const struct snd_pci_quirk *q;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001949
Kai Vehmanen56275032020-07-03 18:38:17 +03001950 nodes = snd_hda_get_sub_nodes(codec, codec->core.afg, &start_nid);
1951 if (!start_nid || nodes < 0) {
Takashi Iwai4e76a882014-02-25 12:21:03 +01001952 codec_warn(codec, "HDMI: failed to get afg sub nodes\n");
Wu Fengguang079d88c2010-03-08 10:44:23 +08001953 return -EINVAL;
1954 }
1955
Kai-Heng Fengcd72c312020-08-04 23:58:34 +08001956 q = snd_pci_quirk_lookup(codec->bus->pci, force_connect_list);
1957
1958 if (q && q->value)
1959 spec->force_connect = true;
1960
Kai Vehmanen56275032020-07-03 18:38:17 +03001961 /*
1962 * hdmi_add_pin() assumes total amount of converters to
1963 * be known, so first discover all converters
1964 */
1965 for (i = 0; i < nodes; i++) {
1966 hda_nid_t nid = start_nid + i;
Wu Fengguang079d88c2010-03-08 10:44:23 +08001967
Takashi Iwaiefc2f8de2012-11-21 14:27:37 +01001968 caps = get_wcaps(codec, nid);
Wu Fengguang079d88c2010-03-08 10:44:23 +08001969
1970 if (!(caps & AC_WCAP_DIGITAL))
1971 continue;
1972
Kai Vehmanen56275032020-07-03 18:38:17 +03001973 if (get_wcaps_type(caps) == AC_WID_AUD_OUT)
Stephen Warren384a48d2011-06-01 11:14:21 -06001974 hdmi_add_cvt(codec, nid);
Kai Vehmanen56275032020-07-03 18:38:17 +03001975 }
1976
1977 /* discover audio pins */
1978 for (i = 0; i < nodes; i++) {
1979 hda_nid_t nid = start_nid + i;
1980
1981 caps = get_wcaps(codec, nid);
1982
1983 if (!(caps & AC_WCAP_DIGITAL))
1984 continue;
1985
1986 if (get_wcaps_type(caps) == AC_WID_PIN)
Wu Fengguang3eaead52010-05-14 16:36:15 +08001987 hdmi_add_pin(codec, nid);
Wu Fengguang079d88c2010-03-08 10:44:23 +08001988 }
1989
Wu Fengguang079d88c2010-03-08 10:44:23 +08001990 return 0;
1991}
1992
Takashi Iwai84eb01b2010-09-07 12:27:25 +02001993/*
1994 */
Takashi Iwai1a6003b2012-09-06 17:42:08 +02001995static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1996{
1997 struct hda_spdif_out *spdif;
1998 bool non_pcm;
1999
2000 mutex_lock(&codec->spdif_mutex);
2001 spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
Libin Yang960a5812016-06-16 11:13:25 +08002002 /* Add sanity check to pass klockwork check.
2003 * This should never happen.
2004 */
Wu Boa2f647242020-04-26 21:17:22 +08002005 if (WARN_ON(spdif == NULL)) {
2006 mutex_unlock(&codec->spdif_mutex);
Libin Yang960a5812016-06-16 11:13:25 +08002007 return true;
Wu Boa2f647242020-04-26 21:17:22 +08002008 }
Takashi Iwai1a6003b2012-09-06 17:42:08 +02002009 non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
2010 mutex_unlock(&codec->spdif_mutex);
2011 return non_pcm;
2012}
2013
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002014/*
2015 * HDMI callbacks
2016 */
2017
2018static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2019 struct hda_codec *codec,
2020 unsigned int stream_tag,
2021 unsigned int format,
2022 struct snd_pcm_substream *substream)
2023{
Stephen Warren384a48d2011-06-01 11:14:21 -06002024 hda_nid_t cvt_nid = hinfo->nid;
2025 struct hdmi_spec *spec = codec->spec;
Libin Yang42b29872015-12-16 13:42:42 +08002026 int pin_idx;
2027 struct hdmi_spec_per_pin *per_pin;
Libin Yangddd621f2015-09-02 14:11:40 +08002028 struct snd_pcm_runtime *runtime = substream->runtime;
Takashi Iwai1a6003b2012-09-06 17:42:08 +02002029 bool non_pcm;
Sameer Pujar053b0552019-01-14 23:51:12 +05302030 int pinctl, stripe;
Takashi Iwaif69548f2018-07-12 23:06:51 +02002031 int err = 0;
Takashi Iwai1a6003b2012-09-06 17:42:08 +02002032
Libin Yang42b29872015-12-16 13:42:42 +08002033 mutex_lock(&spec->pcm_lock);
2034 pin_idx = hinfo_to_pin_index(codec, hinfo);
2035 if (spec->dyn_pcm_assign && pin_idx < 0) {
2036 /* when dyn_pcm_assign and pcm is not bound to a pin
2037 * skip pin setup and return 0 to make audio playback
2038 * be ongoing
2039 */
Takashi Iwai4846a672016-03-21 12:56:46 +01002040 pin_cvt_fixup(codec, NULL, cvt_nid);
Libin Yang42b29872015-12-16 13:42:42 +08002041 snd_hda_codec_setup_stream(codec, cvt_nid,
2042 stream_tag, 0, format);
Takashi Iwaif69548f2018-07-12 23:06:51 +02002043 goto unlock;
Libin Yang42b29872015-12-16 13:42:42 +08002044 }
2045
2046 if (snd_BUG_ON(pin_idx < 0)) {
Takashi Iwaif69548f2018-07-12 23:06:51 +02002047 err = -EINVAL;
2048 goto unlock;
Libin Yang42b29872015-12-16 13:42:42 +08002049 }
2050 per_pin = get_pin(spec, pin_idx);
Takashi Iwai4846a672016-03-21 12:56:46 +01002051
2052 /* Verify pin:cvt selections to avoid silent audio after S3.
2053 * After S3, the audio driver restores pin:cvt selections
2054 * but this can happen before gfx is ready and such selection
2055 * is overlooked by HW. Thus multiple pins can share a same
2056 * default convertor and mute control will affect each other,
2057 * which can cause a resumed audio playback become silent
2058 * after S3.
2059 */
2060 pin_cvt_fixup(codec, per_pin, 0);
Mengdong Lin2df67422014-03-20 13:01:06 +08002061
Libin Yangddd621f2015-09-02 14:11:40 +08002062 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */
2063 /* Todo: add DP1.2 MST audio support later */
Takashi Iwai93a9ff12016-03-18 19:45:13 +01002064 if (codec_has_acomp(codec))
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302065 snd_hdac_sync_audio_rate(&codec->core, per_pin->pin_nid,
2066 per_pin->dev_id, runtime->rate);
Libin Yangddd621f2015-09-02 14:11:40 +08002067
Takashi Iwai1a6003b2012-09-06 17:42:08 +02002068 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002069 mutex_lock(&per_pin->lock);
Takashi Iwaib0540872013-09-02 12:33:02 +02002070 per_pin->channels = substream->runtime->channels;
2071 per_pin->setup = true;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002072
Sameer Pujar053b0552019-01-14 23:51:12 +05302073 if (get_wcaps(codec, cvt_nid) & AC_WCAP_STRIPE) {
2074 stripe = snd_hdac_get_stream_stripe_ctl(&codec->bus->core,
2075 substream);
2076 snd_hda_codec_write(codec, cvt_nid, 0,
2077 AC_VERB_SET_STRIPE_CONTROL,
2078 stripe);
2079 }
2080
Takashi Iwaib0540872013-09-02 12:33:02 +02002081 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002082 mutex_unlock(&per_pin->lock);
Stephen Warren75fae112014-01-30 11:52:16 -07002083 if (spec->dyn_pin_out) {
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302084 snd_hda_set_dev_select(codec, per_pin->pin_nid,
2085 per_pin->dev_id);
2086 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
Stephen Warren75fae112014-01-30 11:52:16 -07002087 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302088 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
Stephen Warren75fae112014-01-30 11:52:16 -07002089 AC_VERB_SET_PIN_WIDGET_CONTROL,
2090 pinctl | PIN_OUT);
2091 }
2092
Libin Yang91520852017-01-12 16:04:53 +08002093 /* snd_hda_set_dev_select() has been called before */
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302094 err = spec->ops.setup_stream(codec, cvt_nid, per_pin->pin_nid,
2095 per_pin->dev_id, stream_tag, format);
Takashi Iwaif69548f2018-07-12 23:06:51 +02002096 unlock:
Libin Yang42b29872015-12-16 13:42:42 +08002097 mutex_unlock(&spec->pcm_lock);
2098 return err;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002099}
2100
Takashi Iwai8dfaa572012-08-06 14:49:36 +02002101static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2102 struct hda_codec *codec,
2103 struct snd_pcm_substream *substream)
2104{
2105 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
2106 return 0;
2107}
2108
Takashi Iwaif2ad24f2012-07-26 18:08:14 +02002109static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
2110 struct hda_codec *codec,
2111 struct snd_pcm_substream *substream)
Stephen Warren384a48d2011-06-01 11:14:21 -06002112{
2113 struct hdmi_spec *spec = codec->spec;
Libin Yang2bf3c852015-12-16 13:42:43 +08002114 int cvt_idx, pin_idx, pcm_idx;
Stephen Warren384a48d2011-06-01 11:14:21 -06002115 struct hdmi_spec_per_cvt *per_cvt;
2116 struct hdmi_spec_per_pin *per_pin;
Stephen Warren75fae112014-01-30 11:52:16 -07002117 int pinctl;
Takashi Iwaif69548f2018-07-12 23:06:51 +02002118 int err = 0;
Stephen Warren384a48d2011-06-01 11:14:21 -06002119
Kai Vehmanence1558c2020-10-13 18:26:28 +03002120 mutex_lock(&spec->pcm_lock);
Stephen Warren384a48d2011-06-01 11:14:21 -06002121 if (hinfo->nid) {
Libin Yang2bf3c852015-12-16 13:42:43 +08002122 pcm_idx = hinfo_to_pcm_index(codec, hinfo);
Kai Vehmanence1558c2020-10-13 18:26:28 +03002123 if (snd_BUG_ON(pcm_idx < 0)) {
2124 err = -EINVAL;
2125 goto unlock;
2126 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01002127 cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid);
Kai Vehmanence1558c2020-10-13 18:26:28 +03002128 if (snd_BUG_ON(cvt_idx < 0)) {
2129 err = -EINVAL;
2130 goto unlock;
2131 }
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002132 per_cvt = get_cvt(spec, cvt_idx);
Stephen Warren384a48d2011-06-01 11:14:21 -06002133 per_cvt->assigned = 0;
2134 hinfo->nid = 0;
2135
Takashi Iwai6fd739c2019-12-14 18:52:17 +01002136 azx_stream(get_azx_dev(substream))->stripe = 0;
2137
Libin Yangb09887f82016-01-29 13:53:27 +08002138 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
Libin Yangac983792015-12-16 16:48:16 +08002139 clear_bit(pcm_idx, &spec->pcm_in_use);
Takashi Iwai4e76a882014-02-25 12:21:03 +01002140 pin_idx = hinfo_to_pin_index(codec, hinfo);
Takashi Iwaif69548f2018-07-12 23:06:51 +02002141 if (spec->dyn_pcm_assign && pin_idx < 0)
2142 goto unlock;
Libin Yang42b29872015-12-16 13:42:42 +08002143
2144 if (snd_BUG_ON(pin_idx < 0)) {
Takashi Iwaif69548f2018-07-12 23:06:51 +02002145 err = -EINVAL;
2146 goto unlock;
Libin Yang42b29872015-12-16 13:42:42 +08002147 }
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002148 per_pin = get_pin(spec, pin_idx);
Stephen Warren384a48d2011-06-01 11:14:21 -06002149
Stephen Warren75fae112014-01-30 11:52:16 -07002150 if (spec->dyn_pin_out) {
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302151 snd_hda_set_dev_select(codec, per_pin->pin_nid,
2152 per_pin->dev_id);
Stephen Warren75fae112014-01-30 11:52:16 -07002153 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
2154 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2155 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
2156 AC_VERB_SET_PIN_WIDGET_CONTROL,
2157 pinctl & ~PIN_OUT);
2158 }
2159
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002160 mutex_lock(&per_pin->lock);
Takashi Iwaid45e6882012-07-31 11:36:00 +02002161 per_pin->chmap_set = false;
2162 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
Takashi Iwaib0540872013-09-02 12:33:02 +02002163
2164 per_pin->setup = false;
2165 per_pin->channels = 0;
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002166 mutex_unlock(&per_pin->lock);
Stephen Warren384a48d2011-06-01 11:14:21 -06002167 }
Takashi Iwaid45e6882012-07-31 11:36:00 +02002168
Kai Vehmanence1558c2020-10-13 18:26:28 +03002169unlock:
2170 mutex_unlock(&spec->pcm_lock);
2171
Takashi Iwaif69548f2018-07-12 23:06:51 +02002172 return err;
Stephen Warren384a48d2011-06-01 11:14:21 -06002173}
2174
2175static const struct hda_pcm_ops generic_ops = {
2176 .open = hdmi_pcm_open,
Takashi Iwaif2ad24f2012-07-26 18:08:14 +02002177 .close = hdmi_pcm_close,
Stephen Warren384a48d2011-06-01 11:14:21 -06002178 .prepare = generic_hdmi_playback_pcm_prepare,
Takashi Iwai8dfaa572012-08-06 14:49:36 +02002179 .cleanup = generic_hdmi_playback_pcm_cleanup,
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002180};
2181
Subhransu S. Prusty44fde3b2016-04-04 19:23:54 +05302182static int hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
2183{
Kai-Heng Feng8c118272020-05-05 11:03:53 +08002184 struct hda_codec *codec = hdac_to_hda_codec(hdac);
Subhransu S. Prusty44fde3b2016-04-04 19:23:54 +05302185 struct hdmi_spec *spec = codec->spec;
2186 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
2187
2188 if (!per_pin)
2189 return 0;
2190
2191 return per_pin->sink_eld.info.spk_alloc;
2192}
2193
Subhransu S. Prusty9b3dc8a2016-03-04 19:59:47 +05302194static void hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
2195 unsigned char *chmap)
2196{
Kai-Heng Feng8c118272020-05-05 11:03:53 +08002197 struct hda_codec *codec = hdac_to_hda_codec(hdac);
Subhransu S. Prusty9b3dc8a2016-03-04 19:59:47 +05302198 struct hdmi_spec *spec = codec->spec;
2199 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
2200
2201 /* chmap is already set to 0 in caller */
2202 if (!per_pin)
2203 return;
2204
2205 memcpy(chmap, per_pin->chmap, ARRAY_SIZE(per_pin->chmap));
2206}
2207
2208static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
2209 unsigned char *chmap, int prepared)
2210{
Kai-Heng Feng8c118272020-05-05 11:03:53 +08002211 struct hda_codec *codec = hdac_to_hda_codec(hdac);
Subhransu S. Prusty9b3dc8a2016-03-04 19:59:47 +05302212 struct hdmi_spec *spec = codec->spec;
2213 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
2214
Libin Yanged0739b2016-04-18 09:16:28 +08002215 if (!per_pin)
2216 return;
Subhransu S. Prusty9b3dc8a2016-03-04 19:59:47 +05302217 mutex_lock(&per_pin->lock);
2218 per_pin->chmap_set = true;
2219 memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap));
2220 if (prepared)
2221 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
2222 mutex_unlock(&per_pin->lock);
2223}
2224
2225static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
2226{
Kai-Heng Feng8c118272020-05-05 11:03:53 +08002227 struct hda_codec *codec = hdac_to_hda_codec(hdac);
Subhransu S. Prusty9b3dc8a2016-03-04 19:59:47 +05302228 struct hdmi_spec *spec = codec->spec;
2229 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
2230
2231 return per_pin ? true:false;
2232}
2233
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002234static int generic_hdmi_build_pcms(struct hda_codec *codec)
2235{
2236 struct hdmi_spec *spec = codec->spec;
Kai Vehmanen2a2edfb2019-10-29 15:40:09 +02002237 int idx, pcm_num;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002238
Libin Yang91520852017-01-12 16:04:53 +08002239 /*
2240 * for non-mst mode, pcm number is the same as before
Kai Vehmanen2a2edfb2019-10-29 15:40:09 +02002241 * for DP MST mode without extra PCM, pcm number is same
2242 * for DP MST mode with extra PCMs, pcm number is
2243 * (nid number + dev_num - 1)
2244 * dev_num is the device entry number in a pin
Libin Yang91520852017-01-12 16:04:53 +08002245 */
Kai Vehmanen2a2edfb2019-10-29 15:40:09 +02002246
2247 if (codec->mst_no_extra_pcms)
2248 pcm_num = spec->num_nids;
2249 else
2250 pcm_num = spec->num_nids + spec->dev_num - 1;
2251
2252 codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
2253
2254 for (idx = 0; idx < pcm_num; idx++) {
Stephen Warren384a48d2011-06-01 11:14:21 -06002255 struct hda_pcm *info;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002256 struct hda_pcm_stream *pstr;
2257
Libin Yang91520852017-01-12 16:04:53 +08002258 info = snd_hda_codec_pcm_new(codec, "HDMI %d", idx);
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002259 if (!info)
2260 return -ENOMEM;
Libin Yang2bea2412016-01-12 11:13:26 +08002261
Libin Yang91520852017-01-12 16:04:53 +08002262 spec->pcm_rec[idx].pcm = info;
Libin Yang2bf3c852015-12-16 13:42:43 +08002263 spec->pcm_used++;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002264 info->pcm_type = HDA_PCM_TYPE_HDMI;
Takashi Iwaid45e6882012-07-31 11:36:00 +02002265 info->own_chmap = true;
Stephen Warren384a48d2011-06-01 11:14:21 -06002266
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002267 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
Stephen Warren384a48d2011-06-01 11:14:21 -06002268 pstr->substreams = 1;
2269 pstr->ops = generic_ops;
Libin Yang91520852017-01-12 16:04:53 +08002270 /* pcm number is less than 16 */
2271 if (spec->pcm_used >= 16)
2272 break;
Stephen Warren384a48d2011-06-01 11:14:21 -06002273 /* other pstr fields are set in open */
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002274 }
2275
2276 return 0;
2277}
2278
Libin Yang25e4abb2016-01-12 11:13:27 +08002279static void free_hdmi_jack_priv(struct snd_jack *jack)
Takashi Iwai788d4412015-11-12 15:36:13 +01002280{
Libin Yang25e4abb2016-01-12 11:13:27 +08002281 struct hdmi_pcm *pcm = jack->private_data;
Takashi Iwai788d4412015-11-12 15:36:13 +01002282
Libin Yang25e4abb2016-01-12 11:13:27 +08002283 pcm->jack = NULL;
Takashi Iwai788d4412015-11-12 15:36:13 +01002284}
2285
Takashi Iwaidb845402020-02-06 17:28:02 +01002286static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
Takashi Iwai788d4412015-11-12 15:36:13 +01002287{
Takashi Iwaidb845402020-02-06 17:28:02 +01002288 char hdmi_str[32] = "HDMI/DP";
2289 struct hdmi_spec *spec = codec->spec;
2290 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pcm_idx);
Takashi Iwai788d4412015-11-12 15:36:13 +01002291 struct snd_jack *jack;
Takashi Iwaidb845402020-02-06 17:28:02 +01002292 int pcmdev = get_pcm_rec(spec, pcm_idx)->device;
Takashi Iwai788d4412015-11-12 15:36:13 +01002293 int err;
2294
Takashi Iwaidb845402020-02-06 17:28:02 +01002295 if (pcmdev > 0)
2296 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
2297 if (!spec->dyn_pcm_assign &&
2298 !is_jack_detectable(codec, per_pin->pin_nid))
2299 strncat(hdmi_str, " Phantom",
2300 sizeof(hdmi_str) - strlen(hdmi_str) - 1);
2301
2302 err = snd_jack_new(codec->card, hdmi_str, SND_JACK_AVOUT, &jack,
Takashi Iwai788d4412015-11-12 15:36:13 +01002303 true, false);
2304 if (err < 0)
2305 return err;
Libin Yang25e4abb2016-01-12 11:13:27 +08002306
2307 spec->pcm_rec[pcm_idx].jack = jack;
2308 jack->private_data = &spec->pcm_rec[pcm_idx];
2309 jack->private_free = free_hdmi_jack_priv;
Takashi Iwai788d4412015-11-12 15:36:13 +01002310 return 0;
2311}
2312
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002313static int generic_hdmi_build_controls(struct hda_codec *codec)
2314{
2315 struct hdmi_spec *spec = codec->spec;
Wang YanQing1f7f51a2017-09-03 21:18:49 +08002316 int dev, err;
Libin Yang25e4abb2016-01-12 11:13:27 +08002317 int pin_idx, pcm_idx;
2318
Libin Yang25e4abb2016-01-12 11:13:27 +08002319 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
Takashi Iwai8a7d6002018-04-25 16:19:13 +02002320 if (!get_pcm_rec(spec, pcm_idx)->pcm) {
2321 /* no PCM: mark this for skipping permanently */
2322 set_bit(pcm_idx, &spec->pcm_bitmap);
2323 continue;
2324 }
2325
Libin Yang25e4abb2016-01-12 11:13:27 +08002326 err = generic_hdmi_build_jack(codec, pcm_idx);
2327 if (err < 0)
2328 return err;
Libin Yangb09887f82016-01-29 13:53:27 +08002329
2330 /* create the spdif for each pcm
2331 * pin will be bound when monitor is connected
2332 */
2333 if (spec->dyn_pcm_assign)
2334 err = snd_hda_create_dig_out_ctls(codec,
2335 0, spec->cvt_nids[0],
2336 HDA_PCM_TYPE_HDMI);
2337 else {
2338 struct hdmi_spec_per_pin *per_pin =
2339 get_pin(spec, pcm_idx);
2340 err = snd_hda_create_dig_out_ctls(codec,
2341 per_pin->pin_nid,
2342 per_pin->mux_nids[0],
2343 HDA_PCM_TYPE_HDMI);
2344 }
2345 if (err < 0)
2346 return err;
2347 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
Libin Yangfb087ea2016-02-23 16:33:37 +08002348
Wang YanQing1f7f51a2017-09-03 21:18:49 +08002349 dev = get_pcm_rec(spec, pcm_idx)->device;
2350 if (dev != SNDRV_PCM_INVALID_DEVICE) {
2351 /* add control for ELD Bytes */
2352 err = hdmi_create_eld_ctl(codec, pcm_idx, dev);
2353 if (err < 0)
2354 return err;
2355 }
Libin Yang25e4abb2016-01-12 11:13:27 +08002356 }
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002357
Stephen Warren384a48d2011-06-01 11:14:21 -06002358 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002359 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
Kai Vehmanenca762822020-04-28 15:38:36 +03002360 struct hdmi_eld *pin_eld = &per_pin->sink_eld;
David Henningsson0b6c49b2011-08-23 16:56:03 +02002361
Kai Vehmanenca762822020-04-28 15:38:36 +03002362 pin_eld->eld_valid = false;
Takashi Iwai82b1d732011-12-20 15:53:07 +01002363 hdmi_present_sense(per_pin, 0);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002364 }
2365
Takashi Iwaid45e6882012-07-31 11:36:00 +02002366 /* add channel maps */
Libin Yang022f3442016-02-03 10:48:34 +08002367 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01002368 struct hda_pcm *pcm;
Takashi Iwai2ca320e2013-08-22 09:55:36 +02002369
Libin Yang022f3442016-02-03 10:48:34 +08002370 pcm = get_pcm_rec(spec, pcm_idx);
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01002371 if (!pcm || !pcm->pcm)
Takashi Iwai2ca320e2013-08-22 09:55:36 +02002372 break;
Subhransu S. Prusty2f6e8a82016-03-04 19:59:51 +05302373 err = snd_hdac_add_chmap_ctls(pcm->pcm, pcm_idx, &spec->chmap);
Takashi Iwaid45e6882012-07-31 11:36:00 +02002374 if (err < 0)
2375 return err;
Takashi Iwaid45e6882012-07-31 11:36:00 +02002376 }
2377
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002378 return 0;
2379}
2380
Takashi Iwai8b8d654b2012-06-20 16:32:22 +02002381static int generic_hdmi_init_per_pins(struct hda_codec *codec)
2382{
2383 struct hdmi_spec *spec = codec->spec;
2384 int pin_idx;
2385
2386 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002387 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
Takashi Iwai8b8d654b2012-06-20 16:32:22 +02002388
2389 per_pin->codec = codec;
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002390 mutex_init(&per_pin->lock);
Takashi Iwai8b8d654b2012-06-20 16:32:22 +02002391 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002392 eld_proc_new(per_pin, pin_idx);
Takashi Iwai8b8d654b2012-06-20 16:32:22 +02002393 }
2394 return 0;
2395}
2396
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002397static int generic_hdmi_init(struct hda_codec *codec)
2398{
2399 struct hdmi_spec *spec = codec->spec;
Stephen Warren384a48d2011-06-01 11:14:21 -06002400 int pin_idx;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002401
Takashi Iwai302d5a82019-10-29 21:41:20 +01002402 mutex_lock(&spec->bind_lock);
Stephen Warren384a48d2011-06-01 11:14:21 -06002403 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002404 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
Stephen Warren384a48d2011-06-01 11:14:21 -06002405 hda_nid_t pin_nid = per_pin->pin_nid;
Libin Yang91520852017-01-12 16:04:53 +08002406 int dev_id = per_pin->dev_id;
Stephen Warren384a48d2011-06-01 11:14:21 -06002407
Libin Yang91520852017-01-12 16:04:53 +08002408 snd_hda_set_dev_select(codec, pin_nid, dev_id);
Stephen Warren384a48d2011-06-01 11:14:21 -06002409 hdmi_init_pin(codec, pin_nid);
Takashi Iwaiade49db2018-07-11 18:05:52 +02002410 if (codec_has_acomp(codec))
2411 continue;
Takashi Iwaidb845402020-02-06 17:28:02 +01002412 snd_hda_jack_detect_enable_callback_mst(codec, pin_nid, dev_id,
2413 jack_callback);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002414 }
Takashi Iwai302d5a82019-10-29 21:41:20 +01002415 mutex_unlock(&spec->bind_lock);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002416 return 0;
2417}
2418
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002419static void hdmi_array_init(struct hdmi_spec *spec, int nums)
2420{
2421 snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums);
2422 snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums);
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002423}
2424
2425static void hdmi_array_free(struct hdmi_spec *spec)
2426{
2427 snd_array_free(&spec->pins);
2428 snd_array_free(&spec->cvts);
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002429}
2430
Takashi Iwaia6866322016-03-21 12:18:33 +01002431static void generic_spec_free(struct hda_codec *codec)
2432{
2433 struct hdmi_spec *spec = codec->spec;
2434
2435 if (spec) {
2436 hdmi_array_free(spec);
2437 kfree(spec);
2438 codec->spec = NULL;
2439 }
2440 codec->dp_mst = false;
2441}
2442
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002443static void generic_hdmi_free(struct hda_codec *codec)
2444{
2445 struct hdmi_spec *spec = codec->spec;
Libin Yang25e4abb2016-01-12 11:13:27 +08002446 int pin_idx, pcm_idx;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002447
Takashi Iwaiade49db2018-07-11 18:05:52 +02002448 if (spec->acomp_registered) {
2449 snd_hdac_acomp_exit(&codec->bus->core);
2450 } else if (codec_has_acomp(codec)) {
Takashi Iwaia57942b2018-07-11 16:23:16 +02002451 snd_hdac_acomp_register_notifier(&codec->bus->core, NULL);
Takashi Iwai4914da22019-07-16 08:56:51 +02002452 }
Takashi Iwai10a95942019-11-22 14:26:24 +01002453 codec->relaxed_resume = 0;
David Henningsson25adc132015-08-19 10:48:58 +02002454
Stephen Warren384a48d2011-06-01 11:14:21 -06002455 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01002456 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
Takashi Iwai2f35c632015-02-27 22:43:26 +01002457 cancel_delayed_work_sync(&per_pin->work);
Takashi Iwaia4e9a382013-10-17 18:21:12 +02002458 eld_proc_free(per_pin);
Libin Yang25e4abb2016-01-12 11:13:27 +08002459 }
2460
2461 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
2462 if (spec->pcm_rec[pcm_idx].jack == NULL)
2463 continue;
2464 if (spec->dyn_pcm_assign)
2465 snd_device_free(codec->card,
2466 spec->pcm_rec[pcm_idx].jack);
2467 else
2468 spec->pcm_rec[pcm_idx].jack = NULL;
Stephen Warren384a48d2011-06-01 11:14:21 -06002469 }
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002470
Takashi Iwaia6866322016-03-21 12:18:33 +01002471 generic_spec_free(codec);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002472}
2473
Wang Xingchao28cb72e2013-06-24 07:45:23 -04002474#ifdef CONFIG_PM
2475static int generic_hdmi_resume(struct hda_codec *codec)
2476{
2477 struct hdmi_spec *spec = codec->spec;
2478 int pin_idx;
2479
Pierre Ossmana2833682014-06-18 21:48:09 +02002480 codec->patch_ops.init(codec);
Takashi Iwai1a462be2020-01-09 10:01:04 +01002481 snd_hda_regmap_sync(codec);
Wang Xingchao28cb72e2013-06-24 07:45:23 -04002482
2483 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2484 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2485 hdmi_present_sense(per_pin, 1);
2486 }
2487 return 0;
2488}
2489#endif
2490
Takashi Iwaifb79e1e2011-05-02 12:17:41 +02002491static const struct hda_codec_ops generic_hdmi_patch_ops = {
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002492 .init = generic_hdmi_init,
2493 .free = generic_hdmi_free,
2494 .build_pcms = generic_hdmi_build_pcms,
2495 .build_controls = generic_hdmi_build_controls,
2496 .unsol_event = hdmi_unsol_event,
Wang Xingchao28cb72e2013-06-24 07:45:23 -04002497#ifdef CONFIG_PM
2498 .resume = generic_hdmi_resume,
2499#endif
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002500};
2501
Anssi Hannula307229d2013-10-24 21:10:34 +03002502static const struct hdmi_ops generic_standard_hdmi_ops = {
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302503 .pin_get_eld = hdmi_pin_get_eld,
Anssi Hannula307229d2013-10-24 21:10:34 +03002504 .pin_setup_infoframe = hdmi_pin_setup_infoframe,
2505 .pin_hbr_setup = hdmi_pin_hbr_setup,
2506 .setup_stream = hdmi_setup_stream,
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05302507};
2508
Takashi Iwaia6866322016-03-21 12:18:33 +01002509/* allocate codec->spec and assign/initialize generic parser ops */
2510static int alloc_generic_hdmi(struct hda_codec *codec)
2511{
2512 struct hdmi_spec *spec;
2513
2514 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2515 if (!spec)
2516 return -ENOMEM;
2517
Takashi Iwaiade49db2018-07-11 18:05:52 +02002518 spec->codec = codec;
Takashi Iwaia6866322016-03-21 12:18:33 +01002519 spec->ops = generic_standard_hdmi_ops;
Libin Yang91520852017-01-12 16:04:53 +08002520 spec->dev_num = 1; /* initialize to 1 */
Takashi Iwaia6866322016-03-21 12:18:33 +01002521 mutex_init(&spec->pcm_lock);
Takashi Iwai302d5a82019-10-29 21:41:20 +01002522 mutex_init(&spec->bind_lock);
Takashi Iwaia6866322016-03-21 12:18:33 +01002523 snd_hdac_register_chmap_ops(&codec->core, &spec->chmap);
2524
2525 spec->chmap.ops.get_chmap = hdmi_get_chmap;
2526 spec->chmap.ops.set_chmap = hdmi_set_chmap;
2527 spec->chmap.ops.is_pcm_attached = is_hdmi_pcm_attached;
Julia Lawall46394db2020-10-11 11:19:33 +02002528 spec->chmap.ops.get_spk_alloc = hdmi_get_spk_alloc;
Takashi Iwaia6866322016-03-21 12:18:33 +01002529
2530 codec->spec = spec;
2531 hdmi_array_init(spec, 4);
2532
2533 codec->patch_ops = generic_hdmi_patch_ops;
2534
2535 return 0;
2536}
2537
2538/* generic HDMI parser */
2539static int patch_generic_hdmi(struct hda_codec *codec)
2540{
2541 int err;
2542
2543 err = alloc_generic_hdmi(codec);
2544 if (err < 0)
2545 return err;
2546
2547 err = hdmi_parse_codec(codec);
2548 if (err < 0) {
2549 generic_spec_free(codec);
2550 return err;
2551 }
2552
2553 generic_hdmi_init_per_pins(codec);
2554 return 0;
2555}
2556
2557/*
Takashi Iwaiade49db2018-07-11 18:05:52 +02002558 * generic audio component binding
2559 */
2560
2561/* turn on / off the unsol event jack detection dynamically */
2562static void reprogram_jack_detect(struct hda_codec *codec, hda_nid_t nid,
Nikhil Mahale5204a052019-11-19 14:17:08 +05302563 int dev_id, bool use_acomp)
Takashi Iwaiade49db2018-07-11 18:05:52 +02002564{
2565 struct hda_jack_tbl *tbl;
2566
Nikhil Mahale5204a052019-11-19 14:17:08 +05302567 tbl = snd_hda_jack_tbl_get_mst(codec, nid, dev_id);
Takashi Iwaiade49db2018-07-11 18:05:52 +02002568 if (tbl) {
2569 /* clear unsol even if component notifier is used, or re-enable
2570 * if notifier is cleared
2571 */
2572 unsigned int val = use_acomp ? 0 : (AC_USRSP_EN | tbl->tag);
2573 snd_hda_codec_write_cache(codec, nid, 0,
2574 AC_VERB_SET_UNSOLICITED_ENABLE, val);
Takashi Iwaiade49db2018-07-11 18:05:52 +02002575 }
2576}
2577
2578/* set up / clear component notifier dynamically */
2579static void generic_acomp_notifier_set(struct drm_audio_component *acomp,
2580 bool use_acomp)
2581{
2582 struct hdmi_spec *spec;
2583 int i;
2584
2585 spec = container_of(acomp->audio_ops, struct hdmi_spec, drm_audio_ops);
Takashi Iwai302d5a82019-10-29 21:41:20 +01002586 mutex_lock(&spec->bind_lock);
Takashi Iwaiade49db2018-07-11 18:05:52 +02002587 spec->use_acomp_notifier = use_acomp;
2588 spec->codec->relaxed_resume = use_acomp;
Takashi Iwaic2c36572020-07-28 10:20:33 +02002589 spec->codec->bus->keep_power = 0;
Takashi Iwaiade49db2018-07-11 18:05:52 +02002590 /* reprogram each jack detection logic depending on the notifier */
Takashi Iwaidb845402020-02-06 17:28:02 +01002591 for (i = 0; i < spec->num_pins; i++)
2592 reprogram_jack_detect(spec->codec,
2593 get_pin(spec, i)->pin_nid,
2594 get_pin(spec, i)->dev_id,
2595 use_acomp);
Takashi Iwai302d5a82019-10-29 21:41:20 +01002596 mutex_unlock(&spec->bind_lock);
Takashi Iwaiade49db2018-07-11 18:05:52 +02002597}
2598
2599/* enable / disable the notifier via master bind / unbind */
2600static int generic_acomp_master_bind(struct device *dev,
2601 struct drm_audio_component *acomp)
2602{
2603 generic_acomp_notifier_set(acomp, true);
2604 return 0;
2605}
2606
2607static void generic_acomp_master_unbind(struct device *dev,
2608 struct drm_audio_component *acomp)
2609{
2610 generic_acomp_notifier_set(acomp, false);
2611}
2612
2613/* check whether both HD-audio and DRM PCI devices belong to the same bus */
2614static int match_bound_vga(struct device *dev, int subtype, void *data)
2615{
2616 struct hdac_bus *bus = data;
2617 struct pci_dev *pci, *master;
2618
2619 if (!dev_is_pci(dev) || !dev_is_pci(bus->dev))
2620 return 0;
2621 master = to_pci_dev(bus->dev);
2622 pci = to_pci_dev(dev);
2623 return master->bus == pci->bus;
2624}
2625
2626/* audio component notifier for AMD/Nvidia HDMI codecs */
2627static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)
2628{
2629 struct hda_codec *codec = audio_ptr;
2630 struct hdmi_spec *spec = codec->spec;
2631 hda_nid_t pin_nid = spec->port2pin(codec, port);
2632
2633 if (!pin_nid)
2634 return;
2635 if (get_wcaps_type(get_wcaps(codec, pin_nid)) != AC_WID_PIN)
2636 return;
2637 /* skip notification during system suspend (but not in runtime PM);
2638 * the state will be updated at resume
2639 */
2640 if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
2641 return;
2642 /* ditto during suspend/resume process itself */
2643 if (snd_hdac_is_in_pm(&codec->core))
2644 return;
2645
2646 check_presence_and_report(codec, pin_nid, dev_id);
2647}
2648
2649/* set up the private drm_audio_ops from the template */
2650static void setup_drm_audio_ops(struct hda_codec *codec,
2651 const struct drm_audio_component_audio_ops *ops)
2652{
2653 struct hdmi_spec *spec = codec->spec;
2654
2655 spec->drm_audio_ops.audio_ptr = codec;
2656 /* intel_audio_codec_enable() or intel_audio_codec_disable()
2657 * will call pin_eld_notify with using audio_ptr pointer
2658 * We need make sure audio_ptr is really setup
2659 */
2660 wmb();
2661 spec->drm_audio_ops.pin2port = ops->pin2port;
2662 spec->drm_audio_ops.pin_eld_notify = ops->pin_eld_notify;
2663 spec->drm_audio_ops.master_bind = ops->master_bind;
2664 spec->drm_audio_ops.master_unbind = ops->master_unbind;
2665}
2666
2667/* initialize the generic HDMI audio component */
2668static void generic_acomp_init(struct hda_codec *codec,
2669 const struct drm_audio_component_audio_ops *ops,
2670 int (*port2pin)(struct hda_codec *, int))
2671{
2672 struct hdmi_spec *spec = codec->spec;
2673
Takashi Iwaib3923502020-04-15 18:25:23 +02002674 if (!enable_acomp) {
2675 codec_info(codec, "audio component disabled by module option\n");
2676 return;
2677 }
2678
Takashi Iwaiade49db2018-07-11 18:05:52 +02002679 spec->port2pin = port2pin;
2680 setup_drm_audio_ops(codec, ops);
2681 if (!snd_hdac_acomp_init(&codec->bus->core, &spec->drm_audio_ops,
Takashi Iwaidd23e1d2019-08-27 16:37:50 +02002682 match_bound_vga, 0)) {
Takashi Iwaiade49db2018-07-11 18:05:52 +02002683 spec->acomp_registered = true;
Takashi Iwaidd23e1d2019-08-27 16:37:50 +02002684 }
Takashi Iwaiade49db2018-07-11 18:05:52 +02002685}
2686
2687/*
Takashi Iwaia6866322016-03-21 12:18:33 +01002688 * Intel codec parsers and helpers
2689 */
2690
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002691#define INTEL_GET_VENDOR_VERB 0xf81
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002692#define INTEL_SET_VENDOR_VERB 0x781
2693#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
2694#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
Mengdong Lin1611a9c2013-02-08 17:09:52 -05002695
2696static void intel_haswell_enable_all_pins(struct hda_codec *codec,
Takashi Iwai17df3f52013-05-08 08:09:34 +02002697 bool update_tree)
Mengdong Lin1611a9c2013-02-08 17:09:52 -05002698{
2699 unsigned int vendor_param;
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302700 struct hdmi_spec *spec = codec->spec;
Mengdong Lin1611a9c2013-02-08 17:09:52 -05002701
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302702 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
Mengdong Lin1611a9c2013-02-08 17:09:52 -05002703 INTEL_GET_VENDOR_VERB, 0);
2704 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
2705 return;
2706
2707 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302708 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
Mengdong Lin1611a9c2013-02-08 17:09:52 -05002709 INTEL_SET_VENDOR_VERB, vendor_param);
2710 if (vendor_param == -1)
2711 return;
2712
Takashi Iwai17df3f52013-05-08 08:09:34 +02002713 if (update_tree)
2714 snd_hda_codec_update_widgets(codec);
Mengdong Lin1611a9c2013-02-08 17:09:52 -05002715}
2716
Takashi Iwaic88d4e82013-02-08 17:10:04 -05002717static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec)
2718{
2719 unsigned int vendor_param;
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302720 struct hdmi_spec *spec = codec->spec;
Takashi Iwaic88d4e82013-02-08 17:10:04 -05002721
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302722 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
Takashi Iwaic88d4e82013-02-08 17:10:04 -05002723 INTEL_GET_VENDOR_VERB, 0);
2724 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
2725 return;
2726
2727 /* enable DP1.2 mode */
2728 vendor_param |= INTEL_EN_DP12;
Takashi Iwaia551d912015-02-26 12:34:49 +01002729 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB);
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302730 snd_hda_codec_write_cache(codec, spec->vendor_nid, 0,
Takashi Iwaic88d4e82013-02-08 17:10:04 -05002731 INTEL_SET_VENDOR_VERB, vendor_param);
2732}
2733
Takashi Iwai17df3f52013-05-08 08:09:34 +02002734/* Haswell needs to re-issue the vendor-specific verbs before turning to D0.
2735 * Otherwise you may get severe h/w communication errors.
2736 */
2737static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2738 unsigned int power_state)
2739{
2740 if (power_state == AC_PWRST_D0) {
2741 intel_haswell_enable_all_pins(codec, false);
2742 intel_haswell_fixup_enable_dp12(codec);
2743 }
Takashi Iwaic88d4e82013-02-08 17:10:04 -05002744
Takashi Iwai17df3f52013-05-08 08:09:34 +02002745 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, power_state);
2746 snd_hda_codec_set_power_to_all(codec, fg, power_state);
2747}
Mengdong Lin6ffe1682012-12-18 16:59:15 -05002748
Takashi Iwaia57942b2018-07-11 16:23:16 +02002749/* There is a fixed mapping between audio pin node and display port.
2750 * on SNB, IVY, HSW, BSW, SKL, BXT, KBL:
2751 * Pin Widget 5 - PORT B (port = 1 in i915 driver)
2752 * Pin Widget 6 - PORT C (port = 2 in i915 driver)
2753 * Pin Widget 7 - PORT D (port = 3 in i915 driver)
2754 *
2755 * on VLV, ILK:
2756 * Pin Widget 4 - PORT B (port = 1 in i915 driver)
2757 * Pin Widget 5 - PORT C (port = 2 in i915 driver)
2758 * Pin Widget 6 - PORT D (port = 3 in i915 driver)
2759 */
2760static int intel_base_nid(struct hda_codec *codec)
2761{
2762 switch (codec->core.vendor_id) {
2763 case 0x80860054: /* ILK */
2764 case 0x80862804: /* ILK */
2765 case 0x80862882: /* VLV */
2766 return 4;
2767 default:
2768 return 5;
2769 }
2770}
2771
2772static int intel_pin2port(void *audio_ptr, int pin_nid)
2773{
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002774 struct hda_codec *codec = audio_ptr;
2775 struct hdmi_spec *spec = codec->spec;
2776 int base_nid, i;
Takashi Iwaia57942b2018-07-11 16:23:16 +02002777
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002778 if (!spec->port_num) {
2779 base_nid = intel_base_nid(codec);
2780 if (WARN_ON(pin_nid < base_nid || pin_nid >= base_nid + 3))
2781 return -1;
Kai Vehmanenc8e3eb92019-11-15 14:44:48 +02002782 return pin_nid - base_nid + 1;
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002783 }
2784
2785 /*
2786 * looking for the pin number in the mapping table and return
2787 * the index which indicate the port number
2788 */
2789 for (i = 0; i < spec->port_num; i++) {
2790 if (pin_nid == spec->port_map[i])
Kai Vehmanend577cf72019-11-15 14:44:47 +02002791 return i;
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002792 }
2793
Kai Vehmanen13b1f8a2020-12-11 14:45:47 +02002794 codec_info(codec, "Can't find the HDMI/DP port for pin NID 0x%x\n", pin_nid);
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002795 return -1;
Takashi Iwaia57942b2018-07-11 16:23:16 +02002796}
2797
Takashi Iwai3140aaf2019-07-15 23:14:53 +02002798static int intel_port2pin(struct hda_codec *codec, int port)
2799{
2800 struct hdmi_spec *spec = codec->spec;
2801
2802 if (!spec->port_num) {
2803 /* we assume only from port-B to port-D */
2804 if (port < 1 || port > 3)
2805 return 0;
Takashi Iwai3140aaf2019-07-15 23:14:53 +02002806 return port + intel_base_nid(codec) - 1;
2807 }
2808
Kai Vehmanend577cf72019-11-15 14:44:47 +02002809 if (port < 0 || port >= spec->port_num)
Takashi Iwai3140aaf2019-07-15 23:14:53 +02002810 return 0;
Kai Vehmanend577cf72019-11-15 14:44:47 +02002811 return spec->port_map[port];
Takashi Iwai3140aaf2019-07-15 23:14:53 +02002812}
2813
Pandiyan, Dhinakaranf9318942016-09-21 13:02:48 -07002814static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
David Henningsson25adc132015-08-19 10:48:58 +02002815{
2816 struct hda_codec *codec = audio_ptr;
Takashi Iwai7ff652f2016-03-21 14:50:24 +01002817 int pin_nid;
Libin Yang91520852017-01-12 16:04:53 +08002818 int dev_id = pipe;
David Henningsson25adc132015-08-19 10:48:58 +02002819
Takashi Iwai3140aaf2019-07-15 23:14:53 +02002820 pin_nid = intel_port2pin(codec, port);
2821 if (!pin_nid)
Takashi Iwai4f8e4f32016-03-10 12:02:49 +01002822 return;
Takashi Iwai8ae743e2015-11-27 14:23:00 +01002823 /* skip notification during system suspend (but not in runtime PM);
2824 * the state will be updated at resume
2825 */
2826 if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
2827 return;
Takashi Iwaieb399d32015-11-27 14:53:35 +01002828 /* ditto during suspend/resume process itself */
Takashi Iwaifeb20fa2018-06-27 09:03:51 +02002829 if (snd_hdac_is_in_pm(&codec->core))
Takashi Iwaieb399d32015-11-27 14:53:35 +01002830 return;
Takashi Iwai8ae743e2015-11-27 14:23:00 +01002831
Takashi Iwaibb03ed22016-04-21 16:39:17 +02002832 snd_hdac_i915_set_bclk(&codec->bus->core);
Libin Yang91520852017-01-12 16:04:53 +08002833 check_presence_and_report(codec, pin_nid, dev_id);
David Henningsson25adc132015-08-19 10:48:58 +02002834}
2835
Takashi Iwaiade49db2018-07-11 18:05:52 +02002836static const struct drm_audio_component_audio_ops intel_audio_ops = {
2837 .pin2port = intel_pin2port,
2838 .pin_eld_notify = intel_pin_eld_notify,
2839};
2840
Takashi Iwaia6866322016-03-21 12:18:33 +01002841/* register i915 component pin_eld_notify callback */
2842static void register_i915_notifier(struct hda_codec *codec)
2843{
2844 struct hdmi_spec *spec = codec->spec;
2845
2846 spec->use_acomp_notifier = true;
Takashi Iwaiade49db2018-07-11 18:05:52 +02002847 spec->port2pin = intel_port2pin;
2848 setup_drm_audio_ops(codec, &intel_audio_ops);
Takashi Iwaia57942b2018-07-11 16:23:16 +02002849 snd_hdac_acomp_register_notifier(&codec->bus->core,
Takashi Iwai82887c02018-07-11 15:48:18 +02002850 &spec->drm_audio_ops);
Takashi Iwai4914da22019-07-16 08:56:51 +02002851 /* no need for forcible resume for jack check thanks to notifier */
2852 codec->relaxed_resume = 1;
Takashi Iwaia6866322016-03-21 12:18:33 +01002853}
2854
Takashi Iwai2c1c9b82016-03-21 12:42:06 +01002855/* setup_stream ops override for HSW+ */
2856static int i915_hsw_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302857 hda_nid_t pin_nid, int dev_id, u32 stream_tag,
2858 int format)
Takashi Iwai2c1c9b82016-03-21 12:42:06 +01002859{
2860 haswell_verify_D0(codec, cvt_nid, pin_nid);
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05302861 return hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
2862 stream_tag, format);
Takashi Iwai2c1c9b82016-03-21 12:42:06 +01002863}
2864
Takashi Iwai4846a672016-03-21 12:56:46 +01002865/* pin_cvt_fixup ops override for HSW+ and VLV+ */
2866static void i915_pin_cvt_fixup(struct hda_codec *codec,
2867 struct hdmi_spec_per_pin *per_pin,
2868 hda_nid_t cvt_nid)
2869{
2870 if (per_pin) {
Kai Vehmanen858e0ad2020-08-26 20:03:06 +03002871 haswell_verify_D0(codec, per_pin->cvt_nid, per_pin->pin_nid);
Libin Yang91520852017-01-12 16:04:53 +08002872 snd_hda_set_dev_select(codec, per_pin->pin_nid,
2873 per_pin->dev_id);
Takashi Iwai4846a672016-03-21 12:56:46 +01002874 intel_verify_pin_cvt_connect(codec, per_pin);
2875 intel_not_share_assigned_cvt(codec, per_pin->pin_nid,
Libin Yang91520852017-01-12 16:04:53 +08002876 per_pin->dev_id, per_pin->mux_idx);
Takashi Iwai4846a672016-03-21 12:56:46 +01002877 } else {
Libin Yang91520852017-01-12 16:04:53 +08002878 intel_not_share_assigned_cvt_nid(codec, 0, 0, cvt_nid);
Takashi Iwai4846a672016-03-21 12:56:46 +01002879 }
2880}
2881
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002882/* precondition and allocation for Intel codecs */
2883static int alloc_intel_hdmi(struct hda_codec *codec)
2884{
Takashi Iwaif2dbe872019-08-13 17:11:28 +02002885 int err;
2886
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002887 /* requires i915 binding */
2888 if (!codec->bus->core.audio_component) {
2889 codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n");
Takashi Iwaifdd49c52018-06-27 09:54:46 +02002890 /* set probe_id here to prevent generic fallback binding */
2891 codec->probe_id = HDA_CODEC_ID_SKIP_PROBE;
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002892 return -ENODEV;
2893 }
2894
Takashi Iwaif2dbe872019-08-13 17:11:28 +02002895 err = alloc_generic_hdmi(codec);
2896 if (err < 0)
2897 return err;
2898 /* no need to handle unsol events */
2899 codec->patch_ops.unsol_event = NULL;
2900 return 0;
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002901}
2902
2903/* parse and post-process for Intel codecs */
2904static int parse_intel_hdmi(struct hda_codec *codec)
2905{
Kai Vehmanen2928fa02020-01-20 18:01:17 +02002906 int err, retries = 3;
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002907
Kai Vehmanen2928fa02020-01-20 18:01:17 +02002908 do {
2909 err = hdmi_parse_codec(codec);
2910 } while (err < 0 && retries--);
2911
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002912 if (err < 0) {
2913 generic_spec_free(codec);
2914 return err;
2915 }
2916
2917 generic_hdmi_init_per_pins(codec);
2918 register_i915_notifier(codec);
2919 return 0;
2920}
2921
Takashi Iwaia6866322016-03-21 12:18:33 +01002922/* Intel Haswell and onwards; audio component with eld notifier */
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002923static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
2924 const int *port_map, int port_num)
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002925{
2926 struct hdmi_spec *spec;
Takashi Iwaia6866322016-03-21 12:18:33 +01002927 int err;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02002928
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002929 err = alloc_intel_hdmi(codec);
Takashi Iwaia6866322016-03-21 12:18:33 +01002930 if (err < 0)
2931 return err;
2932 spec = codec->spec;
Libin Yang91520852017-01-12 16:04:53 +08002933 codec->dp_mst = true;
2934 spec->dyn_pcm_assign = true;
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302935 spec->vendor_nid = vendor_nid;
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002936 spec->port_map = port_map;
2937 spec->port_num = port_num;
Takashi Iwaicb457222019-11-11 20:09:37 +01002938 spec->intel_hsw_fixup = true;
Takashi Iwaia6866322016-03-21 12:18:33 +01002939
2940 intel_haswell_enable_all_pins(codec, true);
2941 intel_haswell_fixup_enable_dp12(codec);
2942
Takashi Iwai46594d32018-12-09 10:10:19 +01002943 codec->display_power_control = 1;
Takashi Iwaia6866322016-03-21 12:18:33 +01002944
2945 codec->patch_ops.set_power_state = haswell_set_power_state;
Takashi Iwaia6866322016-03-21 12:18:33 +01002946 codec->depop_delay = 0;
2947 codec->auto_runtime_pm = 1;
2948
Takashi Iwai2c1c9b82016-03-21 12:42:06 +01002949 spec->ops.setup_stream = i915_hsw_setup_stream;
Takashi Iwai4846a672016-03-21 12:56:46 +01002950 spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
Takashi Iwai2c1c9b82016-03-21 12:42:06 +01002951
Harsha Priya951894c2020-07-06 13:53:17 -07002952 /*
2953 * Enable silent stream feature, if it is enabled via
2954 * module param or Kconfig option
2955 */
2956 if (enable_silent_stream)
2957 spec->send_silent_stream = true;
2958
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02002959 return parse_intel_hdmi(codec);
Takashi Iwaia6866322016-03-21 12:18:33 +01002960}
2961
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302962static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2963{
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002964 return intel_hsw_common_init(codec, 0x08, NULL, 0);
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302965}
2966
2967static int patch_i915_glk_hdmi(struct hda_codec *codec)
2968{
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002969 return intel_hsw_common_init(codec, 0x0b, NULL, 0);
2970}
2971
2972static int patch_i915_icl_hdmi(struct hda_codec *codec)
2973{
2974 /*
2975 * pin to port mapping table where the value indicate the pin number and
Kai Vehmanend577cf72019-11-15 14:44:47 +02002976 * the index indicate the port number.
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002977 */
Kai Vehmanend577cf72019-11-15 14:44:47 +02002978 static const int map[] = {0x0, 0x4, 0x6, 0x8, 0xa, 0xb};
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01002979
2980 return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05302981}
2982
Kai Vehmanen9a11ba72019-11-05 18:10:53 +02002983static int patch_i915_tgl_hdmi(struct hda_codec *codec)
2984{
2985 /*
2986 * pin to port mapping table where the value indicate the pin number and
Kai Vehmanend577cf72019-11-15 14:44:47 +02002987 * the index indicate the port number.
Kai Vehmanen9a11ba72019-11-05 18:10:53 +02002988 */
2989 static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
2990
2991 return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
2992}
2993
Takashi Iwai7ff652f2016-03-21 14:50:24 +01002994/* Intel Baytrail and Braswell; with eld notifier */
Takashi Iwaia6866322016-03-21 12:18:33 +01002995static int patch_i915_byt_hdmi(struct hda_codec *codec)
2996{
2997 struct hdmi_spec *spec;
2998 int err;
2999
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02003000 err = alloc_intel_hdmi(codec);
Takashi Iwaia6866322016-03-21 12:18:33 +01003001 if (err < 0)
3002 return err;
3003 spec = codec->spec;
3004
Mengdong Lin2bd1f73f2015-04-29 17:43:43 +08003005 /* For Valleyview/Cherryview, only the display codec is in the display
3006 * power well and can use link_power ops to request/release the power.
Mengdong Lin2bd1f73f2015-04-29 17:43:43 +08003007 */
Takashi Iwai029d92c2018-12-08 17:31:49 +01003008 codec->display_power_control = 1;
Mengdong Lin2bd1f73f2015-04-29 17:43:43 +08003009
Takashi Iwaia6866322016-03-21 12:18:33 +01003010 codec->depop_delay = 0;
3011 codec->auto_runtime_pm = 1;
Takashi Iwai17df3f52013-05-08 08:09:34 +02003012
Takashi Iwai4846a672016-03-21 12:56:46 +01003013 spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
3014
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02003015 return parse_intel_hdmi(codec);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003016}
3017
Takashi Iwai7ff652f2016-03-21 14:50:24 +01003018/* Intel IronLake, SandyBridge and IvyBridge; with eld notifier */
Takashi Iwaie85015a32016-03-21 13:56:19 +01003019static int patch_i915_cpt_hdmi(struct hda_codec *codec)
3020{
Takashi Iwaie85015a32016-03-21 13:56:19 +01003021 int err;
3022
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02003023 err = alloc_intel_hdmi(codec);
Takashi Iwaie85015a32016-03-21 13:56:19 +01003024 if (err < 0)
3025 return err;
Takashi Iwai43f6c8d2017-06-28 14:18:29 +02003026 return parse_intel_hdmi(codec);
Takashi Iwaie85015a32016-03-21 13:56:19 +01003027}
3028
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003029/*
Stephen Warren3aaf8982011-06-01 11:14:19 -06003030 * Shared non-generic implementations
3031 */
3032
3033static int simple_playback_build_pcms(struct hda_codec *codec)
3034{
3035 struct hdmi_spec *spec = codec->spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003036 struct hda_pcm *info;
Takashi Iwai8ceb3322012-06-21 08:23:27 +02003037 unsigned int chans;
3038 struct hda_pcm_stream *pstr;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003039 struct hdmi_spec_per_cvt *per_cvt;
Stephen Warren3aaf8982011-06-01 11:14:19 -06003040
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003041 per_cvt = get_cvt(spec, 0);
3042 chans = get_wcaps(codec, per_cvt->cvt_nid);
Takashi Iwai8ceb3322012-06-21 08:23:27 +02003043 chans = get_wcaps_channels(chans);
Stephen Warren3aaf8982011-06-01 11:14:19 -06003044
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01003045 info = snd_hda_codec_pcm_new(codec, "HDMI 0");
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003046 if (!info)
3047 return -ENOMEM;
Libin Yang2bea2412016-01-12 11:13:26 +08003048 spec->pcm_rec[0].pcm = info;
Takashi Iwai8ceb3322012-06-21 08:23:27 +02003049 info->pcm_type = HDA_PCM_TYPE_HDMI;
3050 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
3051 *pstr = spec->pcm_playback;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003052 pstr->nid = per_cvt->cvt_nid;
Takashi Iwai8ceb3322012-06-21 08:23:27 +02003053 if (pstr->channels_max <= 2 && chans && chans <= 16)
3054 pstr->channels_max = chans;
Stephen Warren3aaf8982011-06-01 11:14:19 -06003055
3056 return 0;
3057}
3058
Takashi Iwai4b6ace92012-06-15 11:53:32 +02003059/* unsolicited event for jack sensing */
3060static void simple_hdmi_unsol_event(struct hda_codec *codec,
3061 unsigned int res)
3062{
Takashi Iwai9dd8cf12012-06-21 10:43:15 +02003063 snd_hda_jack_set_dirty_all(codec);
Takashi Iwai4b6ace92012-06-15 11:53:32 +02003064 snd_hda_jack_report_sync(codec);
3065}
3066
3067/* generic_hdmi_build_jack can be used for simple_hdmi, too,
3068 * as long as spec->pins[] is set correctly
3069 */
3070#define simple_hdmi_build_jack generic_hdmi_build_jack
3071
Stephen Warren3aaf8982011-06-01 11:14:19 -06003072static int simple_playback_build_controls(struct hda_codec *codec)
3073{
3074 struct hdmi_spec *spec = codec->spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003075 struct hdmi_spec_per_cvt *per_cvt;
Stephen Warren3aaf8982011-06-01 11:14:19 -06003076 int err;
Stephen Warren3aaf8982011-06-01 11:14:19 -06003077
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003078 per_cvt = get_cvt(spec, 0);
Anssi Hannulac9a63382013-12-10 22:46:34 +02003079 err = snd_hda_create_dig_out_ctls(codec, per_cvt->cvt_nid,
3080 per_cvt->cvt_nid,
3081 HDA_PCM_TYPE_HDMI);
Takashi Iwai8ceb3322012-06-21 08:23:27 +02003082 if (err < 0)
3083 return err;
3084 return simple_hdmi_build_jack(codec, 0);
Stephen Warren3aaf8982011-06-01 11:14:19 -06003085}
3086
Takashi Iwai4f0110c2012-06-15 12:45:43 +02003087static int simple_playback_init(struct hda_codec *codec)
3088{
3089 struct hdmi_spec *spec = codec->spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003090 struct hdmi_spec_per_pin *per_pin = get_pin(spec, 0);
3091 hda_nid_t pin = per_pin->pin_nid;
Takashi Iwai4f0110c2012-06-15 12:45:43 +02003092
Takashi Iwai8ceb3322012-06-21 08:23:27 +02003093 snd_hda_codec_write(codec, pin, 0,
3094 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3095 /* some codecs require to unmute the pin */
3096 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
3097 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3098 AMP_OUT_UNMUTE);
Nikhil Mahale5204a052019-11-19 14:17:08 +05303099 snd_hda_jack_detect_enable(codec, pin, per_pin->dev_id);
Takashi Iwai4f0110c2012-06-15 12:45:43 +02003100 return 0;
3101}
3102
Stephen Warren3aaf8982011-06-01 11:14:19 -06003103static void simple_playback_free(struct hda_codec *codec)
3104{
3105 struct hdmi_spec *spec = codec->spec;
3106
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003107 hdmi_array_free(spec);
Stephen Warren3aaf8982011-06-01 11:14:19 -06003108 kfree(spec);
3109}
3110
3111/*
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003112 * Nvidia specific implementations
3113 */
3114
3115#define Nv_VERB_SET_Channel_Allocation 0xF79
3116#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
3117#define Nv_VERB_SET_Audio_Protection_On 0xF98
3118#define Nv_VERB_SET_Audio_Protection_Off 0xF99
3119
3120#define nvhdmi_master_con_nid_7x 0x04
3121#define nvhdmi_master_pin_nid_7x 0x05
3122
Takashi Iwaifb79e1e2011-05-02 12:17:41 +02003123static const hda_nid_t nvhdmi_con_nids_7x[4] = {
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003124 /*front, rear, clfe, rear_surr */
3125 0x6, 0x8, 0xa, 0xc,
3126};
3127
Takashi Iwaiceaa86b2012-06-15 14:38:31 +02003128static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = {
3129 /* set audio protect on */
3130 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
3131 /* enable digital output on pin widget */
3132 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
3133 {} /* terminator */
3134};
3135
3136static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = {
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003137 /* set audio protect on */
3138 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
3139 /* enable digital output on pin widget */
3140 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
3141 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
3142 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
3143 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
3144 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
3145 {} /* terminator */
3146};
3147
3148#ifdef LIMITED_RATE_FMT_SUPPORT
3149/* support only the safe format and rate */
3150#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
3151#define SUPPORTED_MAXBPS 16
3152#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
3153#else
3154/* support all rates and formats */
3155#define SUPPORTED_RATES \
3156 (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
3157 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
3158 SNDRV_PCM_RATE_192000)
3159#define SUPPORTED_MAXBPS 24
3160#define SUPPORTED_FORMATS \
3161 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
3162#endif
3163
Takashi Iwaiceaa86b2012-06-15 14:38:31 +02003164static int nvhdmi_7x_init_2ch(struct hda_codec *codec)
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003165{
Takashi Iwaiceaa86b2012-06-15 14:38:31 +02003166 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch);
3167 return 0;
3168}
3169
3170static int nvhdmi_7x_init_8ch(struct hda_codec *codec)
3171{
3172 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003173 return 0;
3174}
3175
Takashi Iwai50c697adf2017-06-07 14:20:07 +02003176static const unsigned int channels_2_6_8[] = {
Nitin Daga393004b2011-01-10 21:49:31 +05303177 2, 6, 8
3178};
3179
Takashi Iwai50c697adf2017-06-07 14:20:07 +02003180static const unsigned int channels_2_8[] = {
Nitin Daga393004b2011-01-10 21:49:31 +05303181 2, 8
3182};
3183
Takashi Iwai50c697adf2017-06-07 14:20:07 +02003184static const struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = {
Nitin Daga393004b2011-01-10 21:49:31 +05303185 .count = ARRAY_SIZE(channels_2_6_8),
3186 .list = channels_2_6_8,
3187 .mask = 0,
3188};
3189
Takashi Iwai50c697adf2017-06-07 14:20:07 +02003190static const struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = {
Nitin Daga393004b2011-01-10 21:49:31 +05303191 .count = ARRAY_SIZE(channels_2_8),
3192 .list = channels_2_8,
3193 .mask = 0,
3194};
3195
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003196static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
3197 struct hda_codec *codec,
3198 struct snd_pcm_substream *substream)
3199{
3200 struct hdmi_spec *spec = codec->spec;
Takashi Iwai50c697adf2017-06-07 14:20:07 +02003201 const struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL;
Nitin Daga393004b2011-01-10 21:49:31 +05303202
Takashi Iwaib9a94a92015-10-01 16:20:04 +02003203 switch (codec->preset->vendor_id) {
Nitin Daga393004b2011-01-10 21:49:31 +05303204 case 0x10de0002:
3205 case 0x10de0003:
3206 case 0x10de0005:
3207 case 0x10de0006:
3208 hw_constraints_channels = &hw_constraints_2_8_channels;
3209 break;
3210 case 0x10de0007:
3211 hw_constraints_channels = &hw_constraints_2_6_8_channels;
3212 break;
3213 default:
3214 break;
3215 }
3216
3217 if (hw_constraints_channels != NULL) {
3218 snd_pcm_hw_constraint_list(substream->runtime, 0,
3219 SNDRV_PCM_HW_PARAM_CHANNELS,
3220 hw_constraints_channels);
Takashi Iwaiad09fc92011-01-14 09:42:27 +01003221 } else {
3222 snd_pcm_hw_constraint_step(substream->runtime, 0,
3223 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
Nitin Daga393004b2011-01-10 21:49:31 +05303224 }
3225
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003226 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3227}
3228
3229static int simple_playback_pcm_close(struct hda_pcm_stream *hinfo,
3230 struct hda_codec *codec,
3231 struct snd_pcm_substream *substream)
3232{
3233 struct hdmi_spec *spec = codec->spec;
3234 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3235}
3236
3237static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3238 struct hda_codec *codec,
3239 unsigned int stream_tag,
3240 unsigned int format,
3241 struct snd_pcm_substream *substream)
3242{
3243 struct hdmi_spec *spec = codec->spec;
3244 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3245 stream_tag, format, substream);
3246}
3247
Takashi Iwaid0b12522012-06-15 14:34:42 +02003248static const struct hda_pcm_stream simple_pcm_playback = {
3249 .substreams = 1,
3250 .channels_min = 2,
3251 .channels_max = 2,
3252 .ops = {
3253 .open = simple_playback_pcm_open,
3254 .close = simple_playback_pcm_close,
3255 .prepare = simple_playback_pcm_prepare
3256 },
3257};
3258
3259static const struct hda_codec_ops simple_hdmi_patch_ops = {
3260 .build_controls = simple_playback_build_controls,
3261 .build_pcms = simple_playback_build_pcms,
3262 .init = simple_playback_init,
3263 .free = simple_playback_free,
Takashi Iwai250e41a2012-06-15 14:40:21 +02003264 .unsol_event = simple_hdmi_unsol_event,
Takashi Iwaid0b12522012-06-15 14:34:42 +02003265};
3266
3267static int patch_simple_hdmi(struct hda_codec *codec,
3268 hda_nid_t cvt_nid, hda_nid_t pin_nid)
3269{
3270 struct hdmi_spec *spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003271 struct hdmi_spec_per_cvt *per_cvt;
3272 struct hdmi_spec_per_pin *per_pin;
Takashi Iwaid0b12522012-06-15 14:34:42 +02003273
3274 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3275 if (!spec)
3276 return -ENOMEM;
3277
Takashi Iwaiade49db2018-07-11 18:05:52 +02003278 spec->codec = codec;
Takashi Iwaid0b12522012-06-15 14:34:42 +02003279 codec->spec = spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003280 hdmi_array_init(spec, 1);
Takashi Iwaid0b12522012-06-15 14:34:42 +02003281
3282 spec->multiout.num_dacs = 0; /* no analog */
3283 spec->multiout.max_channels = 2;
3284 spec->multiout.dig_out_nid = cvt_nid;
3285 spec->num_cvts = 1;
3286 spec->num_pins = 1;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003287 per_pin = snd_array_new(&spec->pins);
3288 per_cvt = snd_array_new(&spec->cvts);
3289 if (!per_pin || !per_cvt) {
3290 simple_playback_free(codec);
3291 return -ENOMEM;
3292 }
3293 per_cvt->cvt_nid = cvt_nid;
3294 per_pin->pin_nid = pin_nid;
Takashi Iwaid0b12522012-06-15 14:34:42 +02003295 spec->pcm_playback = simple_pcm_playback;
3296
3297 codec->patch_ops = simple_hdmi_patch_ops;
3298
3299 return 0;
3300}
3301
Aaron Plattner1f348522011-04-06 17:19:04 -07003302static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
3303 int channels)
3304{
3305 unsigned int chanmask;
3306 int chan = channels ? (channels - 1) : 1;
3307
3308 switch (channels) {
3309 default:
3310 case 0:
3311 case 2:
3312 chanmask = 0x00;
3313 break;
3314 case 4:
3315 chanmask = 0x08;
3316 break;
3317 case 6:
3318 chanmask = 0x0b;
3319 break;
3320 case 8:
3321 chanmask = 0x13;
3322 break;
3323 }
3324
3325 /* Set the audio infoframe channel allocation and checksum fields. The
3326 * channel count is computed implicitly by the hardware. */
3327 snd_hda_codec_write(codec, 0x1, 0,
3328 Nv_VERB_SET_Channel_Allocation, chanmask);
3329
3330 snd_hda_codec_write(codec, 0x1, 0,
3331 Nv_VERB_SET_Info_Frame_Checksum,
3332 (0x71 - chan - chanmask));
3333}
3334
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003335static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo,
3336 struct hda_codec *codec,
3337 struct snd_pcm_substream *substream)
3338{
3339 struct hdmi_spec *spec = codec->spec;
3340 int i;
3341
3342 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
3343 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
3344 for (i = 0; i < 4; i++) {
3345 /* set the stream id */
3346 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
3347 AC_VERB_SET_CHANNEL_STREAMID, 0);
3348 /* set the stream format */
3349 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
3350 AC_VERB_SET_STREAM_FORMAT, 0);
3351 }
3352
Aaron Plattner1f348522011-04-06 17:19:04 -07003353 /* The audio hardware sends a channel count of 0x7 (8ch) when all the
3354 * streams are disabled. */
3355 nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8);
3356
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003357 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3358}
3359
3360static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
3361 struct hda_codec *codec,
3362 unsigned int stream_tag,
3363 unsigned int format,
3364 struct snd_pcm_substream *substream)
3365{
3366 int chs;
Takashi Iwai112daa72011-11-02 21:40:06 +01003367 unsigned int dataDCC2, channel_id;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003368 int i;
Stephen Warren7c935972011-06-01 11:14:17 -06003369 struct hdmi_spec *spec = codec->spec;
Takashi Iwaie3245cd2012-05-10 10:21:29 +02003370 struct hda_spdif_out *spdif;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003371 struct hdmi_spec_per_cvt *per_cvt;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003372
3373 mutex_lock(&codec->spdif_mutex);
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003374 per_cvt = get_cvt(spec, 0);
3375 spdif = snd_hda_spdif_out_of_nid(codec, per_cvt->cvt_nid);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003376
3377 chs = substream->runtime->channels;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003378
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003379 dataDCC2 = 0x2;
3380
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003381 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
Stephen Warren7c935972011-06-01 11:14:17 -06003382 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003383 snd_hda_codec_write(codec,
3384 nvhdmi_master_con_nid_7x,
3385 0,
3386 AC_VERB_SET_DIGI_CONVERT_1,
Stephen Warren7c935972011-06-01 11:14:17 -06003387 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003388
3389 /* set the stream id */
3390 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
3391 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
3392
3393 /* set the stream format */
3394 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
3395 AC_VERB_SET_STREAM_FORMAT, format);
3396
3397 /* turn on again (if needed) */
3398 /* enable and set the channel status audio/data flag */
Stephen Warren7c935972011-06-01 11:14:17 -06003399 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) {
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003400 snd_hda_codec_write(codec,
3401 nvhdmi_master_con_nid_7x,
3402 0,
3403 AC_VERB_SET_DIGI_CONVERT_1,
Stephen Warren7c935972011-06-01 11:14:17 -06003404 spdif->ctls & 0xff);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003405 snd_hda_codec_write(codec,
3406 nvhdmi_master_con_nid_7x,
3407 0,
3408 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
3409 }
3410
3411 for (i = 0; i < 4; i++) {
3412 if (chs == 2)
3413 channel_id = 0;
3414 else
3415 channel_id = i * 2;
3416
3417 /* turn off SPDIF once;
3418 *otherwise the IEC958 bits won't be updated
3419 */
3420 if (codec->spdif_status_reset &&
Stephen Warren7c935972011-06-01 11:14:17 -06003421 (spdif->ctls & AC_DIG1_ENABLE))
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003422 snd_hda_codec_write(codec,
3423 nvhdmi_con_nids_7x[i],
3424 0,
3425 AC_VERB_SET_DIGI_CONVERT_1,
Stephen Warren7c935972011-06-01 11:14:17 -06003426 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003427 /* set the stream id */
3428 snd_hda_codec_write(codec,
3429 nvhdmi_con_nids_7x[i],
3430 0,
3431 AC_VERB_SET_CHANNEL_STREAMID,
3432 (stream_tag << 4) | channel_id);
3433 /* set the stream format */
3434 snd_hda_codec_write(codec,
3435 nvhdmi_con_nids_7x[i],
3436 0,
3437 AC_VERB_SET_STREAM_FORMAT,
3438 format);
3439 /* turn on again (if needed) */
3440 /* enable and set the channel status audio/data flag */
3441 if (codec->spdif_status_reset &&
Stephen Warren7c935972011-06-01 11:14:17 -06003442 (spdif->ctls & AC_DIG1_ENABLE)) {
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003443 snd_hda_codec_write(codec,
3444 nvhdmi_con_nids_7x[i],
3445 0,
3446 AC_VERB_SET_DIGI_CONVERT_1,
Stephen Warren7c935972011-06-01 11:14:17 -06003447 spdif->ctls & 0xff);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003448 snd_hda_codec_write(codec,
3449 nvhdmi_con_nids_7x[i],
3450 0,
3451 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
3452 }
3453 }
3454
Aaron Plattner1f348522011-04-06 17:19:04 -07003455 nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003456
3457 mutex_unlock(&codec->spdif_mutex);
3458 return 0;
3459}
3460
Takashi Iwaifb79e1e2011-05-02 12:17:41 +02003461static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003462 .substreams = 1,
3463 .channels_min = 2,
3464 .channels_max = 8,
3465 .nid = nvhdmi_master_con_nid_7x,
3466 .rates = SUPPORTED_RATES,
3467 .maxbps = SUPPORTED_MAXBPS,
3468 .formats = SUPPORTED_FORMATS,
3469 .ops = {
3470 .open = simple_playback_pcm_open,
3471 .close = nvhdmi_8ch_7x_pcm_close,
3472 .prepare = nvhdmi_8ch_7x_pcm_prepare
3473 },
3474};
3475
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003476static int patch_nvhdmi_2ch(struct hda_codec *codec)
3477{
3478 struct hdmi_spec *spec;
Takashi Iwaid0b12522012-06-15 14:34:42 +02003479 int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x,
3480 nvhdmi_master_pin_nid_7x);
3481 if (err < 0)
3482 return err;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003483
Takashi Iwaiceaa86b2012-06-15 14:38:31 +02003484 codec->patch_ops.init = nvhdmi_7x_init_2ch;
Takashi Iwaid0b12522012-06-15 14:34:42 +02003485 /* override the PCM rates, etc, as the codec doesn't give full list */
3486 spec = codec->spec;
3487 spec->pcm_playback.rates = SUPPORTED_RATES;
3488 spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
3489 spec->pcm_playback.formats = SUPPORTED_FORMATS;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003490 return 0;
3491}
3492
Takashi Iwai53775b02012-08-01 12:17:41 +02003493static int nvhdmi_7x_8ch_build_pcms(struct hda_codec *codec)
3494{
3495 struct hdmi_spec *spec = codec->spec;
3496 int err = simple_playback_build_pcms(codec);
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003497 if (!err) {
3498 struct hda_pcm *info = get_pcm_rec(spec, 0);
3499 info->own_chmap = true;
3500 }
Takashi Iwai53775b02012-08-01 12:17:41 +02003501 return err;
3502}
3503
3504static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec)
3505{
3506 struct hdmi_spec *spec = codec->spec;
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003507 struct hda_pcm *info;
Takashi Iwai53775b02012-08-01 12:17:41 +02003508 struct snd_pcm_chmap *chmap;
3509 int err;
3510
3511 err = simple_playback_build_controls(codec);
3512 if (err < 0)
3513 return err;
3514
3515 /* add channel maps */
Takashi Iwaibce0d2a2013-03-13 14:40:31 +01003516 info = get_pcm_rec(spec, 0);
3517 err = snd_pcm_add_chmap_ctls(info->pcm,
Takashi Iwai53775b02012-08-01 12:17:41 +02003518 SNDRV_PCM_STREAM_PLAYBACK,
3519 snd_pcm_alt_chmaps, 8, 0, &chmap);
3520 if (err < 0)
3521 return err;
Takashi Iwaib9a94a92015-10-01 16:20:04 +02003522 switch (codec->preset->vendor_id) {
Takashi Iwai53775b02012-08-01 12:17:41 +02003523 case 0x10de0002:
3524 case 0x10de0003:
3525 case 0x10de0005:
3526 case 0x10de0006:
3527 chmap->channel_mask = (1U << 2) | (1U << 8);
3528 break;
3529 case 0x10de0007:
3530 chmap->channel_mask = (1U << 2) | (1U << 6) | (1U << 8);
3531 }
3532 return 0;
3533}
3534
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003535static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
3536{
3537 struct hdmi_spec *spec;
3538 int err = patch_nvhdmi_2ch(codec);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003539 if (err < 0)
3540 return err;
3541 spec = codec->spec;
3542 spec->multiout.max_channels = 8;
Takashi Iwaid0b12522012-06-15 14:34:42 +02003543 spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;
Takashi Iwaiceaa86b2012-06-15 14:38:31 +02003544 codec->patch_ops.init = nvhdmi_7x_init_8ch;
Takashi Iwai53775b02012-08-01 12:17:41 +02003545 codec->patch_ops.build_pcms = nvhdmi_7x_8ch_build_pcms;
3546 codec->patch_ops.build_controls = nvhdmi_7x_8ch_build_controls;
Aaron Plattner1f348522011-04-06 17:19:04 -07003547
3548 /* Initialize the audio infoframe channel mask and checksum to something
3549 * valid */
3550 nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8);
3551
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003552 return 0;
3553}
3554
3555/*
Anssi Hannula611885b2013-11-03 17:15:00 +02003556 * NVIDIA codecs ignore ASP mapping for 2ch - confirmed on:
3557 * - 0x10de0015
3558 * - 0x10de0040
3559 */
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05303560static int nvhdmi_chmap_cea_alloc_validate_get_type(struct hdac_chmap *chmap,
Subhransu S. Prustyf3022402016-03-04 19:59:48 +05303561 struct hdac_cea_channel_speaker_allocation *cap, int channels)
Anssi Hannula611885b2013-11-03 17:15:00 +02003562{
3563 if (cap->ca_index == 0x00 && channels == 2)
3564 return SNDRV_CTL_TLVT_CHMAP_FIXED;
3565
Subhransu S. Prusty028cb682016-03-14 10:35:06 +05303566 /* If the speaker allocation matches the channel count, it is OK. */
3567 if (cap->channels != channels)
3568 return -1;
3569
3570 /* all channels are remappable freely */
3571 return SNDRV_CTL_TLVT_CHMAP_VAR;
Anssi Hannula611885b2013-11-03 17:15:00 +02003572}
3573
Subhransu S. Prusty828cb4e2016-03-04 19:59:50 +05303574static int nvhdmi_chmap_validate(struct hdac_chmap *chmap,
3575 int ca, int chs, unsigned char *map)
Anssi Hannula611885b2013-11-03 17:15:00 +02003576{
3577 if (ca == 0x00 && (map[0] != SNDRV_CHMAP_FL || map[1] != SNDRV_CHMAP_FR))
3578 return -EINVAL;
3579
3580 return 0;
3581}
3582
Takashi Iwaiade49db2018-07-11 18:05:52 +02003583/* map from pin NID to port; port is 0-based */
3584/* for Nvidia: assume widget NID starting from 4, with step 1 (4, 5, 6, ...) */
3585static int nvhdmi_pin2port(void *audio_ptr, int pin_nid)
3586{
3587 return pin_nid - 4;
3588}
3589
3590/* reverse-map from port to pin NID: see above */
3591static int nvhdmi_port2pin(struct hda_codec *codec, int port)
3592{
3593 return port + 4;
3594}
3595
3596static const struct drm_audio_component_audio_ops nvhdmi_audio_ops = {
3597 .pin2port = nvhdmi_pin2port,
3598 .pin_eld_notify = generic_acomp_pin_eld_notify,
3599 .master_bind = generic_acomp_master_bind,
3600 .master_unbind = generic_acomp_master_unbind,
3601};
3602
Anssi Hannula611885b2013-11-03 17:15:00 +02003603static int patch_nvhdmi(struct hda_codec *codec)
3604{
3605 struct hdmi_spec *spec;
3606 int err;
3607
Nikhil Mahale5398e942019-11-19 14:17:10 +05303608 err = alloc_generic_hdmi(codec);
3609 if (err < 0)
3610 return err;
3611 codec->dp_mst = true;
3612
3613 spec = codec->spec;
3614 spec->dyn_pcm_assign = true;
3615
3616 err = hdmi_parse_codec(codec);
3617 if (err < 0) {
3618 generic_spec_free(codec);
3619 return err;
3620 }
3621
3622 generic_hdmi_init_per_pins(codec);
3623
3624 spec->dyn_pin_out = true;
3625
3626 spec->chmap.ops.chmap_cea_alloc_validate_get_type =
3627 nvhdmi_chmap_cea_alloc_validate_get_type;
3628 spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
3629
3630 codec->link_down_at_suspend = 1;
3631
3632 generic_acomp_init(codec, &nvhdmi_audio_ops, nvhdmi_port2pin);
3633
3634 return 0;
3635}
3636
3637static int patch_nvhdmi_legacy(struct hda_codec *codec)
3638{
3639 struct hdmi_spec *spec;
3640 int err;
3641
Anssi Hannula611885b2013-11-03 17:15:00 +02003642 err = patch_generic_hdmi(codec);
3643 if (err)
3644 return err;
3645
3646 spec = codec->spec;
Stephen Warren75fae112014-01-30 11:52:16 -07003647 spec->dyn_pin_out = true;
Anssi Hannula611885b2013-11-03 17:15:00 +02003648
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05303649 spec->chmap.ops.chmap_cea_alloc_validate_get_type =
Anssi Hannula611885b2013-11-03 17:15:00 +02003650 nvhdmi_chmap_cea_alloc_validate_get_type;
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05303651 spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
Anssi Hannula611885b2013-11-03 17:15:00 +02003652
Lukas Wunner94989e32019-10-17 17:04:11 +02003653 codec->link_down_at_suspend = 1;
3654
Anssi Hannula611885b2013-11-03 17:15:00 +02003655 return 0;
3656}
3657
3658/*
Thierry Reding26e9a962015-05-05 14:56:20 +02003659 * The HDA codec on NVIDIA Tegra contains two scratch registers that are
3660 * accessed using vendor-defined verbs. These registers can be used for
3661 * interoperability between the HDA and HDMI drivers.
3662 */
3663
3664/* Audio Function Group node */
3665#define NVIDIA_AFG_NID 0x01
3666
3667/*
3668 * The SCRATCH0 register is used to notify the HDMI codec of changes in audio
3669 * format. On Tegra, bit 31 is used as a trigger that causes an interrupt to
3670 * be raised in the HDMI codec. The remainder of the bits is arbitrary. This
3671 * implementation stores the HDA format (see AC_FMT_*) in bits [15:0] and an
3672 * additional bit (at position 30) to signal the validity of the format.
3673 *
3674 * | 31 | 30 | 29 16 | 15 0 |
3675 * +---------+-------+--------+--------+
3676 * | TRIGGER | VALID | UNUSED | FORMAT |
3677 * +-----------------------------------|
3678 *
3679 * Note that for the trigger bit to take effect it needs to change value
3680 * (i.e. it needs to be toggled).
3681 */
3682#define NVIDIA_GET_SCRATCH0 0xfa6
3683#define NVIDIA_SET_SCRATCH0_BYTE0 0xfa7
3684#define NVIDIA_SET_SCRATCH0_BYTE1 0xfa8
3685#define NVIDIA_SET_SCRATCH0_BYTE2 0xfa9
3686#define NVIDIA_SET_SCRATCH0_BYTE3 0xfaa
3687#define NVIDIA_SCRATCH_TRIGGER (1 << 7)
3688#define NVIDIA_SCRATCH_VALID (1 << 6)
3689
3690#define NVIDIA_GET_SCRATCH1 0xfab
3691#define NVIDIA_SET_SCRATCH1_BYTE0 0xfac
3692#define NVIDIA_SET_SCRATCH1_BYTE1 0xfad
3693#define NVIDIA_SET_SCRATCH1_BYTE2 0xfae
3694#define NVIDIA_SET_SCRATCH1_BYTE3 0xfaf
3695
3696/*
3697 * The format parameter is the HDA audio format (see AC_FMT_*). If set to 0,
3698 * the format is invalidated so that the HDMI codec can be disabled.
3699 */
3700static void tegra_hdmi_set_format(struct hda_codec *codec, unsigned int format)
3701{
3702 unsigned int value;
3703
3704 /* bits [31:30] contain the trigger and valid bits */
3705 value = snd_hda_codec_read(codec, NVIDIA_AFG_NID, 0,
3706 NVIDIA_GET_SCRATCH0, 0);
3707 value = (value >> 24) & 0xff;
3708
3709 /* bits [15:0] are used to store the HDA format */
3710 snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
3711 NVIDIA_SET_SCRATCH0_BYTE0,
3712 (format >> 0) & 0xff);
3713 snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
3714 NVIDIA_SET_SCRATCH0_BYTE1,
3715 (format >> 8) & 0xff);
3716
3717 /* bits [16:24] are unused */
3718 snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
3719 NVIDIA_SET_SCRATCH0_BYTE2, 0);
3720
3721 /*
3722 * Bit 30 signals that the data is valid and hence that HDMI audio can
3723 * be enabled.
3724 */
3725 if (format == 0)
3726 value &= ~NVIDIA_SCRATCH_VALID;
3727 else
3728 value |= NVIDIA_SCRATCH_VALID;
3729
3730 /*
3731 * Whenever the trigger bit is toggled, an interrupt is raised in the
3732 * HDMI codec. The HDMI driver will use that as trigger to update its
3733 * configuration.
3734 */
3735 value ^= NVIDIA_SCRATCH_TRIGGER;
3736
3737 snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
3738 NVIDIA_SET_SCRATCH0_BYTE3, value);
3739}
3740
3741static int tegra_hdmi_pcm_prepare(struct hda_pcm_stream *hinfo,
3742 struct hda_codec *codec,
3743 unsigned int stream_tag,
3744 unsigned int format,
3745 struct snd_pcm_substream *substream)
3746{
3747 int err;
3748
3749 err = generic_hdmi_playback_pcm_prepare(hinfo, codec, stream_tag,
3750 format, substream);
3751 if (err < 0)
3752 return err;
3753
3754 /* notify the HDMI codec of the format change */
3755 tegra_hdmi_set_format(codec, format);
3756
3757 return 0;
3758}
3759
3760static int tegra_hdmi_pcm_cleanup(struct hda_pcm_stream *hinfo,
3761 struct hda_codec *codec,
3762 struct snd_pcm_substream *substream)
3763{
3764 /* invalidate the format in the HDMI codec */
3765 tegra_hdmi_set_format(codec, 0);
3766
3767 return generic_hdmi_playback_pcm_cleanup(hinfo, codec, substream);
3768}
3769
3770static struct hda_pcm *hda_find_pcm_by_type(struct hda_codec *codec, int type)
3771{
3772 struct hdmi_spec *spec = codec->spec;
3773 unsigned int i;
3774
3775 for (i = 0; i < spec->num_pins; i++) {
3776 struct hda_pcm *pcm = get_pcm_rec(spec, i);
3777
3778 if (pcm->pcm_type == type)
3779 return pcm;
3780 }
3781
3782 return NULL;
3783}
3784
3785static int tegra_hdmi_build_pcms(struct hda_codec *codec)
3786{
3787 struct hda_pcm_stream *stream;
3788 struct hda_pcm *pcm;
3789 int err;
3790
3791 err = generic_hdmi_build_pcms(codec);
3792 if (err < 0)
3793 return err;
3794
3795 pcm = hda_find_pcm_by_type(codec, HDA_PCM_TYPE_HDMI);
3796 if (!pcm)
3797 return -ENODEV;
3798
3799 /*
3800 * Override ->prepare() and ->cleanup() operations to notify the HDMI
3801 * codec about format changes.
3802 */
3803 stream = &pcm->stream[SNDRV_PCM_STREAM_PLAYBACK];
3804 stream->ops.prepare = tegra_hdmi_pcm_prepare;
3805 stream->ops.cleanup = tegra_hdmi_pcm_cleanup;
3806
3807 return 0;
3808}
3809
3810static int patch_tegra_hdmi(struct hda_codec *codec)
3811{
Mohan Kumar216116e2020-08-25 10:54:14 +05303812 struct hdmi_spec *spec;
Thierry Reding26e9a962015-05-05 14:56:20 +02003813 int err;
3814
3815 err = patch_generic_hdmi(codec);
3816 if (err)
3817 return err;
3818
3819 codec->patch_ops.build_pcms = tegra_hdmi_build_pcms;
Mohan Kumar216116e2020-08-25 10:54:14 +05303820 spec = codec->spec;
3821 spec->chmap.ops.chmap_cea_alloc_validate_get_type =
3822 nvhdmi_chmap_cea_alloc_validate_get_type;
3823 spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
Thierry Reding26e9a962015-05-05 14:56:20 +02003824
3825 return 0;
3826}
3827
3828/*
Anssi Hannula5a6135842013-10-24 21:10:35 +03003829 * ATI/AMD-specific implementations
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003830 */
3831
Anssi Hannula5a6135842013-10-24 21:10:35 +03003832#define is_amdhdmi_rev3_or_later(codec) \
Takashi Iwai7639a062015-03-03 10:07:24 +01003833 ((codec)->core.vendor_id == 0x1002aa01 && \
3834 ((codec)->core.revision_id & 0xff00) >= 0x0300)
Anssi Hannula5a6135842013-10-24 21:10:35 +03003835#define has_amd_full_remap_support(codec) is_amdhdmi_rev3_or_later(codec)
Takashi Iwai84eb01b2010-09-07 12:27:25 +02003836
Anssi Hannula5a6135842013-10-24 21:10:35 +03003837/* ATI/AMD specific HDA pin verbs, see the AMD HDA Verbs specification */
3838#define ATI_VERB_SET_CHANNEL_ALLOCATION 0x771
3839#define ATI_VERB_SET_DOWNMIX_INFO 0x772
3840#define ATI_VERB_SET_MULTICHANNEL_01 0x777
3841#define ATI_VERB_SET_MULTICHANNEL_23 0x778
3842#define ATI_VERB_SET_MULTICHANNEL_45 0x779
3843#define ATI_VERB_SET_MULTICHANNEL_67 0x77a
Anssi Hannula461cf6b2013-10-24 21:10:37 +03003844#define ATI_VERB_SET_HBR_CONTROL 0x77c
Anssi Hannula5a6135842013-10-24 21:10:35 +03003845#define ATI_VERB_SET_MULTICHANNEL_1 0x785
3846#define ATI_VERB_SET_MULTICHANNEL_3 0x786
3847#define ATI_VERB_SET_MULTICHANNEL_5 0x787
3848#define ATI_VERB_SET_MULTICHANNEL_7 0x788
3849#define ATI_VERB_SET_MULTICHANNEL_MODE 0x789
3850#define ATI_VERB_GET_CHANNEL_ALLOCATION 0xf71
3851#define ATI_VERB_GET_DOWNMIX_INFO 0xf72
3852#define ATI_VERB_GET_MULTICHANNEL_01 0xf77
3853#define ATI_VERB_GET_MULTICHANNEL_23 0xf78
3854#define ATI_VERB_GET_MULTICHANNEL_45 0xf79
3855#define ATI_VERB_GET_MULTICHANNEL_67 0xf7a
Anssi Hannula461cf6b2013-10-24 21:10:37 +03003856#define ATI_VERB_GET_HBR_CONTROL 0xf7c
Anssi Hannula5a6135842013-10-24 21:10:35 +03003857#define ATI_VERB_GET_MULTICHANNEL_1 0xf85
3858#define ATI_VERB_GET_MULTICHANNEL_3 0xf86
3859#define ATI_VERB_GET_MULTICHANNEL_5 0xf87
3860#define ATI_VERB_GET_MULTICHANNEL_7 0xf88
3861#define ATI_VERB_GET_MULTICHANNEL_MODE 0xf89
3862
Anssi Hannula84d69e72013-10-24 21:10:38 +03003863/* AMD specific HDA cvt verbs */
3864#define ATI_VERB_SET_RAMP_RATE 0x770
3865#define ATI_VERB_GET_RAMP_RATE 0xf70
3866
Anssi Hannula5a6135842013-10-24 21:10:35 +03003867#define ATI_OUT_ENABLE 0x1
3868
3869#define ATI_MULTICHANNEL_MODE_PAIRED 0
3870#define ATI_MULTICHANNEL_MODE_SINGLE 1
3871
Anssi Hannula461cf6b2013-10-24 21:10:37 +03003872#define ATI_HBR_CAPABLE 0x01
3873#define ATI_HBR_ENABLE 0x10
3874
Anssi Hannula89250f82013-10-24 21:10:36 +03003875static int atihdmi_pin_get_eld(struct hda_codec *codec, hda_nid_t nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05303876 int dev_id, unsigned char *buf, int *eld_size)
Anssi Hannula89250f82013-10-24 21:10:36 +03003877{
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05303878 WARN_ON(dev_id != 0);
Anssi Hannula89250f82013-10-24 21:10:36 +03003879 /* call hda_eld.c ATI/AMD-specific function */
3880 return snd_hdmi_get_eld_ati(codec, nid, buf, eld_size,
3881 is_amdhdmi_rev3_or_later(codec));
3882}
3883
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05303884static void atihdmi_pin_setup_infoframe(struct hda_codec *codec,
3885 hda_nid_t pin_nid, int dev_id, int ca,
Anssi Hannula5a6135842013-10-24 21:10:35 +03003886 int active_channels, int conn_type)
3887{
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05303888 WARN_ON(dev_id != 0);
Anssi Hannula5a6135842013-10-24 21:10:35 +03003889 snd_hda_codec_write(codec, pin_nid, 0, ATI_VERB_SET_CHANNEL_ALLOCATION, ca);
3890}
3891
3892static int atihdmi_paired_swap_fc_lfe(int pos)
3893{
3894 /*
3895 * ATI/AMD have automatic FC/LFE swap built-in
3896 * when in pairwise mapping mode.
3897 */
3898
3899 switch (pos) {
3900 /* see channel_allocations[].speakers[] */
3901 case 2: return 3;
3902 case 3: return 2;
3903 default: break;
3904 }
3905
3906 return pos;
3907}
3908
Subhransu S. Prusty828cb4e2016-03-04 19:59:50 +05303909static int atihdmi_paired_chmap_validate(struct hdac_chmap *chmap,
3910 int ca, int chs, unsigned char *map)
Anssi Hannula5a6135842013-10-24 21:10:35 +03003911{
Subhransu S. Prustyf3022402016-03-04 19:59:48 +05303912 struct hdac_cea_channel_speaker_allocation *cap;
Anssi Hannula5a6135842013-10-24 21:10:35 +03003913 int i, j;
3914
3915 /* check that only channel pairs need to be remapped on old pre-rev3 ATI/AMD */
3916
Subhransu S. Prustybb63f722016-03-04 19:59:52 +05303917 cap = snd_hdac_get_ch_alloc_from_ca(ca);
Anssi Hannula5a6135842013-10-24 21:10:35 +03003918 for (i = 0; i < chs; ++i) {
Subhransu S. Prustybb63f722016-03-04 19:59:52 +05303919 int mask = snd_hdac_chmap_to_spk_mask(map[i]);
Anssi Hannula5a6135842013-10-24 21:10:35 +03003920 bool ok = false;
3921 bool companion_ok = false;
3922
3923 if (!mask)
3924 continue;
3925
3926 for (j = 0 + i % 2; j < 8; j += 2) {
3927 int chan_idx = 7 - atihdmi_paired_swap_fc_lfe(j);
3928 if (cap->speakers[chan_idx] == mask) {
3929 /* channel is in a supported position */
3930 ok = true;
3931
3932 if (i % 2 == 0 && i + 1 < chs) {
3933 /* even channel, check the odd companion */
3934 int comp_chan_idx = 7 - atihdmi_paired_swap_fc_lfe(j + 1);
Subhransu S. Prustybb63f722016-03-04 19:59:52 +05303935 int comp_mask_req = snd_hdac_chmap_to_spk_mask(map[i+1]);
Anssi Hannula5a6135842013-10-24 21:10:35 +03003936 int comp_mask_act = cap->speakers[comp_chan_idx];
3937
3938 if (comp_mask_req == comp_mask_act)
3939 companion_ok = true;
3940 else
3941 return -EINVAL;
3942 }
3943 break;
3944 }
3945 }
3946
3947 if (!ok)
3948 return -EINVAL;
3949
3950 if (companion_ok)
3951 i++; /* companion channel already checked */
3952 }
3953
3954 return 0;
3955}
3956
Subhransu S. Prusty739ffee2016-03-04 19:59:49 +05303957static int atihdmi_pin_set_slot_channel(struct hdac_device *hdac,
3958 hda_nid_t pin_nid, int hdmi_slot, int stream_channel)
Anssi Hannula5a6135842013-10-24 21:10:35 +03003959{
Kai-Heng Feng8c118272020-05-05 11:03:53 +08003960 struct hda_codec *codec = hdac_to_hda_codec(hdac);
Anssi Hannula5a6135842013-10-24 21:10:35 +03003961 int verb;
3962 int ati_channel_setup = 0;
3963
3964 if (hdmi_slot > 7)
3965 return -EINVAL;
3966
3967 if (!has_amd_full_remap_support(codec)) {
3968 hdmi_slot = atihdmi_paired_swap_fc_lfe(hdmi_slot);
3969
3970 /* In case this is an odd slot but without stream channel, do not
3971 * disable the slot since the corresponding even slot could have a
3972 * channel. In case neither have a channel, the slot pair will be
3973 * disabled when this function is called for the even slot. */
3974 if (hdmi_slot % 2 != 0 && stream_channel == 0xf)
3975 return 0;
3976
3977 hdmi_slot -= hdmi_slot % 2;
3978
3979 if (stream_channel != 0xf)
3980 stream_channel -= stream_channel % 2;
3981 }
3982
3983 verb = ATI_VERB_SET_MULTICHANNEL_01 + hdmi_slot/2 + (hdmi_slot % 2) * 0x00e;
3984
3985 /* ati_channel_setup format: [7..4] = stream_channel_id, [1] = mute, [0] = enable */
3986
3987 if (stream_channel != 0xf)
3988 ati_channel_setup = (stream_channel << 4) | ATI_OUT_ENABLE;
3989
3990 return snd_hda_codec_write(codec, pin_nid, 0, verb, ati_channel_setup);
3991}
3992
Subhransu S. Prusty739ffee2016-03-04 19:59:49 +05303993static int atihdmi_pin_get_slot_channel(struct hdac_device *hdac,
3994 hda_nid_t pin_nid, int asp_slot)
Anssi Hannula5a6135842013-10-24 21:10:35 +03003995{
Kai-Heng Feng8c118272020-05-05 11:03:53 +08003996 struct hda_codec *codec = hdac_to_hda_codec(hdac);
Anssi Hannula5a6135842013-10-24 21:10:35 +03003997 bool was_odd = false;
3998 int ati_asp_slot = asp_slot;
3999 int verb;
4000 int ati_channel_setup;
4001
4002 if (asp_slot > 7)
4003 return -EINVAL;
4004
4005 if (!has_amd_full_remap_support(codec)) {
4006 ati_asp_slot = atihdmi_paired_swap_fc_lfe(asp_slot);
4007 if (ati_asp_slot % 2 != 0) {
4008 ati_asp_slot -= 1;
4009 was_odd = true;
4010 }
4011 }
4012
4013 verb = ATI_VERB_GET_MULTICHANNEL_01 + ati_asp_slot/2 + (ati_asp_slot % 2) * 0x00e;
4014
4015 ati_channel_setup = snd_hda_codec_read(codec, pin_nid, 0, verb, 0);
4016
4017 if (!(ati_channel_setup & ATI_OUT_ENABLE))
4018 return 0xf;
4019
4020 return ((ati_channel_setup & 0xf0) >> 4) + !!was_odd;
4021}
4022
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05304023static int atihdmi_paired_chmap_cea_alloc_validate_get_type(
4024 struct hdac_chmap *chmap,
Subhransu S. Prustyf3022402016-03-04 19:59:48 +05304025 struct hdac_cea_channel_speaker_allocation *cap,
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05304026 int channels)
Anssi Hannula5a6135842013-10-24 21:10:35 +03004027{
4028 int c;
4029
4030 /*
4031 * Pre-rev3 ATI/AMD codecs operate in a paired channel mode, so
4032 * we need to take that into account (a single channel may take 2
4033 * channel slots if we need to carry a silent channel next to it).
4034 * On Rev3+ AMD codecs this function is not used.
4035 */
4036 int chanpairs = 0;
4037
4038 /* We only produce even-numbered channel count TLVs */
4039 if ((channels % 2) != 0)
4040 return -1;
4041
4042 for (c = 0; c < 7; c += 2) {
4043 if (cap->speakers[c] || cap->speakers[c+1])
4044 chanpairs++;
4045 }
4046
4047 if (chanpairs * 2 != channels)
4048 return -1;
4049
4050 return SNDRV_CTL_TLVT_CHMAP_PAIRED;
4051}
4052
Subhransu S. Prusty828cb4e2016-03-04 19:59:50 +05304053static void atihdmi_paired_cea_alloc_to_tlv_chmap(struct hdac_chmap *hchmap,
Subhransu S. Prustyf3022402016-03-04 19:59:48 +05304054 struct hdac_cea_channel_speaker_allocation *cap,
4055 unsigned int *chmap, int channels)
Anssi Hannula5a6135842013-10-24 21:10:35 +03004056{
4057 /* produce paired maps for pre-rev3 ATI/AMD codecs */
4058 int count = 0;
4059 int c;
4060
4061 for (c = 7; c >= 0; c--) {
4062 int chan = 7 - atihdmi_paired_swap_fc_lfe(7 - c);
4063 int spk = cap->speakers[chan];
4064 if (!spk) {
4065 /* add N/A channel if the companion channel is occupied */
4066 if (cap->speakers[chan + (chan % 2 ? -1 : 1)])
4067 chmap[count++] = SNDRV_CHMAP_NA;
4068
4069 continue;
4070 }
4071
Subhransu S. Prustybb63f722016-03-04 19:59:52 +05304072 chmap[count++] = snd_hdac_spk_to_chmap(spk);
Anssi Hannula5a6135842013-10-24 21:10:35 +03004073 }
4074
4075 WARN_ON(count != channels);
4076}
4077
Anssi Hannula461cf6b2013-10-24 21:10:37 +03004078static int atihdmi_pin_hbr_setup(struct hda_codec *codec, hda_nid_t pin_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05304079 int dev_id, bool hbr)
Anssi Hannula461cf6b2013-10-24 21:10:37 +03004080{
4081 int hbr_ctl, hbr_ctl_new;
4082
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05304083 WARN_ON(dev_id != 0);
4084
Anssi Hannula461cf6b2013-10-24 21:10:37 +03004085 hbr_ctl = snd_hda_codec_read(codec, pin_nid, 0, ATI_VERB_GET_HBR_CONTROL, 0);
Anssi Hannula13122e62013-11-10 20:56:10 +02004086 if (hbr_ctl >= 0 && (hbr_ctl & ATI_HBR_CAPABLE)) {
Anssi Hannula461cf6b2013-10-24 21:10:37 +03004087 if (hbr)
4088 hbr_ctl_new = hbr_ctl | ATI_HBR_ENABLE;
4089 else
4090 hbr_ctl_new = hbr_ctl & ~ATI_HBR_ENABLE;
4091
Takashi Iwai4e76a882014-02-25 12:21:03 +01004092 codec_dbg(codec,
4093 "atihdmi_pin_hbr_setup: NID=0x%x, %shbr-ctl=0x%x\n",
Anssi Hannula461cf6b2013-10-24 21:10:37 +03004094 pin_nid,
4095 hbr_ctl == hbr_ctl_new ? "" : "new-",
4096 hbr_ctl_new);
4097
4098 if (hbr_ctl != hbr_ctl_new)
4099 snd_hda_codec_write(codec, pin_nid, 0,
4100 ATI_VERB_SET_HBR_CONTROL,
4101 hbr_ctl_new);
4102
4103 } else if (hbr)
4104 return -EINVAL;
4105
4106 return 0;
4107}
4108
Anssi Hannula84d69e72013-10-24 21:10:38 +03004109static int atihdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05304110 hda_nid_t pin_nid, int dev_id,
4111 u32 stream_tag, int format)
Anssi Hannula84d69e72013-10-24 21:10:38 +03004112{
Anssi Hannula84d69e72013-10-24 21:10:38 +03004113 if (is_amdhdmi_rev3_or_later(codec)) {
4114 int ramp_rate = 180; /* default as per AMD spec */
4115 /* disable ramp-up/down for non-pcm as per AMD spec */
4116 if (format & AC_FMT_TYPE_NON_PCM)
4117 ramp_rate = 0;
4118
4119 snd_hda_codec_write(codec, cvt_nid, 0, ATI_VERB_SET_RAMP_RATE, ramp_rate);
4120 }
4121
Nikhil Mahale9c32fea2019-11-19 14:17:09 +05304122 return hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
4123 stream_tag, format);
Anssi Hannula84d69e72013-10-24 21:10:38 +03004124}
4125
4126
Anssi Hannula5a6135842013-10-24 21:10:35 +03004127static int atihdmi_init(struct hda_codec *codec)
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004128{
4129 struct hdmi_spec *spec = codec->spec;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004130 int pin_idx, err;
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004131
Anssi Hannula5a6135842013-10-24 21:10:35 +03004132 err = generic_hdmi_init(codec);
4133
4134 if (err)
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004135 return err;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004136
4137 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
4138 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
4139
4140 /* make sure downmix information in infoframe is zero */
4141 snd_hda_codec_write(codec, per_pin->pin_nid, 0, ATI_VERB_SET_DOWNMIX_INFO, 0);
4142
4143 /* enable channel-wise remap mode if supported */
4144 if (has_amd_full_remap_support(codec))
4145 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
4146 ATI_VERB_SET_MULTICHANNEL_MODE,
4147 ATI_MULTICHANNEL_MODE_SINGLE);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004148 }
Alex Deucher8218df92019-11-22 16:43:53 -05004149 codec->auto_runtime_pm = 1;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004150
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004151 return 0;
4152}
4153
Takashi Iwaiade49db2018-07-11 18:05:52 +02004154/* map from pin NID to port; port is 0-based */
4155/* for AMD: assume widget NID starting from 3, with step 2 (3, 5, 7, ...) */
4156static int atihdmi_pin2port(void *audio_ptr, int pin_nid)
4157{
4158 return pin_nid / 2 - 1;
4159}
4160
4161/* reverse-map from port to pin NID: see above */
4162static int atihdmi_port2pin(struct hda_codec *codec, int port)
4163{
4164 return port * 2 + 3;
4165}
4166
4167static const struct drm_audio_component_audio_ops atihdmi_audio_ops = {
4168 .pin2port = atihdmi_pin2port,
4169 .pin_eld_notify = generic_acomp_pin_eld_notify,
4170 .master_bind = generic_acomp_master_bind,
4171 .master_unbind = generic_acomp_master_unbind,
4172};
4173
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004174static int patch_atihdmi(struct hda_codec *codec)
4175{
4176 struct hdmi_spec *spec;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004177 struct hdmi_spec_per_cvt *per_cvt;
4178 int err, cvt_idx;
4179
4180 err = patch_generic_hdmi(codec);
4181
4182 if (err)
Takashi Iwaid0b12522012-06-15 14:34:42 +02004183 return err;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004184
4185 codec->patch_ops.init = atihdmi_init;
4186
Takashi Iwaid0b12522012-06-15 14:34:42 +02004187 spec = codec->spec;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004188
Anssi Hannula89250f82013-10-24 21:10:36 +03004189 spec->ops.pin_get_eld = atihdmi_pin_get_eld;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004190 spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe;
Anssi Hannula461cf6b2013-10-24 21:10:37 +03004191 spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;
Anssi Hannula84d69e72013-10-24 21:10:38 +03004192 spec->ops.setup_stream = atihdmi_setup_stream;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004193
Takashi Iwai39669222016-05-11 14:56:12 +02004194 spec->chmap.ops.pin_get_slot_channel = atihdmi_pin_get_slot_channel;
4195 spec->chmap.ops.pin_set_slot_channel = atihdmi_pin_set_slot_channel;
4196
Anssi Hannula5a6135842013-10-24 21:10:35 +03004197 if (!has_amd_full_remap_support(codec)) {
4198 /* override to ATI/AMD-specific versions with pairwise mapping */
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05304199 spec->chmap.ops.chmap_cea_alloc_validate_get_type =
Anssi Hannula5a6135842013-10-24 21:10:35 +03004200 atihdmi_paired_chmap_cea_alloc_validate_get_type;
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05304201 spec->chmap.ops.cea_alloc_to_tlv_chmap =
4202 atihdmi_paired_cea_alloc_to_tlv_chmap;
4203 spec->chmap.ops.chmap_validate = atihdmi_paired_chmap_validate;
Anssi Hannula5a6135842013-10-24 21:10:35 +03004204 }
4205
4206 /* ATI/AMD converters do not advertise all of their capabilities */
4207 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
4208 per_cvt = get_cvt(spec, cvt_idx);
4209 per_cvt->channels_max = max(per_cvt->channels_max, 8u);
4210 per_cvt->rates |= SUPPORTED_RATES;
4211 per_cvt->formats |= SUPPORTED_FORMATS;
4212 per_cvt->maxbps = max(per_cvt->maxbps, 24u);
4213 }
4214
Subhransu S. Prusty67b90cb2016-03-04 19:59:46 +05304215 spec->chmap.channels_max = max(spec->chmap.channels_max, 8u);
Anssi Hannula5a6135842013-10-24 21:10:35 +03004216
Takashi Iwai57cb54e2018-06-21 13:33:53 +02004217 /* AMD GPUs have neither EPSS nor CLKSTOP bits, hence preventing
4218 * the link-down as is. Tell the core to allow it.
4219 */
4220 codec->link_down_at_suspend = 1;
4221
Takashi Iwaiade49db2018-07-11 18:05:52 +02004222 generic_acomp_init(codec, &atihdmi_audio_ops, atihdmi_port2pin);
4223
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004224 return 0;
4225}
4226
Annie Liu3de5ff82012-06-08 19:18:42 +08004227/* VIA HDMI Implementation */
4228#define VIAHDMI_CVT_NID 0x02 /* audio converter1 */
4229#define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */
4230
Annie Liu3de5ff82012-06-08 19:18:42 +08004231static int patch_via_hdmi(struct hda_codec *codec)
4232{
Takashi Iwai250e41a2012-06-15 14:40:21 +02004233 return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
Annie Liu3de5ff82012-06-08 19:18:42 +08004234}
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004235
4236/*
4237 * patch entries
4238 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004239static const struct hda_device_id snd_hda_id_hdmi[] = {
4240HDA_CODEC_ENTRY(0x1002793c, "RS600 HDMI", patch_atihdmi),
4241HDA_CODEC_ENTRY(0x10027919, "RS600 HDMI", patch_atihdmi),
4242HDA_CODEC_ENTRY(0x1002791a, "RS690/780 HDMI", patch_atihdmi),
4243HDA_CODEC_ENTRY(0x1002aa01, "R6xx HDMI", patch_atihdmi),
4244HDA_CODEC_ENTRY(0x10951390, "SiI1390 HDMI", patch_generic_hdmi),
4245HDA_CODEC_ENTRY(0x10951392, "SiI1392 HDMI", patch_generic_hdmi),
4246HDA_CODEC_ENTRY(0x17e80047, "Chrontel HDMI", patch_generic_hdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004247HDA_CODEC_ENTRY(0x10de0001, "MCP73 HDMI", patch_nvhdmi_2ch),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004248HDA_CODEC_ENTRY(0x10de0002, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
4249HDA_CODEC_ENTRY(0x10de0003, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004250HDA_CODEC_ENTRY(0x10de0004, "GPU 04 HDMI", patch_nvhdmi_8ch_7x),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004251HDA_CODEC_ENTRY(0x10de0005, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
4252HDA_CODEC_ENTRY(0x10de0006, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
4253HDA_CODEC_ENTRY(0x10de0007, "MCP79/7A HDMI", patch_nvhdmi_8ch_7x),
Nikhil Mahale5398e942019-11-19 14:17:10 +05304254HDA_CODEC_ENTRY(0x10de0008, "GPU 08 HDMI/DP", patch_nvhdmi_legacy),
4255HDA_CODEC_ENTRY(0x10de0009, "GPU 09 HDMI/DP", patch_nvhdmi_legacy),
4256HDA_CODEC_ENTRY(0x10de000a, "GPU 0a HDMI/DP", patch_nvhdmi_legacy),
4257HDA_CODEC_ENTRY(0x10de000b, "GPU 0b HDMI/DP", patch_nvhdmi_legacy),
4258HDA_CODEC_ENTRY(0x10de000c, "MCP89 HDMI", patch_nvhdmi_legacy),
4259HDA_CODEC_ENTRY(0x10de000d, "GPU 0d HDMI/DP", patch_nvhdmi_legacy),
4260HDA_CODEC_ENTRY(0x10de0010, "GPU 10 HDMI/DP", patch_nvhdmi_legacy),
4261HDA_CODEC_ENTRY(0x10de0011, "GPU 11 HDMI/DP", patch_nvhdmi_legacy),
4262HDA_CODEC_ENTRY(0x10de0012, "GPU 12 HDMI/DP", patch_nvhdmi_legacy),
4263HDA_CODEC_ENTRY(0x10de0013, "GPU 13 HDMI/DP", patch_nvhdmi_legacy),
4264HDA_CODEC_ENTRY(0x10de0014, "GPU 14 HDMI/DP", patch_nvhdmi_legacy),
4265HDA_CODEC_ENTRY(0x10de0015, "GPU 15 HDMI/DP", patch_nvhdmi_legacy),
4266HDA_CODEC_ENTRY(0x10de0016, "GPU 16 HDMI/DP", patch_nvhdmi_legacy),
Richard Samsonc8900a02011-03-03 12:46:13 +01004267/* 17 is known to be absent */
Nikhil Mahale5398e942019-11-19 14:17:10 +05304268HDA_CODEC_ENTRY(0x10de0018, "GPU 18 HDMI/DP", patch_nvhdmi_legacy),
4269HDA_CODEC_ENTRY(0x10de0019, "GPU 19 HDMI/DP", patch_nvhdmi_legacy),
4270HDA_CODEC_ENTRY(0x10de001a, "GPU 1a HDMI/DP", patch_nvhdmi_legacy),
4271HDA_CODEC_ENTRY(0x10de001b, "GPU 1b HDMI/DP", patch_nvhdmi_legacy),
4272HDA_CODEC_ENTRY(0x10de001c, "GPU 1c HDMI/DP", patch_nvhdmi_legacy),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004273HDA_CODEC_ENTRY(0x10de0020, "Tegra30 HDMI", patch_tegra_hdmi),
4274HDA_CODEC_ENTRY(0x10de0022, "Tegra114 HDMI", patch_tegra_hdmi),
4275HDA_CODEC_ENTRY(0x10de0028, "Tegra124 HDMI", patch_tegra_hdmi),
4276HDA_CODEC_ENTRY(0x10de0029, "Tegra210 HDMI/DP", patch_tegra_hdmi),
Thierry Reding917bb902018-12-03 16:53:17 +01004277HDA_CODEC_ENTRY(0x10de002d, "Tegra186 HDMI/DP0", patch_tegra_hdmi),
4278HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi),
4279HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi),
4280HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004281HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi),
4282HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi),
4283HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi),
4284HDA_CODEC_ENTRY(0x10de0043, "GPU 43 HDMI/DP", patch_nvhdmi),
4285HDA_CODEC_ENTRY(0x10de0044, "GPU 44 HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004286HDA_CODEC_ENTRY(0x10de0045, "GPU 45 HDMI/DP", patch_nvhdmi),
4287HDA_CODEC_ENTRY(0x10de0050, "GPU 50 HDMI/DP", patch_nvhdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004288HDA_CODEC_ENTRY(0x10de0051, "GPU 51 HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004289HDA_CODEC_ENTRY(0x10de0052, "GPU 52 HDMI/DP", patch_nvhdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004290HDA_CODEC_ENTRY(0x10de0060, "GPU 60 HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004291HDA_CODEC_ENTRY(0x10de0061, "GPU 61 HDMI/DP", patch_nvhdmi),
4292HDA_CODEC_ENTRY(0x10de0062, "GPU 62 HDMI/DP", patch_nvhdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004293HDA_CODEC_ENTRY(0x10de0067, "MCP67 HDMI", patch_nvhdmi_2ch),
4294HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI/DP", patch_nvhdmi),
4295HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi),
4296HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004297HDA_CODEC_ENTRY(0x10de0073, "GPU 73 HDMI/DP", patch_nvhdmi),
4298HDA_CODEC_ENTRY(0x10de0074, "GPU 74 HDMI/DP", patch_nvhdmi),
4299HDA_CODEC_ENTRY(0x10de0076, "GPU 76 HDMI/DP", patch_nvhdmi),
4300HDA_CODEC_ENTRY(0x10de007b, "GPU 7b HDMI/DP", patch_nvhdmi),
4301HDA_CODEC_ENTRY(0x10de007c, "GPU 7c HDMI/DP", patch_nvhdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004302HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004303HDA_CODEC_ENTRY(0x10de007e, "GPU 7e HDMI/DP", patch_nvhdmi),
Hui Wangaf677162017-02-09 09:20:54 +08004304HDA_CODEC_ENTRY(0x10de0080, "GPU 80 HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004305HDA_CODEC_ENTRY(0x10de0081, "GPU 81 HDMI/DP", patch_nvhdmi),
Aaron Plattner2d369c72016-03-13 13:58:57 -07004306HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP", patch_nvhdmi),
Aaron Plattner3ec622f2016-01-28 14:07:38 -08004307HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP", patch_nvhdmi),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004308HDA_CODEC_ENTRY(0x10de0084, "GPU 84 HDMI/DP", patch_nvhdmi),
4309HDA_CODEC_ENTRY(0x10de0090, "GPU 90 HDMI/DP", patch_nvhdmi),
4310HDA_CODEC_ENTRY(0x10de0091, "GPU 91 HDMI/DP", patch_nvhdmi),
4311HDA_CODEC_ENTRY(0x10de0092, "GPU 92 HDMI/DP", patch_nvhdmi),
4312HDA_CODEC_ENTRY(0x10de0093, "GPU 93 HDMI/DP", patch_nvhdmi),
4313HDA_CODEC_ENTRY(0x10de0094, "GPU 94 HDMI/DP", patch_nvhdmi),
4314HDA_CODEC_ENTRY(0x10de0095, "GPU 95 HDMI/DP", patch_nvhdmi),
4315HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi),
4316HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi),
4317HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi),
Aaron Plattneradb36a822020-06-11 11:08:45 -07004318HDA_CODEC_ENTRY(0x10de009a, "GPU 9a HDMI/DP", patch_nvhdmi),
4319HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP", patch_nvhdmi),
4320HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP", patch_nvhdmi),
4321HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi),
4322HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004323HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
Daniel Dadap74ec1182017-07-13 19:27:39 -05004324HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004325HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
4326HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP", patch_via_hdmi),
4327HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),
4328HDA_CODEC_ENTRY(0x11069f85, "VX11 HDMI/DP", patch_generic_hdmi),
Takashi Iwai7ff652f2016-03-21 14:50:24 +01004329HDA_CODEC_ENTRY(0x80860054, "IbexPeak HDMI", patch_i915_cpt_hdmi),
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01004330HDA_CODEC_ENTRY(0x80862800, "Geminilake HDMI", patch_i915_glk_hdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004331HDA_CODEC_ENTRY(0x80862801, "Bearlake HDMI", patch_generic_hdmi),
4332HDA_CODEC_ENTRY(0x80862802, "Cantiga HDMI", patch_generic_hdmi),
4333HDA_CODEC_ENTRY(0x80862803, "Eaglelake HDMI", patch_generic_hdmi),
Takashi Iwai7ff652f2016-03-21 14:50:24 +01004334HDA_CODEC_ENTRY(0x80862804, "IbexPeak HDMI", patch_i915_cpt_hdmi),
Takashi Iwaie85015a32016-03-21 13:56:19 +01004335HDA_CODEC_ENTRY(0x80862805, "CougarPoint HDMI", patch_i915_cpt_hdmi),
4336HDA_CODEC_ENTRY(0x80862806, "PantherPoint HDMI", patch_i915_cpt_hdmi),
Takashi Iwaia6866322016-03-21 12:18:33 +01004337HDA_CODEC_ENTRY(0x80862807, "Haswell HDMI", patch_i915_hsw_hdmi),
4338HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_i915_hsw_hdmi),
4339HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi),
4340HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi),
4341HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi),
Guneshwor Singh2b4584d2017-12-07 18:06:20 +05304342HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI", patch_i915_glk_hdmi),
Ander Conselvan De Oliveiraa87a4d22017-04-13 13:05:35 +05304343HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
Jaroslav Kyselab0d8bc52019-03-13 17:09:23 +01004344HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi),
Kai Vehmanen9a11ba72019-11-05 18:10:53 +02004345HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
Kai Vehmanen69b08bd2020-09-21 17:17:38 +03004346HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi),
Kai Vehmanend78359b2020-11-16 16:19:55 +02004347HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi),
Kai Vehmanen5e941fc2021-01-13 17:56:29 +02004348HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_tgl_hdmi),
Rander Wangf804a322020-09-02 18:42:07 +03004349HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi),
Yong Zhi78be2222020-01-31 14:40:03 -06004350HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
Libin Yangd233c492020-04-09 13:58:17 -05004351HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004352HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
Takashi Iwaia6866322016-03-21 12:18:33 +01004353HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
4354HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004355HDA_CODEC_ENTRY(0x808629fb, "Crestline HDMI", patch_generic_hdmi),
Takashi Iwaid8a766a2015-02-17 15:25:37 +01004356/* special ID for generic HDMI */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004357HDA_CODEC_ENTRY(HDA_CODEC_ID_GENERIC_HDMI, "Generic HDMI", patch_generic_hdmi),
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004358{} /* terminator */
4359};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004360MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_hdmi);
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004361
4362MODULE_LICENSE("GPL");
4363MODULE_DESCRIPTION("HDMI HD-audio codec");
4364MODULE_ALIAS("snd-hda-codec-intelhdmi");
4365MODULE_ALIAS("snd-hda-codec-nvhdmi");
4366MODULE_ALIAS("snd-hda-codec-atihdmi");
4367
Takashi Iwaid8a766a2015-02-17 15:25:37 +01004368static struct hda_codec_driver hdmi_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02004369 .id = snd_hda_id_hdmi,
Takashi Iwai84eb01b2010-09-07 12:27:25 +02004370};
4371
Takashi Iwaid8a766a2015-02-17 15:25:37 +01004372module_hda_codec_driver(hdmi_driver);