aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_intelhdmi.c89
1 files changed, 67 insertions, 22 deletions
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 0d5dd1ba8205..3990182777ee 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -146,38 +146,78 @@ struct cea_channel_speaker_allocation {
146}; 146};
147 147
148/* 148/*
149 * ALSA sequence is:
150 *
151 * surround40 surround41 surround50 surround51 surround71
152 * ch0 front left = = = =
153 * ch1 front right = = = =
154 * ch2 rear left = = = =
155 * ch3 rear right = = = =
156 * ch4 LFE center center center
157 * ch5 LFE LFE
158 * ch6 side left
159 * ch7 side right
160 *
161 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
162 */
163static int hdmi_channel_mapping[0x32][8] = {
164 /* stereo */
165 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
166 /* 2.1 */
167 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
168 /* Dolby Surround */
169 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
170 /* surround40 */
171 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
172 /* 4ch */
173 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
174 /* surround41 */
175 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
176 /* surround50 */
177 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
178 /* surround51 */
179 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
180 /* 7.1 */
181 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
182};
183
184/*
149 * This is an ordered list! 185 * This is an ordered list!
150 * 186 *
151 * The preceding ones have better chances to be selected by 187 * The preceding ones have better chances to be selected by
152 * hdmi_setup_channel_allocation(). 188 * hdmi_setup_channel_allocation().
153 */ 189 */
154static struct cea_channel_speaker_allocation channel_allocations[] = { 190static struct cea_channel_speaker_allocation channel_allocations[] = {
155/* channel: 8 7 6 5 4 3 2 1 */ 191/* channel: 7 6 5 4 3 2 1 0 */
156{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, 192{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
157 /* 2.1 */ 193 /* 2.1 */
158{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, 194{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
159 /* Dolby Surround */ 195 /* Dolby Surround */
160{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, 196{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
197 /* surround40 */
198{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
199 /* surround41 */
200{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
201 /* surround50 */
202{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
203 /* surround51 */
204{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
205 /* 6.1 */
206{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
207 /* surround71 */
208{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
209
161{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, 210{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
162{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, 211{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
163{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, 212{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
164{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, 213{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
165{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, 214{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
166{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
167{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
168{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
169 /* 5.1 */
170{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
171{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, 215{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
172{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, 216{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
173{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, 217{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
174 /* 6.1 */
175{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
176{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, 218{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
177{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, 219{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
178{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, 220{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
179 /* 7.1 */
180{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
181{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, 221{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
182{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, 222{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
183{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, 223{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
@@ -210,7 +250,6 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
210{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, 250{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
211}; 251};
212 252
213
214/* 253/*
215 * HDA/HDMI auto parsing 254 * HDA/HDMI auto parsing
216 */ 255 */
@@ -625,19 +664,25 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec,
625 struct hdmi_audio_infoframe *ai) 664 struct hdmi_audio_infoframe *ai)
626{ 665{
627 int i; 666 int i;
667 int ca = ai->CA;
668 int err;
628 669
629 if (!ai->CA) 670 if (hdmi_channel_mapping[ca][1] == 0) {
630 return; 671 for (i = 0; i < channel_allocations[ca].channels; i++)
631 672 hdmi_channel_mapping[ca][i] = i | (i << 4);
632 /* 673 for (; i < 8; i++)
633 * TODO: adjust channel mapping if necessary 674 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
634 * ALSA sequence is front/surr/clfe/side? 675 }
635 */
636 676
637 for (i = 0; i < 8; i++) 677 for (i = 0; i < 8; i++) {
638 snd_hda_codec_write(codec, pin_nid, 0, 678 err = snd_hda_codec_write(codec, pin_nid, 0,
639 AC_VERB_SET_HDMI_CHAN_SLOT, 679 AC_VERB_SET_HDMI_CHAN_SLOT,
640 (i << 4) | i); 680 hdmi_channel_mapping[ca][i]);
681 if (err) {
682 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
683 break;
684 }
685 }
641 686
642 hdmi_debug_channel_mapping(codec, pin_nid); 687 hdmi_debug_channel_mapping(codec, pin_nid);
643} 688}