aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r--sound/pci/hda/patch_hdmi.c308
1 files changed, 303 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 333d5338c15c..4a5d24fe8adf 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -35,6 +35,7 @@
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/jack.h> 36#include <sound/jack.h>
37#include <sound/asoundef.h> 37#include <sound/asoundef.h>
38#include <sound/tlv.h>
38#include "hda_codec.h" 39#include "hda_codec.h"
39#include "hda_local.h" 40#include "hda_local.h"
40#include "hda_jack.h" 41#include "hda_jack.h"
@@ -73,6 +74,8 @@ struct hdmi_spec_per_pin {
73 struct delayed_work work; 74 struct delayed_work work;
74 int repoll_count; 75 int repoll_count;
75 bool non_pcm; 76 bool non_pcm;
77 bool chmap_set; /* channel-map override by ALSA API? */
78 unsigned char chmap[8]; /* ALSA API channel-map */
76}; 79};
77 80
78struct hdmi_spec { 81struct hdmi_spec {
@@ -82,6 +85,7 @@ struct hdmi_spec {
82 int num_pins; 85 int num_pins;
83 struct hdmi_spec_per_pin pins[MAX_HDMI_PINS]; 86 struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
84 struct hda_pcm pcm_rec[MAX_HDMI_PINS]; 87 struct hda_pcm pcm_rec[MAX_HDMI_PINS];
88 unsigned int channels_max; /* max over all cvts */
85 89
86 /* 90 /*
87 * Non-generic ATI/NVIDIA specific 91 * Non-generic ATI/NVIDIA specific
@@ -548,7 +552,7 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
548} 552}
549 553
550 554
551static void hdmi_setup_channel_mapping(struct hda_codec *codec, 555static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
552 hda_nid_t pin_nid, 556 hda_nid_t pin_nid,
553 bool non_pcm, 557 bool non_pcm,
554 int ca) 558 int ca)
@@ -588,6 +592,136 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec,
588 hdmi_debug_channel_mapping(codec, pin_nid); 592 hdmi_debug_channel_mapping(codec, pin_nid);
589} 593}
590 594
595struct channel_map_table {
596 unsigned char map; /* ALSA API channel map position */
597 unsigned char cea_slot; /* CEA slot value */
598 int spk_mask; /* speaker position bit mask */
599};
600
601static struct channel_map_table map_tables[] = {
602 { SNDRV_CHMAP_FL, 0x00, FL },
603 { SNDRV_CHMAP_FR, 0x01, FR },
604 { SNDRV_CHMAP_RL, 0x04, RL },
605 { SNDRV_CHMAP_RR, 0x05, RR },
606 { SNDRV_CHMAP_LFE, 0x02, LFE },
607 { SNDRV_CHMAP_FC, 0x03, FC },
608 { SNDRV_CHMAP_RLC, 0x06, RLC },
609 { SNDRV_CHMAP_RRC, 0x07, RRC },
610 {} /* terminator */
611};
612
613/* from ALSA API channel position to speaker bit mask */
614static int to_spk_mask(unsigned char c)
615{
616 struct channel_map_table *t = map_tables;
617 for (; t->map; t++) {
618 if (t->map == c)
619 return t->spk_mask;
620 }
621 return 0;
622}
623
624/* from ALSA API channel position to CEA slot */
625static int to_cea_slot(unsigned char c)
626{
627 struct channel_map_table *t = map_tables;
628 for (; t->map; t++) {
629 if (t->map == c)
630 return t->cea_slot;
631 }
632 return 0x0f;
633}
634
635/* from CEA slot to ALSA API channel position */
636static int from_cea_slot(unsigned char c)
637{
638 struct channel_map_table *t = map_tables;
639 for (; t->map; t++) {
640 if (t->cea_slot == c)
641 return t->map;
642 }
643 return 0;
644}
645
646/* from speaker bit mask to ALSA API channel position */
647static int spk_to_chmap(int spk)
648{
649 struct channel_map_table *t = map_tables;
650 for (; t->map; t++) {
651 if (t->spk_mask == spk)
652 return t->map;
653 }
654 return 0;
655}
656
657/* get the CA index corresponding to the given ALSA API channel map */
658static int hdmi_manual_channel_allocation(int chs, unsigned char *map)
659{
660 int i, spks = 0, spk_mask = 0;
661
662 for (i = 0; i < chs; i++) {
663 int mask = to_spk_mask(map[i]);
664 if (mask) {
665 spk_mask |= mask;
666 spks++;
667 }
668 }
669
670 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
671 if ((chs == channel_allocations[i].channels ||
672 spks == channel_allocations[i].channels) &&
673 (spk_mask & channel_allocations[i].spk_mask) ==
674 channel_allocations[i].spk_mask)
675 return channel_allocations[i].ca_index;
676 }
677 return -1;
678}
679
680/* set up the channel slots for the given ALSA API channel map */
681static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
682 hda_nid_t pin_nid,
683 int chs, unsigned char *map)
684{
685 int i;
686 for (i = 0; i < 8; i++) {
687 int val, err;
688 if (i < chs)
689 val = to_cea_slot(map[i]);
690 else
691 val = 0xf;
692 val |= (i << 4);
693 err = snd_hda_codec_write(codec, pin_nid, 0,
694 AC_VERB_SET_HDMI_CHAN_SLOT, val);
695 if (err)
696 return -EINVAL;
697 }
698 return 0;
699}
700
701/* store ALSA API channel map from the current default map */
702static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
703{
704 int i;
705 for (i = 0; i < 8; i++) {
706 if (i < channel_allocations[ca].channels)
707 map[i] = from_cea_slot((hdmi_channel_mapping[ca][i] >> 4) & 0x0f);
708 else
709 map[i] = 0;
710 }
711}
712
713static void hdmi_setup_channel_mapping(struct hda_codec *codec,
714 hda_nid_t pin_nid, bool non_pcm, int ca,
715 int channels, unsigned char *map)
716{
717 if (!non_pcm && map) {
718 hdmi_manual_setup_channel_mapping(codec, pin_nid,
719 channels, map);
720 } else {
721 hdmi_std_setup_channel_mapping(codec, pin_nid, non_pcm, ca);
722 hdmi_setup_fake_chmap(map, ca);
723 }
724}
591 725
592/* 726/*
593 * Audio InfoFrame routines 727 * Audio InfoFrame routines
@@ -726,7 +860,12 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
726 if (!eld->monitor_present) 860 if (!eld->monitor_present)
727 return; 861 return;
728 862
729 ca = hdmi_channel_allocation(eld, channels); 863 if (!non_pcm && per_pin->chmap_set)
864 ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
865 else
866 ca = hdmi_channel_allocation(eld, channels);
867 if (ca < 0)
868 ca = 0;
730 869
731 memset(&ai, 0, sizeof(ai)); 870 memset(&ai, 0, sizeof(ai));
732 if (eld->conn_type == 0) { /* HDMI */ 871 if (eld->conn_type == 0) { /* HDMI */
@@ -763,7 +902,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
763 "pin=%d channels=%d\n", 902 "pin=%d channels=%d\n",
764 pin_nid, 903 pin_nid,
765 channels); 904 channels);
766 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca); 905 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
906 channels, per_pin->chmap);
767 hdmi_stop_infoframe_trans(codec, pin_nid); 907 hdmi_stop_infoframe_trans(codec, pin_nid);
768 hdmi_fill_audio_infoframe(codec, pin_nid, 908 hdmi_fill_audio_infoframe(codec, pin_nid,
769 ai.bytes, sizeof(ai)); 909 ai.bytes, sizeof(ai));
@@ -772,7 +912,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
772 /* For non-pcm audio switch, setup new channel mapping 912 /* For non-pcm audio switch, setup new channel mapping
773 * accordingly */ 913 * accordingly */
774 if (per_pin->non_pcm != non_pcm) 914 if (per_pin->non_pcm != non_pcm)
775 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca); 915 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
916 channels, per_pin->chmap);
776 } 917 }
777 918
778 per_pin->non_pcm = non_pcm; 919 per_pin->non_pcm = non_pcm;
@@ -1098,8 +1239,11 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1098 1239
1099 per_cvt->cvt_nid = cvt_nid; 1240 per_cvt->cvt_nid = cvt_nid;
1100 per_cvt->channels_min = 2; 1241 per_cvt->channels_min = 2;
1101 if (chans <= 16) 1242 if (chans <= 16) {
1102 per_cvt->channels_max = chans; 1243 per_cvt->channels_max = chans;
1244 if (chans > spec->channels_max)
1245 spec->channels_max = chans;
1246 }
1103 1247
1104 err = snd_hda_query_supported_pcm(codec, cvt_nid, 1248 err = snd_hda_query_supported_pcm(codec, cvt_nid,
1105 &per_cvt->rates, 1249 &per_cvt->rates,
@@ -1250,7 +1394,10 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1250 AC_VERB_SET_PIN_WIDGET_CONTROL, 1394 AC_VERB_SET_PIN_WIDGET_CONTROL,
1251 pinctl & ~PIN_OUT); 1395 pinctl & ~PIN_OUT);
1252 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1396 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1397 per_pin->chmap_set = false;
1398 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
1253 } 1399 }
1400
1254 return 0; 1401 return 0;
1255} 1402}
1256 1403
@@ -1261,6 +1408,135 @@ static const struct hda_pcm_ops generic_ops = {
1261 .cleanup = generic_hdmi_playback_pcm_cleanup, 1408 .cleanup = generic_hdmi_playback_pcm_cleanup,
1262}; 1409};
1263 1410
1411/*
1412 * ALSA API channel-map control callbacks
1413 */
1414static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
1415 struct snd_ctl_elem_info *uinfo)
1416{
1417 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
1418 struct hda_codec *codec = info->private_data;
1419 struct hdmi_spec *spec = codec->spec;
1420 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1421 uinfo->count = spec->channels_max;
1422 uinfo->value.integer.min = 0;
1423 uinfo->value.integer.max = SNDRV_CHMAP_LAST;
1424 return 0;
1425}
1426
1427static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1428 unsigned int size, unsigned int __user *tlv)
1429{
1430 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
1431 struct hda_codec *codec = info->private_data;
1432 struct hdmi_spec *spec = codec->spec;
1433 const unsigned int valid_mask =
1434 FL | FR | RL | RR | LFE | FC | RLC | RRC;
1435 unsigned int __user *dst;
1436 int chs, count = 0;
1437
1438 if (size < 8)
1439 return -ENOMEM;
1440 if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
1441 return -EFAULT;
1442 size -= 8;
1443 dst = tlv + 2;
1444 for (chs = 2; chs <= spec->channels_max; chs += 2) {
1445 int i, c;
1446 struct cea_channel_speaker_allocation *cap;
1447 cap = channel_allocations;
1448 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
1449 int chs_bytes = chs * 4;
1450 if (cap->channels != chs)
1451 continue;
1452 if (cap->spk_mask & ~valid_mask)
1453 continue;
1454 if (size < 8)
1455 return -ENOMEM;
1456 if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) ||
1457 put_user(chs_bytes, dst + 1))
1458 return -EFAULT;
1459 dst += 2;
1460 size -= 8;
1461 count += 8;
1462 if (size < chs_bytes)
1463 return -ENOMEM;
1464 size -= chs_bytes;
1465 count += chs_bytes;
1466 for (c = 7; c >= 0; c--) {
1467 int spk = cap->speakers[c];
1468 if (!spk)
1469 continue;
1470 if (put_user(spk_to_chmap(spk), dst))
1471 return -EFAULT;
1472 dst++;
1473 }
1474 }
1475 }
1476 if (put_user(count, tlv + 1))
1477 return -EFAULT;
1478 return 0;
1479}
1480
1481static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
1482 struct snd_ctl_elem_value *ucontrol)
1483{
1484 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
1485 struct hda_codec *codec = info->private_data;
1486 struct hdmi_spec *spec = codec->spec;
1487 int pin_idx = kcontrol->private_value;
1488 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1489 int i;
1490
1491 for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++)
1492 ucontrol->value.integer.value[i] = per_pin->chmap[i];
1493 return 0;
1494}
1495
1496static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1497 struct snd_ctl_elem_value *ucontrol)
1498{
1499 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
1500 struct hda_codec *codec = info->private_data;
1501 struct hdmi_spec *spec = codec->spec;
1502 int pin_idx = kcontrol->private_value;
1503 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1504 unsigned int ctl_idx;
1505 struct snd_pcm_substream *substream;
1506 unsigned char chmap[8];
1507 int i, ca, prepared = 0;
1508
1509 ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1510 substream = snd_pcm_chmap_substream(info, ctl_idx);
1511 if (!substream || !substream->runtime)
1512 return -EBADFD;
1513 switch (substream->runtime->status->state) {
1514 case SNDRV_PCM_STATE_OPEN:
1515 case SNDRV_PCM_STATE_SETUP:
1516 break;
1517 case SNDRV_PCM_STATE_PREPARED:
1518 prepared = 1;
1519 break;
1520 default:
1521 return -EBUSY;
1522 }
1523 memset(chmap, 0, sizeof(chmap));
1524 for (i = 0; i < ARRAY_SIZE(chmap); i++)
1525 chmap[i] = ucontrol->value.integer.value[i];
1526 if (!memcmp(chmap, per_pin->chmap, sizeof(chmap)))
1527 return 0;
1528 ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
1529 if (ca < 0)
1530 return -EINVAL;
1531 per_pin->chmap_set = true;
1532 memcpy(per_pin->chmap, chmap, sizeof(chmap));
1533 if (prepared)
1534 hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm,
1535 substream);
1536
1537 return 0;
1538}
1539
1264static int generic_hdmi_build_pcms(struct hda_codec *codec) 1540static int generic_hdmi_build_pcms(struct hda_codec *codec)
1265{ 1541{
1266 struct hdmi_spec *spec = codec->spec; 1542 struct hdmi_spec *spec = codec->spec;
@@ -1273,6 +1549,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
1273 info = &spec->pcm_rec[pin_idx]; 1549 info = &spec->pcm_rec[pin_idx];
1274 info->name = get_hdmi_pcm_name(pin_idx); 1550 info->name = get_hdmi_pcm_name(pin_idx);
1275 info->pcm_type = HDA_PCM_TYPE_HDMI; 1551 info->pcm_type = HDA_PCM_TYPE_HDMI;
1552 info->own_chmap = true;
1276 1553
1277 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1554 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1278 pstr->substreams = 1; 1555 pstr->substreams = 1;
@@ -1330,6 +1607,27 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1330 hdmi_present_sense(per_pin, 0); 1607 hdmi_present_sense(per_pin, 0);
1331 } 1608 }
1332 1609
1610 /* add channel maps */
1611 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1612 struct snd_pcm_chmap *chmap;
1613 struct snd_kcontrol *kctl;
1614 int i;
1615 err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm,
1616 SNDRV_PCM_STREAM_PLAYBACK,
1617 NULL, 0, pin_idx, &chmap);
1618 if (err < 0)
1619 return err;
1620 /* override handlers */
1621 chmap->private_data = codec;
1622 kctl = chmap->kctl;
1623 for (i = 0; i < kctl->count; i++)
1624 kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
1625 kctl->info = hdmi_chmap_ctl_info;
1626 kctl->get = hdmi_chmap_ctl_get;
1627 kctl->put = hdmi_chmap_ctl_put;
1628 kctl->tlv.c = hdmi_chmap_ctl_tlv;
1629 }
1630
1333 return 0; 1631 return 0;
1334} 1632}
1335 1633