diff options
-rw-r--r-- | sound/pci/hda/hda_codec.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 611 |
3 files changed, 350 insertions, 266 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c63a06703de3..ce418c805a1a 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -3412,7 +3412,7 @@ static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) | |||
3412 | * | 3412 | * |
3413 | * Returns 0 if successful, otherwise a negative error code. | 3413 | * Returns 0 if successful, otherwise a negative error code. |
3414 | */ | 3414 | */ |
3415 | static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | 3415 | int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, |
3416 | u32 *ratesp, u64 *formatsp, unsigned int *bpsp) | 3416 | u32 *ratesp, u64 *formatsp, unsigned int *bpsp) |
3417 | { | 3417 | { |
3418 | unsigned int i, val, wcaps; | 3418 | unsigned int i, val, wcaps; |
@@ -3504,6 +3504,7 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
3504 | 3504 | ||
3505 | return 0; | 3505 | return 0; |
3506 | } | 3506 | } |
3507 | EXPORT_SYMBOL_HDA(snd_hda_query_supported_pcm); | ||
3507 | 3508 | ||
3508 | /** | 3509 | /** |
3509 | * snd_hda_is_supported_format - Check the validity of the format | 3510 | * snd_hda_is_supported_format - Check the validity of the format |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 96c35cab57bf..070efac7e207 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -903,6 +903,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, | |||
903 | hda_nid_t *start_id); | 903 | hda_nid_t *start_id); |
904 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | 904 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, |
905 | hda_nid_t *conn_list, int max_conns); | 905 | hda_nid_t *conn_list, int max_conns); |
906 | int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | ||
907 | u32 *ratesp, u64 *formatsp, unsigned int *bpsp); | ||
906 | 908 | ||
907 | struct hda_verb { | 909 | struct hda_verb { |
908 | hda_nid_t nid; | 910 | hda_nid_t nid; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 338546531c17..19cb72db9c38 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); | |||
43 | 43 | ||
44 | /* | 44 | /* |
45 | * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device | 45 | * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device |
46 | * could support two independent pipes, each of them can be connected to one or | 46 | * could support N independent pipes, each of them can be connected to one or |
47 | * more ports (DVI, HDMI or DisplayPort). | 47 | * more ports (DVI, HDMI or DisplayPort). |
48 | * | 48 | * |
49 | * The HDA correspondence of pipes/ports are converter/pin nodes. | 49 | * The HDA correspondence of pipes/ports are converter/pin nodes. |
@@ -51,30 +51,33 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); | |||
51 | #define MAX_HDMI_CVTS 4 | 51 | #define MAX_HDMI_CVTS 4 |
52 | #define MAX_HDMI_PINS 4 | 52 | #define MAX_HDMI_PINS 4 |
53 | 53 | ||
54 | struct hdmi_spec { | 54 | struct hdmi_spec_per_cvt { |
55 | int num_cvts; | 55 | hda_nid_t cvt_nid; |
56 | int num_pins; | 56 | int assigned; |
57 | hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */ | 57 | unsigned int channels_min; |
58 | hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */ | 58 | unsigned int channels_max; |
59 | u32 rates; | ||
60 | u64 formats; | ||
61 | unsigned int maxbps; | ||
62 | }; | ||
59 | 63 | ||
60 | /* | 64 | struct hdmi_spec_per_pin { |
61 | * source connection for each pin | 65 | hda_nid_t pin_nid; |
62 | */ | 66 | int num_mux_nids; |
63 | hda_nid_t pin_cvt[MAX_HDMI_PINS+1]; | 67 | hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; |
68 | struct hdmi_eld sink_eld; | ||
69 | }; | ||
64 | 70 | ||
65 | /* | 71 | struct hdmi_spec { |
66 | * HDMI sink attached to each pin | 72 | int num_cvts; |
67 | */ | 73 | struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS]; |
68 | struct hdmi_eld sink_eld[MAX_HDMI_PINS]; | ||
69 | 74 | ||
70 | /* | 75 | int num_pins; |
71 | * export one pcm per pipe | 76 | struct hdmi_spec_per_pin pins[MAX_HDMI_PINS]; |
72 | */ | 77 | struct hda_pcm pcm_rec[MAX_HDMI_PINS]; |
73 | struct hda_pcm pcm_rec[MAX_HDMI_CVTS]; | ||
74 | struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS]; | ||
75 | 78 | ||
76 | /* | 79 | /* |
77 | * ati/nvhdmi specific | 80 | * Non-generic ATI/NVIDIA specific |
78 | */ | 81 | */ |
79 | struct hda_multi_out multiout; | 82 | struct hda_multi_out multiout; |
80 | const struct hda_pcm_stream *pcm_playback; | 83 | const struct hda_pcm_stream *pcm_playback; |
@@ -284,15 +287,40 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { | |||
284 | * HDMI routines | 287 | * HDMI routines |
285 | */ | 288 | */ |
286 | 289 | ||
287 | static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) | 290 | static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid) |
288 | { | 291 | { |
289 | int i; | 292 | int pin_idx; |
290 | 293 | ||
291 | for (i = 0; nids[i]; i++) | 294 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) |
292 | if (nids[i] == nid) | 295 | if (spec->pins[pin_idx].pin_nid == pin_nid) |
293 | return i; | 296 | return pin_idx; |
294 | 297 | ||
295 | snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid); | 298 | snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid); |
299 | return -EINVAL; | ||
300 | } | ||
301 | |||
302 | static int hinfo_to_pin_index(struct hdmi_spec *spec, | ||
303 | struct hda_pcm_stream *hinfo) | ||
304 | { | ||
305 | int pin_idx; | ||
306 | |||
307 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) | ||
308 | if (&spec->pcm_rec[pin_idx].stream[0] == hinfo) | ||
309 | return pin_idx; | ||
310 | |||
311 | snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | |||
315 | static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid) | ||
316 | { | ||
317 | int cvt_idx; | ||
318 | |||
319 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) | ||
320 | if (spec->cvts[cvt_idx].cvt_nid == cvt_nid) | ||
321 | return cvt_idx; | ||
322 | |||
323 | snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid); | ||
296 | return -EINVAL; | 324 | return -EINVAL; |
297 | } | 325 | } |
298 | 326 | ||
@@ -326,28 +354,28 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid, | |||
326 | snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val); | 354 | snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val); |
327 | } | 355 | } |
328 | 356 | ||
329 | static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid) | 357 | static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
330 | { | 358 | { |
331 | /* Unmute */ | 359 | /* Unmute */ |
332 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) | 360 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) |
333 | snd_hda_codec_write(codec, pin_nid, 0, | 361 | snd_hda_codec_write(codec, pin_nid, 0, |
334 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 362 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); |
335 | /* Enable pin out */ | 363 | /* Disable pin out until stream is active*/ |
336 | snd_hda_codec_write(codec, pin_nid, 0, | 364 | snd_hda_codec_write(codec, pin_nid, 0, |
337 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 365 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); |
338 | } | 366 | } |
339 | 367 | ||
340 | static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid) | 368 | static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid) |
341 | { | 369 | { |
342 | return 1 + snd_hda_codec_read(codec, nid, 0, | 370 | return 1 + snd_hda_codec_read(codec, cvt_nid, 0, |
343 | AC_VERB_GET_CVT_CHAN_COUNT, 0); | 371 | AC_VERB_GET_CVT_CHAN_COUNT, 0); |
344 | } | 372 | } |
345 | 373 | ||
346 | static void hdmi_set_channel_count(struct hda_codec *codec, | 374 | static void hdmi_set_channel_count(struct hda_codec *codec, |
347 | hda_nid_t nid, int chs) | 375 | hda_nid_t cvt_nid, int chs) |
348 | { | 376 | { |
349 | if (chs != hdmi_get_channel_count(codec, nid)) | 377 | if (chs != hdmi_get_channel_count(codec, cvt_nid)) |
350 | snd_hda_codec_write(codec, nid, 0, | 378 | snd_hda_codec_write(codec, cvt_nid, 0, |
351 | AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); | 379 | AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); |
352 | } | 380 | } |
353 | 381 | ||
@@ -384,11 +412,8 @@ static void init_channel_allocations(void) | |||
384 | * | 412 | * |
385 | * TODO: it could select the wrong CA from multiple candidates. | 413 | * TODO: it could select the wrong CA from multiple candidates. |
386 | */ | 414 | */ |
387 | static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid, | 415 | static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels) |
388 | int channels) | ||
389 | { | 416 | { |
390 | struct hdmi_spec *spec = codec->spec; | ||
391 | struct hdmi_eld *eld; | ||
392 | int i; | 417 | int i; |
393 | int ca = 0; | 418 | int ca = 0; |
394 | int spk_mask = 0; | 419 | int spk_mask = 0; |
@@ -400,19 +425,6 @@ static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid, | |||
400 | if (channels <= 2) | 425 | if (channels <= 2) |
401 | return 0; | 426 | return 0; |
402 | 427 | ||
403 | i = hda_node_index(spec->pin_cvt, nid); | ||
404 | if (i < 0) | ||
405 | return 0; | ||
406 | eld = &spec->sink_eld[i]; | ||
407 | |||
408 | /* | ||
409 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
410 | * in console or for audio devices. Assume the highest speakers | ||
411 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
412 | */ | ||
413 | if (!eld->spk_alloc) | ||
414 | eld->spk_alloc = 0xffff; | ||
415 | |||
416 | /* | 428 | /* |
417 | * expand ELD's speaker allocation mask | 429 | * expand ELD's speaker allocation mask |
418 | * | 430 | * |
@@ -608,67 +620,63 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, | |||
608 | return true; | 620 | return true; |
609 | } | 621 | } |
610 | 622 | ||
611 | static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | 623 | static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, |
612 | struct snd_pcm_substream *substream) | 624 | struct snd_pcm_substream *substream) |
613 | { | 625 | { |
614 | struct hdmi_spec *spec = codec->spec; | 626 | struct hdmi_spec *spec = codec->spec; |
615 | hda_nid_t pin_nid; | 627 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
628 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
616 | int channels = substream->runtime->channels; | 629 | int channels = substream->runtime->channels; |
630 | struct hdmi_eld *eld; | ||
617 | int ca; | 631 | int ca; |
618 | int i; | ||
619 | union audio_infoframe ai; | 632 | union audio_infoframe ai; |
620 | 633 | ||
621 | ca = hdmi_channel_allocation(codec, nid, channels); | 634 | eld = &spec->pins[pin_idx].sink_eld; |
622 | 635 | if (!eld->monitor_present) | |
623 | for (i = 0; i < spec->num_pins; i++) { | 636 | return; |
624 | if (spec->pin_cvt[i] != nid) | ||
625 | continue; | ||
626 | if (!spec->sink_eld[i].monitor_present) | ||
627 | continue; | ||
628 | 637 | ||
629 | pin_nid = spec->pin[i]; | 638 | ca = hdmi_channel_allocation(eld, channels); |
630 | 639 | ||
631 | memset(&ai, 0, sizeof(ai)); | 640 | memset(&ai, 0, sizeof(ai)); |
632 | if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ | 641 | if (eld->conn_type == 0) { /* HDMI */ |
633 | struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; | 642 | struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; |
634 | 643 | ||
635 | hdmi_ai->type = 0x84; | 644 | hdmi_ai->type = 0x84; |
636 | hdmi_ai->ver = 0x01; | 645 | hdmi_ai->ver = 0x01; |
637 | hdmi_ai->len = 0x0a; | 646 | hdmi_ai->len = 0x0a; |
638 | hdmi_ai->CC02_CT47 = channels - 1; | 647 | hdmi_ai->CC02_CT47 = channels - 1; |
639 | hdmi_ai->CA = ca; | 648 | hdmi_ai->CA = ca; |
640 | hdmi_checksum_audio_infoframe(hdmi_ai); | 649 | hdmi_checksum_audio_infoframe(hdmi_ai); |
641 | } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ | 650 | } else if (eld->conn_type == 1) { /* DisplayPort */ |
642 | struct dp_audio_infoframe *dp_ai = &ai.dp; | 651 | struct dp_audio_infoframe *dp_ai = &ai.dp; |
643 | 652 | ||
644 | dp_ai->type = 0x84; | 653 | dp_ai->type = 0x84; |
645 | dp_ai->len = 0x1b; | 654 | dp_ai->len = 0x1b; |
646 | dp_ai->ver = 0x11 << 2; | 655 | dp_ai->ver = 0x11 << 2; |
647 | dp_ai->CC02_CT47 = channels - 1; | 656 | dp_ai->CC02_CT47 = channels - 1; |
648 | dp_ai->CA = ca; | 657 | dp_ai->CA = ca; |
649 | } else { | 658 | } else { |
650 | snd_printd("HDMI: unknown connection type at pin %d\n", | 659 | snd_printd("HDMI: unknown connection type at pin %d\n", |
651 | pin_nid); | 660 | pin_nid); |
652 | continue; | 661 | return; |
653 | } | 662 | } |
654 | 663 | ||
655 | /* | 664 | /* |
656 | * sizeof(ai) is used instead of sizeof(*hdmi_ai) or | 665 | * sizeof(ai) is used instead of sizeof(*hdmi_ai) or |
657 | * sizeof(*dp_ai) to avoid partial match/update problems when | 666 | * sizeof(*dp_ai) to avoid partial match/update problems when |
658 | * the user switches between HDMI/DP monitors. | 667 | * the user switches between HDMI/DP monitors. |
659 | */ | 668 | */ |
660 | if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, | 669 | if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, |
661 | sizeof(ai))) { | 670 | sizeof(ai))) { |
662 | snd_printdd("hdmi_setup_audio_infoframe: " | 671 | snd_printdd("hdmi_setup_audio_infoframe: " |
663 | "cvt=%d pin=%d channels=%d\n", | 672 | "pin=%d channels=%d\n", |
664 | nid, pin_nid, | 673 | pin_nid, |
665 | channels); | 674 | channels); |
666 | hdmi_setup_channel_mapping(codec, pin_nid, ca); | 675 | hdmi_setup_channel_mapping(codec, pin_nid, ca); |
667 | hdmi_stop_infoframe_trans(codec, pin_nid); | 676 | hdmi_stop_infoframe_trans(codec, pin_nid); |
668 | hdmi_fill_audio_infoframe(codec, pin_nid, | 677 | hdmi_fill_audio_infoframe(codec, pin_nid, |
669 | ai.bytes, sizeof(ai)); | 678 | ai.bytes, sizeof(ai)); |
670 | hdmi_start_infoframe_trans(codec, pin_nid); | 679 | hdmi_start_infoframe_trans(codec, pin_nid); |
671 | } | ||
672 | } | 680 | } |
673 | } | 681 | } |
674 | 682 | ||
@@ -686,17 +694,27 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
686 | int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; | 694 | int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; |
687 | int pd = !!(res & AC_UNSOL_RES_PD); | 695 | int pd = !!(res & AC_UNSOL_RES_PD); |
688 | int eldv = !!(res & AC_UNSOL_RES_ELDV); | 696 | int eldv = !!(res & AC_UNSOL_RES_ELDV); |
689 | int index; | 697 | int pin_idx; |
698 | struct hdmi_eld *eld; | ||
690 | 699 | ||
691 | printk(KERN_INFO | 700 | printk(KERN_INFO |
692 | "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 701 | "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
693 | pin_nid, pd, eldv); | 702 | codec->addr, pin_nid, pd, eldv); |
694 | 703 | ||
695 | index = hda_node_index(spec->pin, pin_nid); | 704 | pin_idx = pin_nid_to_pin_index(spec, pin_nid); |
696 | if (index < 0) | 705 | if (pin_idx < 0) |
697 | return; | 706 | return; |
707 | eld = &spec->pins[pin_idx].sink_eld; | ||
698 | 708 | ||
699 | hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); | 709 | hdmi_present_sense(codec, pin_nid, eld); |
710 | |||
711 | /* | ||
712 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
713 | * in console or for audio devices. Assume the highest speakers | ||
714 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
715 | */ | ||
716 | if (!eld->spk_alloc) | ||
717 | eld->spk_alloc = 0xffff; | ||
700 | } | 718 | } |
701 | 719 | ||
702 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | 720 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) |
@@ -707,7 +725,8 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
707 | int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); | 725 | int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); |
708 | 726 | ||
709 | printk(KERN_INFO | 727 | printk(KERN_INFO |
710 | "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", | 728 | "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", |
729 | codec->addr, | ||
711 | tag, | 730 | tag, |
712 | subtag, | 731 | subtag, |
713 | cp_state, | 732 | cp_state, |
@@ -727,7 +746,7 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) | |||
727 | int tag = res >> AC_UNSOL_RES_TAG_SHIFT; | 746 | int tag = res >> AC_UNSOL_RES_TAG_SHIFT; |
728 | int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; | 747 | int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; |
729 | 748 | ||
730 | if (hda_node_index(spec->pin, tag) < 0) { | 749 | if (pin_nid_to_pin_index(spec, tag) < 0) { |
731 | snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); | 750 | snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); |
732 | return; | 751 | return; |
733 | } | 752 | } |
@@ -746,21 +765,14 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) | |||
746 | #define is_hbr_format(format) \ | 765 | #define is_hbr_format(format) \ |
747 | ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) | 766 | ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) |
748 | 767 | ||
749 | static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 768 | static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, |
750 | u32 stream_tag, int format) | 769 | hda_nid_t pin_nid, u32 stream_tag, int format) |
751 | { | 770 | { |
752 | struct hdmi_spec *spec = codec->spec; | ||
753 | int pinctl; | 771 | int pinctl; |
754 | int new_pinctl = 0; | 772 | int new_pinctl = 0; |
755 | int i; | ||
756 | 773 | ||
757 | for (i = 0; i < spec->num_pins; i++) { | 774 | if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) { |
758 | if (spec->pin_cvt[i] != nid) | 775 | pinctl = snd_hda_codec_read(codec, pin_nid, 0, |
759 | continue; | ||
760 | if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR)) | ||
761 | continue; | ||
762 | |||
763 | pinctl = snd_hda_codec_read(codec, spec->pin[i], 0, | ||
764 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 776 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
765 | 777 | ||
766 | new_pinctl = pinctl & ~AC_PINCTL_EPT; | 778 | new_pinctl = pinctl & ~AC_PINCTL_EPT; |
@@ -771,22 +783,22 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
771 | 783 | ||
772 | snd_printdd("hdmi_setup_stream: " | 784 | snd_printdd("hdmi_setup_stream: " |
773 | "NID=0x%x, %spinctl=0x%x\n", | 785 | "NID=0x%x, %spinctl=0x%x\n", |
774 | spec->pin[i], | 786 | pin_nid, |
775 | pinctl == new_pinctl ? "" : "new-", | 787 | pinctl == new_pinctl ? "" : "new-", |
776 | new_pinctl); | 788 | new_pinctl); |
777 | 789 | ||
778 | if (pinctl != new_pinctl) | 790 | if (pinctl != new_pinctl) |
779 | snd_hda_codec_write(codec, spec->pin[i], 0, | 791 | snd_hda_codec_write(codec, pin_nid, 0, |
780 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 792 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
781 | new_pinctl); | 793 | new_pinctl); |
782 | } | ||
783 | 794 | ||
795 | } | ||
784 | if (is_hbr_format(format) && !new_pinctl) { | 796 | if (is_hbr_format(format) && !new_pinctl) { |
785 | snd_printdd("hdmi_setup_stream: HBR is not supported\n"); | 797 | snd_printdd("hdmi_setup_stream: HBR is not supported\n"); |
786 | return -EINVAL; | 798 | return -EINVAL; |
787 | } | 799 | } |
788 | 800 | ||
789 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | 801 | snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format); |
790 | return 0; | 802 | return 0; |
791 | } | 803 | } |
792 | 804 | ||
@@ -798,31 +810,62 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
798 | struct snd_pcm_substream *substream) | 810 | struct snd_pcm_substream *substream) |
799 | { | 811 | { |
800 | struct hdmi_spec *spec = codec->spec; | 812 | struct hdmi_spec *spec = codec->spec; |
801 | struct hdmi_eld *eld; | ||
802 | struct hda_pcm_stream *codec_pars; | ||
803 | struct snd_pcm_runtime *runtime = substream->runtime; | 813 | struct snd_pcm_runtime *runtime = substream->runtime; |
804 | unsigned int idx; | 814 | int pin_idx, cvt_idx, mux_idx = 0; |
815 | struct hdmi_spec_per_pin *per_pin; | ||
816 | struct hdmi_eld *eld; | ||
817 | struct hdmi_spec_per_cvt *per_cvt = NULL; | ||
818 | int pinctl; | ||
805 | 819 | ||
806 | for (idx = 0; idx < spec->num_cvts; idx++) | 820 | /* Validate hinfo */ |
807 | if (hinfo->nid == spec->cvt[idx]) | 821 | pin_idx = hinfo_to_pin_index(spec, hinfo); |
808 | break; | 822 | if (snd_BUG_ON(pin_idx < 0)) |
809 | if (snd_BUG_ON(idx >= spec->num_cvts) || | ||
810 | snd_BUG_ON(idx >= spec->num_pins)) | ||
811 | return -EINVAL; | 823 | return -EINVAL; |
824 | per_pin = &spec->pins[pin_idx]; | ||
825 | eld = &per_pin->sink_eld; | ||
826 | |||
827 | /* Dynamically assign converter to stream */ | ||
828 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { | ||
829 | per_cvt = &spec->cvts[cvt_idx]; | ||
812 | 830 | ||
813 | /* save the PCM info the codec provides */ | 831 | /* Must not already be assigned */ |
814 | codec_pars = &spec->codec_pcm_pars[idx]; | 832 | if (per_cvt->assigned) |
815 | if (!codec_pars->rates) | 833 | continue; |
816 | *codec_pars = *hinfo; | 834 | /* Must be in pin's mux's list of converters */ |
835 | for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++) | ||
836 | if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid) | ||
837 | break; | ||
838 | /* Not in mux list */ | ||
839 | if (mux_idx == per_pin->num_mux_nids) | ||
840 | continue; | ||
841 | break; | ||
842 | } | ||
843 | /* No free converters */ | ||
844 | if (cvt_idx == spec->num_cvts) | ||
845 | return -ENODEV; | ||
846 | |||
847 | /* Claim converter */ | ||
848 | per_cvt->assigned = 1; | ||
849 | hinfo->nid = per_cvt->cvt_nid; | ||
850 | |||
851 | snd_hda_codec_write(codec, per_pin->pin_nid, 0, | ||
852 | AC_VERB_SET_CONNECT_SEL, | ||
853 | mux_idx); | ||
854 | pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0, | ||
855 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
856 | snd_hda_codec_write(codec, per_pin->pin_nid, 0, | ||
857 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
858 | pinctl | PIN_OUT); | ||
859 | snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); | ||
817 | 860 | ||
818 | /* Initially set the converter's capabilities */ | 861 | /* Initially set the converter's capabilities */ |
819 | hinfo->channels_min = codec_pars->channels_min; | 862 | hinfo->channels_min = per_cvt->channels_min; |
820 | hinfo->channels_max = codec_pars->channels_max; | 863 | hinfo->channels_max = per_cvt->channels_max; |
821 | hinfo->rates = codec_pars->rates; | 864 | hinfo->rates = per_cvt->rates; |
822 | hinfo->formats = codec_pars->formats; | 865 | hinfo->formats = per_cvt->formats; |
823 | hinfo->maxbps = codec_pars->maxbps; | 866 | hinfo->maxbps = per_cvt->maxbps; |
824 | 867 | ||
825 | eld = &spec->sink_eld[idx]; | 868 | /* Restrict capabilities by ELD if this isn't disabled */ |
826 | if (!static_hdmi_pcm && eld->eld_valid) { | 869 | if (!static_hdmi_pcm && eld->eld_valid) { |
827 | snd_hdmi_eld_update_pcm_info(eld, hinfo); | 870 | snd_hdmi_eld_update_pcm_info(eld, hinfo); |
828 | if (hinfo->channels_min > hinfo->channels_max || | 871 | if (hinfo->channels_min > hinfo->channels_max || |
@@ -844,12 +887,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
844 | /* | 887 | /* |
845 | * HDA/HDMI auto parsing | 888 | * HDA/HDMI auto parsing |
846 | */ | 889 | */ |
847 | static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) | 890 | static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) |
848 | { | 891 | { |
849 | struct hdmi_spec *spec = codec->spec; | 892 | struct hdmi_spec *spec = codec->spec; |
850 | hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; | 893 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
851 | int conn_len, curr; | 894 | hda_nid_t pin_nid = per_pin->pin_nid; |
852 | int index; | ||
853 | 895 | ||
854 | if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { | 896 | if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { |
855 | snd_printk(KERN_WARNING | 897 | snd_printk(KERN_WARNING |
@@ -859,19 +901,9 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) | |||
859 | return -EINVAL; | 901 | return -EINVAL; |
860 | } | 902 | } |
861 | 903 | ||
862 | conn_len = snd_hda_get_connections(codec, pin_nid, conn_list, | 904 | per_pin->num_mux_nids = snd_hda_get_connections(codec, pin_nid, |
863 | HDA_MAX_CONNECTIONS); | 905 | per_pin->mux_nids, |
864 | if (conn_len > 1) | 906 | HDA_MAX_CONNECTIONS); |
865 | curr = snd_hda_codec_read(codec, pin_nid, 0, | ||
866 | AC_VERB_GET_CONNECT_SEL, 0); | ||
867 | else | ||
868 | curr = 0; | ||
869 | |||
870 | index = hda_node_index(spec->pin, pin_nid); | ||
871 | if (index < 0) | ||
872 | return -EINVAL; | ||
873 | |||
874 | spec->pin_cvt[index] = conn_list[curr]; | ||
875 | 907 | ||
876 | return 0; | 908 | return 0; |
877 | } | 909 | } |
@@ -898,8 +930,8 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
898 | eld->eld_valid = 0; | 930 | eld->eld_valid = 0; |
899 | 931 | ||
900 | printk(KERN_INFO | 932 | printk(KERN_INFO |
901 | "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 933 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
902 | pin_nid, eld->monitor_present, eld->eld_valid); | 934 | codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); |
903 | 935 | ||
904 | if (eld->eld_valid) | 936 | if (eld->eld_valid) |
905 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | 937 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) |
@@ -911,47 +943,75 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
911 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | 943 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
912 | { | 944 | { |
913 | struct hdmi_spec *spec = codec->spec; | 945 | struct hdmi_spec *spec = codec->spec; |
946 | unsigned int caps, config; | ||
947 | int pin_idx; | ||
948 | struct hdmi_spec_per_pin *per_pin; | ||
949 | struct hdmi_eld *eld; | ||
914 | int err; | 950 | int err; |
915 | 951 | ||
916 | if (spec->num_pins >= MAX_HDMI_PINS) { | 952 | caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP); |
917 | snd_printk(KERN_WARNING | 953 | if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) |
918 | "HDMI: no space for pin %d\n", pin_nid); | 954 | return 0; |
955 | |||
956 | config = snd_hda_codec_read(codec, pin_nid, 0, | ||
957 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
958 | if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) | ||
959 | return 0; | ||
960 | |||
961 | if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS)) | ||
919 | return -E2BIG; | 962 | return -E2BIG; |
920 | } | 963 | |
964 | pin_idx = spec->num_pins; | ||
965 | per_pin = &spec->pins[pin_idx]; | ||
966 | eld = &per_pin->sink_eld; | ||
967 | |||
968 | per_pin->pin_nid = pin_nid; | ||
921 | 969 | ||
922 | err = snd_hda_input_jack_add(codec, pin_nid, | 970 | err = snd_hda_input_jack_add(codec, pin_nid, |
923 | SND_JACK_VIDEOOUT, NULL); | 971 | SND_JACK_VIDEOOUT, NULL); |
924 | if (err < 0) | 972 | if (err < 0) |
925 | return err; | 973 | return err; |
926 | 974 | ||
927 | hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); | 975 | err = hdmi_read_pin_conn(codec, pin_idx); |
976 | if (err < 0) | ||
977 | return err; | ||
928 | 978 | ||
929 | spec->pin[spec->num_pins] = pin_nid; | ||
930 | spec->num_pins++; | 979 | spec->num_pins++; |
931 | 980 | ||
932 | return hdmi_read_pin_conn(codec, pin_nid); | 981 | hdmi_present_sense(codec, pin_nid, eld); |
982 | |||
983 | return 0; | ||
933 | } | 984 | } |
934 | 985 | ||
935 | static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) | 986 | static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) |
936 | { | 987 | { |
937 | int i, found_pin = 0; | ||
938 | struct hdmi_spec *spec = codec->spec; | 988 | struct hdmi_spec *spec = codec->spec; |
939 | 989 | int cvt_idx; | |
940 | for (i = 0; i < spec->num_pins; i++) | 990 | struct hdmi_spec_per_cvt *per_cvt; |
941 | if (nid == spec->pin_cvt[i]) { | 991 | unsigned int chans; |
942 | found_pin = 1; | 992 | int err; |
943 | break; | ||
944 | } | ||
945 | |||
946 | if (!found_pin) { | ||
947 | snd_printdd("HDMI: Skipping node %d (no connection)\n", nid); | ||
948 | return -EINVAL; | ||
949 | } | ||
950 | 993 | ||
951 | if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) | 994 | if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) |
952 | return -E2BIG; | 995 | return -E2BIG; |
953 | 996 | ||
954 | spec->cvt[spec->num_cvts] = nid; | 997 | chans = get_wcaps(codec, cvt_nid); |
998 | chans = get_wcaps_channels(chans); | ||
999 | |||
1000 | cvt_idx = spec->num_cvts; | ||
1001 | per_cvt = &spec->cvts[cvt_idx]; | ||
1002 | |||
1003 | per_cvt->cvt_nid = cvt_nid; | ||
1004 | per_cvt->channels_min = 2; | ||
1005 | if (chans <= 16) | ||
1006 | per_cvt->channels_max = chans; | ||
1007 | |||
1008 | err = snd_hda_query_supported_pcm(codec, cvt_nid, | ||
1009 | &per_cvt->rates, | ||
1010 | &per_cvt->formats, | ||
1011 | &per_cvt->maxbps); | ||
1012 | if (err < 0) | ||
1013 | return err; | ||
1014 | |||
955 | spec->num_cvts++; | 1015 | spec->num_cvts++; |
956 | 1016 | ||
957 | return 0; | 1017 | return 0; |
@@ -961,8 +1021,6 @@ static int hdmi_parse_codec(struct hda_codec *codec) | |||
961 | { | 1021 | { |
962 | hda_nid_t nid; | 1022 | hda_nid_t nid; |
963 | int i, nodes; | 1023 | int i, nodes; |
964 | int num_tmp_cvts = 0; | ||
965 | hda_nid_t tmp_cvt[MAX_HDMI_CVTS]; | ||
966 | 1024 | ||
967 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); | 1025 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); |
968 | if (!nid || nodes < 0) { | 1026 | if (!nid || nodes < 0) { |
@@ -973,7 +1031,6 @@ static int hdmi_parse_codec(struct hda_codec *codec) | |||
973 | for (i = 0; i < nodes; i++, nid++) { | 1031 | for (i = 0; i < nodes; i++, nid++) { |
974 | unsigned int caps; | 1032 | unsigned int caps; |
975 | unsigned int type; | 1033 | unsigned int type; |
976 | unsigned int config; | ||
977 | 1034 | ||
978 | caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); | 1035 | caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); |
979 | type = get_wcaps_type(caps); | 1036 | type = get_wcaps_type(caps); |
@@ -983,32 +1040,14 @@ static int hdmi_parse_codec(struct hda_codec *codec) | |||
983 | 1040 | ||
984 | switch (type) { | 1041 | switch (type) { |
985 | case AC_WID_AUD_OUT: | 1042 | case AC_WID_AUD_OUT: |
986 | if (num_tmp_cvts >= MAX_HDMI_CVTS) { | 1043 | hdmi_add_cvt(codec, nid); |
987 | snd_printk(KERN_WARNING | ||
988 | "HDMI: no space for converter %d\n", nid); | ||
989 | continue; | ||
990 | } | ||
991 | tmp_cvt[num_tmp_cvts] = nid; | ||
992 | num_tmp_cvts++; | ||
993 | break; | 1044 | break; |
994 | case AC_WID_PIN: | 1045 | case AC_WID_PIN: |
995 | caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
996 | if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) | ||
997 | continue; | ||
998 | |||
999 | config = snd_hda_codec_read(codec, nid, 0, | ||
1000 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
1001 | if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) | ||
1002 | continue; | ||
1003 | |||
1004 | hdmi_add_pin(codec, nid); | 1046 | hdmi_add_pin(codec, nid); |
1005 | break; | 1047 | break; |
1006 | } | 1048 | } |
1007 | } | 1049 | } |
1008 | 1050 | ||
1009 | for (i = 0; i < num_tmp_cvts; i++) | ||
1010 | hdmi_add_cvt(codec, tmp_cvt[i]); | ||
1011 | |||
1012 | /* | 1051 | /* |
1013 | * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event | 1052 | * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event |
1014 | * can be lost and presence sense verb will become inaccurate if the | 1053 | * can be lost and presence sense verb will become inaccurate if the |
@@ -1025,7 +1064,7 @@ static int hdmi_parse_codec(struct hda_codec *codec) | |||
1025 | 1064 | ||
1026 | /* | 1065 | /* |
1027 | */ | 1066 | */ |
1028 | static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { | 1067 | static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = { |
1029 | "HDMI 0", | 1068 | "HDMI 0", |
1030 | "HDMI 1", | 1069 | "HDMI 1", |
1031 | "HDMI 2", | 1070 | "HDMI 2", |
@@ -1042,51 +1081,84 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1042 | unsigned int format, | 1081 | unsigned int format, |
1043 | struct snd_pcm_substream *substream) | 1082 | struct snd_pcm_substream *substream) |
1044 | { | 1083 | { |
1045 | hdmi_set_channel_count(codec, hinfo->nid, | 1084 | hda_nid_t cvt_nid = hinfo->nid; |
1046 | substream->runtime->channels); | 1085 | struct hdmi_spec *spec = codec->spec; |
1086 | int pin_idx = hinfo_to_pin_index(spec, hinfo); | ||
1087 | hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; | ||
1088 | |||
1089 | hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); | ||
1047 | 1090 | ||
1048 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); | 1091 | hdmi_setup_audio_infoframe(codec, pin_idx, substream); |
1049 | 1092 | ||
1050 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 1093 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); |
1051 | } | 1094 | } |
1052 | 1095 | ||
1053 | static const struct hda_pcm_stream generic_hdmi_pcm_playback = { | 1096 | static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
1054 | .substreams = 1, | 1097 | struct hda_codec *codec, |
1055 | .channels_min = 2, | 1098 | struct snd_pcm_substream *substream) |
1056 | .ops = { | 1099 | { |
1057 | .open = hdmi_pcm_open, | 1100 | struct hdmi_spec *spec = codec->spec; |
1058 | .prepare = generic_hdmi_playback_pcm_prepare, | 1101 | int cvt_idx, pin_idx; |
1059 | }, | 1102 | struct hdmi_spec_per_cvt *per_cvt; |
1103 | struct hdmi_spec_per_pin *per_pin; | ||
1104 | int pinctl; | ||
1105 | |||
1106 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); | ||
1107 | |||
1108 | if (hinfo->nid) { | ||
1109 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); | ||
1110 | if (snd_BUG_ON(cvt_idx < 0)) | ||
1111 | return -EINVAL; | ||
1112 | per_cvt = &spec->cvts[cvt_idx]; | ||
1113 | |||
1114 | snd_BUG_ON(!per_cvt->assigned); | ||
1115 | per_cvt->assigned = 0; | ||
1116 | hinfo->nid = 0; | ||
1117 | |||
1118 | pin_idx = hinfo_to_pin_index(spec, hinfo); | ||
1119 | if (snd_BUG_ON(pin_idx < 0)) | ||
1120 | return -EINVAL; | ||
1121 | per_pin = &spec->pins[pin_idx]; | ||
1122 | |||
1123 | pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0, | ||
1124 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1125 | snd_hda_codec_write(codec, per_pin->pin_nid, 0, | ||
1126 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1127 | pinctl & ~PIN_OUT); | ||
1128 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | ||
1129 | } | ||
1130 | |||
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1134 | static const struct hda_pcm_ops generic_ops = { | ||
1135 | .open = hdmi_pcm_open, | ||
1136 | .prepare = generic_hdmi_playback_pcm_prepare, | ||
1137 | .cleanup = generic_hdmi_playback_pcm_cleanup, | ||
1060 | }; | 1138 | }; |
1061 | 1139 | ||
1062 | static int generic_hdmi_build_pcms(struct hda_codec *codec) | 1140 | static int generic_hdmi_build_pcms(struct hda_codec *codec) |
1063 | { | 1141 | { |
1064 | struct hdmi_spec *spec = codec->spec; | 1142 | struct hdmi_spec *spec = codec->spec; |
1065 | struct hda_pcm *info = spec->pcm_rec; | 1143 | int pin_idx; |
1066 | int i; | ||
1067 | 1144 | ||
1068 | codec->num_pcms = spec->num_cvts; | 1145 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1069 | codec->pcm_info = info; | 1146 | struct hda_pcm *info; |
1070 | |||
1071 | for (i = 0; i < codec->num_pcms; i++, info++) { | ||
1072 | unsigned int chans; | ||
1073 | struct hda_pcm_stream *pstr; | 1147 | struct hda_pcm_stream *pstr; |
1074 | 1148 | ||
1075 | chans = get_wcaps(codec, spec->cvt[i]); | 1149 | info = &spec->pcm_rec[pin_idx]; |
1076 | chans = get_wcaps_channels(chans); | 1150 | info->name = generic_hdmi_pcm_names[pin_idx]; |
1077 | |||
1078 | info->name = generic_hdmi_pcm_names[i]; | ||
1079 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1151 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1152 | |||
1080 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1153 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1081 | if (spec->pcm_playback) | 1154 | pstr->substreams = 1; |
1082 | *pstr = *spec->pcm_playback; | 1155 | pstr->ops = generic_ops; |
1083 | else | 1156 | /* other pstr fields are set in open */ |
1084 | *pstr = generic_hdmi_pcm_playback; | ||
1085 | pstr->nid = spec->cvt[i]; | ||
1086 | if (pstr->channels_max <= 2 && chans && chans <= 16) | ||
1087 | pstr->channels_max = chans; | ||
1088 | } | 1157 | } |
1089 | 1158 | ||
1159 | codec->num_pcms = spec->num_pins; | ||
1160 | codec->pcm_info = spec->pcm_rec; | ||
1161 | |||
1090 | return 0; | 1162 | return 0; |
1091 | } | 1163 | } |
1092 | 1164 | ||
@@ -1094,13 +1166,16 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
1094 | { | 1166 | { |
1095 | struct hdmi_spec *spec = codec->spec; | 1167 | struct hdmi_spec *spec = codec->spec; |
1096 | int err; | 1168 | int err; |
1097 | int i; | 1169 | int pin_idx; |
1098 | 1170 | ||
1099 | for (i = 0; i < codec->num_pcms; i++) { | 1171 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1100 | err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i], | 1172 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
1101 | spec->cvt[i]); | 1173 | err = snd_hda_create_spdif_out_ctls(codec, |
1174 | per_pin->pin_nid, | ||
1175 | per_pin->mux_nids[0]); | ||
1102 | if (err < 0) | 1176 | if (err < 0) |
1103 | return err; | 1177 | return err; |
1178 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | ||
1104 | } | 1179 | } |
1105 | 1180 | ||
1106 | return 0; | 1181 | return 0; |
@@ -1109,13 +1184,19 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
1109 | static int generic_hdmi_init(struct hda_codec *codec) | 1184 | static int generic_hdmi_init(struct hda_codec *codec) |
1110 | { | 1185 | { |
1111 | struct hdmi_spec *spec = codec->spec; | 1186 | struct hdmi_spec *spec = codec->spec; |
1112 | int i; | 1187 | int pin_idx; |
1188 | |||
1189 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | ||
1190 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | ||
1191 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
1192 | struct hdmi_eld *eld = &per_pin->sink_eld; | ||
1113 | 1193 | ||
1114 | for (i = 0; spec->pin[i]; i++) { | 1194 | hdmi_init_pin(codec, pin_nid); |
1115 | hdmi_enable_output(codec, spec->pin[i]); | 1195 | snd_hda_codec_write(codec, pin_nid, 0, |
1116 | snd_hda_codec_write(codec, spec->pin[i], 0, | ||
1117 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1196 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1118 | AC_USRSP_EN | spec->pin[i]); | 1197 | AC_USRSP_EN | pin_nid); |
1198 | |||
1199 | snd_hda_eld_proc_new(codec, eld, pin_idx); | ||
1119 | } | 1200 | } |
1120 | return 0; | 1201 | return 0; |
1121 | } | 1202 | } |
@@ -1123,10 +1204,14 @@ static int generic_hdmi_init(struct hda_codec *codec) | |||
1123 | static void generic_hdmi_free(struct hda_codec *codec) | 1204 | static void generic_hdmi_free(struct hda_codec *codec) |
1124 | { | 1205 | { |
1125 | struct hdmi_spec *spec = codec->spec; | 1206 | struct hdmi_spec *spec = codec->spec; |
1126 | int i; | 1207 | int pin_idx; |
1208 | |||
1209 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | ||
1210 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | ||
1211 | struct hdmi_eld *eld = &per_pin->sink_eld; | ||
1127 | 1212 | ||
1128 | for (i = 0; i < spec->num_pins; i++) | 1213 | snd_hda_eld_proc_free(codec, eld); |
1129 | snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); | 1214 | } |
1130 | snd_hda_input_jack_free(codec); | 1215 | snd_hda_input_jack_free(codec); |
1131 | 1216 | ||
1132 | kfree(spec); | 1217 | kfree(spec); |
@@ -1143,7 +1228,6 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = { | |||
1143 | static int patch_generic_hdmi(struct hda_codec *codec) | 1228 | static int patch_generic_hdmi(struct hda_codec *codec) |
1144 | { | 1229 | { |
1145 | struct hdmi_spec *spec; | 1230 | struct hdmi_spec *spec; |
1146 | int i; | ||
1147 | 1231 | ||
1148 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1232 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1149 | if (spec == NULL) | 1233 | if (spec == NULL) |
@@ -1157,9 +1241,6 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1157 | } | 1241 | } |
1158 | codec->patch_ops = generic_hdmi_patch_ops; | 1242 | codec->patch_ops = generic_hdmi_patch_ops; |
1159 | 1243 | ||
1160 | for (i = 0; i < spec->num_pins; i++) | ||
1161 | snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i); | ||
1162 | |||
1163 | init_channel_allocations(); | 1244 | init_channel_allocations(); |
1164 | 1245 | ||
1165 | return 0; | 1246 | return 0; |
@@ -1182,7 +1263,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
1182 | unsigned int chans; | 1263 | unsigned int chans; |
1183 | struct hda_pcm_stream *pstr; | 1264 | struct hda_pcm_stream *pstr; |
1184 | 1265 | ||
1185 | chans = get_wcaps(codec, spec->cvt[i]); | 1266 | chans = get_wcaps(codec, spec->cvts[i].cvt_nid); |
1186 | chans = get_wcaps_channels(chans); | 1267 | chans = get_wcaps_channels(chans); |
1187 | 1268 | ||
1188 | info->name = generic_hdmi_pcm_names[i]; | 1269 | info->name = generic_hdmi_pcm_names[i]; |
@@ -1190,7 +1271,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
1190 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1271 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1191 | snd_BUG_ON(!spec->pcm_playback); | 1272 | snd_BUG_ON(!spec->pcm_playback); |
1192 | *pstr = *spec->pcm_playback; | 1273 | *pstr = *spec->pcm_playback; |
1193 | pstr->nid = spec->cvt[i]; | 1274 | pstr->nid = spec->cvts[i].cvt_nid; |
1194 | if (pstr->channels_max <= 2 && chans && chans <= 16) | 1275 | if (pstr->channels_max <= 2 && chans && chans <= 16) |
1195 | pstr->channels_max = chans; | 1276 | pstr->channels_max = chans; |
1196 | } | 1277 | } |
@@ -1206,8 +1287,8 @@ static int simple_playback_build_controls(struct hda_codec *codec) | |||
1206 | 1287 | ||
1207 | for (i = 0; i < codec->num_pcms; i++) { | 1288 | for (i = 0; i < codec->num_pcms; i++) { |
1208 | err = snd_hda_create_spdif_out_ctls(codec, | 1289 | err = snd_hda_create_spdif_out_ctls(codec, |
1209 | spec->cvt[i], | 1290 | spec->cvts[i].cvt_nid, |
1210 | spec->cvt[i]); | 1291 | spec->cvts[i].cvt_nid); |
1211 | if (err < 0) | 1292 | if (err < 0) |
1212 | return err; | 1293 | return err; |
1213 | } | 1294 | } |
@@ -1414,7 +1495,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1414 | int i; | 1495 | int i; |
1415 | struct hdmi_spec *spec = codec->spec; | 1496 | struct hdmi_spec *spec = codec->spec; |
1416 | struct hda_spdif_out *spdif = | 1497 | struct hda_spdif_out *spdif = |
1417 | snd_hda_spdif_out_of_nid(codec, spec->cvt[0]); | 1498 | snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid); |
1418 | 1499 | ||
1419 | mutex_lock(&codec->spdif_mutex); | 1500 | mutex_lock(&codec->spdif_mutex); |
1420 | 1501 | ||
@@ -1561,7 +1642,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) | |||
1561 | spec->multiout.max_channels = 2; | 1642 | spec->multiout.max_channels = 2; |
1562 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | 1643 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; |
1563 | spec->num_cvts = 1; | 1644 | spec->num_cvts = 1; |
1564 | spec->cvt[0] = nvhdmi_master_con_nid_7x; | 1645 | spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x; |
1565 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; | 1646 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; |
1566 | 1647 | ||
1567 | codec->patch_ops = nvhdmi_patch_ops_2ch; | 1648 | codec->patch_ops = nvhdmi_patch_ops_2ch; |
@@ -1612,11 +1693,11 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1612 | substream); | 1693 | substream); |
1613 | if (err < 0) | 1694 | if (err < 0) |
1614 | return err; | 1695 | return err; |
1615 | snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT, | 1696 | snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0, |
1616 | chans - 1); | 1697 | AC_VERB_SET_CVT_CHAN_COUNT, chans - 1); |
1617 | /* FIXME: XXX */ | 1698 | /* FIXME: XXX */ |
1618 | for (i = 0; i < chans; i++) { | 1699 | for (i = 0; i < chans; i++) { |
1619 | snd_hda_codec_write(codec, spec->cvt[0], 0, | 1700 | snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0, |
1620 | AC_VERB_SET_HDMI_CHAN_SLOT, | 1701 | AC_VERB_SET_HDMI_CHAN_SLOT, |
1621 | (i << 4) | i); | 1702 | (i << 4) | i); |
1622 | } | 1703 | } |
@@ -1647,8 +1728,8 @@ static int atihdmi_init(struct hda_codec *codec) | |||
1647 | 1728 | ||
1648 | snd_hda_sequence_write(codec, atihdmi_basic_init); | 1729 | snd_hda_sequence_write(codec, atihdmi_basic_init); |
1649 | /* SI codec requires to unmute the pin */ | 1730 | /* SI codec requires to unmute the pin */ |
1650 | if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP) | 1731 | if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP) |
1651 | snd_hda_codec_write(codec, spec->pin[0], 0, | 1732 | snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0, |
1652 | AC_VERB_SET_AMP_GAIN_MUTE, | 1733 | AC_VERB_SET_AMP_GAIN_MUTE, |
1653 | AMP_OUT_UNMUTE); | 1734 | AMP_OUT_UNMUTE); |
1654 | return 0; | 1735 | return 0; |
@@ -1676,8 +1757,8 @@ static int patch_atihdmi(struct hda_codec *codec) | |||
1676 | spec->multiout.max_channels = 2; | 1757 | spec->multiout.max_channels = 2; |
1677 | spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; | 1758 | spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; |
1678 | spec->num_cvts = 1; | 1759 | spec->num_cvts = 1; |
1679 | spec->cvt[0] = ATIHDMI_CVT_NID; | 1760 | spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID; |
1680 | spec->pin[0] = ATIHDMI_PIN_NID; | 1761 | spec->pins[0].pin_nid = ATIHDMI_PIN_NID; |
1681 | spec->pcm_playback = &atihdmi_pcm_digital_playback; | 1762 | spec->pcm_playback = &atihdmi_pcm_digital_playback; |
1682 | 1763 | ||
1683 | codec->patch_ops = atihdmi_patch_ops; | 1764 | codec->patch_ops = atihdmi_patch_ops; |