diff options
-rw-r--r-- | sound/pci/Kconfig | 4 | ||||
-rw-r--r-- | sound/pci/hda/Makefile | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_eld.c | 454 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 41 | ||||
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 480 |
5 files changed, 505 insertions, 475 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 21e9327a0ef4..157a0a6b10ae 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -582,6 +582,10 @@ config SND_HDA_CODEC_INTELHDMI | |||
582 | Say Y here to include INTEL HDMI HD-audio codec support in | 582 | Say Y here to include INTEL HDMI HD-audio codec support in |
583 | snd-hda-intel driver, such as Eaglelake integrated HDMI. | 583 | snd-hda-intel driver, such as Eaglelake integrated HDMI. |
584 | 584 | ||
585 | config SND_HDA_ELD | ||
586 | def_bool y | ||
587 | depends on SND_HDA_CODEC_INTELHDMI | ||
588 | |||
585 | config SND_HDA_CODEC_CONEXANT | 589 | config SND_HDA_CODEC_CONEXANT |
586 | bool "Build Conexant HD-audio codec support" | 590 | bool "Build Conexant HD-audio codec support" |
587 | depends on SND_HDA_INTEL | 591 | depends on SND_HDA_INTEL |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 6fb5add1e39a..6daf5fd9a279 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
@@ -4,6 +4,7 @@ snd-hda-intel-y := hda_intel.o | |||
4 | # designed to be individual modules | 4 | # designed to be individual modules |
5 | snd-hda-intel-y += hda_codec.o | 5 | snd-hda-intel-y += hda_codec.o |
6 | snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o | 6 | snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o |
7 | snd-hda-intel-$(CONFIG_SND_HDA_ELD) += hda_eld.o | ||
7 | snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o | 8 | snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o |
8 | snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o | 9 | snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o |
9 | snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o | 10 | snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c new file mode 100644 index 000000000000..a69a7e87d26a --- /dev/null +++ b/sound/pci/hda/hda_eld.c | |||
@@ -0,0 +1,454 @@ | |||
1 | /* | ||
2 | * Generic routines and proc interface for ELD(EDID Like Data) information | ||
3 | * | ||
4 | * Copyright(c) 2008 Intel Corporation. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Wu Fengguang <wfg@linux.intel.com> | ||
8 | * | ||
9 | * This driver is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This driver is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <asm/unaligned.h> | ||
27 | #include "hda_codec.h" | ||
28 | #include "hda_local.h" | ||
29 | |||
30 | enum eld_versions { | ||
31 | ELD_VER_CEA_861D = 2, | ||
32 | ELD_VER_PARTIAL = 31, | ||
33 | }; | ||
34 | |||
35 | static char *eld_versoin_names[32] = { | ||
36 | "reserved", | ||
37 | "reserved", | ||
38 | "CEA-861D or below", | ||
39 | [3 ... 30] = "reserved", | ||
40 | [31] = "partial" | ||
41 | }; | ||
42 | |||
43 | enum cea_edid_versions { | ||
44 | CEA_EDID_VER_NONE = 0, | ||
45 | CEA_EDID_VER_CEA861 = 1, | ||
46 | CEA_EDID_VER_CEA861A = 2, | ||
47 | CEA_EDID_VER_CEA861BCD = 3, | ||
48 | CEA_EDID_VER_RESERVED = 4, | ||
49 | }; | ||
50 | |||
51 | static char *cea_edid_version_names[8] = { | ||
52 | "no CEA EDID Timing Extension block present", | ||
53 | "CEA-861", | ||
54 | "CEA-861-A", | ||
55 | "CEA-861-B, C or D", | ||
56 | [4 ... 7] = "reserved" | ||
57 | }; | ||
58 | |||
59 | static char *cea_speaker_allocation_names[] = { | ||
60 | /* 0 */ "FL/FR", | ||
61 | /* 1 */ "LFE", | ||
62 | /* 2 */ "FC", | ||
63 | /* 3 */ "RL/RR", | ||
64 | /* 4 */ "RC", | ||
65 | /* 5 */ "FLC/FRC", | ||
66 | /* 6 */ "RLC/RRC", | ||
67 | /* 7 */ "FLW/FRW", | ||
68 | /* 8 */ "FLH/FRH", | ||
69 | /* 9 */ "TC", | ||
70 | /* 10 */ "FCH", | ||
71 | }; | ||
72 | |||
73 | static char *eld_connection_type_names[4] = { | ||
74 | "HDMI", | ||
75 | "Display Port", | ||
76 | "2-reserved", | ||
77 | "3-reserved" | ||
78 | }; | ||
79 | |||
80 | enum cea_audio_coding_types { | ||
81 | AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, | ||
82 | AUDIO_CODING_TYPE_LPCM = 1, | ||
83 | AUDIO_CODING_TYPE_AC3 = 2, | ||
84 | AUDIO_CODING_TYPE_MPEG1 = 3, | ||
85 | AUDIO_CODING_TYPE_MP3 = 4, | ||
86 | AUDIO_CODING_TYPE_MPEG2 = 5, | ||
87 | AUDIO_CODING_TYPE_AACLC = 6, | ||
88 | AUDIO_CODING_TYPE_DTS = 7, | ||
89 | AUDIO_CODING_TYPE_ATRAC = 8, | ||
90 | AUDIO_CODING_TYPE_SACD = 9, | ||
91 | AUDIO_CODING_TYPE_EAC3 = 10, | ||
92 | AUDIO_CODING_TYPE_DTS_HD = 11, | ||
93 | AUDIO_CODING_TYPE_MLP = 12, | ||
94 | AUDIO_CODING_TYPE_DST = 13, | ||
95 | AUDIO_CODING_TYPE_WMAPRO = 14, | ||
96 | AUDIO_CODING_TYPE_REF_CXT = 15, | ||
97 | /* also include valid xtypes below */ | ||
98 | AUDIO_CODING_TYPE_HE_AAC = 15, | ||
99 | AUDIO_CODING_TYPE_HE_AAC2 = 16, | ||
100 | AUDIO_CODING_TYPE_MPEG_SURROUND = 17, | ||
101 | }; | ||
102 | |||
103 | enum cea_audio_coding_xtypes { | ||
104 | AUDIO_CODING_XTYPE_HE_REF_CT = 0, | ||
105 | AUDIO_CODING_XTYPE_HE_AAC = 1, | ||
106 | AUDIO_CODING_XTYPE_HE_AAC2 = 2, | ||
107 | AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, | ||
108 | AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, | ||
109 | }; | ||
110 | |||
111 | static char *cea_audio_coding_type_names[] = { | ||
112 | /* 0 */ "undefined", | ||
113 | /* 1 */ "LPCM", | ||
114 | /* 2 */ "AC-3", | ||
115 | /* 3 */ "MPEG1", | ||
116 | /* 4 */ "MP3", | ||
117 | /* 5 */ "MPEG2", | ||
118 | /* 6 */ "AAC-LC", | ||
119 | /* 7 */ "DTS", | ||
120 | /* 8 */ "ATRAC", | ||
121 | /* 9 */ "DSD (1-bit audio)", | ||
122 | /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", | ||
123 | /* 11 */ "DTS-HD", | ||
124 | /* 12 */ "MLP (Dolby TrueHD)", | ||
125 | /* 13 */ "DST", | ||
126 | /* 14 */ "WMAPro", | ||
127 | /* 15 */ "HE-AAC", | ||
128 | /* 16 */ "HE-AACv2", | ||
129 | /* 17 */ "MPEG Surround", | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * The following two lists are shared between | ||
134 | * - HDMI audio InfoFrame (source to sink) | ||
135 | * - CEA E-EDID extension (sink to source) | ||
136 | */ | ||
137 | |||
138 | /* | ||
139 | * SS1:SS0 index => sample size | ||
140 | */ | ||
141 | static int cea_sample_sizes[4] = { | ||
142 | 0, /* 0: Refer to Stream Header */ | ||
143 | AC_SUPPCM_BITS_16, /* 1: 16 bits */ | ||
144 | AC_SUPPCM_BITS_20, /* 2: 20 bits */ | ||
145 | AC_SUPPCM_BITS_24, /* 3: 24 bits */ | ||
146 | }; | ||
147 | |||
148 | /* | ||
149 | * SF2:SF1:SF0 index => sampling frequency | ||
150 | */ | ||
151 | static int cea_sampling_frequencies[8] = { | ||
152 | 0, /* 0: Refer to Stream Header */ | ||
153 | SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ | ||
154 | SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ | ||
155 | SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ | ||
156 | SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ | ||
157 | SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ | ||
158 | SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ | ||
159 | SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ | ||
160 | }; | ||
161 | |||
162 | static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid, | ||
163 | int byte_index) | ||
164 | { | ||
165 | unsigned int val; | ||
166 | |||
167 | val = snd_hda_codec_read(codec, nid, 0, | ||
168 | AC_VERB_GET_HDMI_ELDD, byte_index); | ||
169 | |||
170 | #ifdef BE_PARANOID | ||
171 | printk(KERN_INFO "ELD data byte %d: 0x%x\n", byte_index, val); | ||
172 | #endif | ||
173 | |||
174 | if ((val & AC_ELDD_ELD_VALID) == 0) { | ||
175 | snd_printd(KERN_INFO "Invalid ELD data byte %d\n", | ||
176 | byte_index); | ||
177 | val = 0; | ||
178 | } | ||
179 | |||
180 | return val & AC_ELDD_ELD_DATA; | ||
181 | } | ||
182 | |||
183 | #define GRAB_BITS(buf, byte, lowbit, bits) \ | ||
184 | ({ \ | ||
185 | BUILD_BUG_ON(lowbit > 7); \ | ||
186 | BUILD_BUG_ON(bits > 8); \ | ||
187 | BUILD_BUG_ON(bits <= 0); \ | ||
188 | \ | ||
189 | (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ | ||
190 | }) | ||
191 | |||
192 | static void hdmi_update_short_audio_desc(struct cea_sad *a, | ||
193 | const unsigned char *buf) | ||
194 | { | ||
195 | int i; | ||
196 | int val; | ||
197 | |||
198 | val = GRAB_BITS(buf, 1, 0, 7); | ||
199 | a->rates = 0; | ||
200 | for (i = 0; i < 7; i++) | ||
201 | if (val & (1 << i)) | ||
202 | a->rates |= cea_sampling_frequencies[i + 1]; | ||
203 | |||
204 | a->channels = GRAB_BITS(buf, 0, 0, 3); | ||
205 | a->channels++; | ||
206 | |||
207 | a->format = GRAB_BITS(buf, 0, 3, 4); | ||
208 | switch (a->format) { | ||
209 | case AUDIO_CODING_TYPE_REF_STREAM_HEADER: | ||
210 | snd_printd(KERN_INFO | ||
211 | "audio coding type 0 not expected in ELD\n"); | ||
212 | break; | ||
213 | |||
214 | case AUDIO_CODING_TYPE_LPCM: | ||
215 | val = GRAB_BITS(buf, 2, 0, 3); | ||
216 | a->sample_bits = 0; | ||
217 | for (i = 0; i < 3; i++) | ||
218 | if (val & (1 << i)) | ||
219 | a->sample_bits |= cea_sample_sizes[i + 1]; | ||
220 | break; | ||
221 | |||
222 | case AUDIO_CODING_TYPE_AC3: | ||
223 | case AUDIO_CODING_TYPE_MPEG1: | ||
224 | case AUDIO_CODING_TYPE_MP3: | ||
225 | case AUDIO_CODING_TYPE_MPEG2: | ||
226 | case AUDIO_CODING_TYPE_AACLC: | ||
227 | case AUDIO_CODING_TYPE_DTS: | ||
228 | case AUDIO_CODING_TYPE_ATRAC: | ||
229 | a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); | ||
230 | a->max_bitrate *= 8000; | ||
231 | break; | ||
232 | |||
233 | case AUDIO_CODING_TYPE_SACD: | ||
234 | break; | ||
235 | |||
236 | case AUDIO_CODING_TYPE_EAC3: | ||
237 | break; | ||
238 | |||
239 | case AUDIO_CODING_TYPE_DTS_HD: | ||
240 | break; | ||
241 | |||
242 | case AUDIO_CODING_TYPE_MLP: | ||
243 | break; | ||
244 | |||
245 | case AUDIO_CODING_TYPE_DST: | ||
246 | break; | ||
247 | |||
248 | case AUDIO_CODING_TYPE_WMAPRO: | ||
249 | a->profile = GRAB_BITS(buf, 2, 0, 3); | ||
250 | break; | ||
251 | |||
252 | case AUDIO_CODING_TYPE_REF_CXT: | ||
253 | a->format = GRAB_BITS(buf, 2, 3, 5); | ||
254 | if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || | ||
255 | a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { | ||
256 | snd_printd(KERN_INFO | ||
257 | "audio coding xtype %d not expected in ELD\n", | ||
258 | a->format); | ||
259 | a->format = 0; | ||
260 | } else | ||
261 | a->format += AUDIO_CODING_TYPE_HE_AAC - | ||
262 | AUDIO_CODING_XTYPE_HE_AAC; | ||
263 | break; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Be careful, ELD buf could be totally rubbish! | ||
269 | */ | ||
270 | static int hdmi_update_sink_eld(struct sink_eld *e, | ||
271 | const unsigned char *buf, int size) | ||
272 | { | ||
273 | int mnl; | ||
274 | int i; | ||
275 | |||
276 | e->eld_ver = GRAB_BITS(buf, 0, 3, 5); | ||
277 | if (e->eld_ver != ELD_VER_CEA_861D && | ||
278 | e->eld_ver != ELD_VER_PARTIAL) { | ||
279 | snd_printd(KERN_INFO "Unknown ELD version %d\n", e->eld_ver); | ||
280 | goto out_fail; | ||
281 | } | ||
282 | |||
283 | e->eld_size = size; | ||
284 | e->baseline_len = GRAB_BITS(buf, 2, 0, 8); | ||
285 | mnl = GRAB_BITS(buf, 4, 0, 5); | ||
286 | e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); | ||
287 | |||
288 | e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); | ||
289 | e->support_ai = GRAB_BITS(buf, 5, 1, 1); | ||
290 | e->conn_type = GRAB_BITS(buf, 5, 2, 2); | ||
291 | e->sad_count = GRAB_BITS(buf, 5, 4, 4); | ||
292 | |||
293 | e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; | ||
294 | e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); | ||
295 | |||
296 | e->port_id = get_unaligned_le64(buf + 8); | ||
297 | |||
298 | /* not specified, but the spec's tendency is little endian */ | ||
299 | e->manufacture_id = get_unaligned_le16(buf + 16); | ||
300 | e->product_id = get_unaligned_le16(buf + 18); | ||
301 | |||
302 | if (mnl > ELD_MAX_MNL) { | ||
303 | snd_printd(KERN_INFO "MNL is reserved value %d\n", mnl); | ||
304 | goto out_fail; | ||
305 | } else if (ELD_FIXED_BYTES + mnl > size) { | ||
306 | snd_printd(KERN_INFO "out of range MNL %d\n", mnl); | ||
307 | goto out_fail; | ||
308 | } else | ||
309 | strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl); | ||
310 | |||
311 | for (i = 0; i < e->sad_count; i++) { | ||
312 | if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { | ||
313 | snd_printd(KERN_INFO "out of range SAD %d\n", i); | ||
314 | goto out_fail; | ||
315 | } | ||
316 | hdmi_update_short_audio_desc(e->sad + i, | ||
317 | buf + ELD_FIXED_BYTES + mnl + 3 * i); | ||
318 | } | ||
319 | |||
320 | return 0; | ||
321 | |||
322 | out_fail: | ||
323 | e->eld_ver = 0; | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | |||
327 | static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid) | ||
328 | { | ||
329 | return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); | ||
330 | } | ||
331 | |||
332 | static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) | ||
333 | { | ||
334 | int eldv; | ||
335 | int present; | ||
336 | |||
337 | present = hdmi_present_sense(codec, nid); | ||
338 | eldv = (present & AC_PINSENSE_ELDV); | ||
339 | present = (present & AC_PINSENSE_PRESENCE); | ||
340 | |||
341 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
342 | printk(KERN_INFO "pinp = %d, eldv = %d\n", !!present, !!eldv); | ||
343 | #endif | ||
344 | |||
345 | return eldv && present; | ||
346 | } | ||
347 | |||
348 | int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) | ||
349 | { | ||
350 | return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, | ||
351 | AC_DIPSIZE_ELD_BUF); | ||
352 | } | ||
353 | |||
354 | int snd_hdmi_get_eld(struct sink_eld *eld, | ||
355 | struct hda_codec *codec, hda_nid_t nid) | ||
356 | { | ||
357 | int i; | ||
358 | int ret; | ||
359 | int size; | ||
360 | unsigned char *buf; | ||
361 | |||
362 | if (!hdmi_eld_valid(codec, nid)) | ||
363 | return -ENOENT; | ||
364 | |||
365 | size = snd_hdmi_get_eld_size(codec, nid); | ||
366 | if (size == 0) { | ||
367 | /* wfg: workaround for ASUS P5E-VM HDMI board */ | ||
368 | snd_printd(KERN_INFO "ELD buf size is 0, force 128\n"); | ||
369 | size = 128; | ||
370 | } | ||
371 | if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { | ||
372 | snd_printd(KERN_INFO "Invalid ELD buf size %d\n", size); | ||
373 | return -ERANGE; | ||
374 | } | ||
375 | |||
376 | buf = kmalloc(size, GFP_KERNEL); | ||
377 | if (!buf) | ||
378 | return -ENOMEM; | ||
379 | |||
380 | for (i = 0; i < size; i++) | ||
381 | buf[i] = hdmi_get_eld_byte(codec, nid, i); | ||
382 | |||
383 | ret = hdmi_update_sink_eld(eld, buf, size); | ||
384 | |||
385 | kfree(buf); | ||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | static void hdmi_show_short_audio_desc(struct cea_sad *a) | ||
390 | { | ||
391 | char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; | ||
392 | |||
393 | printk(KERN_INFO "coding type: %s\n", | ||
394 | cea_audio_coding_type_names[a->format]); | ||
395 | printk(KERN_INFO "channels: %d\n", a->channels); | ||
396 | |||
397 | snd_print_pcm_rates(a->rates, buf, sizeof(buf)); | ||
398 | printk(KERN_INFO "sampling frequencies: %s\n", buf); | ||
399 | |||
400 | if (a->format == AUDIO_CODING_TYPE_LPCM) | ||
401 | printk(KERN_INFO "sample bits: 0x%x\n", a->sample_bits); | ||
402 | |||
403 | if (a->max_bitrate) | ||
404 | printk(KERN_INFO "max bitrate: %d\n", a->max_bitrate); | ||
405 | |||
406 | if (a->profile) | ||
407 | printk(KERN_INFO "profile: %d\n", a->profile); | ||
408 | } | ||
409 | |||
410 | #define HDMI_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 | ||
411 | static void hdmi_print_channel_allocation(int spk_alloc, char *buf, int buflen) | ||
412 | { | ||
413 | int i, j; | ||
414 | |||
415 | for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) { | ||
416 | if (spk_alloc & (1 << i)) | ||
417 | j += snprintf(buf + j, buflen - j, "%s ", | ||
418 | cea_speaker_allocation_names[i]); | ||
419 | } | ||
420 | if (j) | ||
421 | j--; /* skip last space */ | ||
422 | buf[j] = '\0'; /* necessary when j == 0 */ | ||
423 | } | ||
424 | |||
425 | void snd_hdmi_show_eld(struct sink_eld *e) | ||
426 | { | ||
427 | int i; | ||
428 | char buf[HDMI_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; | ||
429 | |||
430 | printk(KERN_INFO "ELD buffer size is %d\n", e->eld_size); | ||
431 | printk(KERN_INFO "ELD baseline len is %d*4\n", e->baseline_len); | ||
432 | printk(KERN_INFO "vendor block len is %d\n", | ||
433 | e->eld_size - e->baseline_len * 4 - 4); | ||
434 | printk(KERN_INFO "ELD version is %s\n", | ||
435 | eld_versoin_names[e->eld_ver]); | ||
436 | printk(KERN_INFO "CEA EDID version is %s\n", | ||
437 | cea_edid_version_names[e->cea_edid_ver]); | ||
438 | printk(KERN_INFO "manufacture id is 0x%x\n", e->manufacture_id); | ||
439 | printk(KERN_INFO "product id is 0x%x\n", e->product_id); | ||
440 | printk(KERN_INFO "port id is 0x%llx\n", (long long)e->port_id); | ||
441 | printk(KERN_INFO "HDCP support is %d\n", e->support_hdcp); | ||
442 | printk(KERN_INFO "AI support is %d\n", e->support_ai); | ||
443 | printk(KERN_INFO "SAD count is %d\n", e->sad_count); | ||
444 | printk(KERN_INFO "audio sync delay is %x\n", e->aud_synch_delay); | ||
445 | printk(KERN_INFO "connection type is %s\n", | ||
446 | eld_connection_type_names[e->conn_type]); | ||
447 | printk(KERN_INFO "monitor name is %s\n", e->monitor_name); | ||
448 | |||
449 | hdmi_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); | ||
450 | printk(KERN_INFO "speaker allocations: (0x%x)%s\n", e->spk_alloc, buf); | ||
451 | |||
452 | for (i = 0; i < e->sad_count; i++) | ||
453 | hdmi_show_short_audio_desc(e->sad + i); | ||
454 | } | ||
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d7e3a164effe..e1b76686672a 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -443,4 +443,45 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
443 | #define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) | 443 | #define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) |
444 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | 444 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) |
445 | 445 | ||
446 | /* | ||
447 | * CEA Short Audio Descriptor data | ||
448 | */ | ||
449 | struct cea_sad { | ||
450 | int channels; | ||
451 | int format; /* (format == 0) indicates invalid SAD */ | ||
452 | int rates; | ||
453 | int sample_bits; /* for LPCM */ | ||
454 | int max_bitrate; /* for AC3...ATRAC */ | ||
455 | int profile; /* for WMAPRO */ | ||
456 | }; | ||
457 | |||
458 | #define ELD_FIXED_BYTES 20 | ||
459 | #define ELD_MAX_MNL 16 | ||
460 | #define ELD_MAX_SAD 16 | ||
461 | |||
462 | /* | ||
463 | * ELD: EDID Like Data | ||
464 | */ | ||
465 | struct sink_eld { | ||
466 | int eld_size; | ||
467 | int baseline_len; | ||
468 | int eld_ver; /* (eld_ver == 0) indicates invalid ELD */ | ||
469 | int cea_edid_ver; | ||
470 | char monitor_name[ELD_MAX_MNL + 1]; | ||
471 | int manufacture_id; | ||
472 | int product_id; | ||
473 | u64 port_id; | ||
474 | int support_hdcp; | ||
475 | int support_ai; | ||
476 | int conn_type; | ||
477 | int aud_synch_delay; | ||
478 | int spk_alloc; | ||
479 | int sad_count; | ||
480 | struct cea_sad sad[ELD_MAX_SAD]; | ||
481 | }; | ||
482 | |||
483 | int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); | ||
484 | int snd_hdmi_get_eld(struct sink_eld *, struct hda_codec *, hda_nid_t); | ||
485 | void snd_hdmi_show_eld(struct sink_eld *eld); | ||
486 | |||
446 | #endif /* __SOUND_HDA_LOCAL_H */ | 487 | #endif /* __SOUND_HDA_LOCAL_H */ |
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index d99cd6297249..489278d3d773 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <sound/core.h> | 32 | #include <sound/core.h> |
33 | #include <asm/unaligned.h> | ||
34 | #include "hda_codec.h" | 33 | #include "hda_codec.h" |
35 | #include "hda_local.h" | 34 | #include "hda_local.h" |
36 | #include "hda_patch.h" | 35 | #include "hda_patch.h" |
@@ -40,43 +39,6 @@ | |||
40 | 39 | ||
41 | #define INTEL_HDMI_EVENT_TAG 0x08 | 40 | #define INTEL_HDMI_EVENT_TAG 0x08 |
42 | 41 | ||
43 | /* | ||
44 | * CEA Short Audio Descriptor data | ||
45 | */ | ||
46 | struct cea_sad { | ||
47 | int channels; | ||
48 | int format; /* (format == 0) indicates invalid SAD */ | ||
49 | int rates; | ||
50 | int sample_bits; /* for LPCM */ | ||
51 | int max_bitrate; /* for AC3...ATRAC */ | ||
52 | int profile; /* for WMAPRO */ | ||
53 | }; | ||
54 | |||
55 | #define ELD_FIXED_BYTES 20 | ||
56 | #define ELD_MAX_MNL 16 | ||
57 | #define ELD_MAX_SAD 16 | ||
58 | |||
59 | /* | ||
60 | * ELD: EDID Like Data | ||
61 | */ | ||
62 | struct sink_eld { | ||
63 | int eld_size; | ||
64 | int baseline_len; | ||
65 | int eld_ver; /* (eld_ver == 0) indicates invalid ELD */ | ||
66 | int cea_edid_ver; | ||
67 | char monitor_name[ELD_MAX_MNL + 1]; | ||
68 | int manufacture_id; | ||
69 | int product_id; | ||
70 | u64 port_id; | ||
71 | int support_hdcp; | ||
72 | int support_ai; | ||
73 | int conn_type; | ||
74 | int aud_synch_delay; | ||
75 | int spk_alloc; | ||
76 | int sad_count; | ||
77 | struct cea_sad sad[ELD_MAX_SAD]; | ||
78 | }; | ||
79 | |||
80 | struct intel_hdmi_spec { | 42 | struct intel_hdmi_spec { |
81 | struct hda_multi_out multiout; | 43 | struct hda_multi_out multiout; |
82 | struct hda_pcm pcm_rec; | 44 | struct hda_pcm pcm_rec; |
@@ -127,160 +89,9 @@ struct hdmi_audio_infoframe { | |||
127 | }; | 89 | }; |
128 | 90 | ||
129 | /* | 91 | /* |
130 | * SS1:SS0 index => sample size | ||
131 | */ | ||
132 | static int cea_sample_sizes[4] = { | ||
133 | 0, /* 0: Refer to Stream Header */ | ||
134 | AC_SUPPCM_BITS_16, /* 1: 16 bits */ | ||
135 | AC_SUPPCM_BITS_20, /* 2: 20 bits */ | ||
136 | AC_SUPPCM_BITS_24, /* 3: 24 bits */ | ||
137 | }; | ||
138 | |||
139 | /* | ||
140 | * SF2:SF1:SF0 index => sampling frequency | ||
141 | */ | ||
142 | static int cea_sampling_frequencies[8] = { | ||
143 | 0, /* 0: Refer to Stream Header */ | ||
144 | SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ | ||
145 | SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ | ||
146 | SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ | ||
147 | SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ | ||
148 | SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ | ||
149 | SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ | ||
150 | SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ | ||
151 | }; | ||
152 | |||
153 | enum eld_versions { | ||
154 | ELD_VER_CEA_861D = 2, | ||
155 | ELD_VER_PARTIAL = 31, | ||
156 | }; | ||
157 | |||
158 | static char *eld_versoin_names[32] = { | ||
159 | "0-reserved", | ||
160 | "1-reserved", | ||
161 | "CEA-861D or below", | ||
162 | "3-reserved", | ||
163 | [4 ... 30] = "reserved", | ||
164 | [31] = "partial" | ||
165 | }; | ||
166 | |||
167 | enum cea_edid_versions { | ||
168 | CEA_EDID_VER_NONE = 0, | ||
169 | CEA_EDID_VER_CEA861 = 1, | ||
170 | CEA_EDID_VER_CEA861A = 2, | ||
171 | CEA_EDID_VER_CEA861BCD = 3, | ||
172 | CEA_EDID_VER_RESERVED = 4, | ||
173 | }; | ||
174 | |||
175 | static char *cea_edid_version_names[8] = { | ||
176 | "no CEA EDID Timing Extension block present", | ||
177 | "CEA-861", | ||
178 | "CEA-861-A", | ||
179 | "CEA-861-B, C or D", | ||
180 | "4-reserved", | ||
181 | [5 ... 7] = "reserved" | ||
182 | }; | ||
183 | |||
184 | /* | ||
185 | * CEA Speaker Allocation data block bits | ||
186 | */ | ||
187 | #define CEA_SA_FLR (0 << 0) | ||
188 | #define CEA_SA_LFE (1 << 1) | ||
189 | #define CEA_SA_FC (1 << 2) | ||
190 | #define CEA_SA_RLR (1 << 3) | ||
191 | #define CEA_SA_RC (1 << 4) | ||
192 | #define CEA_SA_FLRC (1 << 5) | ||
193 | #define CEA_SA_RLRC (1 << 6) | ||
194 | /* the following are not defined in ELD yet */ | ||
195 | #define CEA_SA_FLRW (1 << 7) | ||
196 | #define CEA_SA_FLRH (1 << 8) | ||
197 | #define CEA_SA_TC (1 << 9) | ||
198 | #define CEA_SA_FCH (1 << 10) | ||
199 | |||
200 | static char *cea_speaker_allocation_names[] = { | ||
201 | /* 0 */ "FL/FR", | ||
202 | /* 1 */ "LFE", | ||
203 | /* 2 */ "FC", | ||
204 | /* 3 */ "RL/RR", | ||
205 | /* 4 */ "RC", | ||
206 | /* 5 */ "FLC/FRC", | ||
207 | /* 6 */ "RLC/RRC", | ||
208 | /* 7 */ "FLW/FRW", | ||
209 | /* 8 */ "FLH/FRH", | ||
210 | /* 9 */ "TC", | ||
211 | /* 10 */ "FCH", | ||
212 | }; | ||
213 | |||
214 | static char *eld_connection_type_names[4] = { | ||
215 | "HDMI", | ||
216 | "Display Port", | ||
217 | "2-reserved", | ||
218 | "3-reserved" | ||
219 | }; | ||
220 | |||
221 | enum cea_audio_coding_types { | ||
222 | AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, | ||
223 | AUDIO_CODING_TYPE_LPCM = 1, | ||
224 | AUDIO_CODING_TYPE_AC3 = 2, | ||
225 | AUDIO_CODING_TYPE_MPEG1 = 3, | ||
226 | AUDIO_CODING_TYPE_MP3 = 4, | ||
227 | AUDIO_CODING_TYPE_MPEG2 = 5, | ||
228 | AUDIO_CODING_TYPE_AACLC = 6, | ||
229 | AUDIO_CODING_TYPE_DTS = 7, | ||
230 | AUDIO_CODING_TYPE_ATRAC = 8, | ||
231 | AUDIO_CODING_TYPE_SACD = 9, | ||
232 | AUDIO_CODING_TYPE_EAC3 = 10, | ||
233 | AUDIO_CODING_TYPE_DTS_HD = 11, | ||
234 | AUDIO_CODING_TYPE_MLP = 12, | ||
235 | AUDIO_CODING_TYPE_DST = 13, | ||
236 | AUDIO_CODING_TYPE_WMAPRO = 14, | ||
237 | AUDIO_CODING_TYPE_REF_CXT = 15, | ||
238 | /* also include valid xtypes below */ | ||
239 | AUDIO_CODING_TYPE_HE_AAC = 15, | ||
240 | AUDIO_CODING_TYPE_HE_AAC2 = 16, | ||
241 | AUDIO_CODING_TYPE_MPEG_SURROUND = 17, | ||
242 | }; | ||
243 | |||
244 | enum cea_audio_coding_xtypes { | ||
245 | AUDIO_CODING_XTYPE_HE_REF_CT = 0, | ||
246 | AUDIO_CODING_XTYPE_HE_AAC = 1, | ||
247 | AUDIO_CODING_XTYPE_HE_AAC2 = 2, | ||
248 | AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, | ||
249 | AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, | ||
250 | }; | ||
251 | |||
252 | static char *cea_audio_coding_type_names[] = { | ||
253 | /* 0 */ "undefined", | ||
254 | /* 1 */ "LPCM", | ||
255 | /* 2 */ "AC-3", | ||
256 | /* 3 */ "MPEG1", | ||
257 | /* 4 */ "MP3", | ||
258 | /* 5 */ "MPEG2", | ||
259 | /* 6 */ "AAC-LC", | ||
260 | /* 7 */ "DTS", | ||
261 | /* 8 */ "ATRAC", | ||
262 | /* 9 */ "DSD(1-bit audio)", | ||
263 | /* 10 */ "Dolby Digital Plus(E-AC-3/DD+)", | ||
264 | /* 11 */ "DTS-HD", | ||
265 | /* 12 */ "Dolby TrueHD(MLP)", | ||
266 | /* 13 */ "DST", | ||
267 | /* 14 */ "WMAPro", | ||
268 | /* 15 */ "HE-AAC", | ||
269 | /* 16 */ "HE-AACv2", | ||
270 | /* 17 */ "MPEG Surround", | ||
271 | }; | ||
272 | |||
273 | |||
274 | /* | ||
275 | * HDMI routines | 92 | * HDMI routines |
276 | */ | 93 | */ |
277 | 94 | ||
278 | static int hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) | ||
279 | { | ||
280 | return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, | ||
281 | AC_DIPSIZE_ELD_BUF); | ||
282 | } | ||
283 | |||
284 | #ifdef BE_PARANOID | 95 | #ifdef BE_PARANOID |
285 | static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid, | 96 | static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid, |
286 | int *packet_index, int *byte_index) | 97 | int *packet_index, int *byte_index) |
@@ -375,294 +186,13 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec) | |||
375 | } | 186 | } |
376 | 187 | ||
377 | 188 | ||
378 | /* | ||
379 | * ELD(EDID Like Data) routines | ||
380 | */ | ||
381 | |||
382 | static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid) | ||
383 | { | ||
384 | return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); | ||
385 | } | ||
386 | |||
387 | static void hdmi_debug_present_sense(struct hda_codec *codec) | ||
388 | { | ||
389 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
390 | int eldv; | ||
391 | int present; | ||
392 | |||
393 | present = hdmi_present_sense(codec, PIN_NID); | ||
394 | eldv = (present & AC_PINSENSE_ELDV); | ||
395 | present = (present & AC_PINSENSE_PRESENCE); | ||
396 | |||
397 | printk(KERN_INFO "pinp = %d, eldv = %d\n", !!present, !!eldv); | ||
398 | #endif | ||
399 | } | ||
400 | |||
401 | static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, int byte_index) | ||
402 | { | ||
403 | unsigned int val; | ||
404 | |||
405 | val = snd_hda_codec_read(codec, PIN_NID, 0, | ||
406 | AC_VERB_GET_HDMI_ELDD, byte_index); | ||
407 | |||
408 | #ifdef BE_PARANOID | ||
409 | printk(KERN_INFO "ELD data byte %d: 0x%x\n", byte_index, val); | ||
410 | #endif | ||
411 | |||
412 | if ((val & AC_ELDD_ELD_VALID) == 0) { | ||
413 | snd_printd(KERN_INFO "Invalid ELD data byte %d\n", | ||
414 | byte_index); | ||
415 | val = 0; | ||
416 | } | ||
417 | |||
418 | return val & AC_ELDD_ELD_DATA; | ||
419 | } | ||
420 | |||
421 | static inline unsigned char grab_bits(const unsigned char *buf, | ||
422 | int byte, int lowbit, int bits) | ||
423 | { | ||
424 | BUG_ON(lowbit > 7); | ||
425 | BUG_ON(bits > 8); | ||
426 | BUG_ON(bits <= 0); | ||
427 | |||
428 | return (buf[byte] >> lowbit) & ((1 << bits) - 1); | ||
429 | } | ||
430 | |||
431 | static void hdmi_update_short_audio_desc(struct cea_sad *a, | ||
432 | const unsigned char *buf) | ||
433 | { | ||
434 | int i; | ||
435 | int val; | ||
436 | |||
437 | val = grab_bits(buf, 1, 0, 7); | ||
438 | a->rates = 0; | ||
439 | for (i = 0; i < 7; i++) | ||
440 | if (val & (1 << i)) | ||
441 | a->rates |= cea_sampling_frequencies[i + 1]; | ||
442 | |||
443 | a->channels = grab_bits(buf, 0, 0, 3); | ||
444 | a->channels++; | ||
445 | |||
446 | a->format = grab_bits(buf, 0, 3, 4); | ||
447 | switch (a->format) { | ||
448 | case AUDIO_CODING_TYPE_REF_STREAM_HEADER: | ||
449 | snd_printd(KERN_INFO | ||
450 | "audio coding type 0 not expected in ELD\n"); | ||
451 | break; | ||
452 | |||
453 | case AUDIO_CODING_TYPE_LPCM: | ||
454 | val = grab_bits(buf, 2, 0, 3); | ||
455 | a->sample_bits = 0; | ||
456 | for (i = 0; i < 3; i++) | ||
457 | if (val & (1 << i)) | ||
458 | a->sample_bits |= cea_sample_sizes[i + 1]; | ||
459 | break; | ||
460 | |||
461 | case AUDIO_CODING_TYPE_AC3: | ||
462 | case AUDIO_CODING_TYPE_MPEG1: | ||
463 | case AUDIO_CODING_TYPE_MP3: | ||
464 | case AUDIO_CODING_TYPE_MPEG2: | ||
465 | case AUDIO_CODING_TYPE_AACLC: | ||
466 | case AUDIO_CODING_TYPE_DTS: | ||
467 | case AUDIO_CODING_TYPE_ATRAC: | ||
468 | a->max_bitrate = grab_bits(buf, 2, 0, 8); | ||
469 | a->max_bitrate *= 8000; | ||
470 | break; | ||
471 | |||
472 | case AUDIO_CODING_TYPE_SACD: | ||
473 | break; | ||
474 | |||
475 | case AUDIO_CODING_TYPE_EAC3: | ||
476 | break; | ||
477 | |||
478 | case AUDIO_CODING_TYPE_DTS_HD: | ||
479 | break; | ||
480 | |||
481 | case AUDIO_CODING_TYPE_MLP: | ||
482 | break; | ||
483 | |||
484 | case AUDIO_CODING_TYPE_DST: | ||
485 | break; | ||
486 | |||
487 | case AUDIO_CODING_TYPE_WMAPRO: | ||
488 | a->profile = grab_bits(buf, 2, 0, 3); | ||
489 | break; | ||
490 | |||
491 | case AUDIO_CODING_TYPE_REF_CXT: | ||
492 | a->format = grab_bits(buf, 2, 3, 5); | ||
493 | if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || | ||
494 | a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { | ||
495 | snd_printd(KERN_INFO | ||
496 | "audio coding xtype %d not expected in ELD\n", | ||
497 | a->format); | ||
498 | a->format = 0; | ||
499 | } else | ||
500 | a->format += AUDIO_CODING_TYPE_HE_AAC - | ||
501 | AUDIO_CODING_XTYPE_HE_AAC; | ||
502 | break; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | static int hdmi_update_sink_eld(struct hda_codec *codec, | ||
507 | const unsigned char *buf, int size) | ||
508 | { | ||
509 | struct intel_hdmi_spec *spec = codec->spec; | ||
510 | struct sink_eld *e = &spec->sink; | ||
511 | int mnl; | ||
512 | int i; | ||
513 | |||
514 | e->eld_ver = grab_bits(buf, 0, 3, 5); | ||
515 | if (e->eld_ver != ELD_VER_CEA_861D && | ||
516 | e->eld_ver != ELD_VER_PARTIAL) { | ||
517 | snd_printd(KERN_INFO "Unknown ELD version %d\n", e->eld_ver); | ||
518 | goto out_fail; | ||
519 | } | ||
520 | |||
521 | e->eld_size = size; | ||
522 | e->baseline_len = grab_bits(buf, 2, 0, 8); | ||
523 | mnl = grab_bits(buf, 4, 0, 5); | ||
524 | e->cea_edid_ver = grab_bits(buf, 4, 5, 3); | ||
525 | |||
526 | e->support_hdcp = grab_bits(buf, 5, 0, 1); | ||
527 | e->support_ai = grab_bits(buf, 5, 1, 1); | ||
528 | e->conn_type = grab_bits(buf, 5, 2, 2); | ||
529 | e->sad_count = grab_bits(buf, 5, 4, 4); | ||
530 | |||
531 | e->aud_synch_delay = grab_bits(buf, 6, 0, 8); | ||
532 | e->spk_alloc = grab_bits(buf, 7, 0, 7); | ||
533 | |||
534 | e->port_id = get_unaligned_le64(buf + 8); | ||
535 | |||
536 | /* not specified, but the spec's tendency is little endian */ | ||
537 | e->manufacture_id = get_unaligned_le16(buf + 16); | ||
538 | e->product_id = get_unaligned_le16(buf + 18); | ||
539 | |||
540 | if (mnl > ELD_MAX_MNL) { | ||
541 | snd_printd(KERN_INFO "MNL is reserved value %d\n", mnl); | ||
542 | goto out_fail; | ||
543 | } else if (ELD_FIXED_BYTES + mnl > size) { | ||
544 | snd_printd(KERN_INFO "out of range MNL %d\n", mnl); | ||
545 | goto out_fail; | ||
546 | } else | ||
547 | strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl); | ||
548 | |||
549 | for (i = 0; i < e->sad_count; i++) { | ||
550 | if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { | ||
551 | snd_printd(KERN_INFO "out of range SAD %d\n", i); | ||
552 | goto out_fail; | ||
553 | } | ||
554 | hdmi_update_short_audio_desc(e->sad + i, | ||
555 | buf + ELD_FIXED_BYTES + mnl + 3 * i); | ||
556 | } | ||
557 | |||
558 | return 0; | ||
559 | |||
560 | out_fail: | ||
561 | e->eld_ver = 0; | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | static int hdmi_get_eld(struct hda_codec *codec) | ||
566 | { | ||
567 | int i; | ||
568 | int ret; | ||
569 | int size; | ||
570 | unsigned char *buf; | ||
571 | |||
572 | i = hdmi_present_sense(codec, PIN_NID) & AC_PINSENSE_ELDV; | ||
573 | if (!i) | ||
574 | return -ENOENT; | ||
575 | |||
576 | size = hdmi_get_eld_size(codec, PIN_NID); | ||
577 | if (size == 0) { | ||
578 | /* wfg: workaround for ASUS P5E-VM HDMI board */ | ||
579 | snd_printd(KERN_INFO "ELD buf size is 0, force 128\n"); | ||
580 | size = 128; | ||
581 | } | ||
582 | if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { | ||
583 | snd_printd(KERN_INFO "Invalid ELD buf size %d\n", size); | ||
584 | return -ERANGE; | ||
585 | } | ||
586 | |||
587 | buf = kmalloc(size, GFP_KERNEL); | ||
588 | if (!buf) | ||
589 | return -ENOMEM; | ||
590 | |||
591 | for (i = 0; i < size; i++) | ||
592 | buf[i] = hdmi_get_eld_byte(codec, i); | ||
593 | |||
594 | ret = hdmi_update_sink_eld(codec, buf, size); | ||
595 | |||
596 | kfree(buf); | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | static void hdmi_show_short_audio_desc(struct cea_sad *a) | ||
601 | { | ||
602 | printk(KERN_INFO "coding type: %s\n", | ||
603 | cea_audio_coding_type_names[a->format]); | ||
604 | printk(KERN_INFO "channels: %d\n", a->channels); | ||
605 | printk(KERN_INFO "sampling frequencies: 0x%x\n", a->rates); | ||
606 | |||
607 | if (a->format == AUDIO_CODING_TYPE_LPCM) | ||
608 | printk(KERN_INFO "sample bits: 0x%x\n", a->sample_bits); | ||
609 | |||
610 | if (a->max_bitrate) | ||
611 | printk(KERN_INFO "max bitrate: %d HZ\n", a->max_bitrate); | ||
612 | |||
613 | if (a->profile) | ||
614 | printk(KERN_INFO "profile: %d\n", a->profile); | ||
615 | } | ||
616 | |||
617 | static void hdmi_show_eld(struct hda_codec *codec) | ||
618 | { | ||
619 | int i; | ||
620 | int j; | ||
621 | struct intel_hdmi_spec *spec = codec->spec; | ||
622 | struct sink_eld *e = &spec->sink; | ||
623 | char buf[80]; | ||
624 | |||
625 | printk(KERN_INFO "ELD buffer size is %d\n", e->eld_size); | ||
626 | printk(KERN_INFO "ELD baseline len is %d*4\n", e->baseline_len); | ||
627 | printk(KERN_INFO "vendor block len is %d\n", | ||
628 | e->eld_size - e->baseline_len * 4 - 4); | ||
629 | printk(KERN_INFO "ELD version is %s\n", | ||
630 | eld_versoin_names[e->eld_ver]); | ||
631 | printk(KERN_INFO "CEA EDID version is %s\n", | ||
632 | cea_edid_version_names[e->cea_edid_ver]); | ||
633 | printk(KERN_INFO "manufacture id is 0x%x\n", e->manufacture_id); | ||
634 | printk(KERN_INFO "product id is 0x%x\n", e->product_id); | ||
635 | printk(KERN_INFO "port id is 0x%llx\n", (long long)e->port_id); | ||
636 | printk(KERN_INFO "HDCP support is %d\n", e->support_hdcp); | ||
637 | printk(KERN_INFO "AI support is %d\n", e->support_ai); | ||
638 | printk(KERN_INFO "SAD count is %d\n", e->sad_count); | ||
639 | printk(KERN_INFO "audio sync delay is %x\n", e->aud_synch_delay); | ||
640 | printk(KERN_INFO "connection type is %s\n", | ||
641 | eld_connection_type_names[e->conn_type]); | ||
642 | printk(KERN_INFO "monitor name is %s\n", e->monitor_name); | ||
643 | |||
644 | j = 0; | ||
645 | for (i = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) { | ||
646 | if (e->spk_alloc & (1 << i)) | ||
647 | j += snprintf(buf + j, sizeof(buf) - j, " %s", | ||
648 | cea_speaker_allocation_names[i]); | ||
649 | } | ||
650 | buf[j] = '\0'; /* necessary when j == 0 */ | ||
651 | printk(KERN_INFO "speaker allocations: (0x%x)%s\n", e->spk_alloc, buf); | ||
652 | |||
653 | for (i = 0; i < e->sad_count; i++) | ||
654 | hdmi_show_short_audio_desc(e->sad + i); | ||
655 | } | ||
656 | |||
657 | /* | ||
658 | * Be careful, ELD buf could be totally rubbish! | ||
659 | */ | ||
660 | static void hdmi_parse_eld(struct hda_codec *codec) | 189 | static void hdmi_parse_eld(struct hda_codec *codec) |
661 | { | 190 | { |
662 | hdmi_debug_present_sense(codec); | 191 | struct intel_hdmi_spec *spec = codec->spec; |
192 | struct sink_eld *eld = &spec->sink; | ||
663 | 193 | ||
664 | if (!hdmi_get_eld(codec)) | 194 | if (!snd_hdmi_get_eld(eld, codec, PIN_NID)) |
665 | hdmi_show_eld(codec); | 195 | snd_hdmi_show_eld(eld); |
666 | } | 196 | } |
667 | 197 | ||
668 | 198 | ||
@@ -676,7 +206,7 @@ static void hdmi_debug_dip_size(struct hda_codec *codec) | |||
676 | int i; | 206 | int i; |
677 | int size; | 207 | int size; |
678 | 208 | ||
679 | size = hdmi_get_eld_size(codec, PIN_NID); | 209 | size = snd_hdmi_get_eld_size(codec, PIN_NID); |
680 | printk(KERN_DEBUG "ELD buf size is %d\n", size); | 210 | printk(KERN_DEBUG "ELD buf size is %d\n", size); |
681 | 211 | ||
682 | for (i = 0; i < 8; i++) { | 212 | for (i = 0; i < 8; i++) { |