aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi/ctatc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ctxfi/ctatc.c')
-rw-r--r--sound/pci/ctxfi/ctatc.c107
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[] = {
53static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { 51static 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
973static int atc_have_digit_io_switch(struct ct_atc *atc) 974static 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
981static 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
988static 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
995static 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
1002static 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
980static int atc_select_digit_io(struct ct_atc *atc) 1009static 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
1077static int atc_mic_unmute(struct ct_atc *atc, unsigned char state)
1078{
1079 return atc_daio_unmute(atc, state, MIC);
1080}
1081
1048static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) 1082static 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,