diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 89 |
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 | */ | ||
163 | static 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 | */ |
154 | static struct cea_channel_speaker_allocation channel_allocations[] = { | 190 | static 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 | } |