aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-07 10:44:06 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-12 02:44:08 -0500
commita07a949be6eb1c9aab06adaadce72dbd27b7d9cb (patch)
tree728f1ff2218cf11fc4440878440a93ae143a994c /sound
parentaffdb62b815b38261f09f9d4ec210a35c7ffb1f3 (diff)
ALSA: hda - Fix multi-io channel mode management
The multi-io channels can vary not only from 1 to 6 but also may vary from 6 to 8 or such. At the same time, there are more speaker pins available than the primary output pins. So, we need three variables to check: the minimum channel counts for primary outputs, the current channel counts for primary outputs, and the minimum channel counts for all outputs. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_generic.c92
-rw-r--r--sound/pci/hda/hda_generic.h16
2 files changed, 76 insertions, 32 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1fbc1b32359c..afa54f87b691 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -1125,6 +1125,25 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
1125 return snd_hda_get_path_idx(codec, path); 1125 return snd_hda_get_path_idx(codec, path);
1126} 1126}
1127 1127
1128/* fill the empty entries in the dac array for speaker/hp with the
1129 * shared dac pointed by the paths
1130 */
1131static void refill_shared_dacs(struct hda_codec *codec, int num_outs,
1132 hda_nid_t *dacs, int *path_idx)
1133{
1134 struct nid_path *path;
1135 int i;
1136
1137 for (i = 0; i < num_outs; i++) {
1138 if (dacs[i])
1139 continue;
1140 path = snd_hda_get_path_from_idx(codec, path_idx[i]);
1141 if (!path)
1142 continue;
1143 dacs[i] = path->path[0];
1144 }
1145}
1146
1128/* fill in the dac_nids table from the parsed pin configuration */ 1147/* fill in the dac_nids table from the parsed pin configuration */
1129static int fill_and_eval_dacs(struct hda_codec *codec, 1148static int fill_and_eval_dacs(struct hda_codec *codec,
1130 bool fill_hardwired, 1149 bool fill_hardwired,
@@ -1183,19 +1202,6 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1183 spec->private_dac_nids, spec->out_paths, 1202 spec->private_dac_nids, spec->out_paths,
1184 &main_out_badness); 1203 &main_out_badness);
1185 1204
1186 /* re-count num_dacs and squash invalid entries */
1187 spec->multiout.num_dacs = 0;
1188 for (i = 0; i < cfg->line_outs; i++) {
1189 if (spec->private_dac_nids[i])
1190 spec->multiout.num_dacs++;
1191 else {
1192 memmove(spec->private_dac_nids + i,
1193 spec->private_dac_nids + i + 1,
1194 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
1195 spec->private_dac_nids[cfg->line_outs - 1] = 0;
1196 }
1197 }
1198
1199 if (fill_mio_first && 1205 if (fill_mio_first &&
1200 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1206 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1201 /* try to fill multi-io first */ 1207 /* try to fill multi-io first */
@@ -1246,16 +1252,41 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1246 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2) 1252 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2)
1247 spec->multi_ios = 1; /* give badness */ 1253 spec->multi_ios = 1; /* give badness */
1248 1254
1255 /* re-count num_dacs and squash invalid entries */
1256 spec->multiout.num_dacs = 0;
1257 for (i = 0; i < cfg->line_outs; i++) {
1258 if (spec->private_dac_nids[i])
1259 spec->multiout.num_dacs++;
1260 else {
1261 memmove(spec->private_dac_nids + i,
1262 spec->private_dac_nids + i + 1,
1263 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
1264 spec->private_dac_nids[cfg->line_outs - 1] = 0;
1265 }
1266 }
1267
1268 spec->ext_channel_count = spec->min_channel_count =
1269 spec->multiout.num_dacs;
1270
1249 if (spec->multi_ios == 2) { 1271 if (spec->multi_ios == 2) {
1250 for (i = 0; i < 2; i++) 1272 for (i = 0; i < 2; i++)
1251 spec->private_dac_nids[spec->multiout.num_dacs++] = 1273 spec->private_dac_nids[spec->multiout.num_dacs++] =
1252 spec->multi_io[i].dac; 1274 spec->multi_io[i].dac;
1253 spec->ext_channel_count = 2;
1254 } else if (spec->multi_ios) { 1275 } else if (spec->multi_ios) {
1255 spec->multi_ios = 0; 1276 spec->multi_ios = 0;
1256 badness += BAD_MULTI_IO; 1277 badness += BAD_MULTI_IO;
1257 } 1278 }
1258 1279
1280 /* re-fill the shared DAC for speaker / headphone */
1281 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1282 refill_shared_dacs(codec, cfg->hp_outs,
1283 spec->multiout.hp_out_nid,
1284 spec->hp_paths);
1285 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1286 refill_shared_dacs(codec, cfg->speaker_outs,
1287 spec->multiout.extra_out_nid,
1288 spec->speaker_paths);
1289
1259 return badness; 1290 return badness;
1260} 1291}
1261 1292
@@ -1610,14 +1641,15 @@ static int ch_mode_info(struct snd_kcontrol *kcontrol,
1610{ 1641{
1611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1612 struct hda_gen_spec *spec = codec->spec; 1643 struct hda_gen_spec *spec = codec->spec;
1644 int chs;
1613 1645
1614 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1646 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1615 uinfo->count = 1; 1647 uinfo->count = 1;
1616 uinfo->value.enumerated.items = spec->multi_ios + 1; 1648 uinfo->value.enumerated.items = spec->multi_ios + 1;
1617 if (uinfo->value.enumerated.item > spec->multi_ios) 1649 if (uinfo->value.enumerated.item > spec->multi_ios)
1618 uinfo->value.enumerated.item = spec->multi_ios; 1650 uinfo->value.enumerated.item = spec->multi_ios;
1619 sprintf(uinfo->value.enumerated.name, "%dch", 1651 chs = uinfo->value.enumerated.item * 2 + spec->min_channel_count;
1620 (uinfo->value.enumerated.item + 1) * 2); 1652 sprintf(uinfo->value.enumerated.name, "%dch", chs);
1621 return 0; 1653 return 0;
1622} 1654}
1623 1655
@@ -1626,7 +1658,8 @@ static int ch_mode_get(struct snd_kcontrol *kcontrol,
1626{ 1658{
1627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1659 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1628 struct hda_gen_spec *spec = codec->spec; 1660 struct hda_gen_spec *spec = codec->spec;
1629 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; 1661 ucontrol->value.enumerated.item[0] =
1662 (spec->ext_channel_count - spec->min_channel_count) / 2;
1630 return 0; 1663 return 0;
1631} 1664}
1632 1665
@@ -1674,9 +1707,9 @@ static int ch_mode_put(struct snd_kcontrol *kcontrol,
1674 ch = ucontrol->value.enumerated.item[0]; 1707 ch = ucontrol->value.enumerated.item[0];
1675 if (ch < 0 || ch > spec->multi_ios) 1708 if (ch < 0 || ch > spec->multi_ios)
1676 return -EINVAL; 1709 return -EINVAL;
1677 if (ch == (spec->ext_channel_count - 1) / 2) 1710 if (ch == (spec->ext_channel_count - spec->min_channel_count) / 2)
1678 return 0; 1711 return 0;
1679 spec->ext_channel_count = (ch + 1) * 2; 1712 spec->ext_channel_count = ch * 2 + spec->min_channel_count;
1680 for (i = 0; i < spec->multi_ios; i++) 1713 for (i = 0; i < spec->multi_ios; i++)
1681 set_multi_io(codec, i, i < ch); 1714 set_multi_io(codec, i, i < ch);
1682 spec->multiout.max_channels = max(spec->ext_channel_count, 1715 spec->multiout.max_channels = max(spec->ext_channel_count,
@@ -3127,17 +3160,16 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
3127 if (err < 0) 3160 if (err < 0)
3128 return err; 3161 return err;
3129 3162
3130 /* check the multiple speaker pins */ 3163 spec->const_channel_count = spec->ext_channel_count;
3131 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 3164 /* check the multiple speaker and headphone pins */
3132 spec->const_channel_count = cfg->line_outs * 2; 3165 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
3133 else 3166 spec->const_channel_count = max(spec->const_channel_count,
3134 spec->const_channel_count = cfg->speaker_outs * 2; 3167 cfg->speaker_outs * 2);
3135 3168 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
3136 if (spec->multi_ios > 0) 3169 spec->const_channel_count = max(spec->const_channel_count,
3137 spec->multiout.max_channels = max(spec->ext_channel_count, 3170 cfg->hp_outs * 2);
3138 spec->const_channel_count); 3171 spec->multiout.max_channels = max(spec->ext_channel_count,
3139 else 3172 spec->const_channel_count);
3140 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3141 3173
3142 err = check_auto_mute_availability(codec); 3174 err = check_auto_mute_availability(codec);
3143 if (err < 0) 3175 if (err < 0)
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 00a1eab2c0b2..b65769cbde2b 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -117,8 +117,20 @@ struct hda_gen_spec {
117 unsigned int cur_mux[3]; 117 unsigned int cur_mux[3];
118 118
119 /* channel model */ 119 /* channel model */
120 int const_channel_count; /* min. channel count (for speakers) */ 120 /* min_channel_count contains the minimum channel count for primary
121 int ext_channel_count; /* current channel count for multi-io */ 121 * outputs. When multi_ios is set, the channels can be configured
122 * between min_channel_count and (min_channel_count + multi_ios * 2).
123 *
124 * ext_channel_count contains the current channel count of the primary
125 * out. This varies in the range above.
126 *
127 * Meanwhile, const_channel_count is the channel count for all outputs
128 * including headphone and speakers. It's a constant value, and the
129 * PCM is set up as max(ext_channel_count, const_channel_count).
130 */
131 int min_channel_count; /* min. channel count for primary out */
132 int ext_channel_count; /* current channel count for primary */
133 int const_channel_count; /* channel count for all */
122 134
123 /* PCM information */ 135 /* PCM information */
124 struct hda_pcm pcm_rec[3]; /* used in build_pcms() */ 136 struct hda_pcm pcm_rec[3]; /* used in build_pcms() */