aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c97
1 files changed, 67 insertions, 30 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e2cf02387289..20f7762f7144 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -432,22 +432,26 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
432} 432}
433 433
434/* 434/*
435 * look for an AFG node 435 * look for an AFG and MFG nodes
436 *
437 * return 0 if not found
438 */ 436 */
439static int look_for_afg_node(struct hda_codec *codec) 437static void setup_fg_nodes(struct hda_codec *codec)
440{ 438{
441 int i, total_nodes; 439 int i, total_nodes;
442 hda_nid_t nid; 440 hda_nid_t nid;
443 441
444 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); 442 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
445 for (i = 0; i < total_nodes; i++, nid++) { 443 for (i = 0; i < total_nodes; i++, nid++) {
446 if ((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff) == 444 switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {
447 AC_GRP_AUDIO_FUNCTION) 445 case AC_GRP_AUDIO_FUNCTION:
448 return nid; 446 codec->afg = nid;
447 break;
448 case AC_GRP_MODEM_FUNCTION:
449 codec->mfg = nid;
450 break;
451 default:
452 break;
453 }
449 } 454 }
450 return 0;
451} 455}
452 456
453/* 457/*
@@ -507,10 +511,9 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
507 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); 511 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
508 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); 512 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
509 513
510 /* FIXME: support for multiple AFGs? */ 514 setup_fg_nodes(codec);
511 codec->afg = look_for_afg_node(codec); 515 if (! codec->afg && ! codec->mfg) {
512 if (! codec->afg) { 516 snd_printdd("hda_codec: no AFG or MFG node found\n");
513 snd_printdd("hda_codec: no AFG node found\n");
514 snd_hda_codec_free(codec); 517 snd_hda_codec_free(codec);
515 return -ENODEV; 518 return -ENODEV;
516 } 519 }
@@ -749,12 +752,14 @@ int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
749 long *valp = ucontrol->value.integer.value; 752 long *valp = ucontrol->value.integer.value;
750 int change = 0; 753 int change = 0;
751 754
752 if (chs & 1) 755 if (chs & 1) {
753 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 756 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
754 0x7f, *valp); 757 0x7f, *valp);
758 valp++;
759 }
755 if (chs & 2) 760 if (chs & 2)
756 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 761 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
757 0x7f, valp[1]); 762 0x7f, *valp);
758 return change; 763 return change;
759} 764}
760 765
@@ -796,12 +801,15 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
796 long *valp = ucontrol->value.integer.value; 801 long *valp = ucontrol->value.integer.value;
797 int change = 0; 802 int change = 0;
798 803
799 if (chs & 1) 804 if (chs & 1) {
800 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 805 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
801 0x80, *valp ? 0 : 0x80); 806 0x80, *valp ? 0 : 0x80);
807 valp++;
808 }
802 if (chs & 2) 809 if (chs & 2)
803 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 810 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
804 0x80, valp[1] ? 0 : 0x80); 811 0x80, *valp ? 0 : 0x80);
812
805 return change; 813 return change;
806} 814}
807 815
@@ -1155,8 +1163,16 @@ int snd_hda_build_controls(struct hda_bus *bus)
1155/* 1163/*
1156 * stream formats 1164 * stream formats
1157 */ 1165 */
1158static unsigned int rate_bits[][3] = { 1166struct hda_rate_tbl {
1167 unsigned int hz;
1168 unsigned int alsa_bits;
1169 unsigned int hda_fmt;
1170};
1171
1172static struct hda_rate_tbl rate_bits[] = {
1159 /* rate in Hz, ALSA rate bitmask, HDA format value */ 1173 /* rate in Hz, ALSA rate bitmask, HDA format value */
1174
1175 /* autodetected value used in snd_hda_query_supported_pcm */
1160 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ 1176 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
1161 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ 1177 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
1162 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ 1178 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
@@ -1168,7 +1184,11 @@ static unsigned int rate_bits[][3] = {
1168 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ 1184 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
1169 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ 1185 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
1170 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ 1186 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
1171 { 0 } 1187
1188 /* not autodetected value */
1189 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
1190
1191 { 0 } /* terminator */
1172}; 1192};
1173 1193
1174/** 1194/**
@@ -1190,12 +1210,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
1190 int i; 1210 int i;
1191 unsigned int val = 0; 1211 unsigned int val = 0;
1192 1212
1193 for (i = 0; rate_bits[i][0]; i++) 1213 for (i = 0; rate_bits[i].hz; i++)
1194 if (rate_bits[i][0] == rate) { 1214 if (rate_bits[i].hz == rate) {
1195 val = rate_bits[i][2]; 1215 val = rate_bits[i].hda_fmt;
1196 break; 1216 break;
1197 } 1217 }
1198 if (! rate_bits[i][0]) { 1218 if (! rate_bits[i].hz) {
1199 snd_printdd("invalid rate %d\n", rate); 1219 snd_printdd("invalid rate %d\n", rate);
1200 return 0; 1220 return 0;
1201 } 1221 }
@@ -1258,9 +1278,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
1258 1278
1259 if (ratesp) { 1279 if (ratesp) {
1260 u32 rates = 0; 1280 u32 rates = 0;
1261 for (i = 0; rate_bits[i][0]; i++) { 1281 for (i = 0; rate_bits[i].hz; i++) {
1262 if (val & (1 << i)) 1282 if (val & (1 << i))
1263 rates |= rate_bits[i][1]; 1283 rates |= rate_bits[i].alsa_bits;
1264 } 1284 }
1265 *ratesp = rates; 1285 *ratesp = rates;
1266 } 1286 }
@@ -1352,13 +1372,13 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
1352 } 1372 }
1353 1373
1354 rate = format & 0xff00; 1374 rate = format & 0xff00;
1355 for (i = 0; rate_bits[i][0]; i++) 1375 for (i = 0; rate_bits[i].hz; i++)
1356 if (rate_bits[i][2] == rate) { 1376 if (rate_bits[i].hda_fmt == rate) {
1357 if (val & (1 << i)) 1377 if (val & (1 << i))
1358 break; 1378 break;
1359 return 0; 1379 return 0;
1360 } 1380 }
1361 if (! rate_bits[i][0]) 1381 if (! rate_bits[i].hz)
1362 return 0; 1382 return 0;
1363 1383
1364 stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 1384 stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
@@ -1541,8 +1561,11 @@ int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_c
1541 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1561 for (c = tbl; c->modelname || c->pci_subvendor; c++) {
1542 if (c->pci_subvendor == subsystem_vendor && 1562 if (c->pci_subvendor == subsystem_vendor &&
1543 (! c->pci_subdevice /* all match */|| 1563 (! c->pci_subdevice /* all match */||
1544 (c->pci_subdevice == subsystem_device))) 1564 (c->pci_subdevice == subsystem_device))) {
1565 snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n",
1566 subsystem_vendor, subsystem_device, c->config);
1545 return c->config; 1567 return c->config;
1568 }
1546 } 1569 }
1547 } 1570 }
1548 return -1; 1571 return -1;
@@ -1803,11 +1826,25 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
1803 cfg->line_out_pins[j] = nid; 1826 cfg->line_out_pins[j] = nid;
1804 } 1827 }
1805 1828
1806 /* Swap surround and CLFE: the association order is front/CLFE/surr/back */ 1829 /* Reorder the surround channels
1807 if (cfg->line_outs >= 3) { 1830 * ALSA sequence is front/surr/clfe/side
1831 * HDA sequence is:
1832 * 4-ch: front/surr => OK as it is
1833 * 6-ch: front/clfe/surr
1834 * 8-ch: front/clfe/side/surr
1835 */
1836 switch (cfg->line_outs) {
1837 case 3:
1808 nid = cfg->line_out_pins[1]; 1838 nid = cfg->line_out_pins[1];
1809 cfg->line_out_pins[1] = cfg->line_out_pins[2]; 1839 cfg->line_out_pins[1] = cfg->line_out_pins[2];
1810 cfg->line_out_pins[2] = nid; 1840 cfg->line_out_pins[2] = nid;
1841 break;
1842 case 4:
1843 nid = cfg->line_out_pins[1];
1844 cfg->line_out_pins[1] = cfg->line_out_pins[3];
1845 cfg->line_out_pins[3] = cfg->line_out_pins[2];
1846 cfg->line_out_pins[2] = nid;
1847 break;
1811 } 1848 }
1812 1849
1813 return 0; 1850 return 0;