aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2009-12-10 23:28:36 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-11 01:56:18 -0500
commitb14224bb74e19072c34617c501bceab94ebf579f (patch)
tree75334c097978cab0d6fdee1eb0aca42b486930df /sound/pci/hda
parent1ffc69a6e86aa9458046d1719957e091c8e95f7a (diff)
ALSA: intelhdmi - add channel mapping for typical configurations
IbexPeak is the first Intel HDMI audio codec to support channel mapping. Currently the outstanding problem is, the HDMI channel order do not agree with that of ALSA. This patch presents workaround for some typical use cases. It gives priority to the typical ALSA surround configurations, and defines channel mapping for them. We may need better kernel+userspace interactive channel mapping scheme. For example, in current scheme if user plays with the surround50 device, the kernel is unaware of this and will still select the surround41 channel allocation and channel mapping.. Thanks to Marcin for offering good tips! Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
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}