aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2010-03-07 21:44:23 -0500
committerTakashi Iwai <tiwai@suse.de>2010-03-08 02:21:08 -0500
commit079d88ccc374d2c1a850b8a83595ba4c907fb3df (patch)
treeea1145a3af7355383bdb59dc75ffe59c3fee2f0e /sound/pci
parent4193d13b2c2b694aa59e629e6daf6269d7922f13 (diff)
ALSA: hdmi - merge common code for intelhdmi and nvhdmi
Create patch_hdmi.c to hold common code from intelhdmi and nvhdmi. For now the patch_hdmi.c file is simply included by patch_intelhdmi.c and patch_nvhdmi.c, and does not represent a real codec. There are no behavior changes to intelhdmi. However nvhdmi made several changes when copying code out of intelhdmi, which are all reverted in this patch. Wei Ni confirmed that the reverted code actually works fine. Tested-by: Wei Ni <wni@nvidia.com> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_hdmi.c845
-rw-r--r--sound/pci/hda/patch_intelhdmi.c821
-rw-r--r--sound/pci/hda/patch_nvhdmi.c829
3 files changed, 882 insertions, 1613 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
new file mode 100644
index 000000000000..b2ab39670dda
--- /dev/null
+++ b/sound/pci/hda/patch_hdmi.c
@@ -0,0 +1,845 @@
1/*
2 *
3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
4 *
5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Wu Fengguang <wfg@linux.intel.com>
9 *
10 * Maintained by:
11 * Wu Fengguang <wfg@linux.intel.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28
29struct hdmi_spec {
30 int num_cvts;
31 int num_pins;
32 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */
33 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */
34
35 /*
36 * source connection for each pin
37 */
38 hda_nid_t pin_cvt[MAX_HDMI_PINS+1];
39
40 /*
41 * HDMI sink attached to each pin
42 */
43 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
44
45 /*
46 * export one pcm per pipe
47 */
48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
49
50 /*
51 * nvhdmi specific
52 */
53 struct hda_multi_out multiout;
54 unsigned int codec_type;
55};
56
57
58struct hdmi_audio_infoframe {
59 u8 type; /* 0x84 */
60 u8 ver; /* 0x01 */
61 u8 len; /* 0x0a */
62
63 u8 checksum; /* PB0 */
64 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
65 u8 SS01_SF24;
66 u8 CXT04;
67 u8 CA;
68 u8 LFEPBL01_LSV36_DM_INH7;
69 u8 reserved[5]; /* PB6 - PB10 */
70};
71
72/*
73 * CEA speaker placement:
74 *
75 * FLH FCH FRH
76 * FLW FL FLC FC FRC FR FRW
77 *
78 * LFE
79 * TC
80 *
81 * RL RLC RC RRC RR
82 *
83 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
84 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
85 */
86enum cea_speaker_placement {
87 FL = (1 << 0), /* Front Left */
88 FC = (1 << 1), /* Front Center */
89 FR = (1 << 2), /* Front Right */
90 FLC = (1 << 3), /* Front Left Center */
91 FRC = (1 << 4), /* Front Right Center */
92 RL = (1 << 5), /* Rear Left */
93 RC = (1 << 6), /* Rear Center */
94 RR = (1 << 7), /* Rear Right */
95 RLC = (1 << 8), /* Rear Left Center */
96 RRC = (1 << 9), /* Rear Right Center */
97 LFE = (1 << 10), /* Low Frequency Effect */
98 FLW = (1 << 11), /* Front Left Wide */
99 FRW = (1 << 12), /* Front Right Wide */
100 FLH = (1 << 13), /* Front Left High */
101 FCH = (1 << 14), /* Front Center High */
102 FRH = (1 << 15), /* Front Right High */
103 TC = (1 << 16), /* Top Center */
104};
105
106/*
107 * ELD SA bits in the CEA Speaker Allocation data block
108 */
109static int eld_speaker_allocation_bits[] = {
110 [0] = FL | FR,
111 [1] = LFE,
112 [2] = FC,
113 [3] = RL | RR,
114 [4] = RC,
115 [5] = FLC | FRC,
116 [6] = RLC | RRC,
117 /* the following are not defined in ELD yet */
118 [7] = FLW | FRW,
119 [8] = FLH | FRH,
120 [9] = TC,
121 [10] = FCH,
122};
123
124struct cea_channel_speaker_allocation {
125 int ca_index;
126 int speakers[8];
127
128 /* derived values, just for convenience */
129 int channels;
130 int spk_mask;
131};
132
133/*
134 * ALSA sequence is:
135 *
136 * surround40 surround41 surround50 surround51 surround71
137 * ch0 front left = = = =
138 * ch1 front right = = = =
139 * ch2 rear left = = = =
140 * ch3 rear right = = = =
141 * ch4 LFE center center center
142 * ch5 LFE LFE
143 * ch6 side left
144 * ch7 side right
145 *
146 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
147 */
148static int hdmi_channel_mapping[0x32][8] = {
149 /* stereo */
150 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
151 /* 2.1 */
152 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
153 /* Dolby Surround */
154 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
155 /* surround40 */
156 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
157 /* 4ch */
158 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
159 /* surround41 */
160 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
161 /* surround50 */
162 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
163 /* surround51 */
164 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
165 /* 7.1 */
166 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
167};
168
169/*
170 * This is an ordered list!
171 *
172 * The preceding ones have better chances to be selected by
173 * hdmi_setup_channel_allocation().
174 */
175static struct cea_channel_speaker_allocation channel_allocations[] = {
176/* channel: 7 6 5 4 3 2 1 0 */
177{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
178 /* 2.1 */
179{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
180 /* Dolby Surround */
181{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
182 /* surround40 */
183{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
184 /* surround41 */
185{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
186 /* surround50 */
187{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
188 /* surround51 */
189{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
190 /* 6.1 */
191{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
192 /* surround71 */
193{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
194
195{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
196{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
197{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
198{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
199{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
200{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
203{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
204{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
205{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
206{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
207{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
208{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
209{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
210{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
211{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
212{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
213{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
214{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
215{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
216{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
217{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
218{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
219{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
220{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
222{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
223{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
224{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
225{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
226{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
227{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
228{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
229{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
230{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
231{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
232{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
233{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
234{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
235{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
236};
237
238
239/*
240 * HDMI routines
241 */
242
243static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
244{
245 int i;
246
247 for (i = 0; nids[i]; i++)
248 if (nids[i] == nid)
249 return i;
250
251 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
252 return -EINVAL;
253}
254
255static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
256 struct hdmi_eld *eld)
257{
258 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
259 snd_hdmi_show_eld(eld);
260}
261
262#ifdef BE_PARANOID
263static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
264 int *packet_index, int *byte_index)
265{
266 int val;
267
268 val = snd_hda_codec_read(codec, pin_nid, 0,
269 AC_VERB_GET_HDMI_DIP_INDEX, 0);
270
271 *packet_index = val >> 5;
272 *byte_index = val & 0x1f;
273}
274#endif
275
276static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
277 int packet_index, int byte_index)
278{
279 int val;
280
281 val = (packet_index << 5) | (byte_index & 0x1f);
282
283 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
284}
285
286static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
287 unsigned char val)
288{
289 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
290}
291
292static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
293{
294 /* Unmute */
295 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
296 snd_hda_codec_write(codec, pin_nid, 0,
297 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
298 /* Enable pin out */
299 snd_hda_codec_write(codec, pin_nid, 0,
300 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
301}
302
303static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
304{
305 return 1 + snd_hda_codec_read(codec, nid, 0,
306 AC_VERB_GET_CVT_CHAN_COUNT, 0);
307}
308
309static void hdmi_set_channel_count(struct hda_codec *codec,
310 hda_nid_t nid, int chs)
311{
312 if (chs != hdmi_get_channel_count(codec, nid))
313 snd_hda_codec_write(codec, nid, 0,
314 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
315}
316
317
318/*
319 * Channel mapping routines
320 */
321
322/*
323 * Compute derived values in channel_allocations[].
324 */
325static void init_channel_allocations(void)
326{
327 int i, j;
328 struct cea_channel_speaker_allocation *p;
329
330 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
331 p = channel_allocations + i;
332 p->channels = 0;
333 p->spk_mask = 0;
334 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
335 if (p->speakers[j]) {
336 p->channels++;
337 p->spk_mask |= p->speakers[j];
338 }
339 }
340}
341
342/*
343 * The transformation takes two steps:
344 *
345 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
346 * spk_mask => (channel_allocations[]) => ai->CA
347 *
348 * TODO: it could select the wrong CA from multiple candidates.
349*/
350static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
351 struct hdmi_audio_infoframe *ai)
352{
353 struct hdmi_spec *spec = codec->spec;
354 struct hdmi_eld *eld;
355 int i;
356 int spk_mask = 0;
357 int channels = 1 + (ai->CC02_CT47 & 0x7);
358 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
359
360 /*
361 * CA defaults to 0 for basic stereo audio
362 */
363 if (channels <= 2)
364 return 0;
365
366 i = hda_node_index(spec->pin_cvt, nid);
367 if (i < 0)
368 return 0;
369 eld = &spec->sink_eld[i];
370
371 /*
372 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
373 * in console or for audio devices. Assume the highest speakers
374 * configuration, to _not_ prohibit multi-channel audio playback.
375 */
376 if (!eld->spk_alloc)
377 eld->spk_alloc = 0xffff;
378
379 /*
380 * expand ELD's speaker allocation mask
381 *
382 * ELD tells the speaker mask in a compact(paired) form,
383 * expand ELD's notions to match the ones used by Audio InfoFrame.
384 */
385 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
386 if (eld->spk_alloc & (1 << i))
387 spk_mask |= eld_speaker_allocation_bits[i];
388 }
389
390 /* search for the first working match in the CA table */
391 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
392 if (channels == channel_allocations[i].channels &&
393 (spk_mask & channel_allocations[i].spk_mask) ==
394 channel_allocations[i].spk_mask) {
395 ai->CA = channel_allocations[i].ca_index;
396 break;
397 }
398 }
399
400 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
401 snd_printdd(KERN_INFO
402 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
403 ai->CA, channels, buf);
404
405 return ai->CA;
406}
407
408static void hdmi_debug_channel_mapping(struct hda_codec *codec,
409 hda_nid_t pin_nid)
410{
411#ifdef CONFIG_SND_DEBUG_VERBOSE
412 int i;
413 int slot;
414
415 for (i = 0; i < 8; i++) {
416 slot = snd_hda_codec_read(codec, pin_nid, 0,
417 AC_VERB_GET_HDMI_CHAN_SLOT, i);
418 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
419 slot >> 4, slot & 0xf);
420 }
421#endif
422}
423
424
425static void hdmi_setup_channel_mapping(struct hda_codec *codec,
426 hda_nid_t pin_nid,
427 struct hdmi_audio_infoframe *ai)
428{
429 int i;
430 int ca = ai->CA;
431 int err;
432
433 if (hdmi_channel_mapping[ca][1] == 0) {
434 for (i = 0; i < channel_allocations[ca].channels; i++)
435 hdmi_channel_mapping[ca][i] = i | (i << 4);
436 for (; i < 8; i++)
437 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
438 }
439
440 for (i = 0; i < 8; i++) {
441 err = snd_hda_codec_write(codec, pin_nid, 0,
442 AC_VERB_SET_HDMI_CHAN_SLOT,
443 hdmi_channel_mapping[ca][i]);
444 if (err) {
445 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
446 break;
447 }
448 }
449
450 hdmi_debug_channel_mapping(codec, pin_nid);
451}
452
453
454/*
455 * Audio InfoFrame routines
456 */
457
458/*
459 * Enable Audio InfoFrame Transmission
460 */
461static void hdmi_start_infoframe_trans(struct hda_codec *codec,
462 hda_nid_t pin_nid)
463{
464 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
465 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
466 AC_DIPXMIT_BEST);
467}
468
469/*
470 * Disable Audio InfoFrame Transmission
471 */
472static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
473 hda_nid_t pin_nid)
474{
475 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
476 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
477 AC_DIPXMIT_DISABLE);
478}
479
480static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
481{
482#ifdef CONFIG_SND_DEBUG_VERBOSE
483 int i;
484 int size;
485
486 size = snd_hdmi_get_eld_size(codec, pin_nid);
487 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
488
489 for (i = 0; i < 8; i++) {
490 size = snd_hda_codec_read(codec, pin_nid, 0,
491 AC_VERB_GET_HDMI_DIP_SIZE, i);
492 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
493 }
494#endif
495}
496
497static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
498{
499#ifdef BE_PARANOID
500 int i, j;
501 int size;
502 int pi, bi;
503 for (i = 0; i < 8; i++) {
504 size = snd_hda_codec_read(codec, pin_nid, 0,
505 AC_VERB_GET_HDMI_DIP_SIZE, i);
506 if (size == 0)
507 continue;
508
509 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
510 for (j = 1; j < 1000; j++) {
511 hdmi_write_dip_byte(codec, pin_nid, 0x0);
512 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
513 if (pi != i)
514 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
515 bi, pi, i);
516 if (bi == 0) /* byte index wrapped around */
517 break;
518 }
519 snd_printd(KERN_INFO
520 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
521 i, size, j);
522 }
523#endif
524}
525
526static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
527{
528 u8 *bytes = (u8 *)ai;
529 u8 sum = 0;
530 int i;
531
532 ai->checksum = 0;
533
534 for (i = 0; i < sizeof(*ai); i++)
535 sum += bytes[i];
536
537 ai->checksum = -sum;
538}
539
540static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
541 hda_nid_t pin_nid,
542 struct hdmi_audio_infoframe *ai)
543{
544 u8 *bytes = (u8 *)ai;
545 int i;
546
547 hdmi_debug_dip_size(codec, pin_nid);
548 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
549
550 hdmi_checksum_audio_infoframe(ai);
551
552 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
553 for (i = 0; i < sizeof(*ai); i++)
554 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
555}
556
557static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
558 struct hdmi_audio_infoframe *ai)
559{
560 u8 *bytes = (u8 *)ai;
561 u8 val;
562 int i;
563
564 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
565 != AC_DIPXMIT_BEST)
566 return false;
567
568 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
569 for (i = 0; i < sizeof(*ai); i++) {
570 val = snd_hda_codec_read(codec, pin_nid, 0,
571 AC_VERB_GET_HDMI_DIP_DATA, 0);
572 if (val != bytes[i])
573 return false;
574 }
575
576 return true;
577}
578
579static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
580 struct snd_pcm_substream *substream)
581{
582 struct hdmi_spec *spec = codec->spec;
583 hda_nid_t pin_nid;
584 int i;
585 struct hdmi_audio_infoframe ai = {
586 .type = 0x84,
587 .ver = 0x01,
588 .len = 0x0a,
589 .CC02_CT47 = substream->runtime->channels - 1,
590 };
591
592 hdmi_setup_channel_allocation(codec, nid, &ai);
593
594 for (i = 0; i < spec->num_pins; i++) {
595 if (spec->pin_cvt[i] != nid)
596 continue;
597 if (!spec->sink_eld[i].monitor_present)
598 continue;
599
600 pin_nid = spec->pin[i];
601 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
602 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
603 hdmi_stop_infoframe_trans(codec, pin_nid);
604 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
605 hdmi_start_infoframe_trans(codec, pin_nid);
606 }
607 }
608}
609
610
611/*
612 * Unsolicited events
613 */
614
615static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
616{
617 struct hdmi_spec *spec = codec->spec;
618 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
619 int pind = !!(res & AC_UNSOL_RES_PD);
620 int eldv = !!(res & AC_UNSOL_RES_ELDV);
621 int index;
622
623 printk(KERN_INFO
624 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
625 tag, pind, eldv);
626
627 index = hda_node_index(spec->pin, tag);
628 if (index < 0)
629 return;
630
631 spec->sink_eld[index].monitor_present = pind;
632 spec->sink_eld[index].eld_valid = eldv;
633
634 if (pind && eldv) {
635 hdmi_get_show_eld(codec, spec->pin[index],
636 &spec->sink_eld[index]);
637 /* TODO: do real things about ELD */
638 }
639}
640
641static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
642{
643 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
644 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
645 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
646 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
647
648 printk(KERN_INFO
649 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
650 tag,
651 subtag,
652 cp_state,
653 cp_ready);
654
655 /* TODO */
656 if (cp_state)
657 ;
658 if (cp_ready)
659 ;
660}
661
662
663static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
664{
665 struct hdmi_spec *spec = codec->spec;
666 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
667 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
668
669 if (hda_node_index(spec->pin, tag) < 0) {
670 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
671 return;
672 }
673
674 if (subtag == 0)
675 hdmi_intrinsic_event(codec, res);
676 else
677 hdmi_non_intrinsic_event(codec, res);
678}
679
680/*
681 * Callbacks
682 */
683
684static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
685 u32 stream_tag, int format)
686{
687 int tag;
688 int fmt;
689
690 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
691 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
692
693 snd_printdd("hdmi_setup_stream: "
694 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
695 nid,
696 tag == stream_tag ? "" : "new-",
697 stream_tag,
698 fmt == format ? "" : "new-",
699 format);
700
701 if (tag != stream_tag)
702 snd_hda_codec_write(codec, nid, 0,
703 AC_VERB_SET_CHANNEL_STREAMID,
704 stream_tag << 4);
705 if (fmt != format)
706 snd_hda_codec_write(codec, nid, 0,
707 AC_VERB_SET_STREAM_FORMAT, format);
708}
709
710/*
711 * HDA/HDMI auto parsing
712 */
713
714static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
715{
716 struct hdmi_spec *spec = codec->spec;
717 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
718 int conn_len, curr;
719 int index;
720
721 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
722 snd_printk(KERN_WARNING
723 "HDMI: pin %d wcaps %#x "
724 "does not support connection list\n",
725 pin_nid, get_wcaps(codec, pin_nid));
726 return -EINVAL;
727 }
728
729 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
730 HDA_MAX_CONNECTIONS);
731 if (conn_len > 1)
732 curr = snd_hda_codec_read(codec, pin_nid, 0,
733 AC_VERB_GET_CONNECT_SEL, 0);
734 else
735 curr = 0;
736
737 index = hda_node_index(spec->pin, pin_nid);
738 if (index < 0)
739 return -EINVAL;
740
741 spec->pin_cvt[index] = conn_list[curr];
742
743 return 0;
744}
745
746static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
747 struct hdmi_eld *eld)
748{
749 int present = snd_hda_pin_sense(codec, pin_nid);
750
751 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
752 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
753
754 if (present & AC_PINSENSE_ELDV)
755 hdmi_get_show_eld(codec, pin_nid, eld);
756}
757
758static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
759{
760 struct hdmi_spec *spec = codec->spec;
761
762 if (spec->num_pins >= MAX_HDMI_PINS) {
763 snd_printk(KERN_WARNING
764 "HDMI: no space for pin %d\n", pin_nid);
765 return -EINVAL;
766 }
767
768 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
769
770 spec->pin[spec->num_pins] = pin_nid;
771 spec->num_pins++;
772
773 /*
774 * It is assumed that converter nodes come first in the node list and
775 * hence have been registered and usable now.
776 */
777 return hdmi_read_pin_conn(codec, pin_nid);
778}
779
780static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
781{
782 struct hdmi_spec *spec = codec->spec;
783
784 if (spec->num_cvts >= MAX_HDMI_CVTS) {
785 snd_printk(KERN_WARNING
786 "HDMI: no space for converter %d\n", nid);
787 return -EINVAL;
788 }
789
790 spec->cvt[spec->num_cvts] = nid;
791 spec->num_cvts++;
792
793 return 0;
794}
795
796static int hdmi_parse_codec(struct hda_codec *codec)
797{
798 hda_nid_t nid;
799 int i, nodes;
800
801 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
802 if (!nid || nodes < 0) {
803 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
804 return -EINVAL;
805 }
806
807 for (i = 0; i < nodes; i++, nid++) {
808 unsigned int caps;
809 unsigned int type;
810
811 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
812 type = get_wcaps_type(caps);
813
814 if (!(caps & AC_WCAP_DIGITAL))
815 continue;
816
817 switch (type) {
818 case AC_WID_AUD_OUT:
819 if (hdmi_add_cvt(codec, nid) < 0)
820 return -EINVAL;
821 break;
822 case AC_WID_PIN:
823 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
824 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
825 continue;
826 if (hdmi_add_pin(codec, nid) < 0)
827 return -EINVAL;
828 break;
829 }
830 }
831
832 /*
833 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
834 * can be lost and presence sense verb will become inaccurate if the
835 * HDA link is powered off at hot plug or hw initialization time.
836 */
837#ifdef CONFIG_SND_HDA_POWER_SAVE
838 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
839 AC_PWRST_EPSS))
840 codec->bus->power_keep_link_on = 1;
841#endif
842
843 return 0;
844}
845
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 918f40378d52..88d035104cc5 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,815 +40,20 @@
40 * 40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes. 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */ 42 */
43#define INTEL_HDMI_CVTS 2 43#define MAX_HDMI_CVTS 2
44#define INTEL_HDMI_PINS 3 44#define MAX_HDMI_PINS 3
45 45
46static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = { 46#include "patch_hdmi.c"
47
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
47 "INTEL HDMI 0", 49 "INTEL HDMI 0",
48 "INTEL HDMI 1", 50 "INTEL HDMI 1",
49}; 51};
50 52
51struct intel_hdmi_spec {
52 int num_cvts;
53 int num_pins;
54 hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
55 hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
56
57 /*
58 * source connection for each pin
59 */
60 hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
61
62 /*
63 * HDMI sink attached to each pin
64 */
65 struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
66
67 /*
68 * export one pcm per pipe
69 */
70 struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
71};
72
73struct hdmi_audio_infoframe {
74 u8 type; /* 0x84 */
75 u8 ver; /* 0x01 */
76 u8 len; /* 0x0a */
77
78 u8 checksum; /* PB0 */
79 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
80 u8 SS01_SF24;
81 u8 CXT04;
82 u8 CA;
83 u8 LFEPBL01_LSV36_DM_INH7;
84 u8 reserved[5]; /* PB6 - PB10 */
85};
86
87/*
88 * CEA speaker placement:
89 *
90 * FLH FCH FRH
91 * FLW FL FLC FC FRC FR FRW
92 *
93 * LFE
94 * TC
95 *
96 * RL RLC RC RRC RR
97 *
98 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
99 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
100 */
101enum cea_speaker_placement {
102 FL = (1 << 0), /* Front Left */
103 FC = (1 << 1), /* Front Center */
104 FR = (1 << 2), /* Front Right */
105 FLC = (1 << 3), /* Front Left Center */
106 FRC = (1 << 4), /* Front Right Center */
107 RL = (1 << 5), /* Rear Left */
108 RC = (1 << 6), /* Rear Center */
109 RR = (1 << 7), /* Rear Right */
110 RLC = (1 << 8), /* Rear Left Center */
111 RRC = (1 << 9), /* Rear Right Center */
112 LFE = (1 << 10), /* Low Frequency Effect */
113 FLW = (1 << 11), /* Front Left Wide */
114 FRW = (1 << 12), /* Front Right Wide */
115 FLH = (1 << 13), /* Front Left High */
116 FCH = (1 << 14), /* Front Center High */
117 FRH = (1 << 15), /* Front Right High */
118 TC = (1 << 16), /* Top Center */
119};
120
121/*
122 * ELD SA bits in the CEA Speaker Allocation data block
123 */
124static int eld_speaker_allocation_bits[] = {
125 [0] = FL | FR,
126 [1] = LFE,
127 [2] = FC,
128 [3] = RL | RR,
129 [4] = RC,
130 [5] = FLC | FRC,
131 [6] = RLC | RRC,
132 /* the following are not defined in ELD yet */
133 [7] = FLW | FRW,
134 [8] = FLH | FRH,
135 [9] = TC,
136 [10] = FCH,
137};
138
139struct cea_channel_speaker_allocation {
140 int ca_index;
141 int speakers[8];
142
143 /* derived values, just for convenience */
144 int channels;
145 int spk_mask;
146};
147
148/*
149 * ALSA sequence is:
150 *
151 * surround40 surround41 surround50 surround51 surround71
152 * ch0 front left = = = =
153 * ch1 front right = = = =
154 * ch2 rear left = = = =
155 * ch3 rear right = = = =
156 * ch4 LFE center center center
157 * ch5 LFE LFE
158 * ch6 side left
159 * ch7 side right
160 *
161 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
162 */
163static int hdmi_channel_mapping[0x32][8] = {
164 /* stereo */
165 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
166 /* 2.1 */
167 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
168 /* Dolby Surround */
169 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
170 /* surround40 */
171 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
172 /* 4ch */
173 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
174 /* surround41 */
175 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
176 /* surround50 */
177 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
178 /* surround51 */
179 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
180 /* 7.1 */
181 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
182};
183
184/*
185 * This is an ordered list!
186 *
187 * The preceding ones have better chances to be selected by
188 * hdmi_setup_channel_allocation().
189 */
190static struct cea_channel_speaker_allocation channel_allocations[] = {
191/* channel: 7 6 5 4 3 2 1 0 */
192{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
193 /* 2.1 */
194{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
195 /* Dolby Surround */
196{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
197 /* surround40 */
198{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
199 /* surround41 */
200{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
201 /* surround50 */
202{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
203 /* surround51 */
204{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
205 /* 6.1 */
206{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
207 /* surround71 */
208{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
209
210{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
211{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
212{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
213{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
214{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
215{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
216{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
217{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
218{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
219{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
220{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
222{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
223{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
224{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
225{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
226{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
227{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
228{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
229{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
230{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
231{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
232{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
233{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
234{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
235{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
236{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
237{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
238{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
239{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
240{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
241{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
242{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
243{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
244{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
245{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
246{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
247{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
248{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
249{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
250{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
251};
252
253/*
254 * HDA/HDMI auto parsing
255 */
256
257static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
258{
259 int i;
260
261 for (i = 0; nids[i]; i++)
262 if (nids[i] == nid)
263 return i;
264
265 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
266 return -EINVAL;
267}
268
269static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
270{
271 struct intel_hdmi_spec *spec = codec->spec;
272 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
273 int conn_len, curr;
274 int index;
275
276 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
277 snd_printk(KERN_WARNING
278 "HDMI: pin %d wcaps %#x "
279 "does not support connection list\n",
280 pin_nid, get_wcaps(codec, pin_nid));
281 return -EINVAL;
282 }
283
284 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
285 HDA_MAX_CONNECTIONS);
286 if (conn_len > 1)
287 curr = snd_hda_codec_read(codec, pin_nid, 0,
288 AC_VERB_GET_CONNECT_SEL, 0);
289 else
290 curr = 0;
291
292 index = hda_node_index(spec->pin, pin_nid);
293 if (index < 0)
294 return -EINVAL;
295
296 spec->pin_cvt[index] = conn_list[curr];
297
298 return 0;
299}
300
301static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
302 struct hdmi_eld *eld)
303{
304 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
305 snd_hdmi_show_eld(eld);
306}
307
308static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
309 struct hdmi_eld *eld)
310{
311 int present = snd_hda_pin_sense(codec, pin_nid);
312
313 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
314 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
315
316 if (present & AC_PINSENSE_ELDV)
317 hdmi_get_show_eld(codec, pin_nid, eld);
318}
319
320static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
321{
322 struct intel_hdmi_spec *spec = codec->spec;
323
324 if (spec->num_pins >= INTEL_HDMI_PINS) {
325 snd_printk(KERN_WARNING
326 "HDMI: no space for pin %d \n", pin_nid);
327 return -EINVAL;
328 }
329
330 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
331
332 spec->pin[spec->num_pins] = pin_nid;
333 spec->num_pins++;
334
335 /*
336 * It is assumed that converter nodes come first in the node list and
337 * hence have been registered and usable now.
338 */
339 return intel_hdmi_read_pin_conn(codec, pin_nid);
340}
341
342static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
343{
344 struct intel_hdmi_spec *spec = codec->spec;
345
346 if (spec->num_cvts >= INTEL_HDMI_CVTS) {
347 snd_printk(KERN_WARNING
348 "HDMI: no space for converter %d \n", nid);
349 return -EINVAL;
350 }
351
352 spec->cvt[spec->num_cvts] = nid;
353 spec->num_cvts++;
354
355 return 0;
356}
357
358static int intel_hdmi_parse_codec(struct hda_codec *codec)
359{
360 hda_nid_t nid;
361 int i, nodes;
362
363 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
364 if (!nid || nodes < 0) {
365 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
366 return -EINVAL;
367 }
368
369 for (i = 0; i < nodes; i++, nid++) {
370 unsigned int caps;
371 unsigned int type;
372
373 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
374 type = get_wcaps_type(caps);
375
376 if (!(caps & AC_WCAP_DIGITAL))
377 continue;
378
379 switch (type) {
380 case AC_WID_AUD_OUT:
381 if (intel_hdmi_add_cvt(codec, nid) < 0)
382 return -EINVAL;
383 break;
384 case AC_WID_PIN:
385 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
386 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
387 continue;
388 if (intel_hdmi_add_pin(codec, nid) < 0)
389 return -EINVAL;
390 break;
391 }
392 }
393
394 /*
395 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
396 * can be lost and presence sense verb will become inaccurate if the
397 * HDA link is powered off at hot plug or hw initialization time.
398 */
399#ifdef CONFIG_SND_HDA_POWER_SAVE
400 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
401 AC_PWRST_EPSS))
402 codec->bus->power_keep_link_on = 1;
403#endif
404
405 return 0;
406}
407
408/*
409 * HDMI routines
410 */
411
412#ifdef BE_PARANOID
413static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
414 int *packet_index, int *byte_index)
415{
416 int val;
417
418 val = snd_hda_codec_read(codec, pin_nid, 0,
419 AC_VERB_GET_HDMI_DIP_INDEX, 0);
420
421 *packet_index = val >> 5;
422 *byte_index = val & 0x1f;
423}
424#endif
425
426static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
427 int packet_index, int byte_index)
428{
429 int val;
430
431 val = (packet_index << 5) | (byte_index & 0x1f);
432
433 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
434}
435
436static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
437 unsigned char val)
438{
439 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
440}
441
442static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
443{
444 /* Unmute */
445 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
446 snd_hda_codec_write(codec, pin_nid, 0,
447 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
448 /* Enable pin out */
449 snd_hda_codec_write(codec, pin_nid, 0,
450 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
451}
452
453/*
454 * Enable Audio InfoFrame Transmission
455 */
456static void hdmi_start_infoframe_trans(struct hda_codec *codec,
457 hda_nid_t pin_nid)
458{
459 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
460 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
461 AC_DIPXMIT_BEST);
462}
463
464/*
465 * Disable Audio InfoFrame Transmission
466 */
467static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
468 hda_nid_t pin_nid)
469{
470 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
471 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
472 AC_DIPXMIT_DISABLE);
473}
474
475static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
476{
477 return 1 + snd_hda_codec_read(codec, nid, 0,
478 AC_VERB_GET_CVT_CHAN_COUNT, 0);
479}
480
481static void hdmi_set_channel_count(struct hda_codec *codec,
482 hda_nid_t nid, int chs)
483{
484 if (chs != hdmi_get_channel_count(codec, nid))
485 snd_hda_codec_write(codec, nid, 0,
486 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
487}
488
489static void hdmi_debug_channel_mapping(struct hda_codec *codec,
490 hda_nid_t pin_nid)
491{
492#ifdef CONFIG_SND_DEBUG_VERBOSE
493 int i;
494 int slot;
495
496 for (i = 0; i < 8; i++) {
497 slot = snd_hda_codec_read(codec, pin_nid, 0,
498 AC_VERB_GET_HDMI_CHAN_SLOT, i);
499 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
500 slot >> 4, slot & 0xf);
501 }
502#endif
503}
504
505
506/*
507 * Audio InfoFrame routines
508 */
509
510static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
511{
512#ifdef CONFIG_SND_DEBUG_VERBOSE
513 int i;
514 int size;
515
516 size = snd_hdmi_get_eld_size(codec, pin_nid);
517 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
518
519 for (i = 0; i < 8; i++) {
520 size = snd_hda_codec_read(codec, pin_nid, 0,
521 AC_VERB_GET_HDMI_DIP_SIZE, i);
522 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
523 }
524#endif
525}
526
527static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
528{
529#ifdef BE_PARANOID
530 int i, j;
531 int size;
532 int pi, bi;
533 for (i = 0; i < 8; i++) {
534 size = snd_hda_codec_read(codec, pin_nid, 0,
535 AC_VERB_GET_HDMI_DIP_SIZE, i);
536 if (size == 0)
537 continue;
538
539 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
540 for (j = 1; j < 1000; j++) {
541 hdmi_write_dip_byte(codec, pin_nid, 0x0);
542 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
543 if (pi != i)
544 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
545 bi, pi, i);
546 if (bi == 0) /* byte index wrapped around */
547 break;
548 }
549 snd_printd(KERN_INFO
550 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
551 i, size, j);
552 }
553#endif
554}
555
556static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
557{
558 u8 *bytes = (u8 *)ai;
559 u8 sum = 0;
560 int i;
561
562 ai->checksum = 0;
563
564 for (i = 0; i < sizeof(*ai); i++)
565 sum += bytes[i];
566
567 ai->checksum = - sum;
568}
569
570static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
571 hda_nid_t pin_nid,
572 struct hdmi_audio_infoframe *ai)
573{
574 u8 *bytes = (u8 *)ai;
575 int i;
576
577 hdmi_debug_dip_size(codec, pin_nid);
578 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
579
580 hdmi_checksum_audio_infoframe(ai);
581
582 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
583 for (i = 0; i < sizeof(*ai); i++)
584 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
585}
586
587/*
588 * Compute derived values in channel_allocations[].
589 */
590static void init_channel_allocations(void)
591{
592 int i, j;
593 struct cea_channel_speaker_allocation *p;
594
595 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
596 p = channel_allocations + i;
597 p->channels = 0;
598 p->spk_mask = 0;
599 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
600 if (p->speakers[j]) {
601 p->channels++;
602 p->spk_mask |= p->speakers[j];
603 }
604 }
605}
606
607/*
608 * The transformation takes two steps:
609 *
610 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
611 * spk_mask => (channel_allocations[]) => ai->CA
612 *
613 * TODO: it could select the wrong CA from multiple candidates.
614*/
615static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
616 struct hdmi_audio_infoframe *ai)
617{
618 struct intel_hdmi_spec *spec = codec->spec;
619 struct hdmi_eld *eld;
620 int i;
621 int spk_mask = 0;
622 int channels = 1 + (ai->CC02_CT47 & 0x7);
623 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
624
625 /*
626 * CA defaults to 0 for basic stereo audio
627 */
628 if (channels <= 2)
629 return 0;
630
631 i = hda_node_index(spec->pin_cvt, nid);
632 if (i < 0)
633 return 0;
634 eld = &spec->sink_eld[i];
635
636 /*
637 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
638 * in console or for audio devices. Assume the highest speakers
639 * configuration, to _not_ prohibit multi-channel audio playback.
640 */
641 if (!eld->spk_alloc)
642 eld->spk_alloc = 0xffff;
643
644 /*
645 * expand ELD's speaker allocation mask
646 *
647 * ELD tells the speaker mask in a compact(paired) form,
648 * expand ELD's notions to match the ones used by Audio InfoFrame.
649 */
650 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
651 if (eld->spk_alloc & (1 << i))
652 spk_mask |= eld_speaker_allocation_bits[i];
653 }
654
655 /* search for the first working match in the CA table */
656 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
657 if (channels == channel_allocations[i].channels &&
658 (spk_mask & channel_allocations[i].spk_mask) ==
659 channel_allocations[i].spk_mask) {
660 ai->CA = channel_allocations[i].ca_index;
661 break;
662 }
663 }
664
665 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
666 snd_printdd(KERN_INFO
667 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
668 ai->CA, channels, buf);
669
670 return ai->CA;
671}
672
673static void hdmi_setup_channel_mapping(struct hda_codec *codec,
674 hda_nid_t pin_nid,
675 struct hdmi_audio_infoframe *ai)
676{
677 int i;
678 int ca = ai->CA;
679 int err;
680
681 if (hdmi_channel_mapping[ca][1] == 0) {
682 for (i = 0; i < channel_allocations[ca].channels; i++)
683 hdmi_channel_mapping[ca][i] = i | (i << 4);
684 for (; i < 8; i++)
685 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
686 }
687
688 for (i = 0; i < 8; i++) {
689 err = snd_hda_codec_write(codec, pin_nid, 0,
690 AC_VERB_SET_HDMI_CHAN_SLOT,
691 hdmi_channel_mapping[ca][i]);
692 if (err) {
693 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
694 break;
695 }
696 }
697
698 hdmi_debug_channel_mapping(codec, pin_nid);
699}
700
701static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
702 struct hdmi_audio_infoframe *ai)
703{
704 u8 *bytes = (u8 *)ai;
705 u8 val;
706 int i;
707
708 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
709 != AC_DIPXMIT_BEST)
710 return false;
711
712 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
713 for (i = 0; i < sizeof(*ai); i++) {
714 val = snd_hda_codec_read(codec, pin_nid, 0,
715 AC_VERB_GET_HDMI_DIP_DATA, 0);
716 if (val != bytes[i])
717 return false;
718 }
719
720 return true;
721}
722
723static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
724 struct snd_pcm_substream *substream)
725{
726 struct intel_hdmi_spec *spec = codec->spec;
727 hda_nid_t pin_nid;
728 int i;
729 struct hdmi_audio_infoframe ai = {
730 .type = 0x84,
731 .ver = 0x01,
732 .len = 0x0a,
733 .CC02_CT47 = substream->runtime->channels - 1,
734 };
735
736 hdmi_setup_channel_allocation(codec, nid, &ai);
737
738 for (i = 0; i < spec->num_pins; i++) {
739 if (spec->pin_cvt[i] != nid)
740 continue;
741 if (!spec->sink_eld[i].monitor_present)
742 continue;
743
744 pin_nid = spec->pin[i];
745 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
746 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
747 hdmi_stop_infoframe_trans(codec, pin_nid);
748 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
749 hdmi_start_infoframe_trans(codec, pin_nid);
750 }
751 }
752}
753
754
755/* 53/*
756 * Unsolicited events 54 * HDMI callbacks
757 */ 55 */
758 56
759static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
760{
761 struct intel_hdmi_spec *spec = codec->spec;
762 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
763 int pind = !!(res & AC_UNSOL_RES_PD);
764 int eldv = !!(res & AC_UNSOL_RES_ELDV);
765 int index;
766
767 printk(KERN_INFO
768 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
769 tag, pind, eldv);
770
771 index = hda_node_index(spec->pin, tag);
772 if (index < 0)
773 return;
774
775 spec->sink_eld[index].monitor_present = pind;
776 spec->sink_eld[index].eld_valid = eldv;
777
778 if (pind && eldv) {
779 hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
780 /* TODO: do real things about ELD */
781 }
782}
783
784static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
785{
786 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
787 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
788 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
789 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
790
791 printk(KERN_INFO
792 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
793 tag,
794 subtag,
795 cp_state,
796 cp_ready);
797
798 /* TODO */
799 if (cp_state)
800 ;
801 if (cp_ready)
802 ;
803}
804
805
806static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
807{
808 struct intel_hdmi_spec *spec = codec->spec;
809 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
810 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
811
812 if (hda_node_index(spec->pin, tag) < 0) {
813 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
814 return;
815 }
816
817 if (subtag == 0)
818 hdmi_intrinsic_event(codec, res);
819 else
820 hdmi_non_intrinsic_event(codec, res);
821}
822
823/*
824 * Callbacks
825 */
826
827static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
828 u32 stream_tag, int format)
829{
830 int tag;
831 int fmt;
832
833 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
834 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
835
836 snd_printdd("hdmi_setup_stream: "
837 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
838 nid,
839 tag == stream_tag ? "" : "new-",
840 stream_tag,
841 fmt == format ? "" : "new-",
842 format);
843
844 if (tag != stream_tag)
845 snd_hda_codec_write(codec, nid, 0,
846 AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4);
847 if (fmt != format)
848 snd_hda_codec_write(codec, nid, 0,
849 AC_VERB_SET_STREAM_FORMAT, format);
850}
851
852static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 57static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
853 struct hda_codec *codec, 58 struct hda_codec *codec,
854 unsigned int stream_tag, 59 unsigned int stream_tag,
@@ -882,7 +87,7 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
882 87
883static int intel_hdmi_build_pcms(struct hda_codec *codec) 88static int intel_hdmi_build_pcms(struct hda_codec *codec)
884{ 89{
885 struct intel_hdmi_spec *spec = codec->spec; 90 struct hdmi_spec *spec = codec->spec;
886 struct hda_pcm *info = spec->pcm_rec; 91 struct hda_pcm *info = spec->pcm_rec;
887 int i; 92 int i;
888 93
@@ -908,7 +113,7 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
908 113
909static int intel_hdmi_build_controls(struct hda_codec *codec) 114static int intel_hdmi_build_controls(struct hda_codec *codec)
910{ 115{
911 struct intel_hdmi_spec *spec = codec->spec; 116 struct hdmi_spec *spec = codec->spec;
912 int err; 117 int err;
913 int i; 118 int i;
914 119
@@ -923,7 +128,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec)
923 128
924static int intel_hdmi_init(struct hda_codec *codec) 129static int intel_hdmi_init(struct hda_codec *codec)
925{ 130{
926 struct intel_hdmi_spec *spec = codec->spec; 131 struct hdmi_spec *spec = codec->spec;
927 int i; 132 int i;
928 133
929 for (i = 0; spec->pin[i]; i++) { 134 for (i = 0; spec->pin[i]; i++) {
@@ -937,7 +142,7 @@ static int intel_hdmi_init(struct hda_codec *codec)
937 142
938static void intel_hdmi_free(struct hda_codec *codec) 143static void intel_hdmi_free(struct hda_codec *codec)
939{ 144{
940 struct intel_hdmi_spec *spec = codec->spec; 145 struct hdmi_spec *spec = codec->spec;
941 int i; 146 int i;
942 147
943 for (i = 0; i < spec->num_pins; i++) 148 for (i = 0; i < spec->num_pins; i++)
@@ -951,12 +156,12 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
951 .free = intel_hdmi_free, 156 .free = intel_hdmi_free,
952 .build_pcms = intel_hdmi_build_pcms, 157 .build_pcms = intel_hdmi_build_pcms,
953 .build_controls = intel_hdmi_build_controls, 158 .build_controls = intel_hdmi_build_controls,
954 .unsol_event = intel_hdmi_unsol_event, 159 .unsol_event = hdmi_unsol_event,
955}; 160};
956 161
957static int patch_intel_hdmi(struct hda_codec *codec) 162static int patch_intel_hdmi(struct hda_codec *codec)
958{ 163{
959 struct intel_hdmi_spec *spec; 164 struct hdmi_spec *spec;
960 int i; 165 int i;
961 166
962 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -964,7 +169,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
964 return -ENOMEM; 169 return -ENOMEM;
965 170
966 codec->spec = spec; 171 codec->spec = spec;
967 if (intel_hdmi_parse_codec(codec) < 0) { 172 if (hdmi_parse_codec(codec) < 0) {
968 codec->spec = NULL; 173 codec->spec = NULL;
969 kfree(spec); 174 kfree(spec);
970 return -EINVAL; 175 return -EINVAL;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 1c774f942407..70669a246902 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,6 +29,15 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31 31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
32/* define below to restrict the supported rates and formats */ 41/* define below to restrict the supported rates and formats */
33/* #define LIMITED_RATE_FMT_SUPPORT */ 42/* #define LIMITED_RATE_FMT_SUPPORT */
34 43
@@ -83,802 +92,12 @@ static struct hda_verb nvhdmi_basic_init_7x[] = {
83 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) 92 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
84#endif 93#endif
85 94
86#define NVIDIA_89_HDMI_CVTS 1
87#define NVIDIA_89_HDMI_PINS 1
88
89static char *nvhdmi_pcm_names[NVIDIA_89_HDMI_CVTS] = {
90 "NVIDIA HDMI",
91};
92
93struct nvhdmi_spec {
94 int num_cvts;
95 int num_pins;
96 hda_nid_t cvt[NVIDIA_89_HDMI_CVTS+1]; /* audio sources */
97 hda_nid_t pin[NVIDIA_89_HDMI_PINS+1]; /* audio sinks */
98 hda_nid_t pin_cvt[NVIDIA_89_HDMI_PINS+1];
99 struct hda_pcm pcm_rec[NVIDIA_89_HDMI_CVTS];
100 struct hdmi_eld sink_eld[NVIDIA_89_HDMI_PINS];
101 struct hda_multi_out multiout;
102 unsigned int codec_type;
103};
104
105struct hdmi_audio_infoframe {
106 u8 type; /* 0x84 */
107 u8 ver; /* 0x01 */
108 u8 len; /* 0x0a */
109
110 u8 checksum; /* PB0 */
111 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
112 u8 SS01_SF24;
113 u8 CXT04;
114 u8 CA;
115 u8 LFEPBL01_LSV36_DM_INH7;
116};
117
118/*
119 * CEA speaker placement:
120 *
121 * FLH FCH FRH
122 * FLW FL FLC FC FRC FR FRW
123 *
124 * LFE
125 * TC
126 *
127 * RL RLC RC RRC RR
128 *
129 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
130 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
131 */
132enum cea_speaker_placement {
133 FL = (1 << 0), /* Front Left */
134 FC = (1 << 1), /* Front Center */
135 FR = (1 << 2), /* Front Right */
136 FLC = (1 << 3), /* Front Left Center */
137 FRC = (1 << 4), /* Front Right Center */
138 RL = (1 << 5), /* Rear Left */
139 RC = (1 << 6), /* Rear Center */
140 RR = (1 << 7), /* Rear Right */
141 RLC = (1 << 8), /* Rear Left Center */
142 RRC = (1 << 9), /* Rear Right Center */
143 LFE = (1 << 10), /* Low Frequency Effect */
144 FLW = (1 << 11), /* Front Left Wide */
145 FRW = (1 << 12), /* Front Right Wide */
146 FLH = (1 << 13), /* Front Left High */
147 FCH = (1 << 14), /* Front Center High */
148 FRH = (1 << 15), /* Front Right High */
149 TC = (1 << 16), /* Top Center */
150};
151
152/*
153 * ELD SA bits in the CEA Speaker Allocation data block
154 */
155static int eld_speaker_allocation_bits[] = {
156 [0] = FL | FR,
157 [1] = LFE,
158 [2] = FC,
159 [3] = RL | RR,
160 [4] = RC,
161 [5] = FLC | FRC,
162 [6] = RLC | RRC,
163 /* the following are not defined in ELD yet */
164 [7] = FLW | FRW,
165 [8] = FLH | FRH,
166 [9] = TC,
167 [10] = FCH,
168};
169
170struct cea_channel_speaker_allocation {
171 int ca_index;
172 int speakers[8];
173
174 /* derived values, just for convenience */
175 int channels;
176 int spk_mask;
177};
178
179/*
180 * ALSA sequence is:
181 *
182 * surround40 surround41 surround50 surround51 surround71
183 * ch0 front left = = = =
184 * ch1 front right = = = =
185 * ch2 rear left = = = =
186 * ch3 rear right = = = =
187 * ch4 LFE center center center
188 * ch5 LFE LFE
189 * ch6 side left
190 * ch7 side right
191 *
192 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
193 */
194static int hdmi_channel_mapping[0x32][8] = {
195 /* stereo */
196 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
197 /* 2.1 */
198 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
199 /* Dolby Surround */
200 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
201 /* surround40 */
202 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
203 /* 4ch */
204 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
205 /* surround41 */
206 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
207 /* surround50 */
208 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
209 /* surround51 */
210 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
211 /* 7.1 */
212 [0x13] = { 0x00, 0x11, 0x32, 0x23, 0x64, 0x75, 0x46, 0x57 },
213};
214
215/*
216 * This is an ordered list!
217 *
218 * The preceding ones have better chances to be selected by
219 * hdmi_setup_channel_allocation().
220 */
221static struct cea_channel_speaker_allocation channel_allocations[] = {
222/* channel: 7 6 5 4 3 2 1 0 */
223{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
224 /* 2.1 */
225{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
226 /* Dolby Surround */
227{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
228 /* surround40 */
229{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
230 /* surround41 */
231{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
232 /* surround50 */
233{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
234 /* surround51 */
235{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
236 /* 6.1 */
237{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
238 /* surround71 */
239{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
240
241{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
242{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
243{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
244{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
245{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
246{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
247{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
248{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
249{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
250{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
251{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
252{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
253{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
254{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
255{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
256{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
257{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
258{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
259{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
260{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
261{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
262{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
263{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
264{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
265{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
266{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
267{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
268{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
269{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
270{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
271{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
272{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
273{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
274{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
275{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
276{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
277{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
278{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
279{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
280{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
281{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
282};
283
284/*
285 * HDA/HDMI auto parsing
286 */
287
288static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
289{
290 int i;
291
292 for (i = 0; nids[i]; i++)
293 if (nids[i] == nid)
294 return i;
295
296 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
297 return -EINVAL;
298}
299
300static int nvhdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
301{
302 struct nvhdmi_spec *spec = codec->spec;
303 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
304 int conn_len, curr;
305 int index;
306
307 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
308 snd_printk(KERN_WARNING
309 "HDMI: pin %d wcaps %#x "
310 "does not support connection list\n",
311 pin_nid, get_wcaps(codec, pin_nid));
312 return -EINVAL;
313 }
314
315 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
316 HDA_MAX_CONNECTIONS);
317 if (conn_len > 1)
318 curr = snd_hda_codec_read(codec, pin_nid, 0,
319 AC_VERB_GET_CONNECT_SEL, 0);
320 else
321 curr = 0;
322
323 index = hda_node_index(spec->pin, pin_nid);
324 if (index < 0)
325 return -EINVAL;
326
327 spec->pin_cvt[index] = conn_list[curr];
328
329 return 0;
330}
331
332static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
333 struct hdmi_eld *eld)
334{
335 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
336 snd_hdmi_show_eld(eld);
337}
338
339static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
340 struct hdmi_eld *eld)
341{
342 int present = snd_hda_pin_sense(codec, pin_nid);
343
344 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
345 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
346
347 if (present & AC_PINSENSE_ELDV)
348 hdmi_get_show_eld(codec, pin_nid, eld);
349}
350
351static int nvhdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
352{
353 struct nvhdmi_spec *spec = codec->spec;
354
355 if (spec->num_pins >= NVIDIA_89_HDMI_PINS) {
356 snd_printk(KERN_WARNING
357 "HDMI: no space for pin %d \n", pin_nid);
358 return -EINVAL;
359 }
360
361 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
362
363 spec->pin[spec->num_pins] = pin_nid;
364 spec->num_pins++;
365
366 /*
367 * It is assumed that converter nodes come first in the node list and
368 * hence have been registered and usable now.
369 */
370 return nvhdmi_read_pin_conn(codec, pin_nid);
371}
372
373static int nvhdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
374{
375 struct nvhdmi_spec *spec = codec->spec;
376
377 if (spec->num_cvts >= NVIDIA_89_HDMI_CVTS) {
378 snd_printk(KERN_WARNING
379 "HDMI: no space for converter %d \n", nid);
380 return -EINVAL;
381 }
382
383 spec->cvt[spec->num_cvts] = nid;
384 spec->num_cvts++;
385
386 return 0;
387}
388
389
390static int nvhdmi_parse_codec(struct hda_codec *codec)
391{
392 hda_nid_t nid;
393 int i, nodes;
394
395 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
396 if (!nid || nodes < 0) {
397 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
398 return -EINVAL;
399 }
400
401 for (i = 0; i < nodes; i++, nid++) {
402 unsigned int caps;
403 unsigned int type;
404
405 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
406 type = get_wcaps_type(caps);
407
408 if (!(caps & AC_WCAP_DIGITAL))
409 continue;
410
411 switch (type) {
412 case AC_WID_AUD_OUT:
413 if (nvhdmi_add_cvt(codec, nid) < 0)
414 return -EINVAL;
415 break;
416 case AC_WID_PIN:
417 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
418 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
419 continue;
420 if (nvhdmi_add_pin(codec, nid) < 0)
421 return -EINVAL;
422 break;
423 }
424 }
425
426 /*
427 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
428 * can be lost and presence sense verb will become inaccurate if the
429 * HDA link is powered off at hot plug or hw initialization time.
430 */
431#ifdef CONFIG_SND_HDA_POWER_SAVE
432 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
433 AC_PWRST_EPSS))
434 codec->bus->power_keep_link_on = 1;
435#endif
436
437 return 0;
438}
439
440/*
441 * HDMI routines
442 */
443
444#ifdef BE_PARANOID
445static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
446 int *packet_index, int *byte_index)
447{
448 int val;
449
450 val = snd_hda_codec_read(codec, pin_nid, 0,
451 AC_VERB_GET_HDMI_DIP_INDEX, 0);
452
453 *packet_index = val >> 5;
454 *byte_index = val & 0x1f;
455}
456#endif
457
458static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
459 int packet_index, int byte_index)
460{
461 int val;
462
463 val = (packet_index << 5) | (byte_index & 0x1f);
464
465 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
466}
467
468static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
469 unsigned char val)
470{
471 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
472}
473
474static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
475{
476 /* Unmute */
477 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
478 snd_hda_codec_write(codec, pin_nid, 0,
479 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
480 /* Enable pin out */
481 snd_hda_codec_write(codec, pin_nid, 0,
482 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
483}
484
485/*
486 * Enable Audio InfoFrame Transmission
487 */
488static void hdmi_start_infoframe_trans(struct hda_codec *codec,
489 hda_nid_t pin_nid)
490{
491 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
492 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
493 AC_DIPXMIT_BEST);
494}
495
496/*
497 * Disable Audio InfoFrame Transmission
498 */
499static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
500 hda_nid_t pin_nid)
501{
502 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
503 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
504 AC_DIPXMIT_DISABLE);
505}
506
507static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
508{
509 return 1 + snd_hda_codec_read(codec, nid, 0,
510 AC_VERB_GET_CVT_CHAN_COUNT, 0);
511}
512
513static void hdmi_set_channel_count(struct hda_codec *codec,
514 hda_nid_t nid, int chs)
515{
516 if (chs != hdmi_get_channel_count(codec, nid))
517 snd_hda_codec_write(codec, nid, 0,
518 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
519}
520
521static void hdmi_debug_channel_mapping(struct hda_codec *codec,
522 hda_nid_t pin_nid)
523{
524#ifdef CONFIG_SND_DEBUG_VERBOSE
525 int i;
526 int slot;
527
528 for (i = 0; i < 8; i++) {
529 slot = snd_hda_codec_read(codec, pin_nid, 0,
530 AC_VERB_GET_HDMI_CHAN_SLOT, i);
531 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
532 slot >> 4, slot & 0xf);
533 }
534#endif
535}
536
537
538/*
539 * Audio InfoFrame routines
540 */
541
542static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
543{
544#ifdef CONFIG_SND_DEBUG_VERBOSE
545 int i;
546 int size;
547
548 size = snd_hdmi_get_eld_size(codec, pin_nid);
549 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
550
551 for (i = 0; i < 8; i++) {
552 size = snd_hda_codec_read(codec, pin_nid, 0,
553 AC_VERB_GET_HDMI_DIP_SIZE, i);
554 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
555 }
556#endif
557}
558
559static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
560{
561#ifdef BE_PARANOID
562 int i, j;
563 int size;
564 int pi, bi;
565 for (i = 0; i < 8; i++) {
566 size = snd_hda_codec_read(codec, pin_nid, 0,
567 AC_VERB_GET_HDMI_DIP_SIZE, i);
568 if (size == 0)
569 continue;
570
571 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
572 for (j = 1; j < 1000; j++) {
573 hdmi_write_dip_byte(codec, pin_nid, 0x0);
574 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
575 if (pi != i)
576 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
577 bi, pi, i);
578 if (bi == 0) /* byte index wrapped around */
579 break;
580 }
581 snd_printd(KERN_INFO
582 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
583 i, size, j);
584 }
585#endif
586}
587
588static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
589{
590 ai->checksum = 0;
591}
592
593static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
594 hda_nid_t pin_nid,
595 struct hdmi_audio_infoframe *ai)
596{
597 u8 *bytes = (u8 *)ai;
598 int i;
599
600 hdmi_debug_dip_size(codec, pin_nid);
601 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
602
603 hdmi_checksum_audio_infoframe(ai);
604
605 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
606 for (i = 0; i < sizeof(*ai); i++)
607 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
608}
609
610/*
611 * Compute derived values in channel_allocations[].
612 */
613static void init_channel_allocations(void)
614{
615 int i, j;
616 struct cea_channel_speaker_allocation *p;
617
618 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
619 p = channel_allocations + i;
620 p->channels = 0;
621 p->spk_mask = 0;
622 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
623 if (p->speakers[j]) {
624 p->channels++;
625 p->spk_mask |= p->speakers[j];
626 }
627 }
628}
629
630/*
631 * The transformation takes two steps:
632 *
633 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
634 * spk_mask => (channel_allocations[]) => ai->CA
635 *
636 * TODO: it could select the wrong CA from multiple candidates.
637*/
638static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
639 struct hdmi_audio_infoframe *ai)
640{
641 struct nvhdmi_spec *spec = codec->spec;
642 struct hdmi_eld *eld;
643 int i;
644 int spk_mask = 0;
645 int channels = 1 + (ai->CC02_CT47 & 0x7);
646 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
647
648 /*
649 * CA defaults to 0 for basic stereo audio
650 */
651 if (channels <= 2)
652 return 0;
653
654 i = hda_node_index(spec->pin_cvt, nid);
655 if (i < 0)
656 return 0;
657 eld = &spec->sink_eld[i];
658
659 /*
660 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
661 * in console or for audio devices. Assume the highest speakers
662 * configuration, to _not_ prohibit multi-channel audio playback.
663 */
664 if (!eld->spk_alloc)
665 eld->spk_alloc = 0xffff;
666
667 /*
668 * expand ELD's speaker allocation mask
669 *
670 * ELD tells the speaker mask in a compact(paired) form,
671 * expand ELD's notions to match the ones used by Audio InfoFrame.
672 */
673 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
674 if (eld->spk_alloc & (1 << i))
675 spk_mask |= eld_speaker_allocation_bits[i];
676 }
677
678 /* search for the first working match in the CA table */
679 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
680 if (channels == channel_allocations[i].channels &&
681 (spk_mask & channel_allocations[i].spk_mask) ==
682 channel_allocations[i].spk_mask) {
683 ai->CA = channel_allocations[i].ca_index;
684 break;
685 }
686 }
687
688 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
689 snd_printdd(KERN_INFO
690 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
691 ai->CA, channels, buf);
692
693 return ai->CA;
694}
695
696static void hdmi_setup_channel_mapping(struct hda_codec *codec,
697 hda_nid_t pin_nid,
698 struct hdmi_audio_infoframe *ai)
699{
700 int i;
701 int ca = ai->CA;
702 int err;
703
704 if (hdmi_channel_mapping[ca][1] == 0) {
705 for (i = 0; i < channel_allocations[ca].channels; i++)
706 hdmi_channel_mapping[ca][i] = i | (i << 4);
707 for (; i < 8; i++)
708 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
709 }
710
711 for (i = 0; i < 8; i++) {
712 err = snd_hda_codec_write(codec, pin_nid, 0,
713 AC_VERB_SET_HDMI_CHAN_SLOT,
714 hdmi_channel_mapping[ca][i]);
715 if (err) {
716 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
717 break;
718 }
719 }
720
721 hdmi_debug_channel_mapping(codec, pin_nid);
722}
723
724static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
725 struct hdmi_audio_infoframe *ai)
726{
727 u8 *bytes = (u8 *)ai;
728 u8 val;
729 int i;
730
731 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
732 != AC_DIPXMIT_BEST)
733 return false;
734
735 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
736 for (i = 0; i < sizeof(*ai); i++) {
737 val = snd_hda_codec_read(codec, pin_nid, 0,
738 AC_VERB_GET_HDMI_DIP_DATA, 0);
739 if (val != bytes[i])
740 return false;
741 }
742
743 return true;
744}
745
746static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
747 struct snd_pcm_substream *substream)
748{
749 struct nvhdmi_spec *spec = codec->spec;
750 hda_nid_t pin_nid;
751 int i;
752 struct hdmi_audio_infoframe ai = {
753 .type = 0x84,
754 .ver = 0x01,
755 .len = 0x0a,
756 .CC02_CT47 = substream->runtime->channels - 1,
757 };
758
759 hdmi_setup_channel_allocation(codec, nid, &ai);
760
761 for (i = 0; i < spec->num_pins; i++) {
762 if (spec->pin_cvt[i] != nid)
763 continue;
764 if (!spec->sink_eld[i].monitor_present)
765 continue;
766
767 pin_nid = spec->pin[i];
768 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
769 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
770 hdmi_stop_infoframe_trans(codec, pin_nid);
771 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
772 hdmi_start_infoframe_trans(codec, pin_nid);
773 }
774 }
775}
776
777/*
778 * Unsolicited events
779 */
780
781static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
782{
783 struct nvhdmi_spec *spec = codec->spec;
784 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
785 int pind = !!(res & AC_UNSOL_RES_PD);
786 int eldv = !!(res & AC_UNSOL_RES_ELDV);
787 int index;
788
789 printk(KERN_INFO
790 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
791 tag, pind, eldv);
792
793 index = hda_node_index(spec->pin, tag);
794 if (index < 0)
795 return;
796
797 spec->sink_eld[index].monitor_present = pind;
798 spec->sink_eld[index].eld_valid = eldv;
799
800 if (eldv) {
801 spec->sink_eld[index].monitor_present = 1;
802 hdmi_get_show_eld(codec, spec->pin[index],
803 &spec->sink_eld[index]);
804 /* TODO: do real things about ELD */
805 }
806}
807
808static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
809{
810 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
811 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
812 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
813 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
814
815 printk(KERN_INFO
816 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
817 tag,
818 subtag,
819 cp_state,
820 cp_ready);
821
822 /* TODO */
823 if (cp_state)
824 ;
825 if (cp_ready)
826 ;
827}
828
829static void nvhdmi_unsol_event(struct hda_codec *codec, unsigned int res)
830{
831 struct nvhdmi_spec *spec = codec->spec;
832 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
833 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
834
835 if (hda_node_index(spec->pin, tag) < 0) {
836 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
837 return;
838 }
839
840 if (subtag == 0)
841 hdmi_intrinsic_event(codec, res);
842 else
843 hdmi_non_intrinsic_event(codec, res);
844}
845
846/*
847 * Callbacks
848 */
849
850static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
851 u32 stream_tag, int format)
852{
853 int tag;
854 int fmt;
855
856 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
857 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
858
859 snd_printdd("hdmi_setup_stream: "
860 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
861 nid,
862 tag == stream_tag ? "" : "new-",
863 stream_tag,
864 fmt == format ? "" : "new-",
865 format);
866
867 if (tag != stream_tag)
868 snd_hda_codec_write(codec, nid, 0,
869 AC_VERB_SET_CHANNEL_STREAMID,
870 stream_tag << 4);
871 if (fmt != format)
872 snd_hda_codec_write(codec, nid, 0,
873 AC_VERB_SET_STREAM_FORMAT, format);
874}
875
876/* 95/*
877 * Controls 96 * Controls
878 */ 97 */
879static int nvhdmi_build_controls(struct hda_codec *codec) 98static int nvhdmi_build_controls(struct hda_codec *codec)
880{ 99{
881 struct nvhdmi_spec *spec = codec->spec; 100 struct hdmi_spec *spec = codec->spec;
882 int err; 101 int err;
883 int i; 102 int i;
884 103
@@ -902,7 +121,7 @@ static int nvhdmi_build_controls(struct hda_codec *codec)
902 121
903static int nvhdmi_init(struct hda_codec *codec) 122static int nvhdmi_init(struct hda_codec *codec)
904{ 123{
905 struct nvhdmi_spec *spec = codec->spec; 124 struct hdmi_spec *spec = codec->spec;
906 int i; 125 int i;
907 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89) 126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
908 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) { 127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
@@ -920,7 +139,7 @@ static int nvhdmi_init(struct hda_codec *codec)
920 139
921static void nvhdmi_free(struct hda_codec *codec) 140static void nvhdmi_free(struct hda_codec *codec)
922{ 141{
923 struct nvhdmi_spec *spec = codec->spec; 142 struct hdmi_spec *spec = codec->spec;
924 int i; 143 int i;
925 144
926 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89) 145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
@@ -939,7 +158,7 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
939 struct hda_codec *codec, 158 struct hda_codec *codec,
940 struct snd_pcm_substream *substream) 159 struct snd_pcm_substream *substream)
941{ 160{
942 struct nvhdmi_spec *spec = codec->spec; 161 struct hdmi_spec *spec = codec->spec;
943 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
944} 163}
945 164
@@ -947,7 +166,7 @@ static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
947 struct hda_codec *codec, 166 struct hda_codec *codec,
948 struct snd_pcm_substream *substream) 167 struct snd_pcm_substream *substream)
949{ 168{
950 struct nvhdmi_spec *spec = codec->spec; 169 struct hdmi_spec *spec = codec->spec;
951 int i; 170 int i;
952 171
953 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
@@ -968,7 +187,7 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
968 struct hda_codec *codec, 187 struct hda_codec *codec,
969 struct snd_pcm_substream *substream) 188 struct snd_pcm_substream *substream)
970{ 189{
971 struct nvhdmi_spec *spec = codec->spec; 190 struct hdmi_spec *spec = codec->spec;
972 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
973} 192}
974 193
@@ -1121,7 +340,7 @@ static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
1121 unsigned int format, 340 unsigned int format,
1122 struct snd_pcm_substream *substream) 341 struct snd_pcm_substream *substream)
1123{ 342{
1124 struct nvhdmi_spec *spec = codec->spec; 343 struct hdmi_spec *spec = codec->spec;
1125 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 344 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
1126 format, substream); 345 format, substream);
1127} 346}
@@ -1170,7 +389,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
1170 389
1171static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec) 390static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
1172{ 391{
1173 struct nvhdmi_spec *spec = codec->spec; 392 struct hdmi_spec *spec = codec->spec;
1174 struct hda_pcm *info = spec->pcm_rec; 393 struct hda_pcm *info = spec->pcm_rec;
1175 int i; 394 int i;
1176 395
@@ -1196,7 +415,7 @@ static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
1196 415
1197static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec) 416static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
1198{ 417{
1199 struct nvhdmi_spec *spec = codec->spec; 418 struct hdmi_spec *spec = codec->spec;
1200 struct hda_pcm *info = spec->pcm_rec; 419 struct hda_pcm *info = spec->pcm_rec;
1201 420
1202 codec->num_pcms = 1; 421 codec->num_pcms = 1;
@@ -1212,7 +431,7 @@ static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
1212 431
1213static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) 432static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
1214{ 433{
1215 struct nvhdmi_spec *spec = codec->spec; 434 struct hdmi_spec *spec = codec->spec;
1216 struct hda_pcm *info = spec->pcm_rec; 435 struct hda_pcm *info = spec->pcm_rec;
1217 436
1218 codec->num_pcms = 1; 437 codec->num_pcms = 1;
@@ -1231,7 +450,7 @@ static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
1231 .build_pcms = nvhdmi_build_pcms_8ch_89, 450 .build_pcms = nvhdmi_build_pcms_8ch_89,
1232 .init = nvhdmi_init, 451 .init = nvhdmi_init,
1233 .free = nvhdmi_free, 452 .free = nvhdmi_free,
1234 .unsol_event = nvhdmi_unsol_event, 453 .unsol_event = hdmi_unsol_event,
1235}; 454};
1236 455
1237static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { 456static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
@@ -1250,7 +469,7 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1250 469
1251static int patch_nvhdmi_8ch_89(struct hda_codec *codec) 470static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
1252{ 471{
1253 struct nvhdmi_spec *spec; 472 struct hdmi_spec *spec;
1254 int i; 473 int i;
1255 474
1256 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -1260,7 +479,7 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
1260 codec->spec = spec; 479 codec->spec = spec;
1261 spec->codec_type = HDA_CODEC_NVIDIA_MCP89; 480 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
1262 481
1263 if (nvhdmi_parse_codec(codec) < 0) { 482 if (hdmi_parse_codec(codec) < 0) {
1264 codec->spec = NULL; 483 codec->spec = NULL;
1265 kfree(spec); 484 kfree(spec);
1266 return -EINVAL; 485 return -EINVAL;
@@ -1277,7 +496,7 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
1277 496
1278static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) 497static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
1279{ 498{
1280 struct nvhdmi_spec *spec; 499 struct hdmi_spec *spec;
1281 500
1282 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1283 if (spec == NULL) 502 if (spec == NULL)
@@ -1297,7 +516,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
1297 516
1298static int patch_nvhdmi_2ch(struct hda_codec *codec) 517static int patch_nvhdmi_2ch(struct hda_codec *codec)
1299{ 518{
1300 struct nvhdmi_spec *spec; 519 struct hdmi_spec *spec;
1301 520
1302 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 521 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1303 if (spec == NULL) 522 if (spec == NULL)