]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/alsa-post-ga-hda-intelhdmi
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / alsa-post-ga-hda-intelhdmi
1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: ALSA: Add Intel HDMI support
3 Patch-mainline: 2.6.29
4 References: bnc#485768
5
6 Add the support for Intel HDMI devices.
7
8 Signed-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 };