diff options
Diffstat (limited to 'sound/pci/ctxfi/ctatc.c')
-rw-r--r-- | sound/pci/ctxfi/ctatc.c | 107 |
1 files changed, 71 insertions, 36 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 13f33c0719d3..d8a4423539ce 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "ctatc.h" | 18 | #include "ctatc.h" |
19 | #include "ctpcm.h" | 19 | #include "ctpcm.h" |
20 | #include "ctmixer.h" | 20 | #include "ctmixer.h" |
21 | #include "cthardware.h" | ||
22 | #include "ctsrc.h" | 21 | #include "ctsrc.h" |
23 | #include "ctamixer.h" | 22 | #include "ctamixer.h" |
24 | #include "ctdaio.h" | 23 | #include "ctdaio.h" |
@@ -30,7 +29,6 @@ | |||
30 | #include <sound/asoundef.h> | 29 | #include <sound/asoundef.h> |
31 | 30 | ||
32 | #define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */ | 31 | #define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */ |
33 | #define DAIONUM 7 | ||
34 | #define MAX_MULTI_CHN 8 | 32 | #define MAX_MULTI_CHN 8 |
35 | 33 | ||
36 | #define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \ | 34 | #define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \ |
@@ -53,6 +51,8 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = { | |||
53 | static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { | 51 | static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { |
54 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760, | 52 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760, |
55 | "SB0760", CTSB0760), | 53 | "SB0760", CTSB0760), |
54 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270, | ||
55 | "SB1270", CTSB1270), | ||
56 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801, | 56 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801, |
57 | "SB0880", CTSB0880), | 57 | "SB0880", CTSB0880), |
58 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802, | 58 | SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802, |
@@ -75,6 +75,7 @@ static const char *ct_subsys_name[NUM_CTCARDS] = { | |||
75 | [CTSB0760] = "SB076x", | 75 | [CTSB0760] = "SB076x", |
76 | [CTHENDRIX] = "Hendrix", | 76 | [CTHENDRIX] = "Hendrix", |
77 | [CTSB0880] = "SB0880", | 77 | [CTSB0880] = "SB0880", |
78 | [CTSB1270] = "SB1270", | ||
78 | [CT20K2_UNKNOWN] = "Unknown", | 79 | [CT20K2_UNKNOWN] = "Unknown", |
79 | }; | 80 | }; |
80 | 81 | ||
@@ -459,12 +460,12 @@ static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm, | |||
459 | apcm->substream->runtime->rate); | 460 | apcm->substream->runtime->rate); |
460 | *n_srcc = 0; | 461 | *n_srcc = 0; |
461 | 462 | ||
462 | if (1 == atc->msr) { | 463 | if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */ |
463 | *n_srcc = apcm->substream->runtime->channels; | 464 | *n_srcc = apcm->substream->runtime->channels; |
464 | conf[0].pitch = pitch; | 465 | conf[0].pitch = pitch; |
465 | conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1; | 466 | conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1; |
466 | conf[0].vo = 1; | 467 | conf[0].vo = 1; |
467 | } else if (2 == atc->msr) { | 468 | } else if (2 <= atc->msr) { |
468 | if (0x8000000 < pitch) { | 469 | if (0x8000000 < pitch) { |
469 | /* Need two-stage SRCs, SRCIMPs and | 470 | /* Need two-stage SRCs, SRCIMPs and |
470 | * AMIXERs for converting format */ | 471 | * AMIXERs for converting format */ |
@@ -970,11 +971,39 @@ static int atc_select_mic_in(struct ct_atc *atc) | |||
970 | return 0; | 971 | return 0; |
971 | } | 972 | } |
972 | 973 | ||
973 | static int atc_have_digit_io_switch(struct ct_atc *atc) | 974 | static struct capabilities atc_capabilities(struct ct_atc *atc) |
974 | { | 975 | { |
975 | struct hw *hw = atc->hw; | 976 | struct hw *hw = atc->hw; |
976 | 977 | ||
977 | return hw->have_digit_io_switch(hw); | 978 | return hw->capabilities(hw); |
979 | } | ||
980 | |||
981 | static int atc_output_switch_get(struct ct_atc *atc) | ||
982 | { | ||
983 | struct hw *hw = atc->hw; | ||
984 | |||
985 | return hw->output_switch_get(hw); | ||
986 | } | ||
987 | |||
988 | static int atc_output_switch_put(struct ct_atc *atc, int position) | ||
989 | { | ||
990 | struct hw *hw = atc->hw; | ||
991 | |||
992 | return hw->output_switch_put(hw, position); | ||
993 | } | ||
994 | |||
995 | static int atc_mic_source_switch_get(struct ct_atc *atc) | ||
996 | { | ||
997 | struct hw *hw = atc->hw; | ||
998 | |||
999 | return hw->mic_source_switch_get(hw); | ||
1000 | } | ||
1001 | |||
1002 | static int atc_mic_source_switch_put(struct ct_atc *atc, int position) | ||
1003 | { | ||
1004 | struct hw *hw = atc->hw; | ||
1005 | |||
1006 | return hw->mic_source_switch_put(hw, position); | ||
978 | } | 1007 | } |
979 | 1008 | ||
980 | static int atc_select_digit_io(struct ct_atc *atc) | 1009 | static int atc_select_digit_io(struct ct_atc *atc) |
@@ -1045,6 +1074,11 @@ static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state) | |||
1045 | return atc_daio_unmute(atc, state, LINEIM); | 1074 | return atc_daio_unmute(atc, state, LINEIM); |
1046 | } | 1075 | } |
1047 | 1076 | ||
1077 | static int atc_mic_unmute(struct ct_atc *atc, unsigned char state) | ||
1078 | { | ||
1079 | return atc_daio_unmute(atc, state, MIC); | ||
1080 | } | ||
1081 | |||
1048 | static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) | 1082 | static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) |
1049 | { | 1083 | { |
1050 | return atc_daio_unmute(atc, state, SPDIFOO); | 1084 | return atc_daio_unmute(atc, state, SPDIFOO); |
@@ -1331,17 +1365,20 @@ static int atc_get_resources(struct ct_atc *atc) | |||
1331 | struct srcimp_mgr *srcimp_mgr; | 1365 | struct srcimp_mgr *srcimp_mgr; |
1332 | struct sum_desc sum_dsc = {0}; | 1366 | struct sum_desc sum_dsc = {0}; |
1333 | struct sum_mgr *sum_mgr; | 1367 | struct sum_mgr *sum_mgr; |
1334 | int err, i; | 1368 | int err, i, num_srcs, num_daios; |
1335 | 1369 | ||
1336 | atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); | 1370 | num_daios = ((atc->model == CTSB1270) ? 8 : 7); |
1371 | num_srcs = ((atc->model == CTSB1270) ? 6 : 4); | ||
1372 | |||
1373 | atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL); | ||
1337 | if (!atc->daios) | 1374 | if (!atc->daios) |
1338 | return -ENOMEM; | 1375 | return -ENOMEM; |
1339 | 1376 | ||
1340 | atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); | 1377 | atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); |
1341 | if (!atc->srcs) | 1378 | if (!atc->srcs) |
1342 | return -ENOMEM; | 1379 | return -ENOMEM; |
1343 | 1380 | ||
1344 | atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); | 1381 | atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); |
1345 | if (!atc->srcimps) | 1382 | if (!atc->srcimps) |
1346 | return -ENOMEM; | 1383 | return -ENOMEM; |
1347 | 1384 | ||
@@ -1351,8 +1388,9 @@ static int atc_get_resources(struct ct_atc *atc) | |||
1351 | 1388 | ||
1352 | daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; | 1389 | daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; |
1353 | da_desc.msr = atc->msr; | 1390 | da_desc.msr = atc->msr; |
1354 | for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) { | 1391 | for (i = 0, atc->n_daio = 0; i < num_daios; i++) { |
1355 | da_desc.type = i; | 1392 | da_desc.type = (atc->model != CTSB073X) ? i : |
1393 | ((i == SPDIFIO) ? SPDIFI1 : i); | ||
1356 | err = daio_mgr->get_daio(daio_mgr, &da_desc, | 1394 | err = daio_mgr->get_daio(daio_mgr, &da_desc, |
1357 | (struct daio **)&atc->daios[i]); | 1395 | (struct daio **)&atc->daios[i]); |
1358 | if (err) { | 1396 | if (err) { |
@@ -1362,23 +1400,12 @@ static int atc_get_resources(struct ct_atc *atc) | |||
1362 | } | 1400 | } |
1363 | atc->n_daio++; | 1401 | atc->n_daio++; |
1364 | } | 1402 | } |
1365 | if (atc->model == CTSB073X) | ||
1366 | da_desc.type = SPDIFI1; | ||
1367 | else | ||
1368 | da_desc.type = SPDIFIO; | ||
1369 | err = daio_mgr->get_daio(daio_mgr, &da_desc, | ||
1370 | (struct daio **)&atc->daios[i]); | ||
1371 | if (err) { | ||
1372 | printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n"); | ||
1373 | return err; | ||
1374 | } | ||
1375 | atc->n_daio++; | ||
1376 | 1403 | ||
1377 | src_mgr = atc->rsc_mgrs[SRC]; | 1404 | src_mgr = atc->rsc_mgrs[SRC]; |
1378 | src_dsc.multi = 1; | 1405 | src_dsc.multi = 1; |
1379 | src_dsc.msr = atc->msr; | 1406 | src_dsc.msr = atc->msr; |
1380 | src_dsc.mode = ARCRW; | 1407 | src_dsc.mode = ARCRW; |
1381 | for (i = 0, atc->n_src = 0; i < (2*2); i++) { | 1408 | for (i = 0, atc->n_src = 0; i < num_srcs; i++) { |
1382 | err = src_mgr->get_src(src_mgr, &src_dsc, | 1409 | err = src_mgr->get_src(src_mgr, &src_dsc, |
1383 | (struct src **)&atc->srcs[i]); | 1410 | (struct src **)&atc->srcs[i]); |
1384 | if (err) | 1411 | if (err) |
@@ -1388,8 +1415,8 @@ static int atc_get_resources(struct ct_atc *atc) | |||
1388 | } | 1415 | } |
1389 | 1416 | ||
1390 | srcimp_mgr = atc->rsc_mgrs[SRCIMP]; | 1417 | srcimp_mgr = atc->rsc_mgrs[SRCIMP]; |
1391 | srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */ | 1418 | srcimp_dsc.msr = 8; |
1392 | for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) { | 1419 | for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) { |
1393 | err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, | 1420 | err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, |
1394 | (struct srcimp **)&atc->srcimps[i]); | 1421 | (struct srcimp **)&atc->srcimps[i]); |
1395 | if (err) | 1422 | if (err) |
@@ -1397,15 +1424,6 @@ static int atc_get_resources(struct ct_atc *atc) | |||
1397 | 1424 | ||
1398 | atc->n_srcimp++; | 1425 | atc->n_srcimp++; |
1399 | } | 1426 | } |
1400 | srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */ | ||
1401 | for (i = 0; i < (2*1); i++) { | ||
1402 | err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, | ||
1403 | (struct srcimp **)&atc->srcimps[2*1+i]); | ||
1404 | if (err) | ||
1405 | return err; | ||
1406 | |||
1407 | atc->n_srcimp++; | ||
1408 | } | ||
1409 | 1427 | ||
1410 | sum_mgr = atc->rsc_mgrs[SUM]; | 1428 | sum_mgr = atc->rsc_mgrs[SUM]; |
1411 | sum_dsc.msr = atc->msr; | 1429 | sum_dsc.msr = atc->msr; |
@@ -1488,6 +1506,18 @@ static void atc_connect_resources(struct ct_atc *atc) | |||
1488 | src = atc->srcs[3]; | 1506 | src = atc->srcs[3]; |
1489 | mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); | 1507 | mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); |
1490 | 1508 | ||
1509 | if (atc->model == CTSB1270) { | ||
1510 | /* Titanium HD has a dedicated ADC for the Mic. */ | ||
1511 | dai = container_of(atc->daios[MIC], struct dai, daio); | ||
1512 | atc_connect_dai(atc->rsc_mgrs[SRC], dai, | ||
1513 | (struct src **)&atc->srcs[4], | ||
1514 | (struct srcimp **)&atc->srcimps[4]); | ||
1515 | src = atc->srcs[4]; | ||
1516 | mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc); | ||
1517 | src = atc->srcs[5]; | ||
1518 | mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc); | ||
1519 | } | ||
1520 | |||
1491 | dai = container_of(atc->daios[SPDIFIO], struct dai, daio); | 1521 | dai = container_of(atc->daios[SPDIFIO], struct dai, daio); |
1492 | atc_connect_dai(atc->rsc_mgrs[SRC], dai, | 1522 | atc_connect_dai(atc->rsc_mgrs[SRC], dai, |
1493 | (struct src **)&atc->srcs[0], | 1523 | (struct src **)&atc->srcs[0], |
@@ -1606,12 +1636,17 @@ static struct ct_atc atc_preset __devinitdata = { | |||
1606 | .line_clfe_unmute = atc_line_clfe_unmute, | 1636 | .line_clfe_unmute = atc_line_clfe_unmute, |
1607 | .line_rear_unmute = atc_line_rear_unmute, | 1637 | .line_rear_unmute = atc_line_rear_unmute, |
1608 | .line_in_unmute = atc_line_in_unmute, | 1638 | .line_in_unmute = atc_line_in_unmute, |
1639 | .mic_unmute = atc_mic_unmute, | ||
1609 | .spdif_out_unmute = atc_spdif_out_unmute, | 1640 | .spdif_out_unmute = atc_spdif_out_unmute, |
1610 | .spdif_in_unmute = atc_spdif_in_unmute, | 1641 | .spdif_in_unmute = atc_spdif_in_unmute, |
1611 | .spdif_out_get_status = atc_spdif_out_get_status, | 1642 | .spdif_out_get_status = atc_spdif_out_get_status, |
1612 | .spdif_out_set_status = atc_spdif_out_set_status, | 1643 | .spdif_out_set_status = atc_spdif_out_set_status, |
1613 | .spdif_out_passthru = atc_spdif_out_passthru, | 1644 | .spdif_out_passthru = atc_spdif_out_passthru, |
1614 | .have_digit_io_switch = atc_have_digit_io_switch, | 1645 | .capabilities = atc_capabilities, |
1646 | .output_switch_get = atc_output_switch_get, | ||
1647 | .output_switch_put = atc_output_switch_put, | ||
1648 | .mic_source_switch_get = atc_mic_source_switch_get, | ||
1649 | .mic_source_switch_put = atc_mic_source_switch_put, | ||
1615 | #ifdef CONFIG_PM | 1650 | #ifdef CONFIG_PM |
1616 | .suspend = atc_suspend, | 1651 | .suspend = atc_suspend, |
1617 | .resume = atc_resume, | 1652 | .resume = atc_resume, |