Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: ctxfi: Add support for Creative Titanium HD

Initialise model-specific DAC and ADC parts.
Add controls for output and mic source selection.
Rename some mixer controls according to ControlNames.txt.
Remove Playback switches for Line-in and IEC958-in - these
were controlling the input mute/unmute which affected
capture too. Use the capture switches to control the
input mute/unmute instead - it's less confusing.
Initialise the WM8775 to invert the left-right clock
to swap the left and right channels of the mic and aux
input.

Signed-off-by: Harry Butterworth <heb1001@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Harry Butterworth and committed by
Takashi Iwai
55309216 37f7ec38

+488 -164
+1
include/linux/pci_ids.h
··· 1308 1308 #define PCI_SUBDEVICE_ID_CREATIVE_SB08801 0x0041 1309 1309 #define PCI_SUBDEVICE_ID_CREATIVE_SB08802 0x0042 1310 1310 #define PCI_SUBDEVICE_ID_CREATIVE_SB08803 0x0043 1311 + #define PCI_SUBDEVICE_ID_CREATIVE_SB1270 0x0062 1311 1312 #define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX 0x6000 1312 1313 1313 1314 #define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */
+1
sound/pci/ctxfi/ct20k2reg.h
··· 55 55 /* GPIO Registers */ 56 56 #define GPIO_DATA 0x1B7020 57 57 #define GPIO_CTRL 0x1B7024 58 + #define GPIO_EXT_DATA 0x1B70A0 58 59 59 60 /* Virtual memory registers */ 60 61 #define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
+92 -32
sound/pci/ctxfi/ctatc.c
··· 30 30 #include <sound/asoundef.h> 31 31 32 32 #define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */ 33 - #define DAIONUM 7 34 33 #define MAX_MULTI_CHN 8 35 34 36 35 #define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \ ··· 52 53 static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { 53 54 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760, 54 55 "SB0760", CTSB0760), 56 + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270, 57 + "SB1270", CTSB1270), 55 58 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801, 56 59 "SB0880", CTSB0880), 57 60 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802, ··· 76 75 [CTSB0760] = "SB076x", 77 76 [CTHENDRIX] = "Hendrix", 78 77 [CTSB0880] = "SB0880", 78 + [CTSB1270] = "SB1270", 79 79 [CT20K2_UNKNOWN] = "Unknown", 80 80 }; 81 81 ··· 461 459 apcm->substream->runtime->rate); 462 460 *n_srcc = 0; 463 461 464 - if (1 == atc->msr) { 462 + if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */ 465 463 *n_srcc = apcm->substream->runtime->channels; 466 464 conf[0].pitch = pitch; 467 465 conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1; 468 466 conf[0].vo = 1; 469 - } else if (2 == atc->msr) { 467 + } else if (2 <= atc->msr) { 470 468 if (0x8000000 < pitch) { 471 469 /* Need two-stage SRCs, SRCIMPs and 472 470 * AMIXERs for converting format */ ··· 979 977 return hw->have_digit_io_switch(hw); 980 978 } 981 979 980 + static int atc_have_dedicated_mic(struct ct_atc *atc) 981 + { 982 + struct hw *hw = atc->hw; 983 + 984 + return hw->have_dedicated_mic(hw); 985 + } 986 + 987 + static int atc_have_output_switch(struct ct_atc *atc) 988 + { 989 + struct hw *hw = atc->hw; 990 + 991 + return hw->have_output_switch(hw); 992 + } 993 + 994 + static int atc_output_switch_get(struct ct_atc *atc) 995 + { 996 + struct hw *hw = atc->hw; 997 + 998 + return hw->output_switch_get(hw); 999 + } 1000 + 1001 + static int atc_output_switch_put(struct ct_atc *atc, int position) 1002 + { 1003 + struct hw *hw = atc->hw; 1004 + 1005 + return hw->output_switch_put(hw, position); 1006 + } 1007 + 1008 + static int atc_have_mic_source_switch(struct ct_atc *atc) 1009 + { 1010 + struct hw *hw = atc->hw; 1011 + 1012 + return hw->have_mic_source_switch(hw); 1013 + } 1014 + 1015 + static int atc_mic_source_switch_get(struct ct_atc *atc) 1016 + { 1017 + struct hw *hw = atc->hw; 1018 + 1019 + return hw->mic_source_switch_get(hw); 1020 + } 1021 + 1022 + static int atc_mic_source_switch_put(struct ct_atc *atc, int position) 1023 + { 1024 + struct hw *hw = atc->hw; 1025 + 1026 + return hw->mic_source_switch_put(hw, position); 1027 + } 1028 + 982 1029 static int atc_select_digit_io(struct ct_atc *atc) 983 1030 { 984 1031 struct hw *hw = atc->hw; ··· 1094 1043 static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state) 1095 1044 { 1096 1045 return atc_daio_unmute(atc, state, LINEIM); 1046 + } 1047 + 1048 + static int atc_mic_unmute(struct ct_atc *atc, unsigned char state) 1049 + { 1050 + return atc_daio_unmute(atc, state, MIC); 1097 1051 } 1098 1052 1099 1053 static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) ··· 1387 1331 struct srcimp_mgr *srcimp_mgr; 1388 1332 struct sum_desc sum_dsc = {0}; 1389 1333 struct sum_mgr *sum_mgr; 1390 - int err, i; 1334 + int err, i, num_srcs, num_daios; 1391 1335 1392 - atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); 1336 + num_daios = ((atc->model == CTSB1270) ? 8 : 7); 1337 + num_srcs = ((atc->model == CTSB1270) ? 6 : 4); 1338 + 1339 + atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL); 1393 1340 if (!atc->daios) 1394 1341 return -ENOMEM; 1395 1342 1396 - atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); 1343 + atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); 1397 1344 if (!atc->srcs) 1398 1345 return -ENOMEM; 1399 1346 1400 - atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); 1347 + atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); 1401 1348 if (!atc->srcimps) 1402 1349 return -ENOMEM; 1403 1350 ··· 1410 1351 1411 1352 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; 1412 1353 da_desc.msr = atc->msr; 1413 - for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) { 1414 - da_desc.type = i; 1354 + for (i = 0, atc->n_daio = 0; i < num_daios; i++) { 1355 + da_desc.type = (atc->model != CTSB073X) ? i : 1356 + ((i == SPDIFIO) ? SPDIFI1 : i); 1415 1357 err = daio_mgr->get_daio(daio_mgr, &da_desc, 1416 1358 (struct daio **)&atc->daios[i]); 1417 1359 if (err) { ··· 1422 1362 } 1423 1363 atc->n_daio++; 1424 1364 } 1425 - if (atc->model == CTSB073X) 1426 - da_desc.type = SPDIFI1; 1427 - else 1428 - da_desc.type = SPDIFIO; 1429 - err = daio_mgr->get_daio(daio_mgr, &da_desc, 1430 - (struct daio **)&atc->daios[i]); 1431 - if (err) { 1432 - printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n"); 1433 - return err; 1434 - } 1435 - atc->n_daio++; 1436 1365 1437 1366 src_mgr = atc->rsc_mgrs[SRC]; 1438 1367 src_dsc.multi = 1; 1439 1368 src_dsc.msr = atc->msr; 1440 1369 src_dsc.mode = ARCRW; 1441 - for (i = 0, atc->n_src = 0; i < (2*2); i++) { 1370 + for (i = 0, atc->n_src = 0; i < num_srcs; i++) { 1442 1371 err = src_mgr->get_src(src_mgr, &src_dsc, 1443 1372 (struct src **)&atc->srcs[i]); 1444 1373 if (err) ··· 1437 1388 } 1438 1389 1439 1390 srcimp_mgr = atc->rsc_mgrs[SRCIMP]; 1440 - srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */ 1441 - for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) { 1391 + srcimp_dsc.msr = 8; 1392 + for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) { 1442 1393 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, 1443 1394 (struct srcimp **)&atc->srcimps[i]); 1444 - if (err) 1445 - return err; 1446 - 1447 - atc->n_srcimp++; 1448 - } 1449 - srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */ 1450 - for (i = 0; i < (2*1); i++) { 1451 - err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, 1452 - (struct srcimp **)&atc->srcimps[2*1+i]); 1453 1395 if (err) 1454 1396 return err; 1455 1397 ··· 1527 1487 mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc); 1528 1488 src = atc->srcs[3]; 1529 1489 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); 1490 + 1491 + if (atc->model == CTSB1270) { 1492 + /* Titanium HD has a dedicated ADC for the Mic. */ 1493 + dai = container_of(atc->daios[MIC], struct dai, daio); 1494 + atc_connect_dai(atc->rsc_mgrs[SRC], dai, 1495 + (struct src **)&atc->srcs[4], 1496 + (struct srcimp **)&atc->srcimps[4]); 1497 + src = atc->srcs[4]; 1498 + mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc); 1499 + src = atc->srcs[5]; 1500 + mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc); 1501 + } 1530 1502 1531 1503 dai = container_of(atc->daios[SPDIFIO], struct dai, daio); 1532 1504 atc_connect_dai(atc->rsc_mgrs[SRC], dai, ··· 1658 1606 .line_clfe_unmute = atc_line_clfe_unmute, 1659 1607 .line_rear_unmute = atc_line_rear_unmute, 1660 1608 .line_in_unmute = atc_line_in_unmute, 1609 + .mic_unmute = atc_mic_unmute, 1661 1610 .spdif_out_unmute = atc_spdif_out_unmute, 1662 1611 .spdif_in_unmute = atc_spdif_in_unmute, 1663 1612 .spdif_out_get_status = atc_spdif_out_get_status, 1664 1613 .spdif_out_set_status = atc_spdif_out_set_status, 1665 1614 .spdif_out_passthru = atc_spdif_out_passthru, 1666 1615 .have_digit_io_switch = atc_have_digit_io_switch, 1616 + .have_dedicated_mic = atc_have_dedicated_mic, 1617 + .have_output_switch = atc_have_output_switch, 1618 + .output_switch_get = atc_output_switch_get, 1619 + .output_switch_put = atc_output_switch_put, 1620 + .have_mic_source_switch = atc_have_mic_source_switch, 1621 + .mic_source_switch_get = atc_mic_source_switch_get, 1622 + .mic_source_switch_put = atc_mic_source_switch_put, 1667 1623 #ifdef CONFIG_PM 1668 1624 .suspend = atc_suspend, 1669 1625 .resume = atc_resume,
+8
sound/pci/ctxfi/ctatc.h
··· 115 115 int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state); 116 116 int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state); 117 117 int (*line_in_unmute)(struct ct_atc *atc, unsigned char state); 118 + int (*mic_unmute)(struct ct_atc *atc, unsigned char state); 118 119 int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state); 119 120 int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state); 120 121 int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status); 121 122 int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status); 122 123 int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state); 123 124 int (*have_digit_io_switch)(struct ct_atc *atc); 125 + int (*have_dedicated_mic)(struct ct_atc *atc); 126 + int (*have_output_switch)(struct ct_atc *atc); 127 + int (*output_switch_get)(struct ct_atc *atc); 128 + int (*output_switch_put)(struct ct_atc *atc, int position); 129 + int (*have_mic_source_switch)(struct ct_atc *atc); 130 + int (*mic_source_switch_get)(struct ct_atc *atc); 131 + int (*mic_source_switch_put)(struct ct_atc *atc, int position); 124 132 125 133 /* Don't touch! Used for internal object. */ 126 134 void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
+7 -16
sound/pci/ctxfi/ctdaio.c
··· 22 22 #include <linux/slab.h> 23 23 #include <linux/kernel.h> 24 24 25 - #define DAIO_RESOURCE_NUM NUM_DAIOTYP 26 25 #define DAIO_OUT_MAX SPDIFOO 27 26 28 - union daio_usage { 29 - struct { 30 - unsigned short lineo1:1; 31 - unsigned short lineo2:1; 32 - unsigned short lineo3:1; 33 - unsigned short lineo4:1; 34 - unsigned short spdifoo:1; 35 - unsigned short lineim:1; 36 - unsigned short spdifio:1; 37 - unsigned short spdifi1:1; 38 - } bf; 27 + struct daio_usage { 39 28 unsigned short data; 40 29 }; 41 30 ··· 50 61 [LINEO3] = {.left = 0x50, .right = 0x51}, 51 62 [LINEO4] = {.left = 0x70, .right = 0x71}, 52 63 [LINEIM] = {.left = 0x45, .right = 0xc5}, 64 + [MIC] = {.left = 0x55, .right = 0xd5}, 53 65 [SPDIFOO] = {.left = 0x00, .right = 0x01}, 54 66 [SPDIFIO] = {.left = 0x05, .right = 0x85}, 55 67 }; ··· 128 138 case LINEO3: return 5; 129 139 case LINEO4: return 6; 130 140 case LINEIM: return 4; 141 + case MIC: return 5; 131 142 default: return -EINVAL; 132 143 } 133 144 default: ··· 510 519 511 520 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type) 512 521 { 513 - if (((union daio_usage *)mgr->rscs)->data & (0x1 << type)) 522 + if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type)) 514 523 return -ENOENT; 515 524 516 - ((union daio_usage *)mgr->rscs)->data |= (0x1 << type); 525 + ((struct daio_usage *)mgr->rscs)->data |= (0x1 << type); 517 526 518 527 return 0; 519 528 } 520 529 521 530 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type) 522 531 { 523 - ((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type); 532 + ((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type); 524 533 525 534 return 0; 526 535 } ··· 703 712 if (!daio_mgr) 704 713 return -ENOMEM; 705 714 706 - err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw); 715 + err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw); 707 716 if (err) 708 717 goto error1; 709 718
+1
sound/pci/ctxfi/ctdaio.h
··· 33 33 SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */ 34 34 LINEIM, 35 35 SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */ 36 + MIC, /* Dedicated mic on Titanium HD */ 36 37 SPDIFI1, /* S/PDIF In on internal Drive Bay */ 37 38 NUM_DAIOTYP 38 39 };
+8
sound/pci/ctxfi/cthardware.h
··· 39 39 CT20K2_MODEL_FIRST = CTSB0760, 40 40 CTHENDRIX, 41 41 CTSB0880, 42 + CTSB1270, 42 43 CT20K2_UNKNOWN, 43 44 NUM_CTCARDS /* This should always be the last */ 44 45 }; ··· 72 71 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); 73 72 int (*select_adc_source)(struct hw *hw, enum ADCSRC source); 74 73 int (*have_digit_io_switch)(struct hw *hw); 74 + int (*have_dedicated_mic)(struct hw *hw); 75 + int (*have_output_switch)(struct hw *hw); 76 + int (*output_switch_get)(struct hw *hw); 77 + int (*output_switch_put)(struct hw *hw, int position); 78 + int (*have_mic_source_switch)(struct hw *hw); 79 + int (*mic_source_switch_get)(struct hw *hw); 80 + int (*mic_source_switch_put)(struct hw *hw, int position); 75 81 76 82 /* SRC operations */ 77 83 int (*src_rsc_get_ctrl_blk)(void **rblk);
+18
sound/pci/ctxfi/cthw20k1.c
··· 1783 1783 return !(hw->model == CTSB073X || hw->model == CTUAA); 1784 1784 } 1785 1785 1786 + static int hw_have_dedicated_mic(struct hw *hw) 1787 + { 1788 + return 0; 1789 + } 1790 + 1791 + static int hw_have_output_switch(struct hw *hw) 1792 + { 1793 + return 0; 1794 + } 1795 + 1796 + static int hw_have_mic_source_switch(struct hw *hw) 1797 + { 1798 + return 0; 1799 + } 1800 + 1786 1801 #define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 1787 1802 1788 1803 #define UAA_CFG_PWRSTATUS 0x44 ··· 2188 2173 .is_adc_source_selected = hw_is_adc_input_selected, 2189 2174 .select_adc_source = hw_adc_input_select, 2190 2175 .have_digit_io_switch = hw_have_digit_io_switch, 2176 + .have_dedicated_mic = hw_have_dedicated_mic, 2177 + .have_output_switch = hw_have_output_switch, 2178 + .have_mic_source_switch = hw_have_mic_source_switch, 2191 2179 #ifdef CONFIG_PM 2192 2180 .suspend = hw_suspend, 2193 2181 .resume = hw_resume,
+240 -83
sound/pci/ctxfi/cthw20k2.c
··· 8 8 * @File cthw20k2.c 9 9 * 10 10 * @Brief 11 - * This file contains the implementation of hardware access methord for 20k2. 11 + * This file contains the implementation of hardware access method for 20k2. 12 12 * 13 13 * @Author Liu Chun 14 14 * @Date May 14 2008 ··· 38 38 unsigned char dev_id; 39 39 unsigned char addr_size; 40 40 unsigned char data_size; 41 + 42 + int mic_source; 41 43 }; 42 44 43 45 static u32 hw_read_20kx(struct hw *hw, u32 reg); ··· 1165 1163 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101); 1166 1164 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); 1167 1165 } else if (2 == info->msr) { 1168 - hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111); 1166 + if (hw->model != CTSB1270) { 1167 + hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111); 1168 + } else { 1169 + /* PCM4220 on Titanium HD is different. */ 1170 + hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111); 1171 + } 1169 1172 /* Specify all playing 96khz 1170 1173 * EA [0] - Enabled 1171 1174 * RTA [4:5] - 96kHz ··· 1182 1175 * RTD [28:29] - 96kHz */ 1183 1176 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111); 1184 1177 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); 1178 + } else if ((4 == info->msr) && (hw->model == CTSB1270)) { 1179 + hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111); 1180 + hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121); 1181 + hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); 1185 1182 } else { 1186 1183 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n"); 1187 1184 return -EINVAL; ··· 1193 1182 1194 1183 for (i = 0; i < 8; i++) { 1195 1184 if (i <= 3) { 1185 + /* This comment looks wrong since loop is over 4 */ 1186 + /* channels and emu20k2 supports 4 spdif IOs. */ 1196 1187 /* 1st 3 channels are SPDIFs (SB0960) */ 1197 1188 if (i == 3) 1198 1189 data = 0x1001001; ··· 1219 1206 1220 1207 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B); 1221 1208 } else { 1209 + /* Again, loop is over 4 channels not 5. */ 1222 1210 /* Next 5 channels are I2S (SB0960) */ 1223 1211 data = 0x11; 1224 1212 hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data); 1225 1213 if (2 == info->msr) { 1226 1214 /* Four channels per sample period */ 1227 1215 data |= 0x1000; 1216 + } else if (4 == info->msr) { 1217 + /* FIXME: check this against the chip spec */ 1218 + data |= 0x2000; 1228 1219 } 1229 1220 hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data); 1230 1221 } ··· 1574 1557 1575 1558 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status); 1576 1559 hw20k2_i2c_wait_data_ready(hw); 1577 - /* Dummy write to trigger the write oprtation */ 1560 + /* Dummy write to trigger the write operation */ 1578 1561 hw_write_20kx(hw, I2C_IF_WDATA, 0); 1579 1562 hw20k2_i2c_wait_data_ready(hw); 1580 1563 ··· 1583 1566 hw20k2_i2c_wait_data_ready(hw); 1584 1567 1585 1568 return 0; 1569 + } 1570 + 1571 + static void hw_dac_stop(struct hw *hw) 1572 + { 1573 + u32 data; 1574 + data = hw_read_20kx(hw, GPIO_DATA); 1575 + data &= 0xFFFFFFFD; 1576 + hw_write_20kx(hw, GPIO_DATA, data); 1577 + mdelay(10); 1578 + } 1579 + 1580 + static void hw_dac_start(struct hw *hw) 1581 + { 1582 + u32 data; 1583 + data = hw_read_20kx(hw, GPIO_DATA); 1584 + data |= 0x2; 1585 + hw_write_20kx(hw, GPIO_DATA, data); 1586 + mdelay(50); 1587 + } 1588 + 1589 + static void hw_dac_reset(struct hw *hw) 1590 + { 1591 + hw_dac_stop(hw); 1592 + hw_dac_start(hw); 1586 1593 } 1587 1594 1588 1595 static int hw_dac_init(struct hw *hw, const struct dac_conf *info) ··· 1635 1594 0x00000000 /* Vol Control B4 */ 1636 1595 }; 1637 1596 1597 + if (hw->model == CTSB1270) { 1598 + hw_dac_stop(hw); 1599 + data = hw_read_20kx(hw, GPIO_DATA); 1600 + data &= ~0x0600; 1601 + if (1 == info->msr) 1602 + data |= 0x0000; /* Single Speed Mode 0-50kHz */ 1603 + else if (2 == info->msr) 1604 + data |= 0x0200; /* Double Speed Mode 50-100kHz */ 1605 + else 1606 + data |= 0x0600; /* Quad Speed Mode 100-200kHz */ 1607 + hw_write_20kx(hw, GPIO_DATA, data); 1608 + hw_dac_start(hw); 1609 + return 0; 1610 + } 1611 + 1638 1612 /* Set DAC reset bit as output */ 1639 1613 data = hw_read_20kx(hw, GPIO_CTRL); 1640 1614 data |= 0x02; ··· 1662 1606 for (i = 0; i < 2; i++) { 1663 1607 /* Reset DAC twice just in-case the chip 1664 1608 * didn't initialized properly */ 1665 - data = hw_read_20kx(hw, GPIO_DATA); 1666 - /* GPIO data bit 1 */ 1667 - data &= 0xFFFFFFFD; 1668 - hw_write_20kx(hw, GPIO_DATA, data); 1669 - mdelay(10); 1670 - data |= 0x2; 1671 - hw_write_20kx(hw, GPIO_DATA, data); 1672 - mdelay(50); 1673 - 1674 - /* Reset the 2nd time */ 1675 - data &= 0xFFFFFFFD; 1676 - hw_write_20kx(hw, GPIO_DATA, data); 1677 - mdelay(10); 1678 - data |= 0x2; 1679 - hw_write_20kx(hw, GPIO_DATA, data); 1680 - mdelay(50); 1609 + hw_dac_reset(hw); 1610 + hw_dac_reset(hw); 1681 1611 1682 1612 if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1)) 1683 1613 continue; ··· 1767 1725 static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) 1768 1726 { 1769 1727 u32 data; 1770 - 1728 + if (hw->model == CTSB1270) { 1729 + /* Titanium HD has two ADC chips, one for line in and one */ 1730 + /* for MIC. We don't need to switch the ADC input. */ 1731 + return 1; 1732 + } 1771 1733 data = hw_read_20kx(hw, GPIO_DATA); 1772 1734 switch (type) { 1773 1735 case ADC_MICIN: ··· 1788 1742 1789 1743 #define MIC_BOOST_0DB 0xCF 1790 1744 #define MIC_BOOST_STEPS_PER_DB 2 1791 - #define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB) 1745 + 1746 + static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db) 1747 + { 1748 + u32 adcmc, gain; 1749 + 1750 + if (input > 3) 1751 + input = 3; 1752 + 1753 + adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */ 1754 + 1755 + hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc), 1756 + MAKE_WM8775_DATA(adcmc)); 1757 + 1758 + if (gain_in_db < -103) 1759 + gain_in_db = -103; 1760 + if (gain_in_db > 24) 1761 + gain_in_db = 24; 1762 + 1763 + gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB; 1764 + 1765 + hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain), 1766 + MAKE_WM8775_DATA(gain)); 1767 + /* ...so there should be no need for the following. */ 1768 + hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain), 1769 + MAKE_WM8775_DATA(gain)); 1770 + } 1792 1771 1793 1772 static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) 1794 1773 { 1795 1774 u32 data; 1796 - 1797 1775 data = hw_read_20kx(hw, GPIO_DATA); 1798 1776 switch (type) { 1799 1777 case ADC_MICIN: 1800 1778 data |= (0x1 << 14); 1801 1779 hw_write_20kx(hw, GPIO_DATA, data); 1802 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1803 - MAKE_WM8775_DATA(0x101)); /* Mic-in */ 1804 - hw20k2_i2c_write(hw, 1805 - MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB), 1806 - MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */ 1807 - hw20k2_i2c_write(hw, 1808 - MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB), 1809 - MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */ 1780 + hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */ 1810 1781 break; 1811 1782 case ADC_LINEIN: 1812 1783 data &= ~(0x1 << 14); 1813 1784 hw_write_20kx(hw, GPIO_DATA, data); 1814 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102), 1815 - MAKE_WM8775_DATA(0x102)); /* Line-in */ 1816 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF), 1817 - MAKE_WM8775_DATA(0xCF)); /* No boost */ 1818 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF), 1819 - MAKE_WM8775_DATA(0xCF)); /* No boost */ 1785 + hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */ 1820 1786 break; 1821 1787 default: 1822 1788 break; ··· 1840 1782 static int hw_adc_init(struct hw *hw, const struct adc_conf *info) 1841 1783 { 1842 1784 int err; 1843 - u32 mux = 2, data, ctl; 1785 + u32 data, ctl; 1844 1786 1845 1787 /* Set ADC reset bit as output */ 1846 1788 data = hw_read_20kx(hw, GPIO_CTRL); ··· 1854 1796 goto error; 1855 1797 } 1856 1798 1857 - /* Make ADC in normal operation */ 1799 + /* Reset the ADC (reset is active low). */ 1858 1800 data = hw_read_20kx(hw, GPIO_DATA); 1859 1801 data &= ~(0x1 << 15); 1802 + hw_write_20kx(hw, GPIO_DATA, data); 1803 + 1804 + if (hw->model == CTSB1270) { 1805 + /* Set up the PCM4220 ADC on Titanium HD */ 1806 + data &= ~0x0C; 1807 + if (1 == info->msr) 1808 + data |= 0x00; /* Single Speed Mode 32-50kHz */ 1809 + else if (2 == info->msr) 1810 + data |= 0x08; /* Double Speed Mode 50-108kHz */ 1811 + else 1812 + data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */ 1813 + hw_write_20kx(hw, GPIO_DATA, data); 1814 + } 1815 + 1860 1816 mdelay(10); 1817 + /* Return the ADC to normal operation. */ 1861 1818 data |= (0x1 << 15); 1862 1819 hw_write_20kx(hw, GPIO_DATA, data); 1863 1820 mdelay(50); 1864 1821 1822 + /* I2C write to register offset 0x0B to set ADC LRCLK polarity */ 1823 + /* invert bit, interface format to I2S, word length to 24-bit, */ 1824 + /* enable ADC high pass filter. Fixes bug 5323? */ 1825 + hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26), 1826 + MAKE_WM8775_DATA(0x26)); 1827 + 1865 1828 /* Set the master mode (256fs) */ 1866 1829 if (1 == info->msr) { 1830 + /* slave mode, 128x oversampling 256fs */ 1867 1831 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02), 1868 1832 MAKE_WM8775_DATA(0x02)); 1869 - } else if (2 == info->msr) { 1833 + } else if ((2 == info->msr) || (4 == info->msr)) { 1834 + /* slave mode, 64x oversampling, 256fs */ 1870 1835 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A), 1871 1836 MAKE_WM8775_DATA(0x0A)); 1872 1837 } else { ··· 1899 1818 goto error; 1900 1819 } 1901 1820 1902 - /* Configure GPIO bit 14 change to line-in/mic-in */ 1903 - ctl = hw_read_20kx(hw, GPIO_CTRL); 1904 - ctl |= 0x1 << 14; 1905 - hw_write_20kx(hw, GPIO_CTRL, ctl); 1906 - 1907 - /* Check using Mic-in or Line-in */ 1908 - data = hw_read_20kx(hw, GPIO_DATA); 1909 - 1910 - if (mux == 1) { 1911 - /* Configures GPIO data to select Mic-in */ 1912 - data |= 0x1 << 14; 1913 - hw_write_20kx(hw, GPIO_DATA, data); 1914 - 1915 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1916 - MAKE_WM8775_DATA(0x101)); /* Mic-in */ 1917 - hw20k2_i2c_write(hw, 1918 - MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB), 1919 - MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */ 1920 - hw20k2_i2c_write(hw, 1921 - MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB), 1922 - MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */ 1923 - } else if (mux == 2) { 1924 - /* Configures GPIO data to select Line-in */ 1925 - data &= ~(0x1 << 14); 1926 - hw_write_20kx(hw, GPIO_DATA, data); 1927 - 1928 - /* Setup ADC */ 1929 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102), 1930 - MAKE_WM8775_DATA(0x102)); /* Line-in */ 1931 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF), 1932 - MAKE_WM8775_DATA(0xCF)); /* No boost */ 1933 - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF), 1934 - MAKE_WM8775_DATA(0xCF)); /* No boost */ 1821 + if (hw->model != CTSB1270) { 1822 + /* Configure GPIO bit 14 change to line-in/mic-in */ 1823 + ctl = hw_read_20kx(hw, GPIO_CTRL); 1824 + ctl |= 0x1 << 14; 1825 + hw_write_20kx(hw, GPIO_CTRL, ctl); 1826 + hw_adc_input_select(hw, ADC_LINEIN); 1935 1827 } else { 1936 - printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n"); 1937 - err = -EINVAL; 1938 - goto error; 1828 + hw_wm8775_input_select(hw, 0, 0); 1939 1829 } 1940 1830 1941 1831 return 0; 1942 - 1943 1832 error: 1944 1833 hw20k2_i2c_uninit(hw); 1945 1834 return err; ··· 1918 1867 static int hw_have_digit_io_switch(struct hw *hw) 1919 1868 { 1920 1869 return 0; 1870 + } 1871 + 1872 + static int hw_have_dedicated_mic(struct hw *hw) 1873 + { 1874 + return hw->model == CTSB1270; 1875 + } 1876 + 1877 + static int hw_have_output_switch(struct hw *hw) 1878 + { 1879 + return hw->model == CTSB1270; 1880 + } 1881 + 1882 + static int hw_output_switch_get(struct hw *hw) 1883 + { 1884 + u32 data = hw_read_20kx(hw, GPIO_EXT_DATA); 1885 + 1886 + switch (data & 0x30) { 1887 + case 0x00: 1888 + return 0; 1889 + case 0x10: 1890 + return 1; 1891 + case 0x20: 1892 + return 2; 1893 + default: 1894 + return 3; 1895 + } 1896 + } 1897 + 1898 + static int hw_output_switch_put(struct hw *hw, int position) 1899 + { 1900 + u32 data; 1901 + 1902 + if (position == hw_output_switch_get(hw)) 1903 + return 0; 1904 + 1905 + /* Mute line and headphones (intended for anti-pop). */ 1906 + data = hw_read_20kx(hw, GPIO_DATA); 1907 + data |= (0x03 << 11); 1908 + hw_write_20kx(hw, GPIO_DATA, data); 1909 + 1910 + data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30; 1911 + switch (position) { 1912 + case 0: 1913 + break; 1914 + case 1: 1915 + data |= 0x10; 1916 + break; 1917 + default: 1918 + data |= 0x20; 1919 + } 1920 + hw_write_20kx(hw, GPIO_EXT_DATA, data); 1921 + 1922 + /* Unmute line and headphones. */ 1923 + data = hw_read_20kx(hw, GPIO_DATA); 1924 + data &= ~(0x03 << 11); 1925 + hw_write_20kx(hw, GPIO_DATA, data); 1926 + 1927 + return 1; 1928 + } 1929 + 1930 + static int hw_have_mic_source_switch(struct hw *hw) 1931 + { 1932 + return hw->model == CTSB1270; 1933 + } 1934 + 1935 + static int hw_mic_source_switch_get(struct hw *hw) 1936 + { 1937 + struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; 1938 + 1939 + return hw20k2->mic_source; 1940 + } 1941 + 1942 + static int hw_mic_source_switch_put(struct hw *hw, int position) 1943 + { 1944 + struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; 1945 + 1946 + if (position == hw20k2->mic_source) 1947 + return 0; 1948 + 1949 + switch (position) { 1950 + case 0: 1951 + hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */ 1952 + break; 1953 + case 1: 1954 + hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */ 1955 + break; 1956 + case 2: 1957 + hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */ 1958 + break; 1959 + default: 1960 + return 0; 1961 + } 1962 + 1963 + hw20k2->mic_source = position; 1964 + 1965 + return 1; 1921 1966 } 1922 1967 1923 1968 static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id) ··· 2170 2023 /* Reset all SRC pending interrupts */ 2171 2024 hw_write_20kx(hw, SRC_IP, 0); 2172 2025 2173 - /* TODO: detect the card ID and configure GPIO accordingly. */ 2174 - /* Configures GPIO (0xD802 0x98028) */ 2175 - /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/ 2176 - /* Configures GPIO (SB0880) */ 2177 - /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/ 2178 - hw_write_20kx(hw, GPIO_CTRL, 0xD802); 2179 - 2026 + if (hw->model != CTSB1270) { 2027 + /* TODO: detect the card ID and configure GPIO accordingly. */ 2028 + /* Configures GPIO (0xD802 0x98028) */ 2029 + /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/ 2030 + /* Configures GPIO (SB0880) */ 2031 + /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/ 2032 + hw_write_20kx(hw, GPIO_CTRL, 0xD802); 2033 + } else { 2034 + hw_write_20kx(hw, GPIO_CTRL, 0x9E5F); 2035 + } 2180 2036 /* Enable audio ring */ 2181 2037 hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01); 2182 2038 ··· 2257 2107 .is_adc_source_selected = hw_is_adc_input_selected, 2258 2108 .select_adc_source = hw_adc_input_select, 2259 2109 .have_digit_io_switch = hw_have_digit_io_switch, 2110 + .have_dedicated_mic = hw_have_dedicated_mic, 2111 + .have_output_switch = hw_have_output_switch, 2112 + .output_switch_get = hw_output_switch_get, 2113 + .output_switch_put = hw_output_switch_put, 2114 + .have_mic_source_switch = hw_have_mic_source_switch, 2115 + .mic_source_switch_get = hw_mic_source_switch_get, 2116 + .mic_source_switch_put = hw_mic_source_switch_put, 2260 2117 #ifdef CONFIG_PM 2261 2118 .suspend = hw_suspend, 2262 2119 .resume = hw_resume,
+110 -31
sound/pci/ctxfi/ctmixer.c
··· 86 86 MIXER_LINEIN_C_S, 87 87 MIXER_MIC_C_S, 88 88 MIXER_SPDIFI_C_S, 89 - MIXER_LINEIN_P_S, 90 89 MIXER_SPDIFO_P_S, 91 - MIXER_SPDIFI_P_S, 92 90 MIXER_WAVEF_P_S, 93 91 MIXER_WAVER_P_S, 94 92 MIXER_WAVEC_P_S, ··· 135 137 }, 136 138 [MIXER_LINEIN_P] = { 137 139 .ctl = 1, 138 - .name = "Line-in Playback Volume", 140 + .name = "Line Playback Volume", 139 141 }, 140 142 [MIXER_LINEIN_C] = { 141 143 .ctl = 1, 142 - .name = "Line-in Capture Volume", 144 + .name = "Line Capture Volume", 143 145 }, 144 146 [MIXER_MIC_P] = { 145 147 .ctl = 1, ··· 151 153 }, 152 154 [MIXER_SPDIFI_P] = { 153 155 .ctl = 1, 154 - .name = "S/PDIF-in Playback Volume", 156 + .name = "IEC958 Playback Volume", 155 157 }, 156 158 [MIXER_SPDIFI_C] = { 157 159 .ctl = 1, 158 - .name = "S/PDIF-in Capture Volume", 160 + .name = "IEC958 Capture Volume", 159 161 }, 160 162 [MIXER_SPDIFO_P] = { 161 163 .ctl = 1, 162 - .name = "S/PDIF-out Playback Volume", 164 + .name = "Digital Playback Volume", 163 165 }, 164 166 [MIXER_WAVEF_P] = { 165 167 .ctl = 1, ··· 177 179 .ctl = 1, 178 180 .name = "Surround Playback Volume", 179 181 }, 180 - 181 182 [MIXER_PCM_C_S] = { 182 183 .ctl = 1, 183 184 .name = "PCM Capture Switch", 184 185 }, 185 186 [MIXER_LINEIN_C_S] = { 186 187 .ctl = 1, 187 - .name = "Line-in Capture Switch", 188 + .name = "Line Capture Switch", 188 189 }, 189 190 [MIXER_MIC_C_S] = { 190 191 .ctl = 1, ··· 191 194 }, 192 195 [MIXER_SPDIFI_C_S] = { 193 196 .ctl = 1, 194 - .name = "S/PDIF-in Capture Switch", 195 - }, 196 - [MIXER_LINEIN_P_S] = { 197 - .ctl = 1, 198 - .name = "Line-in Playback Switch", 197 + .name = "IEC958 Capture Switch", 199 198 }, 200 199 [MIXER_SPDIFO_P_S] = { 201 200 .ctl = 1, 202 - .name = "S/PDIF-out Playback Switch", 203 - }, 204 - [MIXER_SPDIFI_P_S] = { 205 - .ctl = 1, 206 - .name = "S/PDIF-in Playback Switch", 201 + .name = "Digital Playback Switch", 207 202 }, 208 203 [MIXER_WAVEF_P_S] = { 209 204 .ctl = 1, ··· 225 236 static void 226 237 ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type); 227 238 239 + /* FIXME: this static looks like it would fail if more than one card was */ 240 + /* installed. */ 228 241 static struct snd_kcontrol *kctls[2] = {NULL}; 229 242 230 243 static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index) ··· 411 420 .tlv = { .p = ct_vol_db_scale }, 412 421 }; 413 422 423 + static int output_switch_info(struct snd_kcontrol *kcontrol, 424 + struct snd_ctl_elem_info *info) 425 + { 426 + static const char *const names[3] = { 427 + "FP Headphones", "Headphones", "Speakers" 428 + }; 429 + 430 + return snd_ctl_enum_info(info, 1, 3, names); 431 + } 432 + 433 + static int output_switch_get(struct snd_kcontrol *kcontrol, 434 + struct snd_ctl_elem_value *ucontrol) 435 + { 436 + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); 437 + ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc); 438 + return 0; 439 + } 440 + 441 + static int output_switch_put(struct snd_kcontrol *kcontrol, 442 + struct snd_ctl_elem_value *ucontrol) 443 + { 444 + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); 445 + if (ucontrol->value.enumerated.item[0] > 2) 446 + return -EINVAL; 447 + return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]); 448 + } 449 + 450 + static struct snd_kcontrol_new output_ctl = { 451 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 452 + .name = "Analog Output Playback Enum", 453 + .info = output_switch_info, 454 + .get = output_switch_get, 455 + .put = output_switch_put, 456 + }; 457 + 458 + static int mic_source_switch_info(struct snd_kcontrol *kcontrol, 459 + struct snd_ctl_elem_info *info) 460 + { 461 + static const char *const names[3] = { 462 + "Mic", "FP Mic", "Aux" 463 + }; 464 + 465 + return snd_ctl_enum_info(info, 1, 3, names); 466 + } 467 + 468 + static int mic_source_switch_get(struct snd_kcontrol *kcontrol, 469 + struct snd_ctl_elem_value *ucontrol) 470 + { 471 + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); 472 + ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc); 473 + return 0; 474 + } 475 + 476 + static int mic_source_switch_put(struct snd_kcontrol *kcontrol, 477 + struct snd_ctl_elem_value *ucontrol) 478 + { 479 + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); 480 + if (ucontrol->value.enumerated.item[0] > 2) 481 + return -EINVAL; 482 + return atc->mic_source_switch_put(atc, 483 + ucontrol->value.enumerated.item[0]); 484 + } 485 + 486 + static struct snd_kcontrol_new mic_source_ctl = { 487 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 488 + .name = "Mic Source Capture Enum", 489 + .info = mic_source_switch_info, 490 + .get = mic_source_switch_get, 491 + .put = mic_source_switch_put, 492 + }; 493 + 414 494 static void 415 495 do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type) 416 496 { ··· 527 465 static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state) 528 466 { 529 467 struct ct_mixer *mixer = atc->mixer; 468 + int have_dedicated_mic = atc->have_dedicated_mic(atc); 530 469 531 470 /* Do changes in mixer. */ 532 471 if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) { ··· 540 477 } 541 478 } 542 479 /* Do changes out of mixer. */ 543 - if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) 544 - do_line_mic_switch(atc, type); 480 + if (!have_dedicated_mic && 481 + (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) { 482 + if (state) 483 + do_line_mic_switch(atc, type); 484 + atc->line_in_unmute(atc, state); 485 + } else if (have_dedicated_mic && (MIXER_LINEIN_C_S == type)) 486 + atc->line_in_unmute(atc, state); 487 + else if (have_dedicated_mic && (MIXER_MIC_C_S == type)) 488 + atc->mic_unmute(atc, state); 489 + else if (MIXER_SPDIFI_C_S == type) 490 + atc->spdif_in_unmute(atc, state); 545 491 else if (MIXER_WAVEF_P_S == type) 546 492 atc->line_front_unmute(atc, state); 547 493 else if (MIXER_WAVES_P_S == type) ··· 559 487 atc->line_clfe_unmute(atc, state); 560 488 else if (MIXER_WAVER_P_S == type) 561 489 atc->line_rear_unmute(atc, state); 562 - else if (MIXER_LINEIN_P_S == type) 563 - atc->line_in_unmute(atc, state); 564 490 else if (MIXER_SPDIFO_P_S == type) 565 491 atc->spdif_out_unmute(atc, state); 566 - else if (MIXER_SPDIFI_P_S == type) 567 - atc->spdif_in_unmute(atc, state); 568 492 else if (MIXER_DIGITAL_IO_S == type) 569 493 do_digit_io_switch(atc, state); 570 494 ··· 754 686 755 687 ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = 756 688 atc->have_digit_io_switch(atc); 689 + 757 690 for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) { 758 691 if (ct_kcontrol_init_table[type].ctl) { 759 692 swh_ctl.name = ct_kcontrol_init_table[type].name; ··· 777 708 if (err) 778 709 return err; 779 710 711 + if (atc->have_output_switch(atc)) { 712 + err = ct_mixer_kcontrol_new(mixer, &output_ctl); 713 + if (err) 714 + return err; 715 + } 716 + 717 + if (atc->have_mic_source_switch(atc)) { 718 + err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl); 719 + if (err) 720 + return err; 721 + } 780 722 atc->line_front_unmute(atc, 1); 781 723 set_switch_state(mixer, MIXER_WAVEF_P_S, 1); 782 724 atc->line_surround_unmute(atc, 0); ··· 799 719 atc->spdif_out_unmute(atc, 0); 800 720 set_switch_state(mixer, MIXER_SPDIFO_P_S, 0); 801 721 atc->line_in_unmute(atc, 0); 802 - set_switch_state(mixer, MIXER_LINEIN_P_S, 0); 722 + if (atc->have_dedicated_mic(atc)) 723 + atc->mic_unmute(atc, 0); 803 724 atc->spdif_in_unmute(atc, 0); 804 - set_switch_state(mixer, MIXER_SPDIFI_P_S, 0); 805 - 806 - set_switch_state(mixer, MIXER_PCM_C_S, 1); 807 - set_switch_state(mixer, MIXER_LINEIN_C_S, 1); 808 - set_switch_state(mixer, MIXER_SPDIFI_C_S, 1); 725 + set_switch_state(mixer, MIXER_PCM_C_S, 0); 726 + set_switch_state(mixer, MIXER_LINEIN_C_S, 0); 727 + set_switch_state(mixer, MIXER_SPDIFI_C_S, 0); 809 728 810 729 return 0; 811 730 }
+2 -2
sound/pci/ctxfi/xfi.c
··· 80 80 "are 48000 and 44100, Value 48000 is assumed.\n"); 81 81 reference_rate = 48000; 82 82 } 83 - if ((multiple != 1) && (multiple != 2)) { 83 + if ((multiple != 1) && (multiple != 2) && (multiple != 4)) { 84 84 printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n", 85 85 multiple); 86 86 printk(KERN_ERR "ctxfi: The valid values for multiple are " 87 - "1 and 2, Value 2 is assumed.\n"); 87 + "1, 2 and 4, Value 2 is assumed.\n"); 88 88 multiple = 2; 89 89 } 90 90 err = ct_atc_create(card, pci, reference_rate, multiple,