]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.drivers/alsa-post-ga-hda-intelhdmi
Merge branch 'master' into next
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / alsa-post-ga-hda-intelhdmi
CommitLineData
2cb7cef9
BS
1From: Takashi Iwai <tiwai@suse.de>
2Subject: ALSA: Add Intel HDMI support
3Patch-mainline: 2.6.29
4References: bnc#485768
5
6Add the support for Intel HDMI devices.
7
8Signed-off-by: Takashi Iwai <tiwai@suse.de>
9
10---
11 sound/pci/Kconfig | 12
12 sound/pci/hda/Makefile | 2
13 sound/pci/hda/hda_codec.c | 87 +++++
14 sound/pci/hda/hda_codec.h | 7
15 sound/pci/hda/hda_eld.c | 592 ++++++++++++++++++++++++++++++++++
16 sound/pci/hda/hda_intel.c | 18 -
17 sound/pci/hda/hda_local.h | 68 +++
18 sound/pci/hda/hda_patch.h | 2
19 sound/pci/hda/hda_proc.c | 75 ----
20 sound/pci/hda/patch_atihdmi.c | 9
21 sound/pci/hda/patch_intelhdmi.c | 694 ++++++++++++++++++++++++++++++++++++++++
22 sound/pci/hda/patch_nvhdmi.c | 7
23 12 files changed, 1504 insertions(+), 69 deletions(-)
24
25--- a/sound/pci/Kconfig
26+++ b/sound/pci/Kconfig
27@@ -573,6 +573,18 @@ config SND_HDA_CODEC_NVHDMI
28 Say Y here to include NVIDIA HDMI HD-audio codec support in
29 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
30
31+config SND_HDA_CODEC_INTELHDMI
32+ bool "Build INTEL HDMI HD-audio codec support"
33+ depends on SND_HDA_INTEL
34+ default y
35+ help
36+ Say Y here to include INTEL HDMI HD-audio codec support in
37+ snd-hda-intel driver, such as Eaglelake integrated HDMI.
38+
39+config SND_HDA_ELD
40+ def_bool y
41+ depends on SND_HDA_CODEC_INTELHDMI
42+
43 config SND_HDA_CODEC_CONEXANT
44 bool "Build Conexant HD-audio codec support"
45 depends on SND_HDA_INTEL
46--- a/sound/pci/hda/Makefile
47+++ b/sound/pci/hda/Makefile
48@@ -16,5 +16,7 @@ snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATI
49 snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o
50 snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o
51 snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o
52+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_INTELHDMI) += patch_intelhdmi.o
53+snd-hda-intel-$(CONFIG_SND_HDA_ELD) += hda_eld.o
54
55 obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
56--- a/sound/pci/hda/hda_codec.c
57+++ b/sound/pci/hda/hda_codec.c
58@@ -55,6 +55,7 @@ static struct hda_vendor_id hda_vendor_i
59 { 0x1002, "ATI" },
60 { 0x1057, "Motorola" },
61 { 0x1095, "Silicon Image" },
62+ { 0x10de, "Nvidia" },
63 { 0x10ec, "Realtek" },
64 { 0x1106, "VIA" },
65 { 0x111d, "IDT" },
66@@ -64,7 +65,9 @@ static struct hda_vendor_id hda_vendor_i
67 { 0x14f1, "Conexant" },
68 { 0x17e8, "Chrontel" },
69 { 0x1854, "LG" },
70+ { 0x1aec, "Wolfson Microelectronics" },
71 { 0x434d, "C-Media" },
72+ { 0x8086, "Intel" },
73 { 0x8384, "SigmaTel" },
74 {} /* terminator */
75 };
76@@ -97,6 +100,9 @@ static const struct hda_codec_preset *hd
77 #ifdef CONFIG_SND_HDA_CODEC_NVHDMI
78 snd_hda_preset_nvhdmi,
79 #endif
80+#ifdef CONFIG_SND_HDA_CODEC_INTELHDMI
81+ snd_hda_preset_intelhdmi,
82+#endif
83 NULL
84 };
85
86@@ -124,6 +130,52 @@ make_codec_cmd(struct hda_codec *codec,
87 return val;
88 }
89
90+const char *snd_hda_get_jack_location(u32 cfg)
91+{
92+ static char *bases[7] = {
93+ "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
94+ };
95+ static unsigned char specials_idx[] = {
96+ 0x07, 0x08,
97+ 0x17, 0x18, 0x19,
98+ 0x37, 0x38
99+ };
100+ static char *specials[] = {
101+ "Rear Panel", "Drive Bar",
102+ "Riser", "HDMI", "ATAPI",
103+ "Mobile-In", "Mobile-Out"
104+ };
105+ int i;
106+ cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
107+ if ((cfg & 0x0f) < 7)
108+ return bases[cfg & 0x0f];
109+ for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
110+ if (cfg == specials_idx[i])
111+ return specials[i];
112+ }
113+ return "UNKNOWN";
114+}
115+
116+const char *snd_hda_get_jack_connectivity(u32 cfg)
117+{
118+ static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
119+
120+ return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
121+}
122+
123+const char *snd_hda_get_jack_type(u32 cfg)
124+{
125+ static char *jack_types[16] = {
126+ "Line Out", "Speaker", "HP Out", "CD",
127+ "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
128+ "Line In", "Aux", "Mic", "Telephony",
129+ "SPDIF In", "Digitial In", "Reserved", "Other"
130+ };
131+
132+ return jack_types[(cfg & AC_DEFCFG_DEVICE)
133+ >> AC_DEFCFG_DEVICE_SHIFT];
134+}
135+
136 /**
137 * snd_hda_codec_read - send a command and get the response
138 * @codec: the HDA codec
139@@ -1636,6 +1688,8 @@ int snd_hda_create_spdif_out_ctls(struct
140 }
141 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
142 kctl = snd_ctl_new1(dig_mix, codec);
143+ if (!kctl)
144+ return -ENOMEM;
145 kctl->id.index = idx;
146 kctl->private_value = nid;
147 err = snd_ctl_add(codec->bus->card, kctl);
148@@ -1783,6 +1837,8 @@ int snd_hda_create_spdif_in_ctls(struct
149 }
150 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
151 kctl = snd_ctl_new1(dig_mix, codec);
152+ if (!kctl)
153+ return -ENOMEM;
154 kctl->private_value = nid;
155 err = snd_ctl_add(codec->bus->card, kctl);
156 if (err < 0)
157@@ -3263,3 +3319,34 @@ int snd_hda_codecs_inuse(struct hda_bus
158 }
159 #endif
160 #endif
161+
162+/*
163+ * used by hda_proc.c and hda_eld.c
164+ */
165+void snd_print_pcm_rates(int pcm, char *buf, int buflen)
166+{
167+ static unsigned int rates[] = {
168+ 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
169+ 96000, 176400, 192000, 384000
170+ };
171+ int i, j;
172+
173+ for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++)
174+ if (pcm & (1 << i))
175+ j += snprintf(buf + j, buflen - j, " %d", rates[i]);
176+
177+ buf[j] = '\0'; /* necessary when j == 0 */
178+}
179+
180+void snd_print_pcm_bits(int pcm, char *buf, int buflen)
181+{
182+ static unsigned int bits[] = { 8, 16, 20, 24, 32 };
183+ int i, j;
184+
185+ for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
186+ if (pcm & (AC_SUPPCM_BITS_8 << i))
187+ j += snprintf(buf + j, buflen - j, " %d", bits[i]);
188+
189+ buf[j] = '\0'; /* necessary when j == 0 */
190+}
191+
192--- a/sound/pci/hda/hda_codec.h
193+++ b/sound/pci/hda/hda_codec.h
194@@ -832,6 +832,13 @@ int snd_hda_resume(struct hda_bus *bus);
195 #endif
196
197 /*
198+ * get widget information
199+ */
200+const char *snd_hda_get_jack_connectivity(u32 cfg);
201+const char *snd_hda_get_jack_type(u32 cfg);
202+const char *snd_hda_get_jack_location(u32 cfg);
203+
204+/*
205 * power saving
206 */
207 #ifdef CONFIG_SND_HDA_POWER_SAVE
208--- /dev/null
209+++ b/sound/pci/hda/hda_eld.c
210@@ -0,0 +1,592 @@
211+/*
212+ * Generic routines and proc interface for ELD(EDID Like Data) information
213+ *
214+ * Copyright(c) 2008 Intel Corporation.
215+ *
216+ * Authors:
217+ * Wu Fengguang <wfg@linux.intel.com>
218+ *
219+ * This driver is free software; you can redistribute it and/or modify
220+ * it under the terms of the GNU General Public License as published by
221+ * the Free Software Foundation; either version 2 of the License, or
222+ * (at your option) any later version.
223+ *
224+ * This driver is distributed in the hope that it will be useful,
225+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
226+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
227+ * GNU General Public License for more details.
228+ *
229+ * You should have received a copy of the GNU General Public License
230+ * along with this program; if not, write to the Free Software
231+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
232+ */
233+
234+#include <linux/init.h>
235+#include <sound/core.h>
236+#include <asm/unaligned.h>
237+#include "hda_codec.h"
238+#include "hda_local.h"
239+
240+enum eld_versions {
241+ ELD_VER_CEA_861D = 2,
242+ ELD_VER_PARTIAL = 31,
243+};
244+
245+enum cea_edid_versions {
246+ CEA_EDID_VER_NONE = 0,
247+ CEA_EDID_VER_CEA861 = 1,
248+ CEA_EDID_VER_CEA861A = 2,
249+ CEA_EDID_VER_CEA861BCD = 3,
250+ CEA_EDID_VER_RESERVED = 4,
251+};
252+
253+static char *cea_speaker_allocation_names[] = {
254+ /* 0 */ "FL/FR",
255+ /* 1 */ "LFE",
256+ /* 2 */ "FC",
257+ /* 3 */ "RL/RR",
258+ /* 4 */ "RC",
259+ /* 5 */ "FLC/FRC",
260+ /* 6 */ "RLC/RRC",
261+ /* 7 */ "FLW/FRW",
262+ /* 8 */ "FLH/FRH",
263+ /* 9 */ "TC",
264+ /* 10 */ "FCH",
265+};
266+
267+static char *eld_connection_type_names[4] = {
268+ "HDMI",
269+ "DisplayPort",
270+ "2-reserved",
271+ "3-reserved"
272+};
273+
274+enum cea_audio_coding_types {
275+ AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
276+ AUDIO_CODING_TYPE_LPCM = 1,
277+ AUDIO_CODING_TYPE_AC3 = 2,
278+ AUDIO_CODING_TYPE_MPEG1 = 3,
279+ AUDIO_CODING_TYPE_MP3 = 4,
280+ AUDIO_CODING_TYPE_MPEG2 = 5,
281+ AUDIO_CODING_TYPE_AACLC = 6,
282+ AUDIO_CODING_TYPE_DTS = 7,
283+ AUDIO_CODING_TYPE_ATRAC = 8,
284+ AUDIO_CODING_TYPE_SACD = 9,
285+ AUDIO_CODING_TYPE_EAC3 = 10,
286+ AUDIO_CODING_TYPE_DTS_HD = 11,
287+ AUDIO_CODING_TYPE_MLP = 12,
288+ AUDIO_CODING_TYPE_DST = 13,
289+ AUDIO_CODING_TYPE_WMAPRO = 14,
290+ AUDIO_CODING_TYPE_REF_CXT = 15,
291+ /* also include valid xtypes below */
292+ AUDIO_CODING_TYPE_HE_AAC = 15,
293+ AUDIO_CODING_TYPE_HE_AAC2 = 16,
294+ AUDIO_CODING_TYPE_MPEG_SURROUND = 17,
295+};
296+
297+enum cea_audio_coding_xtypes {
298+ AUDIO_CODING_XTYPE_HE_REF_CT = 0,
299+ AUDIO_CODING_XTYPE_HE_AAC = 1,
300+ AUDIO_CODING_XTYPE_HE_AAC2 = 2,
301+ AUDIO_CODING_XTYPE_MPEG_SURROUND = 3,
302+ AUDIO_CODING_XTYPE_FIRST_RESERVED = 4,
303+};
304+
305+static char *cea_audio_coding_type_names[] = {
306+ /* 0 */ "undefined",
307+ /* 1 */ "LPCM",
308+ /* 2 */ "AC-3",
309+ /* 3 */ "MPEG1",
310+ /* 4 */ "MP3",
311+ /* 5 */ "MPEG2",
312+ /* 6 */ "AAC-LC",
313+ /* 7 */ "DTS",
314+ /* 8 */ "ATRAC",
315+ /* 9 */ "DSD (One Bit Audio)",
316+ /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)",
317+ /* 11 */ "DTS-HD",
318+ /* 12 */ "MLP (Dolby TrueHD)",
319+ /* 13 */ "DST",
320+ /* 14 */ "WMAPro",
321+ /* 15 */ "HE-AAC",
322+ /* 16 */ "HE-AACv2",
323+ /* 17 */ "MPEG Surround",
324+};
325+
326+/*
327+ * The following two lists are shared between
328+ * - HDMI audio InfoFrame (source to sink)
329+ * - CEA E-EDID Extension (sink to source)
330+ */
331+
332+/*
333+ * SS1:SS0 index => sample size
334+ */
335+static int cea_sample_sizes[4] = {
336+ 0, /* 0: Refer to Stream Header */
337+ AC_SUPPCM_BITS_16, /* 1: 16 bits */
338+ AC_SUPPCM_BITS_20, /* 2: 20 bits */
339+ AC_SUPPCM_BITS_24, /* 3: 24 bits */
340+};
341+
342+/*
343+ * SF2:SF1:SF0 index => sampling frequency
344+ */
345+static int cea_sampling_frequencies[8] = {
346+ 0, /* 0: Refer to Stream Header */
347+ SNDRV_PCM_RATE_32000, /* 1: 32000Hz */
348+ SNDRV_PCM_RATE_44100, /* 2: 44100Hz */
349+ SNDRV_PCM_RATE_48000, /* 3: 48000Hz */
350+ SNDRV_PCM_RATE_88200, /* 4: 88200Hz */
351+ SNDRV_PCM_RATE_96000, /* 5: 96000Hz */
352+ SNDRV_PCM_RATE_176400, /* 6: 176400Hz */
353+ SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
354+};
355+
356+static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
357+ int byte_index)
358+{
359+ unsigned int val;
360+
361+ val = snd_hda_codec_read(codec, nid, 0,
362+ AC_VERB_GET_HDMI_ELDD, byte_index);
363+
364+#ifdef BE_PARANOID
365+ printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
366+#endif
367+
368+ if ((val & AC_ELDD_ELD_VALID) == 0) {
369+ snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
370+ byte_index);
371+ val = 0;
372+ }
373+
374+ return val & AC_ELDD_ELD_DATA;
375+}
376+
377+#define GRAB_BITS(buf, byte, lowbit, bits) \
378+({ \
379+ BUILD_BUG_ON(lowbit > 7); \
380+ BUILD_BUG_ON(bits > 8); \
381+ BUILD_BUG_ON(bits <= 0); \
382+ \
383+ (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \
384+})
385+
386+static void hdmi_update_short_audio_desc(struct cea_sad *a,
387+ const unsigned char *buf)
388+{
389+ int i;
390+ int val;
391+
392+ val = GRAB_BITS(buf, 1, 0, 7);
393+ a->rates = 0;
394+ for (i = 0; i < 7; i++)
395+ if (val & (1 << i))
396+ a->rates |= cea_sampling_frequencies[i + 1];
397+
398+ a->channels = GRAB_BITS(buf, 0, 0, 3);
399+ a->channels++;
400+
401+ a->format = GRAB_BITS(buf, 0, 3, 4);
402+ switch (a->format) {
403+ case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
404+ snd_printd(KERN_INFO
405+ "HDMI: audio coding type 0 not expected\n");
406+ break;
407+
408+ case AUDIO_CODING_TYPE_LPCM:
409+ val = GRAB_BITS(buf, 2, 0, 3);
410+ a->sample_bits = 0;
411+ for (i = 0; i < 3; i++)
412+ if (val & (1 << i))
413+ a->sample_bits |= cea_sample_sizes[i + 1];
414+ break;
415+
416+ case AUDIO_CODING_TYPE_AC3:
417+ case AUDIO_CODING_TYPE_MPEG1:
418+ case AUDIO_CODING_TYPE_MP3:
419+ case AUDIO_CODING_TYPE_MPEG2:
420+ case AUDIO_CODING_TYPE_AACLC:
421+ case AUDIO_CODING_TYPE_DTS:
422+ case AUDIO_CODING_TYPE_ATRAC:
423+ a->max_bitrate = GRAB_BITS(buf, 2, 0, 8);
424+ a->max_bitrate *= 8000;
425+ break;
426+
427+ case AUDIO_CODING_TYPE_SACD:
428+ break;
429+
430+ case AUDIO_CODING_TYPE_EAC3:
431+ break;
432+
433+ case AUDIO_CODING_TYPE_DTS_HD:
434+ break;
435+
436+ case AUDIO_CODING_TYPE_MLP:
437+ break;
438+
439+ case AUDIO_CODING_TYPE_DST:
440+ break;
441+
442+ case AUDIO_CODING_TYPE_WMAPRO:
443+ a->profile = GRAB_BITS(buf, 2, 0, 3);
444+ break;
445+
446+ case AUDIO_CODING_TYPE_REF_CXT:
447+ a->format = GRAB_BITS(buf, 2, 3, 5);
448+ if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
449+ a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
450+ snd_printd(KERN_INFO
451+ "HDMI: audio coding xtype %d not expected\n",
452+ a->format);
453+ a->format = 0;
454+ } else
455+ a->format += AUDIO_CODING_TYPE_HE_AAC -
456+ AUDIO_CODING_XTYPE_HE_AAC;
457+ break;
458+ }
459+}
460+
461+/*
462+ * Be careful, ELD buf could be totally rubbish!
463+ */
464+static int hdmi_update_eld(struct hdmi_eld *e,
465+ const unsigned char *buf, int size)
466+{
467+ int mnl;
468+ int i;
469+
470+ e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
471+ if (e->eld_ver != ELD_VER_CEA_861D &&
472+ e->eld_ver != ELD_VER_PARTIAL) {
473+ snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
474+ e->eld_ver);
475+ goto out_fail;
476+ }
477+
478+ e->eld_size = size;
479+ e->baseline_len = GRAB_BITS(buf, 2, 0, 8);
480+ mnl = GRAB_BITS(buf, 4, 0, 5);
481+ e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3);
482+
483+ e->support_hdcp = GRAB_BITS(buf, 5, 0, 1);
484+ e->support_ai = GRAB_BITS(buf, 5, 1, 1);
485+ e->conn_type = GRAB_BITS(buf, 5, 2, 2);
486+ e->sad_count = GRAB_BITS(buf, 5, 4, 4);
487+
488+ e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2;
489+ e->spk_alloc = GRAB_BITS(buf, 7, 0, 7);
490+
491+ e->port_id = get_unaligned_le64(buf + 8);
492+
493+ /* not specified, but the spec's tendency is little endian */
494+ e->manufacture_id = get_unaligned_le16(buf + 16);
495+ e->product_id = get_unaligned_le16(buf + 18);
496+
497+ if (mnl > ELD_MAX_MNL) {
498+ snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl);
499+ goto out_fail;
500+ } else if (ELD_FIXED_BYTES + mnl > size) {
501+ snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
502+ goto out_fail;
503+ } else
504+ strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl);
505+
506+ for (i = 0; i < e->sad_count; i++) {
507+ if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
508+ snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
509+ goto out_fail;
510+ }
511+ hdmi_update_short_audio_desc(e->sad + i,
512+ buf + ELD_FIXED_BYTES + mnl + 3 * i);
513+ }
514+
515+ return 0;
516+
517+out_fail:
518+ e->eld_ver = 0;
519+ return -EINVAL;
520+}
521+
522+static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid)
523+{
524+ return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0);
525+}
526+
527+static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
528+{
529+ int eldv;
530+ int present;
531+
532+ present = hdmi_present_sense(codec, nid);
533+ eldv = (present & AC_PINSENSE_ELDV);
534+ present = (present & AC_PINSENSE_PRESENCE);
535+
536+#ifdef CONFIG_SND_DEBUG_VERBOSE
537+ printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n",
538+ !!present, !!eldv);
539+#endif
540+
541+ return eldv && present;
542+}
543+
544+int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
545+{
546+ return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
547+ AC_DIPSIZE_ELD_BUF);
548+}
549+
550+int snd_hdmi_get_eld(struct hdmi_eld *eld,
551+ struct hda_codec *codec, hda_nid_t nid)
552+{
553+ int i;
554+ int ret;
555+ int size;
556+ unsigned char *buf;
557+
558+ if (!hdmi_eld_valid(codec, nid))
559+ return -ENOENT;
560+
561+ size = snd_hdmi_get_eld_size(codec, nid);
562+ if (size == 0) {
563+ /* wfg: workaround for ASUS P5E-VM HDMI board */
564+ snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n");
565+ size = 128;
566+ }
567+ if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) {
568+ snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size);
569+ return -ERANGE;
570+ }
571+
572+ buf = kmalloc(size, GFP_KERNEL);
573+ if (!buf)
574+ return -ENOMEM;
575+
576+ for (i = 0; i < size; i++)
577+ buf[i] = hdmi_get_eld_byte(codec, nid, i);
578+
579+ ret = hdmi_update_eld(eld, buf, size);
580+
581+ kfree(buf);
582+ return ret;
583+}
584+
585+static void hdmi_show_short_audio_desc(struct cea_sad *a)
586+{
587+ char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
588+ char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
589+
590+ if (!a->format)
591+ return;
592+
593+ snd_print_pcm_rates(a->rates, buf, sizeof(buf));
594+
595+ if (a->format == AUDIO_CODING_TYPE_LPCM)
596+ snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8));
597+ else if (a->max_bitrate)
598+ snprintf(buf2, sizeof(buf2),
599+ ", max bitrate = %d", a->max_bitrate);
600+ else
601+ buf2[0] = '\0';
602+
603+ printk(KERN_INFO "HDMI: supports coding type %s:"
604+ " channels = %d, rates =%s%s\n",
605+ cea_audio_coding_type_names[a->format],
606+ a->channels,
607+ buf,
608+ buf2);
609+}
610+
611+void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
612+{
613+ int i, j;
614+
615+ for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
616+ if (spk_alloc & (1 << i))
617+ j += snprintf(buf + j, buflen - j, " %s",
618+ cea_speaker_allocation_names[i]);
619+ }
620+ buf[j] = '\0'; /* necessary when j == 0 */
621+}
622+
623+void snd_hdmi_show_eld(struct hdmi_eld *e)
624+{
625+ int i;
626+
627+ printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n",
628+ e->monitor_name,
629+ eld_connection_type_names[e->conn_type]);
630+
631+ if (e->spk_alloc) {
632+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
633+ snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
634+ printk(KERN_INFO "HDMI: available speakers:%s\n", buf);
635+ }
636+
637+ for (i = 0; i < e->sad_count; i++)
638+ hdmi_show_short_audio_desc(e->sad + i);
639+}
640+
641+#ifdef CONFIG_PROC_FS
642+
643+static void hdmi_print_sad_info(int i, struct cea_sad *a,
644+ struct snd_info_buffer *buffer)
645+{
646+ char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
647+
648+ snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n",
649+ i, a->format, cea_audio_coding_type_names[a->format]);
650+ snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels);
651+
652+ snd_print_pcm_rates(a->rates, buf, sizeof(buf));
653+ snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf);
654+
655+ if (a->format == AUDIO_CODING_TYPE_LPCM) {
656+ snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf));
657+ snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n",
658+ i, a->sample_bits, buf);
659+ }
660+
661+ if (a->max_bitrate)
662+ snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n",
663+ i, a->max_bitrate);
664+
665+ if (a->profile)
666+ snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile);
667+}
668+
669+static void hdmi_print_eld_info(struct snd_info_entry *entry,
670+ struct snd_info_buffer *buffer)
671+{
672+ struct hdmi_eld *e = entry->private_data;
673+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
674+ int i;
675+ static char *eld_versoin_names[32] = {
676+ "reserved",
677+ "reserved",
678+ "CEA-861D or below",
679+ [3 ... 30] = "reserved",
680+ [31] = "partial"
681+ };
682+ static char *cea_edid_version_names[8] = {
683+ "no CEA EDID Timing Extension block present",
684+ "CEA-861",
685+ "CEA-861-A",
686+ "CEA-861-B, C or D",
687+ [4 ... 7] = "reserved"
688+ };
689+
690+ snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
691+ snd_iprintf(buffer, "connection_type\t\t%s\n",
692+ eld_connection_type_names[e->conn_type]);
693+ snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver,
694+ eld_versoin_names[e->eld_ver]);
695+ snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver,
696+ cea_edid_version_names[e->cea_edid_ver]);
697+ snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id);
698+ snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id);
699+ snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id);
700+ snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp);
701+ snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);
702+ snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);
703+
704+ snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
705+ snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);
706+
707+ snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);
708+
709+ for (i = 0; i < e->sad_count; i++)
710+ hdmi_print_sad_info(i, e->sad + i, buffer);
711+}
712+
713+static void hdmi_write_eld_info(struct snd_info_entry *entry,
714+ struct snd_info_buffer *buffer)
715+{
716+ struct hdmi_eld *e = entry->private_data;
717+ char line[64];
718+ char name[64];
719+ char *sname;
720+ long long val;
721+ int n;
722+
723+ while (!snd_info_get_line(buffer, line, sizeof(line))) {
724+ if (sscanf(line, "%s %llx", name, &val) != 2)
725+ continue;
726+ /*
727+ * We don't allow modification to these fields:
728+ * monitor_name manufacture_id product_id
729+ * eld_version edid_version
730+ */
731+ if (!strcmp(name, "connection_type"))
732+ e->conn_type = val;
733+ else if (!strcmp(name, "port_id"))
734+ e->port_id = val;
735+ else if (!strcmp(name, "support_hdcp"))
736+ e->support_hdcp = val;
737+ else if (!strcmp(name, "support_ai"))
738+ e->support_ai = val;
739+ else if (!strcmp(name, "audio_sync_delay"))
740+ e->aud_synch_delay = val;
741+ else if (!strcmp(name, "speakers"))
742+ e->spk_alloc = val;
743+ else if (!strcmp(name, "sad_count"))
744+ e->sad_count = val;
745+ else if (!strncmp(name, "sad", 3)) {
746+ sname = name + 4;
747+ n = name[3] - '0';
748+ if (name[4] >= '0' && name[4] <= '9') {
749+ sname++;
750+ n = 10 * n + name[4] - '0';
751+ }
752+ if (n < 0 || n > 31) /* double the CEA limit */
753+ continue;
754+ if (!strcmp(sname, "_coding_type"))
755+ e->sad[n].format = val;
756+ else if (!strcmp(sname, "_channels"))
757+ e->sad[n].channels = val;
758+ else if (!strcmp(sname, "_rates"))
759+ e->sad[n].rates = val;
760+ else if (!strcmp(sname, "_bits"))
761+ e->sad[n].sample_bits = val;
762+ else if (!strcmp(sname, "_max_bitrate"))
763+ e->sad[n].max_bitrate = val;
764+ else if (!strcmp(sname, "_profile"))
765+ e->sad[n].profile = val;
766+ if (n >= e->sad_count)
767+ e->sad_count = n + 1;
768+ }
769+ }
770+}
771+
772+
773+int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld)
774+{
775+ char name[32];
776+ struct snd_info_entry *entry;
777+ int err;
778+
779+ snprintf(name, sizeof(name), "eld#%d", codec->addr);
780+ err = snd_card_proc_new(codec->bus->card, name, &entry);
781+ if (err < 0)
782+ return err;
783+
784+ snd_info_set_text_ops(entry, eld, hdmi_print_eld_info);
785+ entry->c.text.write = hdmi_write_eld_info;
786+ entry->mode |= S_IWUSR;
787+ eld->proc_entry = entry;
788+
789+ return 0;
790+}
791+
792+void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
793+{
794+#if 0 /* we don't support hwdep reconfig yet */
795+ if (!codec->bus->shutdown && eld->proc_entry) {
796+ snd_device_free(codec->bus->card, eld->proc_entry);
797+ eld->proc_entry = NULL;
798+ }
799+#endif
800+}
801+
802+#endif /* CONFIG_PROC_FS */
803--- a/sound/pci/hda/hda_intel.c
804+++ b/sound/pci/hda/hda_intel.c
805@@ -292,6 +292,8 @@ enum {
806 /* Define VIA HD Audio Device ID*/
807 #define VIA_HDAC_DEVICE_ID 0x3288
808
809+/* HD Audio class code */
810+#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
811
812 /*
813 */
814@@ -418,6 +420,7 @@ enum {
815 AZX_DRIVER_ULI,
816 AZX_DRIVER_NVIDIA,
817 AZX_DRIVER_TERA,
818+ AZX_DRIVER_GENERIC,
819 AZX_NUM_DRIVERS, /* keep this as last entry */
820 };
821
822@@ -431,6 +434,7 @@ static char *driver_short_names[] __devi
823 [AZX_DRIVER_ULI] = "HDA ULI M5461",
824 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
825 [AZX_DRIVER_TERA] = "HDA Teradici",
826+ [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
827 };
828
829 /*
830@@ -2321,6 +2325,7 @@ static int __devinit azx_create(struct s
831 chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
832 chip->capture_streams = ATIHDMI_NUM_CAPTURE;
833 break;
834+ case AZX_DRIVER_GENERIC:
835 default:
836 chip->playback_streams = ICH6_NUM_PLAYBACK;
837 chip->capture_streams = ICH6_NUM_CAPTURE;
838@@ -2530,12 +2535,17 @@ static struct pci_device_id azx_ids[] =
839 { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
840 { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
841 { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
842- { PCI_DEVICE(0x10de, 0x0bd4), .driver_data = AZX_DRIVER_NVIDIA },
843- { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA },
844- { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA },
845- { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
846+ { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
847+ { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
848+ { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
849+ { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
850 /* Teradici */
851 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
852+ /* AMD Generic, PCI class code and Vendor ID for HD Audio */
853+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
854+ .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
855+ .class_mask = 0xffffff,
856+ .driver_data = AZX_DRIVER_GENERIC },
857 { 0, }
858 };
859 MODULE_DEVICE_TABLE(pci, azx_ids);
860--- a/sound/pci/hda/hda_local.h
861+++ b/sound/pci/hda/hda_local.h
862@@ -284,6 +284,12 @@ int snd_hda_codec_proc_new(struct hda_co
863 static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
864 #endif
865
866+#define SND_PRINT_RATES_ADVISED_BUFSIZE 80
867+void snd_print_pcm_rates(int pcm, char *buf, int buflen);
868+
869+#define SND_PRINT_BITS_ADVISED_BUFSIZE 16
870+void snd_print_pcm_bits(int pcm, char *buf, int buflen);
871+
872 /*
873 * Misc
874 */
875@@ -436,4 +442,66 @@ int snd_hda_check_amp_list_power(struct
876 #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
877 #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
878
879+/*
880+ * CEA Short Audio Descriptor data
881+ */
882+struct cea_sad {
883+ int channels;
884+ int format; /* (format == 0) indicates invalid SAD */
885+ int rates;
886+ int sample_bits; /* for LPCM */
887+ int max_bitrate; /* for AC3...ATRAC */
888+ int profile; /* for WMAPRO */
889+};
890+
891+#define ELD_FIXED_BYTES 20
892+#define ELD_MAX_MNL 16
893+#define ELD_MAX_SAD 16
894+
895+/*
896+ * ELD: EDID Like Data
897+ */
898+struct hdmi_eld {
899+ int eld_size;
900+ int baseline_len;
901+ int eld_ver; /* (eld_ver == 0) indicates invalid ELD */
902+ int cea_edid_ver;
903+ char monitor_name[ELD_MAX_MNL + 1];
904+ int manufacture_id;
905+ int product_id;
906+ u64 port_id;
907+ int support_hdcp;
908+ int support_ai;
909+ int conn_type;
910+ int aud_synch_delay;
911+ int spk_alloc;
912+ int sad_count;
913+ struct cea_sad sad[ELD_MAX_SAD];
914+#ifdef CONFIG_PROC_FS
915+ struct snd_info_entry *proc_entry;
916+#endif
917+};
918+
919+int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
920+int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
921+void snd_hdmi_show_eld(struct hdmi_eld *eld);
922+
923+#ifdef CONFIG_PROC_FS
924+int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld);
925+void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld);
926+#else
927+static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
928+ struct hdmi_eld *eld)
929+{
930+ return 0;
931+}
932+static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
933+ struct hdmi_eld *eld)
934+{
935+}
936+#endif
937+
938+#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
939+void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
940+
941 #endif /* __SOUND_HDA_LOCAL_H */
942--- a/sound/pci/hda/hda_patch.h
943+++ b/sound/pci/hda/hda_patch.h
944@@ -20,3 +20,5 @@ extern struct hda_codec_preset snd_hda_p
945 extern struct hda_codec_preset snd_hda_preset_via[];
946 /* NVIDIA HDMI codecs */
947 extern struct hda_codec_preset snd_hda_preset_nvhdmi[];
948+/* Intel HDMI codecs */
949+extern struct hda_codec_preset snd_hda_preset_intelhdmi[];
950--- a/sound/pci/hda/hda_proc.c
951+++ b/sound/pci/hda/hda_proc.c
952@@ -91,31 +91,21 @@ static void print_amp_vals(struct snd_in
953
954 static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
955 {
956- static unsigned int rates[] = {
957- 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
958- 96000, 176400, 192000, 384000
959- };
960- int i;
961+ char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
962
963 pcm &= AC_SUPPCM_RATES;
964 snd_iprintf(buffer, " rates [0x%x]:", pcm);
965- for (i = 0; i < ARRAY_SIZE(rates); i++)
966- if (pcm & (1 << i))
967- snd_iprintf(buffer, " %d", rates[i]);
968- snd_iprintf(buffer, "\n");
969+ snd_print_pcm_rates(pcm, buf, sizeof(buf));
970+ snd_iprintf(buffer, "%s\n", buf);
971 }
972
973 static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
974 {
975- static unsigned int bits[] = { 8, 16, 20, 24, 32 };
976- int i;
977+ char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
978
979- pcm = (pcm >> 16) & 0xff;
980- snd_iprintf(buffer, " bits [0x%x]:", pcm);
981- for (i = 0; i < ARRAY_SIZE(bits); i++)
982- if (pcm & (1 << i))
983- snd_iprintf(buffer, " %d", bits[i]);
984- snd_iprintf(buffer, "\n");
985+ snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
986+ snd_print_pcm_bits(pcm, buf, sizeof(buf));
987+ snd_iprintf(buffer, "%s\n", buf);
988 }
989
990 static void print_pcm_formats(struct snd_info_buffer *buffer,
991@@ -145,32 +135,6 @@ static void print_pcm_caps(struct snd_in
992 print_pcm_formats(buffer, stream);
993 }
994
995-static const char *get_jack_location(u32 cfg)
996-{
997- static char *bases[7] = {
998- "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
999- };
1000- static unsigned char specials_idx[] = {
1001- 0x07, 0x08,
1002- 0x17, 0x18, 0x19,
1003- 0x37, 0x38
1004- };
1005- static char *specials[] = {
1006- "Rear Panel", "Drive Bar",
1007- "Riser", "HDMI", "ATAPI",
1008- "Mobile-In", "Mobile-Out"
1009- };
1010- int i;
1011- cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
1012- if ((cfg & 0x0f) < 7)
1013- return bases[cfg & 0x0f];
1014- for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
1015- if (cfg == specials_idx[i])
1016- return specials[i];
1017- }
1018- return "UNKNOWN";
1019-}
1020-
1021 static const char *get_jack_connection(u32 cfg)
1022 {
1023 static char *names[16] = {
1024@@ -206,13 +170,6 @@ static void print_pin_caps(struct snd_in
1025 int *supports_vref)
1026 {
1027 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
1028- static char *jack_types[16] = {
1029- "Line Out", "Speaker", "HP Out", "CD",
1030- "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
1031- "Line In", "Aux", "Mic", "Telephony",
1032- "SPDIF In", "Digitial In", "Reserved", "Other"
1033- };
1034- static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
1035 unsigned int caps, val;
1036
1037 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
1038@@ -236,8 +193,6 @@ static void print_pin_caps(struct snd_in
1039 else
1040 snd_iprintf(buffer, " HDMI");
1041 }
1042- if (caps & AC_PINCAP_LR_SWAP)
1043- snd_iprintf(buffer, " R/L");
1044 if (caps & AC_PINCAP_TRIG_REQ)
1045 snd_iprintf(buffer, " Trigger");
1046 if (caps & AC_PINCAP_IMP_SENSE)
1047@@ -276,9 +231,9 @@ static void print_pin_caps(struct snd_in
1048 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
1049 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
1050 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
1051- jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT],
1052- jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3],
1053- get_jack_location(caps));
1054+ snd_hda_get_jack_type(caps),
1055+ snd_hda_get_jack_connectivity(caps),
1056+ snd_hda_get_jack_location(caps));
1057 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
1058 get_jack_connection(caps),
1059 get_jack_color(caps));
1060@@ -444,7 +399,10 @@ static void print_conn_list(struct snd_i
1061 {
1062 int c, curr = -1;
1063
1064- if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
1065+ if (conn_len > 1 &&
1066+ wid_type != AC_WID_AUD_MIX &&
1067+ wid_type != AC_WID_VOL_KNB &&
1068+ wid_type != AC_WID_POWER)
1069 curr = snd_hda_codec_read(codec, nid, 0,
1070 AC_VERB_GET_CONNECT_SEL, 0);
1071 snd_iprintf(buffer, " Connection: %d\n", conn_len);
1072@@ -502,12 +460,13 @@ static void print_gpio(struct snd_info_b
1073 for (i = 0; i < max; ++i)
1074 snd_iprintf(buffer,
1075 " IO[%d]: enable=%d, dir=%d, wake=%d, "
1076- "sticky=%d, data=%d\n", i,
1077+ "sticky=%d, data=%d, unsol=%d\n", i,
1078 (enable & (1<<i)) ? 1 : 0,
1079 (direction & (1<<i)) ? 1 : 0,
1080 (wake & (1<<i)) ? 1 : 0,
1081 (sticky & (1<<i)) ? 1 : 0,
1082- (data & (1<<i)) ? 1 : 0);
1083+ (data & (1<<i)) ? 1 : 0,
1084+ (unsol & (1<<i)) ? 1 : 0);
1085 /* FIXME: add GPO and GPI pin information */
1086 }
1087
1088--- a/sound/pci/hda/patch_atihdmi.c
1089+++ b/sound/pci/hda/patch_atihdmi.c
1090@@ -188,12 +188,11 @@ static int patch_atihdmi(struct hda_code
1091 * patch entries
1092 */
1093 struct hda_codec_preset snd_hda_preset_atihdmi[] = {
1094- { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
1095- { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
1096- { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
1097- { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi },
1098+ { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
1099+ { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
1100+ { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
1101+ { .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
1102 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
1103- { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi },
1104 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
1105 {} /* terminator */
1106 };
1107--- /dev/null
1108+++ b/sound/pci/hda/patch_intelhdmi.c
1109@@ -0,0 +1,694 @@
1110+/*
1111+ *
1112+ * patch_intelhdmi.c - Patch for Intel HDMI codecs
1113+ *
1114+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
1115+ *
1116+ * Authors:
1117+ * Jiang Zhe <zhe.jiang@intel.com>
1118+ * Wu Fengguang <wfg@linux.intel.com>
1119+ *
1120+ * Maintained by:
1121+ * Wu Fengguang <wfg@linux.intel.com>
1122+ *
1123+ * This program is free software; you can redistribute it and/or modify it
1124+ * under the terms of the GNU General Public License as published by the Free
1125+ * Software Foundation; either version 2 of the License, or (at your option)
1126+ * any later version.
1127+ *
1128+ * This program is distributed in the hope that it will be useful, but
1129+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1130+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1131+ * for more details.
1132+ *
1133+ * You should have received a copy of the GNU General Public License
1134+ * along with this program; if not, write to the Free Software Foundation,
1135+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1136+ */
1137+
1138+#include <linux/init.h>
1139+#include <linux/delay.h>
1140+#include <linux/slab.h>
1141+#include <sound/core.h>
1142+#include "hda_codec.h"
1143+#include "hda_local.h"
1144+#include "hda_patch.h"
1145+
1146+#define CVT_NID 0x02 /* audio converter */
1147+#define PIN_NID 0x03 /* HDMI output pin */
1148+
1149+#define INTEL_HDMI_EVENT_TAG 0x08
1150+
1151+struct intel_hdmi_spec {
1152+ struct hda_multi_out multiout;
1153+ struct hda_pcm pcm_rec;
1154+ struct hdmi_eld sink_eld;
1155+};
1156+
1157+static struct hda_verb pinout_enable_verb[] = {
1158+ {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1159+ {} /* terminator */
1160+};
1161+
1162+static struct hda_verb unsolicited_response_verb[] = {
1163+ {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN |
1164+ INTEL_HDMI_EVENT_TAG},
1165+ {}
1166+};
1167+
1168+static struct hda_verb def_chan_map[] = {
1169+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00},
1170+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11},
1171+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22},
1172+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33},
1173+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44},
1174+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55},
1175+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66},
1176+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77},
1177+ {}
1178+};
1179+
1180+
1181+struct hdmi_audio_infoframe {
1182+ u8 type; /* 0x84 */
1183+ u8 ver; /* 0x01 */
1184+ u8 len; /* 0x0a */
1185+
1186+ u8 checksum; /* PB0 */
1187+ u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
1188+ u8 SS01_SF24;
1189+ u8 CXT04;
1190+ u8 CA;
1191+ u8 LFEPBL01_LSV36_DM_INH7;
1192+ u8 reserved[5]; /* PB6 - PB10 */
1193+};
1194+
1195+/*
1196+ * CEA speaker placement:
1197+ *
1198+ * FLH FCH FRH
1199+ * FLW FL FLC FC FRC FR FRW
1200+ *
1201+ * LFE
1202+ * TC
1203+ *
1204+ * RL RLC RC RRC RR
1205+ *
1206+ * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
1207+ * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
1208+ */
1209+enum cea_speaker_placement {
1210+ FL = (1 << 0), /* Front Left */
1211+ FC = (1 << 1), /* Front Center */
1212+ FR = (1 << 2), /* Front Right */
1213+ FLC = (1 << 3), /* Front Left Center */
1214+ FRC = (1 << 4), /* Front Right Center */
1215+ RL = (1 << 5), /* Rear Left */
1216+ RC = (1 << 6), /* Rear Center */
1217+ RR = (1 << 7), /* Rear Right */
1218+ RLC = (1 << 8), /* Rear Left Center */
1219+ RRC = (1 << 9), /* Rear Right Center */
1220+ LFE = (1 << 10), /* Low Frequency Effect */
1221+ FLW = (1 << 11), /* Front Left Wide */
1222+ FRW = (1 << 12), /* Front Right Wide */
1223+ FLH = (1 << 13), /* Front Left High */
1224+ FCH = (1 << 14), /* Front Center High */
1225+ FRH = (1 << 15), /* Front Right High */
1226+ TC = (1 << 16), /* Top Center */
1227+};
1228+
1229+/*
1230+ * ELD SA bits in the CEA Speaker Allocation data block
1231+ */
1232+static int eld_speaker_allocation_bits[] = {
1233+ [0] = FL | FR,
1234+ [1] = LFE,
1235+ [2] = FC,
1236+ [3] = RL | RR,
1237+ [4] = RC,
1238+ [5] = FLC | FRC,
1239+ [6] = RLC | RRC,
1240+ /* the following are not defined in ELD yet */
1241+ [7] = FLW | FRW,
1242+ [8] = FLH | FRH,
1243+ [9] = TC,
1244+ [10] = FCH,
1245+};
1246+
1247+struct cea_channel_speaker_allocation {
1248+ int ca_index;
1249+ int speakers[8];
1250+
1251+ /* derived values, just for convenience */
1252+ int channels;
1253+ int spk_mask;
1254+};
1255+
1256+/*
1257+ * This is an ordered list!
1258+ *
1259+ * The preceding ones have better chances to be selected by
1260+ * hdmi_setup_channel_allocation().
1261+ */
1262+static struct cea_channel_speaker_allocation channel_allocations[] = {
1263+/* channel: 8 7 6 5 4 3 2 1 */
1264+{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
1265+ /* 2.1 */
1266+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
1267+ /* Dolby Surround */
1268+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
1269+{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
1270+{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
1271+{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
1272+{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
1273+{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
1274+{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
1275+{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
1276+{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
1277+ /* 5.1 */
1278+{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
1279+{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
1280+{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
1281+{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
1282+ /* 6.1 */
1283+{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
1284+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
1285+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
1286+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
1287+ /* 7.1 */
1288+{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
1289+{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
1290+{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
1291+{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
1292+{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
1293+{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
1294+{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
1295+{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
1296+{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
1297+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
1298+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
1299+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
1300+{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
1301+{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
1302+{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
1303+{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
1304+{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
1305+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
1306+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
1307+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
1308+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
1309+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
1310+{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
1311+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
1312+{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
1313+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
1314+{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
1315+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
1316+{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
1317+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
1318+{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
1319+};
1320+
1321+/*
1322+ * HDMI routines
1323+ */
1324+
1325+#ifdef BE_PARANOID
1326+static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid,
1327+ int *packet_index, int *byte_index)
1328+{
1329+ int val;
1330+
1331+ val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0);
1332+
1333+ *packet_index = val >> 5;
1334+ *byte_index = val & 0x1f;
1335+}
1336+#endif
1337+
1338+static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid,
1339+ int packet_index, int byte_index)
1340+{
1341+ int val;
1342+
1343+ val = (packet_index << 5) | (byte_index & 0x1f);
1344+
1345+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
1346+}
1347+
1348+static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
1349+ unsigned char val)
1350+{
1351+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
1352+}
1353+
1354+static void hdmi_enable_output(struct hda_codec *codec)
1355+{
1356+ /* Unmute */
1357+ if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
1358+ snd_hda_codec_write(codec, PIN_NID, 0,
1359+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
1360+ /* Enable pin out */
1361+ snd_hda_sequence_write(codec, pinout_enable_verb);
1362+}
1363+
1364+/*
1365+ * Enable Audio InfoFrame Transmission
1366+ */
1367+static void hdmi_start_infoframe_trans(struct hda_codec *codec)
1368+{
1369+ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
1370+ snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT,
1371+ AC_DIPXMIT_BEST);
1372+}
1373+
1374+/*
1375+ * Disable Audio InfoFrame Transmission
1376+ */
1377+static void hdmi_stop_infoframe_trans(struct hda_codec *codec)
1378+{
1379+ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
1380+ snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT,
1381+ AC_DIPXMIT_DISABLE);
1382+}
1383+
1384+static int hdmi_get_channel_count(struct hda_codec *codec)
1385+{
1386+ return 1 + snd_hda_codec_read(codec, CVT_NID, 0,
1387+ AC_VERB_GET_CVT_CHAN_COUNT, 0);
1388+}
1389+
1390+static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
1391+{
1392+ snd_hda_codec_write(codec, CVT_NID, 0,
1393+ AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
1394+
1395+ if (chs != hdmi_get_channel_count(codec))
1396+ snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n",
1397+ chs, hdmi_get_channel_count(codec));
1398+}
1399+
1400+static void hdmi_debug_channel_mapping(struct hda_codec *codec)
1401+{
1402+#ifdef CONFIG_SND_DEBUG_VERBOSE
1403+ int i;
1404+ int slot;
1405+
1406+ for (i = 0; i < 8; i++) {
1407+ slot = snd_hda_codec_read(codec, CVT_NID, 0,
1408+ AC_VERB_GET_HDMI_CHAN_SLOT, i);
1409+ printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
1410+ slot >> 4, slot & 0x7);
1411+ }
1412+#endif
1413+}
1414+
1415+static void hdmi_parse_eld(struct hda_codec *codec)
1416+{
1417+ struct intel_hdmi_spec *spec = codec->spec;
1418+ struct hdmi_eld *eld = &spec->sink_eld;
1419+
1420+ if (!snd_hdmi_get_eld(eld, codec, PIN_NID))
1421+ snd_hdmi_show_eld(eld);
1422+}
1423+
1424+
1425+/*
1426+ * Audio InfoFrame routines
1427+ */
1428+
1429+static void hdmi_debug_dip_size(struct hda_codec *codec)
1430+{
1431+#ifdef CONFIG_SND_DEBUG_VERBOSE
1432+ int i;
1433+ int size;
1434+
1435+ size = snd_hdmi_get_eld_size(codec, PIN_NID);
1436+ printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
1437+
1438+ for (i = 0; i < 8; i++) {
1439+ size = snd_hda_codec_read(codec, PIN_NID, 0,
1440+ AC_VERB_GET_HDMI_DIP_SIZE, i);
1441+ printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
1442+ }
1443+#endif
1444+}
1445+
1446+static void hdmi_clear_dip_buffers(struct hda_codec *codec)
1447+{
1448+#ifdef BE_PARANOID
1449+ int i, j;
1450+ int size;
1451+ int pi, bi;
1452+ for (i = 0; i < 8; i++) {
1453+ size = snd_hda_codec_read(codec, PIN_NID, 0,
1454+ AC_VERB_GET_HDMI_DIP_SIZE, i);
1455+ if (size == 0)
1456+ continue;
1457+
1458+ hdmi_set_dip_index(codec, PIN_NID, i, 0x0);
1459+ for (j = 1; j < 1000; j++) {
1460+ hdmi_write_dip_byte(codec, PIN_NID, 0x0);
1461+ hdmi_get_dip_index(codec, PIN_NID, &pi, &bi);
1462+ if (pi != i)
1463+ snd_printd(KERN_INFO "dip index %d: %d != %d\n",
1464+ bi, pi, i);
1465+ if (bi == 0) /* byte index wrapped around */
1466+ break;
1467+ }
1468+ snd_printd(KERN_INFO
1469+ "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
1470+ i, size, j);
1471+ }
1472+#endif
1473+}
1474+
1475+static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
1476+ struct hdmi_audio_infoframe *ai)
1477+{
1478+ u8 *params = (u8 *)ai;
1479+ u8 sum = 0;
1480+ int i;
1481+
1482+ hdmi_debug_dip_size(codec);
1483+ hdmi_clear_dip_buffers(codec); /* be paranoid */
1484+
1485+ for (i = 0; i < sizeof(ai); i++)
1486+ sum += params[i];
1487+ ai->checksum = - sum;
1488+
1489+ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
1490+ for (i = 0; i < sizeof(ai); i++)
1491+ hdmi_write_dip_byte(codec, PIN_NID, params[i]);
1492+}
1493+
1494+/*
1495+ * Compute derived values in channel_allocations[].
1496+ */
1497+static void init_channel_allocations(void)
1498+{
1499+ int i, j;
1500+ struct cea_channel_speaker_allocation *p;
1501+
1502+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
1503+ p = channel_allocations + i;
1504+ p->channels = 0;
1505+ p->spk_mask = 0;
1506+ for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
1507+ if (p->speakers[j]) {
1508+ p->channels++;
1509+ p->spk_mask |= p->speakers[j];
1510+ }
1511+ }
1512+}
1513+
1514+/*
1515+ * The transformation takes two steps:
1516+ *
1517+ * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
1518+ * spk_mask => (channel_allocations[]) => ai->CA
1519+ *
1520+ * TODO: it could select the wrong CA from multiple candidates.
1521+*/
1522+static int hdmi_setup_channel_allocation(struct hda_codec *codec,
1523+ struct hdmi_audio_infoframe *ai)
1524+{
1525+ struct intel_hdmi_spec *spec = codec->spec;
1526+ struct hdmi_eld *eld = &spec->sink_eld;
1527+ int i;
1528+ int spk_mask = 0;
1529+ int channels = 1 + (ai->CC02_CT47 & 0x7);
1530+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
1531+
1532+ /*
1533+ * CA defaults to 0 for basic stereo audio
1534+ */
1535+ if (channels <= 2)
1536+ return 0;
1537+
1538+ /*
1539+ * HDMI sink's ELD info cannot always be retrieved for now, e.g.
1540+ * in console or for audio devices. Assume the highest speakers
1541+ * configuration, to _not_ prohibit multi-channel audio playback.
1542+ */
1543+ if (!eld->spk_alloc)
1544+ eld->spk_alloc = 0xffff;
1545+
1546+ /*
1547+ * expand ELD's speaker allocation mask
1548+ *
1549+ * ELD tells the speaker mask in a compact(paired) form,
1550+ * expand ELD's notions to match the ones used by Audio InfoFrame.
1551+ */
1552+ for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
1553+ if (eld->spk_alloc & (1 << i))
1554+ spk_mask |= eld_speaker_allocation_bits[i];
1555+ }
1556+
1557+ /* search for the first working match in the CA table */
1558+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
1559+ if (channels == channel_allocations[i].channels &&
1560+ (spk_mask & channel_allocations[i].spk_mask) ==
1561+ channel_allocations[i].spk_mask) {
1562+ ai->CA = channel_allocations[i].ca_index;
1563+ break;
1564+ }
1565+ }
1566+
1567+ snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
1568+ snd_printdd(KERN_INFO
1569+ "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
1570+ ai->CA, channels, buf);
1571+
1572+ return ai->CA;
1573+}
1574+
1575+static void hdmi_setup_channel_mapping(struct hda_codec *codec,
1576+ struct hdmi_audio_infoframe *ai)
1577+{
1578+ if (!ai->CA)
1579+ return;
1580+
1581+ /*
1582+ * TODO: adjust channel mapping if necessary
1583+ * ALSA sequence is front/surr/clfe/side?
1584+ */
1585+
1586+ snd_hda_sequence_write(codec, def_chan_map);
1587+ hdmi_debug_channel_mapping(codec);
1588+}
1589+
1590+
1591+static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
1592+ struct snd_pcm_substream *substream)
1593+{
1594+ struct hdmi_audio_infoframe ai = {
1595+ .type = 0x84,
1596+ .ver = 0x01,
1597+ .len = 0x0a,
1598+ .CC02_CT47 = substream->runtime->channels - 1,
1599+ };
1600+
1601+ hdmi_setup_channel_allocation(codec, &ai);
1602+ hdmi_setup_channel_mapping(codec, &ai);
1603+
1604+ hdmi_fill_audio_infoframe(codec, &ai);
1605+ hdmi_start_infoframe_trans(codec);
1606+}
1607+
1608+
1609+/*
1610+ * Unsolicited events
1611+ */
1612+
1613+static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
1614+{
1615+ int pind = !!(res & AC_UNSOL_RES_PD);
1616+ int eldv = !!(res & AC_UNSOL_RES_ELDV);
1617+
1618+ printk(KERN_INFO
1619+ "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n",
1620+ pind, eldv);
1621+
1622+ if (pind && eldv) {
1623+ hdmi_parse_eld(codec);
1624+ /* TODO: do real things about ELD */
1625+ }
1626+}
1627+
1628+static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
1629+{
1630+ int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
1631+ int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
1632+ int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
1633+
1634+ printk(KERN_INFO
1635+ "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
1636+ subtag,
1637+ cp_state,
1638+ cp_ready);
1639+
1640+ /* TODO */
1641+ if (cp_state)
1642+ ;
1643+ if (cp_ready)
1644+ ;
1645+}
1646+
1647+
1648+static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
1649+{
1650+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
1651+ int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
1652+
1653+ if (tag != INTEL_HDMI_EVENT_TAG) {
1654+ snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
1655+ return;
1656+ }
1657+
1658+ if (subtag == 0)
1659+ hdmi_intrinsic_event(codec, res);
1660+ else
1661+ hdmi_non_intrinsic_event(codec, res);
1662+}
1663+
1664+/*
1665+ * Callbacks
1666+ */
1667+
1668+static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo,
1669+ struct hda_codec *codec,
1670+ struct snd_pcm_substream *substream)
1671+{
1672+ struct intel_hdmi_spec *spec = codec->spec;
1673+
1674+ return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1675+}
1676+
1677+static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
1678+ struct hda_codec *codec,
1679+ struct snd_pcm_substream *substream)
1680+{
1681+ struct intel_hdmi_spec *spec = codec->spec;
1682+
1683+ hdmi_stop_infoframe_trans(codec);
1684+
1685+ return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1686+}
1687+
1688+static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1689+ struct hda_codec *codec,
1690+ unsigned int stream_tag,
1691+ unsigned int format,
1692+ struct snd_pcm_substream *substream)
1693+{
1694+ struct intel_hdmi_spec *spec = codec->spec;
1695+
1696+ snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
1697+ format, substream);
1698+
1699+ hdmi_set_channel_count(codec, substream->runtime->channels);
1700+
1701+ hdmi_setup_audio_infoframe(codec, substream);
1702+
1703+ return 0;
1704+}
1705+
1706+static struct hda_pcm_stream intel_hdmi_pcm_playback = {
1707+ .substreams = 1,
1708+ .channels_min = 2,
1709+ .channels_max = 8,
1710+ .nid = CVT_NID, /* NID to query formats and rates and setup streams */
1711+ .ops = {
1712+ .open = intel_hdmi_playback_pcm_open,
1713+ .close = intel_hdmi_playback_pcm_close,
1714+ .prepare = intel_hdmi_playback_pcm_prepare
1715+ },
1716+};
1717+
1718+static int intel_hdmi_build_pcms(struct hda_codec *codec)
1719+{
1720+ struct intel_hdmi_spec *spec = codec->spec;
1721+ struct hda_pcm *info = &spec->pcm_rec;
1722+
1723+ codec->num_pcms = 1;
1724+ codec->pcm_info = info;
1725+
1726+ info->name = "INTEL HDMI";
1727+ info->pcm_type = HDA_PCM_TYPE_HDMI;
1728+ info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
1729+
1730+ return 0;
1731+}
1732+
1733+static int intel_hdmi_build_controls(struct hda_codec *codec)
1734+{
1735+ struct intel_hdmi_spec *spec = codec->spec;
1736+ int err;
1737+
1738+ err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
1739+ if (err < 0)
1740+ return err;
1741+
1742+ return 0;
1743+}
1744+
1745+static int intel_hdmi_init(struct hda_codec *codec)
1746+{
1747+ hdmi_enable_output(codec);
1748+
1749+ snd_hda_sequence_write(codec, unsolicited_response_verb);
1750+
1751+ return 0;
1752+}
1753+
1754+static void intel_hdmi_free(struct hda_codec *codec)
1755+{
1756+ struct intel_hdmi_spec *spec = codec->spec;
1757+
1758+ snd_hda_eld_proc_free(codec, &spec->sink_eld);
1759+ kfree(spec);
1760+}
1761+
1762+static struct hda_codec_ops intel_hdmi_patch_ops = {
1763+ .init = intel_hdmi_init,
1764+ .free = intel_hdmi_free,
1765+ .build_pcms = intel_hdmi_build_pcms,
1766+ .build_controls = intel_hdmi_build_controls,
1767+ .unsol_event = intel_hdmi_unsol_event,
1768+};
1769+
1770+static int patch_intel_hdmi(struct hda_codec *codec)
1771+{
1772+ struct intel_hdmi_spec *spec;
1773+
1774+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1775+ if (spec == NULL)
1776+ return -ENOMEM;
1777+
1778+ spec->multiout.num_dacs = 0; /* no analog */
1779+ spec->multiout.max_channels = 8;
1780+ spec->multiout.dig_out_nid = CVT_NID;
1781+
1782+ codec->spec = spec;
1783+ codec->patch_ops = intel_hdmi_patch_ops;
1784+
1785+ snd_hda_eld_proc_new(codec, &spec->sink_eld);
1786+
1787+ init_channel_allocations();
1788+
1789+ return 0;
1790+}
1791+
1792+/*
1793+ * patch entries
1794+ */
1795+struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
1796+ { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
1797+ { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
1798+ { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
1799+ { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
1800+ { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
1801+ { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
1802+ {} /* terminator */
1803+};
1804--- a/sound/pci/hda/patch_nvhdmi.c
1805+++ b/sound/pci/hda/patch_nvhdmi.c
1806@@ -159,7 +159,10 @@ static int patch_nvhdmi(struct hda_codec
1807 * patch entries
1808 */
1809 struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
1810- { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi },
1811- { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi },
1812+ { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
1813+ { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
1814+ { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi },
1815+ { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi },
1816+ { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi },
1817 {} /* terminator */
1818 };