aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_nvhdmi.c
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/hda/patch_nvhdmi.c
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/hda/patch_nvhdmi.c')
-rw-r--r--sound/pci/hda/patch_nvhdmi.c829
1 files changed, 24 insertions, 805 deletions
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)