diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/Kconfig | 17 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0_mixer.c | 2 | ||||
-rw-r--r-- | sound/pci/ca0106/ca0106.h | 5 | ||||
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 136 | ||||
-rw-r--r-- | sound/pci/ca0106/ca0106_mixer.c | 93 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumpu401.c | 2 | ||||
-rw-r--r-- | sound/pci/ice1712/delta.c | 10 | ||||
-rw-r--r-- | sound/pci/ice1712/delta.h | 4 | ||||
-rw-r--r-- | sound/pci/ice1712/pontis.c | 6 | ||||
-rw-r--r-- | sound/pci/ice1712/prodigy192.c | 2 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 4 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen.h | 1 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 55 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 5 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_pcm.c | 12 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_regs.h | 10 | ||||
-rw-r--r-- | sound/pci/oxygen/virtuoso.c | 5 | ||||
-rw-r--r-- | sound/pci/oxygen/xonar_cs43xx.c | 8 | ||||
-rw-r--r-- | sound/pci/oxygen/xonar_pcm179x.c | 29 | ||||
-rw-r--r-- | sound/pci/oxygen/xonar_wm87x6.c | 121 | ||||
-rw-r--r-- | sound/pci/rme96.c | 8 | ||||
-rw-r--r-- | sound/pci/rme9652/hdsp.c | 8 |
22 files changed, 377 insertions, 166 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index e7a8cd058efb..12e34653b8a8 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -207,12 +207,12 @@ config SND_CMIPCI | |||
207 | 207 | ||
208 | config SND_OXYGEN_LIB | 208 | config SND_OXYGEN_LIB |
209 | tristate | 209 | tristate |
210 | select SND_PCM | ||
211 | select SND_MPU401_UART | ||
212 | 210 | ||
213 | config SND_OXYGEN | 211 | config SND_OXYGEN |
214 | tristate "C-Media 8788 (Oxygen)" | 212 | tristate "C-Media 8788 (Oxygen)" |
215 | select SND_OXYGEN_LIB | 213 | select SND_OXYGEN_LIB |
214 | select SND_PCM | ||
215 | select SND_MPU401_UART | ||
216 | help | 216 | help |
217 | Say Y here to include support for sound cards based on the | 217 | Say Y here to include support for sound cards based on the |
218 | C-Media CMI8788 (Oxygen HD Audio) chip: | 218 | C-Media CMI8788 (Oxygen HD Audio) chip: |
@@ -581,6 +581,8 @@ config SND_HDSPM | |||
581 | config SND_HIFIER | 581 | config SND_HIFIER |
582 | tristate "TempoTec HiFier Fantasia" | 582 | tristate "TempoTec HiFier Fantasia" |
583 | select SND_OXYGEN_LIB | 583 | select SND_OXYGEN_LIB |
584 | select SND_PCM | ||
585 | select SND_MPU401_UART | ||
584 | help | 586 | help |
585 | Say Y here to include support for the MediaTek/TempoTec HiFier | 587 | Say Y here to include support for the MediaTek/TempoTec HiFier |
586 | Fantasia sound card. | 588 | Fantasia sound card. |
@@ -815,14 +817,17 @@ config SND_VIA82XX_MODEM | |||
815 | will be called snd-via82xx-modem. | 817 | will be called snd-via82xx-modem. |
816 | 818 | ||
817 | config SND_VIRTUOSO | 819 | config SND_VIRTUOSO |
818 | tristate "Asus Virtuoso 100/200 (Xonar)" | 820 | tristate "Asus Virtuoso 66/100/200 (Xonar)" |
819 | select SND_OXYGEN_LIB | 821 | select SND_OXYGEN_LIB |
822 | select SND_PCM | ||
823 | select SND_MPU401_UART | ||
824 | select SND_JACK if INPUT=y || INPUT=SND | ||
820 | help | 825 | help |
821 | Say Y here to include support for sound cards based on the | 826 | Say Y here to include support for sound cards based on the |
822 | Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, | 827 | Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, |
823 | Essence ST (Deluxe), and Essence STX. | 828 | Essence ST (Deluxe), and Essence STX. |
824 | Support for the DS is experimental. | 829 | Support for the HDAV1.3 (Deluxe) is incomplete; for the |
825 | Support for the HDAV1.3 (Deluxe) is very experimental. | 830 | HDAV1.3 Slim and Xense, missing. |
826 | 831 | ||
827 | To compile this driver as a module, choose M here: the module | 832 | To compile this driver as a module, choose M here: the module |
828 | will be called snd-virtuoso. | 833 | will be called snd-virtuoso. |
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c index c92f493d341e..557c782ae4fc 100644 --- a/sound/pci/au88x0/au88x0_mixer.c +++ b/sound/pci/au88x0/au88x0_mixer.c | |||
@@ -23,7 +23,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex) | |||
23 | if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0) | 23 | if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0) |
24 | return err; | 24 | return err; |
25 | memset(&ac97, 0, sizeof(ac97)); | 25 | memset(&ac97, 0, sizeof(ac97)); |
26 | // Intialize AC97 codec stuff. | 26 | // Initialize AC97 codec stuff. |
27 | ac97.private_data = vortex; | 27 | ac97.private_data = vortex; |
28 | ac97.scaps = AC97_SCAP_NO_SPDIF; | 28 | ac97.scaps = AC97_SCAP_NO_SPDIF; |
29 | err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); | 29 | err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); |
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index 14b8d9a91aae..f19c11077255 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h | |||
@@ -670,8 +670,9 @@ struct snd_ca0106_details { | |||
670 | gpio_type = 2 -> shared side-out/line-in. */ | 670 | gpio_type = 2 -> shared side-out/line-in. */ |
671 | int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume | 671 | int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume |
672 | controls, phone, mic, line-in and aux. */ | 672 | controls, phone, mic, line-in and aux. */ |
673 | int spi_dac; /* spi_dac=1 adds the mute switch for each analog | 673 | u16 spi_dac; /* spi_dac = 0 -> no spi interface for DACs |
674 | output, front, rear, etc. */ | 674 | spi_dac = 0x<front><rear><center-lfe><side> |
675 | -> specifies DAC id for each channel pair. */ | ||
675 | }; | 676 | }; |
676 | 677 | ||
677 | // definition of the chip-specific record | 678 | // definition of the chip-specific record |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 0a3d3d6e77b4..d2d12c08f937 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -227,7 +227,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = { | |||
227 | .name = "Audigy SE [SB0570]", | 227 | .name = "Audigy SE [SB0570]", |
228 | .gpio_type = 1, | 228 | .gpio_type = 1, |
229 | .i2c_adc = 1, | 229 | .i2c_adc = 1, |
230 | .spi_dac = 1 } , | 230 | .spi_dac = 0x4021 } , |
231 | /* New Audigy LS. Has a different DAC. */ | 231 | /* New Audigy LS. Has a different DAC. */ |
232 | /* SB0570: | 232 | /* SB0570: |
233 | * CTRL:CA0106-DAT | 233 | * CTRL:CA0106-DAT |
@@ -238,7 +238,17 @@ static struct snd_ca0106_details ca0106_chip_details[] = { | |||
238 | .name = "Audigy SE OEM [SB0570a]", | 238 | .name = "Audigy SE OEM [SB0570a]", |
239 | .gpio_type = 1, | 239 | .gpio_type = 1, |
240 | .i2c_adc = 1, | 240 | .i2c_adc = 1, |
241 | .spi_dac = 1 } , | 241 | .spi_dac = 0x4021 } , |
242 | /* Sound Blaster 5.1vx | ||
243 | * Tested: Playback on front, rear, center/lfe speakers | ||
244 | * Not-Tested: Capture | ||
245 | */ | ||
246 | { .serial = 0x10041102, | ||
247 | .name = "Sound Blaster 5.1vx [SB1070]", | ||
248 | .gpio_type = 1, | ||
249 | .i2c_adc = 0, | ||
250 | .spi_dac = 0x0124 | ||
251 | } , | ||
242 | /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ | 252 | /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ |
243 | /* SB0438 | 253 | /* SB0438 |
244 | * CTRL:CA0106-DAT | 254 | * CTRL:CA0106-DAT |
@@ -254,7 +264,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = { | |||
254 | .name = "MSI K8N Diamond MB", | 264 | .name = "MSI K8N Diamond MB", |
255 | .gpio_type = 2, | 265 | .gpio_type = 2, |
256 | .i2c_adc = 1, | 266 | .i2c_adc = 1, |
257 | .spi_dac = 1 } , | 267 | .spi_dac = 0x4021 } , |
258 | /* Giga-byte GA-G1975X mobo | 268 | /* Giga-byte GA-G1975X mobo |
259 | * Novell bnc#395807 | 269 | * Novell bnc#395807 |
260 | */ | 270 | */ |
@@ -483,16 +493,18 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime) | |||
483 | } | 493 | } |
484 | 494 | ||
485 | static const int spi_dacd_reg[] = { | 495 | static const int spi_dacd_reg[] = { |
486 | [PCM_FRONT_CHANNEL] = SPI_DACD4_REG, | 496 | SPI_DACD0_REG, |
487 | [PCM_REAR_CHANNEL] = SPI_DACD0_REG, | 497 | SPI_DACD1_REG, |
488 | [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG, | 498 | SPI_DACD2_REG, |
489 | [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, | 499 | 0, |
500 | SPI_DACD4_REG, | ||
490 | }; | 501 | }; |
491 | static const int spi_dacd_bit[] = { | 502 | static const int spi_dacd_bit[] = { |
492 | [PCM_FRONT_CHANNEL] = SPI_DACD4_BIT, | 503 | SPI_DACD0_BIT, |
493 | [PCM_REAR_CHANNEL] = SPI_DACD0_BIT, | 504 | SPI_DACD1_BIT, |
494 | [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_BIT, | 505 | SPI_DACD2_BIT, |
495 | [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, | 506 | 0, |
507 | SPI_DACD4_BIT, | ||
496 | }; | 508 | }; |
497 | 509 | ||
498 | static void restore_spdif_bits(struct snd_ca0106 *chip, int idx) | 510 | static void restore_spdif_bits(struct snd_ca0106 *chip, int idx) |
@@ -504,6 +516,45 @@ static void restore_spdif_bits(struct snd_ca0106 *chip, int idx) | |||
504 | } | 516 | } |
505 | } | 517 | } |
506 | 518 | ||
519 | static int snd_ca0106_channel_dac(struct snd_ca0106_details *details, | ||
520 | int channel_id) | ||
521 | { | ||
522 | switch (channel_id) { | ||
523 | case PCM_FRONT_CHANNEL: | ||
524 | return (details->spi_dac & 0xf000) >> (4 * 3); | ||
525 | case PCM_REAR_CHANNEL: | ||
526 | return (details->spi_dac & 0x0f00) >> (4 * 2); | ||
527 | case PCM_CENTER_LFE_CHANNEL: | ||
528 | return (details->spi_dac & 0x00f0) >> (4 * 1); | ||
529 | case PCM_UNKNOWN_CHANNEL: | ||
530 | return (details->spi_dac & 0x000f) >> (4 * 0); | ||
531 | default: | ||
532 | snd_printk(KERN_DEBUG "ca0106: unknown channel_id %d\n", | ||
533 | channel_id); | ||
534 | } | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int snd_ca0106_pcm_power_dac(struct snd_ca0106 *chip, int channel_id, | ||
539 | int power) | ||
540 | { | ||
541 | if (chip->details->spi_dac) { | ||
542 | const int dac = snd_ca0106_channel_dac(chip->details, | ||
543 | channel_id); | ||
544 | const int reg = spi_dacd_reg[dac]; | ||
545 | const int bit = spi_dacd_bit[dac]; | ||
546 | |||
547 | if (power) | ||
548 | /* Power up */ | ||
549 | chip->spi_dac_reg[reg] &= ~bit; | ||
550 | else | ||
551 | /* Power down */ | ||
552 | chip->spi_dac_reg[reg] |= bit; | ||
553 | return snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); | ||
554 | } | ||
555 | return 0; | ||
556 | } | ||
557 | |||
507 | /* open_playback callback */ | 558 | /* open_playback callback */ |
508 | static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, | 559 | static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, |
509 | int channel_id) | 560 | int channel_id) |
@@ -543,12 +594,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr | |||
543 | return err; | 594 | return err; |
544 | snd_pcm_set_sync(substream); | 595 | snd_pcm_set_sync(substream); |
545 | 596 | ||
546 | if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { | 597 | /* Front channel dac should already be on */ |
547 | const int reg = spi_dacd_reg[channel_id]; | 598 | if (channel_id != PCM_FRONT_CHANNEL) { |
548 | 599 | err = snd_ca0106_pcm_power_dac(chip, channel_id, 1); | |
549 | /* Power up dac */ | ||
550 | chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id]; | ||
551 | err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); | ||
552 | if (err < 0) | 600 | if (err < 0) |
553 | return err; | 601 | return err; |
554 | } | 602 | } |
@@ -568,13 +616,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream) | |||
568 | 616 | ||
569 | restore_spdif_bits(chip, epcm->channel_id); | 617 | restore_spdif_bits(chip, epcm->channel_id); |
570 | 618 | ||
571 | if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { | 619 | /* Front channel dac should stay on */ |
572 | const int reg = spi_dacd_reg[epcm->channel_id]; | 620 | if (epcm->channel_id != PCM_FRONT_CHANNEL) { |
573 | 621 | int err; | |
574 | /* Power down DAC */ | 622 | err = snd_ca0106_pcm_power_dac(chip, epcm->channel_id, 0); |
575 | chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id]; | 623 | if (err < 0) |
576 | snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); | 624 | return err; |
577 | } | 625 | } |
626 | |||
578 | /* FIXME: maybe zero others */ | 627 | /* FIXME: maybe zero others */ |
579 | return 0; | 628 | return 0; |
580 | } | 629 | } |
@@ -1002,29 +1051,27 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream) | |||
1002 | struct snd_ca0106 *emu = snd_pcm_substream_chip(substream); | 1051 | struct snd_ca0106 *emu = snd_pcm_substream_chip(substream); |
1003 | struct snd_pcm_runtime *runtime = substream->runtime; | 1052 | struct snd_pcm_runtime *runtime = substream->runtime; |
1004 | struct snd_ca0106_pcm *epcm = runtime->private_data; | 1053 | struct snd_ca0106_pcm *epcm = runtime->private_data; |
1005 | snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; | 1054 | unsigned int ptr, prev_ptr; |
1006 | int channel = epcm->channel_id; | 1055 | int channel = epcm->channel_id; |
1056 | int timeout = 10; | ||
1007 | 1057 | ||
1008 | if (!epcm->running) | 1058 | if (!epcm->running) |
1009 | return 0; | 1059 | return 0; |
1010 | 1060 | ||
1011 | ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); | 1061 | prev_ptr = -1; |
1012 | ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); | 1062 | do { |
1013 | ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); | 1063 | ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); |
1014 | if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); | 1064 | ptr = (ptr >> 3) * runtime->period_size; |
1015 | ptr2 = bytes_to_frames(runtime, ptr1); | 1065 | ptr += bytes_to_frames(runtime, |
1016 | ptr2+= (ptr4 >> 3) * runtime->period_size; | 1066 | snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel)); |
1017 | ptr=ptr2; | 1067 | if (ptr >= runtime->buffer_size) |
1018 | if (ptr >= runtime->buffer_size) | 1068 | ptr -= runtime->buffer_size; |
1019 | ptr -= runtime->buffer_size; | 1069 | if (prev_ptr == ptr) |
1020 | /* | 1070 | return ptr; |
1021 | printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " | 1071 | prev_ptr = ptr; |
1022 | "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", | 1072 | } while (--timeout); |
1023 | ptr1, ptr2, ptr, (int)runtime->buffer_size, | 1073 | snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n"); |
1024 | (int)runtime->period_size, (int)runtime->frame_bits, | 1074 | return 0; |
1025 | (int)runtime->rate); | ||
1026 | */ | ||
1027 | return ptr; | ||
1028 | } | 1075 | } |
1029 | 1076 | ||
1030 | /* pointer_capture callback */ | 1077 | /* pointer_capture callback */ |
@@ -1362,7 +1409,7 @@ static unsigned int spi_dac_init[] = { | |||
1362 | SPI_REG(12, 0x00), | 1409 | SPI_REG(12, 0x00), |
1363 | SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), | 1410 | SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), |
1364 | SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), | 1411 | SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), |
1365 | SPI_REG(SPI_DACD4_REG, 0x00), | 1412 | SPI_REG(SPI_DACD4_REG, SPI_DACD4_BIT), |
1366 | }; | 1413 | }; |
1367 | 1414 | ||
1368 | static unsigned int i2c_adc_init[][2] = { | 1415 | static unsigned int i2c_adc_init[][2] = { |
@@ -1541,7 +1588,7 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume) | |||
1541 | /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */ | 1588 | /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */ |
1542 | } | 1589 | } |
1543 | 1590 | ||
1544 | if (chip->details->spi_dac == 1) { | 1591 | if (chip->details->spi_dac) { |
1545 | /* The SB0570 use SPI to control DAC. */ | 1592 | /* The SB0570 use SPI to control DAC. */ |
1546 | int size, n; | 1593 | int size, n; |
1547 | 1594 | ||
@@ -1553,6 +1600,9 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume) | |||
1553 | if (reg < ARRAY_SIZE(chip->spi_dac_reg)) | 1600 | if (reg < ARRAY_SIZE(chip->spi_dac_reg)) |
1554 | chip->spi_dac_reg[reg] = spi_dac_init[n]; | 1601 | chip->spi_dac_reg[reg] = spi_dac_init[n]; |
1555 | } | 1602 | } |
1603 | |||
1604 | /* Enable front dac only */ | ||
1605 | snd_ca0106_pcm_power_dac(chip, PCM_FRONT_CHANNEL, 1); | ||
1556 | } | 1606 | } |
1557 | } | 1607 | } |
1558 | 1608 | ||
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 85fd315d9999..630aa4998189 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
@@ -676,28 +676,65 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = | |||
676 | I2C_VOLUME("Aux Capture Volume", 3), | 676 | I2C_VOLUME("Aux Capture Volume", 3), |
677 | }; | 677 | }; |
678 | 678 | ||
679 | #define SPI_SWITCH(xname,reg,bit) \ | 679 | static const int spi_dmute_reg[] = { |
680 | { \ | 680 | SPI_DMUTE0_REG, |
681 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 681 | SPI_DMUTE1_REG, |
682 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | 682 | SPI_DMUTE2_REG, |
683 | .info = spi_mute_info, \ | 683 | 0, |
684 | .get = spi_mute_get, \ | 684 | SPI_DMUTE4_REG, |
685 | .put = spi_mute_put, \ | 685 | }; |
686 | .private_value = (reg<<SPI_REG_SHIFT) | (bit) \ | 686 | static const int spi_dmute_bit[] = { |
687 | } | 687 | SPI_DMUTE0_BIT, |
688 | 688 | SPI_DMUTE1_BIT, | |
689 | static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[] | 689 | SPI_DMUTE2_BIT, |
690 | __devinitdata = { | 690 | 0, |
691 | SPI_SWITCH("Analog Front Playback Switch", | 691 | SPI_DMUTE4_BIT, |
692 | SPI_DMUTE4_REG, SPI_DMUTE4_BIT), | ||
693 | SPI_SWITCH("Analog Rear Playback Switch", | ||
694 | SPI_DMUTE0_REG, SPI_DMUTE0_BIT), | ||
695 | SPI_SWITCH("Analog Center/LFE Playback Switch", | ||
696 | SPI_DMUTE2_REG, SPI_DMUTE2_BIT), | ||
697 | SPI_SWITCH("Analog Side Playback Switch", | ||
698 | SPI_DMUTE1_REG, SPI_DMUTE1_BIT), | ||
699 | }; | 692 | }; |
700 | 693 | ||
694 | static struct snd_kcontrol_new __devinit | ||
695 | snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details, | ||
696 | int channel_id) | ||
697 | { | ||
698 | struct snd_kcontrol_new spi_switch = {0}; | ||
699 | int reg, bit; | ||
700 | int dac_id; | ||
701 | |||
702 | spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
703 | spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | ||
704 | spi_switch.info = spi_mute_info; | ||
705 | spi_switch.get = spi_mute_get; | ||
706 | spi_switch.put = spi_mute_put; | ||
707 | |||
708 | switch (channel_id) { | ||
709 | case PCM_FRONT_CHANNEL: | ||
710 | spi_switch.name = "Analog Front Playback Switch"; | ||
711 | dac_id = (details->spi_dac & 0xf000) >> (4 * 3); | ||
712 | break; | ||
713 | case PCM_REAR_CHANNEL: | ||
714 | spi_switch.name = "Analog Rear Playback Switch"; | ||
715 | dac_id = (details->spi_dac & 0x0f00) >> (4 * 2); | ||
716 | break; | ||
717 | case PCM_CENTER_LFE_CHANNEL: | ||
718 | spi_switch.name = "Analog Center/LFE Playback Switch"; | ||
719 | dac_id = (details->spi_dac & 0x00f0) >> (4 * 1); | ||
720 | break; | ||
721 | case PCM_UNKNOWN_CHANNEL: | ||
722 | spi_switch.name = "Analog Side Playback Switch"; | ||
723 | dac_id = (details->spi_dac & 0x000f) >> (4 * 0); | ||
724 | break; | ||
725 | default: | ||
726 | /* Unused channel */ | ||
727 | spi_switch.name = NULL; | ||
728 | dac_id = 0; | ||
729 | } | ||
730 | reg = spi_dmute_reg[dac_id]; | ||
731 | bit = spi_dmute_bit[dac_id]; | ||
732 | |||
733 | spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit; | ||
734 | |||
735 | return spi_switch; | ||
736 | } | ||
737 | |||
701 | static int __devinit remove_ctl(struct snd_card *card, const char *name) | 738 | static int __devinit remove_ctl(struct snd_card *card, const char *name) |
702 | { | 739 | { |
703 | struct snd_ctl_elem_id id; | 740 | struct snd_ctl_elem_id id; |
@@ -832,8 +869,18 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) | |||
832 | if (err < 0) | 869 | if (err < 0) |
833 | return err; | 870 | return err; |
834 | } | 871 | } |
835 | if (emu->details->spi_dac == 1) | 872 | if (emu->details->spi_dac) { |
836 | ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls); | 873 | int i; |
874 | for (i = 0;; i++) { | ||
875 | struct snd_kcontrol_new ctl; | ||
876 | ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i); | ||
877 | if (!ctl.name) | ||
878 | break; | ||
879 | err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu)); | ||
880 | if (err < 0) | ||
881 | return err; | ||
882 | } | ||
883 | } | ||
837 | 884 | ||
838 | /* Create virtual master controls */ | 885 | /* Create virtual master controls */ |
839 | vmaster = snd_ctl_make_virtual_master("Master Playback Volume", | 886 | vmaster = snd_ctl_make_virtual_master("Master Playback Volume", |
@@ -845,7 +892,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) | |||
845 | return err; | 892 | return err; |
846 | add_slaves(card, vmaster, slave_vols); | 893 | add_slaves(card, vmaster, slave_vols); |
847 | 894 | ||
848 | if (emu->details->spi_dac == 1) { | 895 | if (emu->details->spi_dac) { |
849 | vmaster = snd_ctl_make_virtual_master("Master Playback Switch", | 896 | vmaster = snd_ctl_make_virtual_master("Master Playback Switch", |
850 | NULL); | 897 | NULL); |
851 | if (!vmaster) | 898 | if (!vmaster) |
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c index 8578c70c61f2..bab564824efe 100644 --- a/sound/pci/emu10k1/emumpu401.c +++ b/sound/pci/emu10k1/emumpu401.c | |||
@@ -321,7 +321,7 @@ static struct snd_rawmidi_ops snd_emu10k1_midi_input = | |||
321 | 321 | ||
322 | static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi) | 322 | static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi) |
323 | { | 323 | { |
324 | struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)rmidi->private_data; | 324 | struct snd_emu10k1_midi *midi = rmidi->private_data; |
325 | midi->interrupt = NULL; | 325 | midi->interrupt = NULL; |
326 | midi->rmidi = NULL; | 326 | midi->rmidi = NULL; |
327 | } | 327 | } |
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index d216362626d0..712c1710f9a2 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c | |||
@@ -563,6 +563,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) | |||
563 | case ICE1712_SUBDEVICE_DELTA1010E: | 563 | case ICE1712_SUBDEVICE_DELTA1010E: |
564 | case ICE1712_SUBDEVICE_DELTA1010LT: | 564 | case ICE1712_SUBDEVICE_DELTA1010LT: |
565 | case ICE1712_SUBDEVICE_MEDIASTATION: | 565 | case ICE1712_SUBDEVICE_MEDIASTATION: |
566 | case ICE1712_SUBDEVICE_EDIROLDA2496: | ||
566 | ice->num_total_dacs = 8; | 567 | ice->num_total_dacs = 8; |
567 | ice->num_total_adcs = 8; | 568 | ice->num_total_adcs = 8; |
568 | break; | 569 | break; |
@@ -635,6 +636,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) | |||
635 | err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice); | 636 | err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice); |
636 | break; | 637 | break; |
637 | case ICE1712_SUBDEVICE_DELTA1010LT: | 638 | case ICE1712_SUBDEVICE_DELTA1010LT: |
639 | case ICE1712_SUBDEVICE_EDIROLDA2496: | ||
638 | err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice); | 640 | err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice); |
639 | break; | 641 | break; |
640 | case ICE1712_SUBDEVICE_DELTA66: | 642 | case ICE1712_SUBDEVICE_DELTA66: |
@@ -734,6 +736,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) | |||
734 | case ICE1712_SUBDEVICE_DELTA66: | 736 | case ICE1712_SUBDEVICE_DELTA66: |
735 | case ICE1712_SUBDEVICE_VX442: | 737 | case ICE1712_SUBDEVICE_VX442: |
736 | case ICE1712_SUBDEVICE_DELTA66E: | 738 | case ICE1712_SUBDEVICE_DELTA66E: |
739 | case ICE1712_SUBDEVICE_EDIROLDA2496: | ||
737 | err = snd_ice1712_akm4xxx_build_controls(ice); | 740 | err = snd_ice1712_akm4xxx_build_controls(ice); |
738 | if (err < 0) | 741 | if (err < 0) |
739 | return err; | 742 | return err; |
@@ -813,5 +816,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { | |||
813 | .chip_init = snd_ice1712_delta_init, | 816 | .chip_init = snd_ice1712_delta_init, |
814 | .build_controls = snd_ice1712_delta_add_controls, | 817 | .build_controls = snd_ice1712_delta_add_controls, |
815 | }, | 818 | }, |
819 | { | ||
820 | .subvendor = ICE1712_SUBDEVICE_EDIROLDA2496, | ||
821 | .name = "Edirol DA2496", | ||
822 | .model = "da2496", | ||
823 | .chip_init = snd_ice1712_delta_init, | ||
824 | .build_controls = snd_ice1712_delta_add_controls, | ||
825 | }, | ||
816 | { } /* terminator */ | 826 | { } /* terminator */ |
817 | }; | 827 | }; |
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index f7f14df81f26..1a0ac6cd6501 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h | |||
@@ -34,7 +34,8 @@ | |||
34 | "{MidiMan M Audio,Delta 410},"\ | 34 | "{MidiMan M Audio,Delta 410},"\ |
35 | "{MidiMan M Audio,Audiophile 24/96},"\ | 35 | "{MidiMan M Audio,Audiophile 24/96},"\ |
36 | "{Digigram,VX442},"\ | 36 | "{Digigram,VX442},"\ |
37 | "{Lionstracs,Mediastation}," | 37 | "{Lionstracs,Mediastation},"\ |
38 | "{Edirol,DA2496}," | ||
38 | 39 | ||
39 | #define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 | 40 | #define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 |
40 | #define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6 | 41 | #define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6 |
@@ -47,6 +48,7 @@ | |||
47 | #define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 | 48 | #define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 |
48 | #define ICE1712_SUBDEVICE_VX442 0x12143cd6 | 49 | #define ICE1712_SUBDEVICE_VX442 0x12143cd6 |
49 | #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 | 50 | #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 |
51 | #define ICE1712_SUBDEVICE_EDIROLDA2496 0xce164010 | ||
50 | 52 | ||
51 | /* entry point */ | 53 | /* entry point */ |
52 | extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; | 54 | extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; |
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 6bc3f91b7281..cdb873f5da50 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c | |||
@@ -638,7 +638,7 @@ static struct snd_kcontrol_new pontis_controls[] __devinitdata = { | |||
638 | */ | 638 | */ |
639 | static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 639 | static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
640 | { | 640 | { |
641 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 641 | struct snd_ice1712 *ice = entry->private_data; |
642 | char line[64]; | 642 | char line[64]; |
643 | unsigned int reg, val; | 643 | unsigned int reg, val; |
644 | mutex_lock(&ice->gpio_mutex); | 644 | mutex_lock(&ice->gpio_mutex); |
@@ -653,7 +653,7 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf | |||
653 | 653 | ||
654 | static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 654 | static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
655 | { | 655 | { |
656 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 656 | struct snd_ice1712 *ice = entry->private_data; |
657 | int reg, val; | 657 | int reg, val; |
658 | 658 | ||
659 | mutex_lock(&ice->gpio_mutex); | 659 | mutex_lock(&ice->gpio_mutex); |
@@ -676,7 +676,7 @@ static void wm_proc_init(struct snd_ice1712 *ice) | |||
676 | 676 | ||
677 | static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 677 | static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
678 | { | 678 | { |
679 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 679 | struct snd_ice1712 *ice = entry->private_data; |
680 | int reg, val; | 680 | int reg, val; |
681 | 681 | ||
682 | mutex_lock(&ice->gpio_mutex); | 682 | mutex_lock(&ice->gpio_mutex); |
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 2a8e5cd8f2d8..e36ddb94c382 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c | |||
@@ -654,7 +654,7 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice) | |||
654 | static void stac9460_proc_regs_read(struct snd_info_entry *entry, | 654 | static void stac9460_proc_regs_read(struct snd_info_entry *entry, |
655 | struct snd_info_buffer *buffer) | 655 | struct snd_info_buffer *buffer) |
656 | { | 656 | { |
657 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 657 | struct snd_ice1712 *ice = entry->private_data; |
658 | int reg, val; | 658 | int reg, val; |
659 | /* registers 0x0 - 0x14 */ | 659 | /* registers 0x0 - 0x14 */ |
660 | for (reg = 0; reg <= 0x15; reg++) { | 660 | for (reg = 0; reg <= 0x15; reg++) { |
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 6c0a11adb2a8..98a8eb3c92f7 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -79,6 +79,7 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { | |||
79 | { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, | 79 | { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, |
80 | { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, | 80 | { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, |
81 | { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, | 81 | { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, |
82 | { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, | ||
82 | { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, | 83 | { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, |
83 | { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, | 84 | { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, |
84 | { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, | 85 | { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, |
@@ -505,7 +506,8 @@ static const struct oxygen_model model_generic = { | |||
505 | PLAYBACK_2_TO_AC97_1 | | 506 | PLAYBACK_2_TO_AC97_1 | |
506 | CAPTURE_0_FROM_I2S_1 | | 507 | CAPTURE_0_FROM_I2S_1 | |
507 | CAPTURE_1_FROM_SPDIF | | 508 | CAPTURE_1_FROM_SPDIF | |
508 | CAPTURE_2_FROM_AC97_1, | 509 | CAPTURE_2_FROM_AC97_1 | |
510 | AC97_CD_INPUT, | ||
509 | .dac_channels = 8, | 511 | .dac_channels = 8, |
510 | .dac_volume_min = 0, | 512 | .dac_volume_min = 0, |
511 | .dac_volume_max = 255, | 513 | .dac_volume_max = 255, |
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index a3409edcfb50..7d5222caa0a9 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -34,6 +34,7 @@ | |||
34 | /* CAPTURE_3_FROM_I2S_3 not implemented */ | 34 | /* CAPTURE_3_FROM_I2S_3 not implemented */ |
35 | #define MIDI_OUTPUT 0x0800 | 35 | #define MIDI_OUTPUT 0x0800 |
36 | #define MIDI_INPUT 0x1000 | 36 | #define MIDI_INPUT 0x1000 |
37 | #define AC97_CD_INPUT 0x2000 | ||
37 | 38 | ||
38 | enum { | 39 | enum { |
39 | CONTROL_SPDIF_PCM, | 40 | CONTROL_SPDIF_PCM, |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 7e93cf884437..e5ebe56fb0c5 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -308,25 +308,46 @@ static void oxygen_restore_eeprom(struct oxygen *chip, | |||
308 | } | 308 | } |
309 | } | 309 | } |
310 | 310 | ||
311 | static void pci_bridge_magic(void) | 311 | static void configure_pcie_bridge(struct pci_dev *pci) |
312 | { | 312 | { |
313 | struct pci_dev *pci = NULL; | 313 | enum { PEX811X, PI7C9X110 }; |
314 | static const struct pci_device_id bridge_ids[] = { | ||
315 | { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X }, | ||
316 | { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X }, | ||
317 | { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 }, | ||
318 | { } | ||
319 | }; | ||
320 | struct pci_dev *bridge; | ||
321 | const struct pci_device_id *id; | ||
314 | u32 tmp; | 322 | u32 tmp; |
315 | 323 | ||
316 | for (;;) { | 324 | if (!pci->bus || !pci->bus->self) |
317 | /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */ | 325 | return; |
318 | pci = pci_get_device(0x12d8, 0xe110, pci); | 326 | bridge = pci->bus->self; |
319 | if (!pci) | 327 | |
320 | break; | 328 | id = pci_match_id(bridge_ids, bridge); |
321 | /* | 329 | if (!id) |
322 | * ... configure its secondary internal arbiter to park to | 330 | return; |
323 | * the secondary port, instead of to the last master. | 331 | |
324 | */ | 332 | switch (id->driver_data) { |
325 | if (!pci_read_config_dword(pci, 0x40, &tmp)) { | 333 | case PEX811X: /* PLX PEX8111/PEX8112 PCIe/PCI bridge */ |
326 | tmp |= 1; | 334 | pci_read_config_dword(bridge, 0x48, &tmp); |
327 | pci_write_config_dword(pci, 0x40, tmp); | 335 | tmp |= 1; /* enable blind prefetching */ |
328 | } | 336 | tmp |= 1 << 11; /* enable beacon generation */ |
329 | /* Why? Try asking C-Media. */ | 337 | pci_write_config_dword(bridge, 0x48, tmp); |
338 | |||
339 | pci_write_config_dword(bridge, 0x84, 0x0c); | ||
340 | pci_read_config_dword(bridge, 0x88, &tmp); | ||
341 | tmp &= ~(7 << 27); | ||
342 | tmp |= 2 << 27; /* set prefetch size to 128 bytes */ | ||
343 | pci_write_config_dword(bridge, 0x88, tmp); | ||
344 | break; | ||
345 | |||
346 | case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */ | ||
347 | pci_read_config_dword(bridge, 0x40, &tmp); | ||
348 | tmp |= 1; /* park the PCI arbiter to the sound chip */ | ||
349 | pci_write_config_dword(bridge, 0x40, tmp); | ||
350 | break; | ||
330 | } | 351 | } |
331 | } | 352 | } |
332 | 353 | ||
@@ -613,7 +634,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | |||
613 | snd_card_set_dev(card, &pci->dev); | 634 | snd_card_set_dev(card, &pci->dev); |
614 | card->private_free = oxygen_card_free; | 635 | card->private_free = oxygen_card_free; |
615 | 636 | ||
616 | pci_bridge_magic(); | 637 | configure_pcie_bridge(pci); |
617 | oxygen_init(chip); | 638 | oxygen_init(chip); |
618 | chip->model.init(chip); | 639 | chip->model.init(chip); |
619 | 640 | ||
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index f375b8a27862..2849b36f5f7e 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -708,7 +708,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, | |||
708 | .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ | 708 | .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ |
709 | } | 709 | } |
710 | 710 | ||
711 | static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); | 711 | static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0); |
712 | static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0); | 712 | static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0); |
713 | static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0); | 713 | static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0); |
714 | 714 | ||
@@ -972,6 +972,9 @@ static int add_controls(struct oxygen *chip, | |||
972 | if (!strcmp(template.name, "Stereo Upmixing") && | 972 | if (!strcmp(template.name, "Stereo Upmixing") && |
973 | chip->model.dac_channels == 2) | 973 | chip->model.dac_channels == 2) |
974 | continue; | 974 | continue; |
975 | if (!strncmp(template.name, "CD Capture ", 11) && | ||
976 | !(chip->model.device_config & AC97_CD_INPUT)) | ||
977 | continue; | ||
975 | if (!strcmp(template.name, "Master Playback Volume") && | 978 | if (!strcmp(template.name, "Master Playback Volume") && |
976 | chip->model.dac_tlv) { | 979 | chip->model.dac_tlv) { |
977 | template.tlv.p = chip->model.dac_tlv; | 980 | template.tlv.p = chip->model.dac_tlv; |
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 9dff6954c397..814667442eb0 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c | |||
@@ -56,8 +56,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = { | |||
56 | .channels_max = 2, | 56 | .channels_max = 2, |
57 | .buffer_bytes_max = BUFFER_BYTES_MAX, | 57 | .buffer_bytes_max = BUFFER_BYTES_MAX, |
58 | .period_bytes_min = PERIOD_BYTES_MIN, | 58 | .period_bytes_min = PERIOD_BYTES_MIN, |
59 | .period_bytes_max = BUFFER_BYTES_MAX / 2, | 59 | .period_bytes_max = BUFFER_BYTES_MAX, |
60 | .periods_min = 2, | 60 | .periods_min = 1, |
61 | .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, | 61 | .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, |
62 | }; | 62 | }; |
63 | static const struct snd_pcm_hardware oxygen_multichannel_hardware = { | 63 | static const struct snd_pcm_hardware oxygen_multichannel_hardware = { |
@@ -82,8 +82,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = { | |||
82 | .channels_max = 8, | 82 | .channels_max = 8, |
83 | .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH, | 83 | .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH, |
84 | .period_bytes_min = PERIOD_BYTES_MIN, | 84 | .period_bytes_min = PERIOD_BYTES_MIN, |
85 | .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2, | 85 | .period_bytes_max = BUFFER_BYTES_MAX_MULTICH, |
86 | .periods_min = 2, | 86 | .periods_min = 1, |
87 | .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN, | 87 | .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN, |
88 | }; | 88 | }; |
89 | static const struct snd_pcm_hardware oxygen_ac97_hardware = { | 89 | static const struct snd_pcm_hardware oxygen_ac97_hardware = { |
@@ -100,8 +100,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = { | |||
100 | .channels_max = 2, | 100 | .channels_max = 2, |
101 | .buffer_bytes_max = BUFFER_BYTES_MAX, | 101 | .buffer_bytes_max = BUFFER_BYTES_MAX, |
102 | .period_bytes_min = PERIOD_BYTES_MIN, | 102 | .period_bytes_min = PERIOD_BYTES_MIN, |
103 | .period_bytes_max = BUFFER_BYTES_MAX / 2, | 103 | .period_bytes_max = BUFFER_BYTES_MAX, |
104 | .periods_min = 2, | 104 | .periods_min = 1, |
105 | .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, | 105 | .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, |
106 | }; | 106 | }; |
107 | 107 | ||
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h index 72de159d4567..4dcd41b78258 100644 --- a/sound/pci/oxygen/oxygen_regs.h +++ b/sound/pci/oxygen/oxygen_regs.h | |||
@@ -436,13 +436,15 @@ | |||
436 | /* OXYGEN_CHANNEL_* */ | 436 | /* OXYGEN_CHANNEL_* */ |
437 | 437 | ||
438 | #define OXYGEN_CODEC_VERSION 0xe4 | 438 | #define OXYGEN_CODEC_VERSION 0xe4 |
439 | #define OXYGEN_XCID_MASK 0x07 | 439 | #define OXYGEN_CODEC_ID_MASK 0x07 |
440 | 440 | ||
441 | #define OXYGEN_REVISION 0xe6 | 441 | #define OXYGEN_REVISION 0xe6 |
442 | #define OXYGEN_REVISION_XPKGID_MASK 0x0007 | 442 | #define OXYGEN_PACKAGE_ID_MASK 0x0007 |
443 | #define OXYGEN_PACKAGE_ID_8786 0x0004 | ||
444 | #define OXYGEN_PACKAGE_ID_8787 0x0006 | ||
445 | #define OXYGEN_PACKAGE_ID_8788 0x0007 | ||
443 | #define OXYGEN_REVISION_MASK 0xfff8 | 446 | #define OXYGEN_REVISION_MASK 0xfff8 |
444 | #define OXYGEN_REVISION_2 0x0008 /* bit flag */ | 447 | #define OXYGEN_REVISION_2 0x0008 |
445 | #define OXYGEN_REVISION_8787 0x0014 /* 8 bits */ | ||
446 | 448 | ||
447 | #define OXYGEN_OFFSIN_48K 0xe8 | 449 | #define OXYGEN_OFFSIN_48K 0xe8 |
448 | #define OXYGEN_OFFSBASE_48K 0xe9 | 450 | #define OXYGEN_OFFSBASE_48K 0xe9 |
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 06c863e86e3d..469010a8b849 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
@@ -25,9 +25,9 @@ | |||
25 | #include "xonar.h" | 25 | #include "xonar.h" |
26 | 26 | ||
27 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 27 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
28 | MODULE_DESCRIPTION("Asus AVx00 driver"); | 28 | MODULE_DESCRIPTION("Asus Virtuoso driver"); |
29 | MODULE_LICENSE("GPL v2"); | 29 | MODULE_LICENSE("GPL v2"); |
30 | MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); | 30 | MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}"); |
31 | 31 | ||
32 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 32 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
33 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 33 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
@@ -49,6 +49,7 @@ static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = { | |||
49 | { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, | 49 | { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, |
50 | { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, | 50 | { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, |
51 | { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, | 51 | { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, |
52 | { OXYGEN_PCI_SUBID(0x1043, 0x835e) }, | ||
52 | { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, | 53 | { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, |
53 | { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, | 54 | { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, |
54 | { } | 55 | { } |
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 7c4986b27f2b..aa27c31049af 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c | |||
@@ -367,13 +367,6 @@ static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip, | |||
367 | 367 | ||
368 | static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0); | 368 | static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0); |
369 | 369 | ||
370 | static int xonar_d1_control_filter(struct snd_kcontrol_new *template) | ||
371 | { | ||
372 | if (!strncmp(template->name, "CD Capture ", 11)) | ||
373 | return 1; /* no CD input */ | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static int xonar_d1_mixer_init(struct oxygen *chip) | 370 | static int xonar_d1_mixer_init(struct oxygen *chip) |
378 | { | 371 | { |
379 | int err; | 372 | int err; |
@@ -391,7 +384,6 @@ static const struct oxygen_model model_xonar_d1 = { | |||
391 | .longname = "Asus Virtuoso 100", | 384 | .longname = "Asus Virtuoso 100", |
392 | .chip = "AV200", | 385 | .chip = "AV200", |
393 | .init = xonar_d1_init, | 386 | .init = xonar_d1_init, |
394 | .control_filter = xonar_d1_control_filter, | ||
395 | .mixer_init = xonar_d1_mixer_init, | 387 | .mixer_init = xonar_d1_mixer_init, |
396 | .cleanup = xonar_d1_cleanup, | 388 | .cleanup = xonar_d1_cleanup, |
397 | .suspend = xonar_d1_suspend, | 389 | .suspend = xonar_d1_suspend, |
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index ba18fb546b4f..d491fd6c0be2 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c | |||
@@ -132,6 +132,18 @@ | |||
132 | * GPIO 5 <- 0 | 132 | * GPIO 5 <- 0 |
133 | */ | 133 | */ |
134 | 134 | ||
135 | /* | ||
136 | * Xonar HDAV1.3 Slim | ||
137 | * ------------------ | ||
138 | * | ||
139 | * CMI8788: | ||
140 | * | ||
141 | * GPIO 1 -> enable output | ||
142 | * | ||
143 | * TXD -> HDMI controller | ||
144 | * RXD <- HDMI controller | ||
145 | */ | ||
146 | |||
135 | #include <linux/pci.h> | 147 | #include <linux/pci.h> |
136 | #include <linux/delay.h> | 148 | #include <linux/delay.h> |
137 | #include <linux/mutex.h> | 149 | #include <linux/mutex.h> |
@@ -362,7 +374,6 @@ static void xonar_st_init_common(struct oxygen *chip) | |||
362 | { | 374 | { |
363 | struct xonar_pcm179x *data = chip->model_data; | 375 | struct xonar_pcm179x *data = chip->model_data; |
364 | 376 | ||
365 | data->generic.anti_pop_delay = 100; | ||
366 | data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; | 377 | data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; |
367 | data->dacs = chip->model.private_data ? 4 : 1; | 378 | data->dacs = chip->model.private_data ? 4 : 1; |
368 | data->hp_gain_offset = 2*-18; | 379 | data->hp_gain_offset = 2*-18; |
@@ -408,6 +419,7 @@ static void xonar_st_init(struct oxygen *chip) | |||
408 | { | 419 | { |
409 | struct xonar_pcm179x *data = chip->model_data; | 420 | struct xonar_pcm179x *data = chip->model_data; |
410 | 421 | ||
422 | data->generic.anti_pop_delay = 100; | ||
411 | data->has_cs2000 = 1; | 423 | data->has_cs2000 = 1; |
412 | data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; | 424 | data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; |
413 | 425 | ||
@@ -428,6 +440,7 @@ static void xonar_stx_init(struct oxygen *chip) | |||
428 | struct xonar_pcm179x *data = chip->model_data; | 440 | struct xonar_pcm179x *data = chip->model_data; |
429 | 441 | ||
430 | xonar_st_init_i2c(chip); | 442 | xonar_st_init_i2c(chip); |
443 | data->generic.anti_pop_delay = 800; | ||
431 | data->generic.ext_power_reg = OXYGEN_GPI_DATA; | 444 | data->generic.ext_power_reg = OXYGEN_GPI_DATA; |
432 | data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; | 445 | data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; |
433 | data->generic.ext_power_bit = GPI_EXT_POWER; | 446 | data->generic.ext_power_bit = GPI_EXT_POWER; |
@@ -915,13 +928,6 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template) | |||
915 | return 0; | 928 | return 0; |
916 | } | 929 | } |
917 | 930 | ||
918 | static int xonar_st_control_filter(struct snd_kcontrol_new *template) | ||
919 | { | ||
920 | if (!strncmp(template->name, "CD Capture ", 11)) | ||
921 | return 1; /* no CD input */ | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int add_pcm1796_controls(struct oxygen *chip) | 931 | static int add_pcm1796_controls(struct oxygen *chip) |
926 | { | 932 | { |
927 | int err; | 933 | int err; |
@@ -991,7 +997,8 @@ static const struct oxygen_model model_xonar_d2 = { | |||
991 | CAPTURE_0_FROM_I2S_2 | | 997 | CAPTURE_0_FROM_I2S_2 | |
992 | CAPTURE_1_FROM_SPDIF | | 998 | CAPTURE_1_FROM_SPDIF | |
993 | MIDI_OUTPUT | | 999 | MIDI_OUTPUT | |
994 | MIDI_INPUT, | 1000 | MIDI_INPUT | |
1001 | AC97_CD_INPUT, | ||
995 | .dac_channels = 8, | 1002 | .dac_channels = 8, |
996 | .dac_volume_min = 255 - 2*60, | 1003 | .dac_volume_min = 255 - 2*60, |
997 | .dac_volume_max = 255, | 1004 | .dac_volume_max = 255, |
@@ -1037,7 +1044,6 @@ static const struct oxygen_model model_xonar_st = { | |||
1037 | .longname = "Asus Virtuoso 100", | 1044 | .longname = "Asus Virtuoso 100", |
1038 | .chip = "AV200", | 1045 | .chip = "AV200", |
1039 | .init = xonar_st_init, | 1046 | .init = xonar_st_init, |
1040 | .control_filter = xonar_st_control_filter, | ||
1041 | .mixer_init = xonar_st_mixer_init, | 1047 | .mixer_init = xonar_st_mixer_init, |
1042 | .cleanup = xonar_st_cleanup, | 1048 | .cleanup = xonar_st_cleanup, |
1043 | .suspend = xonar_st_suspend, | 1049 | .suspend = xonar_st_suspend, |
@@ -1108,6 +1114,9 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, | |||
1108 | chip->model.resume = xonar_stx_resume; | 1114 | chip->model.resume = xonar_stx_resume; |
1109 | chip->model.set_dac_params = set_pcm1796_params; | 1115 | chip->model.set_dac_params = set_pcm1796_params; |
1110 | break; | 1116 | break; |
1117 | case 0x835e: | ||
1118 | snd_printk(KERN_ERR "the HDAV1.3 Slim is not supported\n"); | ||
1119 | return -ENODEV; | ||
1111 | default: | 1120 | default: |
1112 | return -EINVAL; | 1121 | return -EINVAL; |
1113 | } | 1122 | } |
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index b82c1cfa96f5..200f7601276f 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c | |||
@@ -25,16 +25,24 @@ | |||
25 | * SPI 0 -> WM8766 (surround, center/LFE, back) | 25 | * SPI 0 -> WM8766 (surround, center/LFE, back) |
26 | * SPI 1 -> WM8776 (front, input) | 26 | * SPI 1 -> WM8776 (front, input) |
27 | * | 27 | * |
28 | * GPIO 4 <- headphone detect | 28 | * GPIO 4 <- headphone detect, 0 = plugged |
29 | * GPIO 6 -> route input jack to input 1/2 (1/0) | 29 | * GPIO 6 -> route input jack to mic-in (0) or line-in (1) |
30 | * GPIO 7 -> enable output to speakers | 30 | * GPIO 7 -> enable output to front L/R speaker channels |
31 | * GPIO 8 -> enable output to speakers | 31 | * GPIO 8 -> enable output to other speaker channels and front panel headphone |
32 | * | ||
33 | * WM8766: | ||
34 | * | ||
35 | * input 1 <- line | ||
36 | * input 2 <- mic | ||
37 | * input 3 <- front mic | ||
38 | * input 4 <- aux | ||
32 | */ | 39 | */ |
33 | 40 | ||
34 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
35 | #include <linux/delay.h> | 42 | #include <linux/delay.h> |
36 | #include <sound/control.h> | 43 | #include <sound/control.h> |
37 | #include <sound/core.h> | 44 | #include <sound/core.h> |
45 | #include <sound/jack.h> | ||
38 | #include <sound/pcm.h> | 46 | #include <sound/pcm.h> |
39 | #include <sound/pcm_params.h> | 47 | #include <sound/pcm_params.h> |
40 | #include <sound/tlv.h> | 48 | #include <sound/tlv.h> |
@@ -44,7 +52,8 @@ | |||
44 | 52 | ||
45 | #define GPIO_DS_HP_DETECT 0x0010 | 53 | #define GPIO_DS_HP_DETECT 0x0010 |
46 | #define GPIO_DS_INPUT_ROUTE 0x0040 | 54 | #define GPIO_DS_INPUT_ROUTE 0x0040 |
47 | #define GPIO_DS_OUTPUT_ENABLE 0x0180 | 55 | #define GPIO_DS_OUTPUT_FRONTLR 0x0080 |
56 | #define GPIO_DS_OUTPUT_ENABLE 0x0100 | ||
48 | 57 | ||
49 | #define LC_CONTROL_LIMITER 0x40000000 | 58 | #define LC_CONTROL_LIMITER 0x40000000 |
50 | #define LC_CONTROL_ALC 0x20000000 | 59 | #define LC_CONTROL_ALC 0x20000000 |
@@ -56,6 +65,7 @@ struct xonar_wm87x6 { | |||
56 | struct snd_kcontrol *line_adcmux_control; | 65 | struct snd_kcontrol *line_adcmux_control; |
57 | struct snd_kcontrol *mic_adcmux_control; | 66 | struct snd_kcontrol *mic_adcmux_control; |
58 | struct snd_kcontrol *lc_controls[13]; | 67 | struct snd_kcontrol *lc_controls[13]; |
68 | struct snd_jack *hp_jack; | ||
59 | }; | 69 | }; |
60 | 70 | ||
61 | static void wm8776_write(struct oxygen *chip, | 71 | static void wm8776_write(struct oxygen *chip, |
@@ -97,8 +107,12 @@ static void wm8766_write(struct oxygen *chip, | |||
97 | (0 << OXYGEN_SPI_CODEC_SHIFT) | | 107 | (0 << OXYGEN_SPI_CODEC_SHIFT) | |
98 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, | 108 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, |
99 | (reg << 9) | value); | 109 | (reg << 9) | value); |
100 | if (reg < ARRAY_SIZE(data->wm8766_regs)) | 110 | if (reg < ARRAY_SIZE(data->wm8766_regs)) { |
111 | if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) || | ||
112 | (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) | ||
113 | value &= ~WM8766_UPDATE; | ||
101 | data->wm8766_regs[reg] = value; | 114 | data->wm8766_regs[reg] = value; |
115 | } | ||
102 | } | 116 | } |
103 | 117 | ||
104 | static void wm8766_write_cached(struct oxygen *chip, | 118 | static void wm8766_write_cached(struct oxygen *chip, |
@@ -107,12 +121,8 @@ static void wm8766_write_cached(struct oxygen *chip, | |||
107 | struct xonar_wm87x6 *data = chip->model_data; | 121 | struct xonar_wm87x6 *data = chip->model_data; |
108 | 122 | ||
109 | if (reg >= ARRAY_SIZE(data->wm8766_regs) || | 123 | if (reg >= ARRAY_SIZE(data->wm8766_regs) || |
110 | value != data->wm8766_regs[reg]) { | 124 | value != data->wm8766_regs[reg]) |
111 | if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) || | ||
112 | (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) | ||
113 | value &= ~WM8766_UPDATE; | ||
114 | wm8766_write(chip, reg, value); | 125 | wm8766_write(chip, reg, value); |
115 | } | ||
116 | } | 126 | } |
117 | 127 | ||
118 | static void wm8776_registers_init(struct oxygen *chip) | 128 | static void wm8776_registers_init(struct oxygen *chip) |
@@ -141,7 +151,10 @@ static void wm8776_registers_init(struct oxygen *chip) | |||
141 | 151 | ||
142 | static void wm8766_registers_init(struct oxygen *chip) | 152 | static void wm8766_registers_init(struct oxygen *chip) |
143 | { | 153 | { |
154 | struct xonar_wm87x6 *data = chip->model_data; | ||
155 | |||
144 | wm8766_write(chip, WM8766_RESET, 0); | 156 | wm8766_write(chip, WM8766_RESET, 0); |
157 | wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]); | ||
145 | wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); | 158 | wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); |
146 | wm8766_write(chip, WM8766_DAC_CTRL2, | 159 | wm8766_write(chip, WM8766_DAC_CTRL2, |
147 | WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); | 160 | WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); |
@@ -170,6 +183,40 @@ static void wm8776_init(struct oxygen *chip) | |||
170 | wm8776_registers_init(chip); | 183 | wm8776_registers_init(chip); |
171 | } | 184 | } |
172 | 185 | ||
186 | static void wm8766_init(struct oxygen *chip) | ||
187 | { | ||
188 | struct xonar_wm87x6 *data = chip->model_data; | ||
189 | |||
190 | data->wm8766_regs[WM8766_DAC_CTRL] = | ||
191 | WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT; | ||
192 | wm8766_registers_init(chip); | ||
193 | } | ||
194 | |||
195 | static void xonar_ds_handle_hp_jack(struct oxygen *chip) | ||
196 | { | ||
197 | struct xonar_wm87x6 *data = chip->model_data; | ||
198 | bool hp_plugged; | ||
199 | unsigned int reg; | ||
200 | |||
201 | mutex_lock(&chip->mutex); | ||
202 | |||
203 | hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) & | ||
204 | GPIO_DS_HP_DETECT); | ||
205 | |||
206 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, | ||
207 | hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR, | ||
208 | GPIO_DS_OUTPUT_FRONTLR); | ||
209 | |||
210 | reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL; | ||
211 | if (hp_plugged) | ||
212 | reg |= WM8766_MUTEALL; | ||
213 | wm8766_write_cached(chip, WM8766_DAC_CTRL, reg); | ||
214 | |||
215 | snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0); | ||
216 | |||
217 | mutex_unlock(&chip->mutex); | ||
218 | } | ||
219 | |||
173 | static void xonar_ds_init(struct oxygen *chip) | 220 | static void xonar_ds_init(struct oxygen *chip) |
174 | { | 221 | { |
175 | struct xonar_wm87x6 *data = chip->model_data; | 222 | struct xonar_wm87x6 *data = chip->model_data; |
@@ -178,16 +225,22 @@ static void xonar_ds_init(struct oxygen *chip) | |||
178 | data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; | 225 | data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; |
179 | 226 | ||
180 | wm8776_init(chip); | 227 | wm8776_init(chip); |
181 | wm8766_registers_init(chip); | 228 | wm8766_init(chip); |
182 | 229 | ||
183 | oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, | 230 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, |
184 | GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); | 231 | GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR); |
232 | oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, | ||
233 | GPIO_DS_HP_DETECT); | ||
185 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); | 234 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); |
186 | oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); | 235 | oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); |
187 | chip->interrupt_mask |= OXYGEN_INT_GPIO; | 236 | chip->interrupt_mask |= OXYGEN_INT_GPIO; |
188 | 237 | ||
189 | xonar_enable_output(chip); | 238 | xonar_enable_output(chip); |
190 | 239 | ||
240 | snd_jack_new(chip->card, "Headphone", | ||
241 | SND_JACK_HEADPHONE, &data->hp_jack); | ||
242 | xonar_ds_handle_hp_jack(chip); | ||
243 | |||
191 | snd_component_add(chip->card, "WM8776"); | 244 | snd_component_add(chip->card, "WM8776"); |
192 | snd_component_add(chip->card, "WM8766"); | 245 | snd_component_add(chip->card, "WM8766"); |
193 | } | 246 | } |
@@ -208,6 +261,7 @@ static void xonar_ds_resume(struct oxygen *chip) | |||
208 | wm8776_registers_init(chip); | 261 | wm8776_registers_init(chip); |
209 | wm8766_registers_init(chip); | 262 | wm8766_registers_init(chip); |
210 | xonar_enable_output(chip); | 263 | xonar_enable_output(chip); |
264 | xonar_ds_handle_hp_jack(chip); | ||
211 | } | 265 | } |
212 | 266 | ||
213 | static void wm8776_adc_hardware_filter(unsigned int channel, | 267 | static void wm8776_adc_hardware_filter(unsigned int channel, |
@@ -323,12 +377,27 @@ static void update_wm87x6_mute(struct oxygen *chip) | |||
323 | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); | 377 | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); |
324 | } | 378 | } |
325 | 379 | ||
326 | static void xonar_ds_gpio_changed(struct oxygen *chip) | 380 | static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed) |
327 | { | 381 | { |
328 | u16 bits; | 382 | struct xonar_wm87x6 *data = chip->model_data; |
383 | unsigned int reg; | ||
329 | 384 | ||
330 | bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); | 385 | /* |
331 | snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT)); | 386 | * The WM8766 can mix left and right channels, but this setting |
387 | * applies to all three stereo pairs. | ||
388 | */ | ||
389 | reg = data->wm8766_regs[WM8766_DAC_CTRL] & | ||
390 | ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK); | ||
391 | if (mixed) | ||
392 | reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX; | ||
393 | else | ||
394 | reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT; | ||
395 | wm8766_write_cached(chip, WM8766_DAC_CTRL, reg); | ||
396 | } | ||
397 | |||
398 | static void xonar_ds_gpio_changed(struct oxygen *chip) | ||
399 | { | ||
400 | xonar_ds_handle_hp_jack(chip); | ||
332 | } | 401 | } |
333 | 402 | ||
334 | static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, | 403 | static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, |
@@ -896,7 +965,10 @@ static const struct snd_kcontrol_new ds_controls[] = { | |||
896 | .put = wm8776_input_mux_put, | 965 | .put = wm8776_input_mux_put, |
897 | .private_value = 1 << 1, | 966 | .private_value = 1 << 1, |
898 | }, | 967 | }, |
899 | WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0), | 968 | WM8776_BIT_SWITCH("Front Mic Capture Switch", |
969 | WM8776_ADCMUX, 1 << 2, 0, 0), | ||
970 | WM8776_BIT_SWITCH("Aux Capture Switch", | ||
971 | WM8776_ADCMUX, 1 << 3, 0, 0), | ||
900 | { | 972 | { |
901 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 973 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
902 | .name = "ADC Filter Capture Enum", | 974 | .name = "ADC Filter Capture Enum", |
@@ -956,13 +1028,6 @@ static const struct snd_kcontrol_new lc_controls[] = { | |||
956 | LC_CONTROL_ALC, wm8776_ngth_db_scale), | 1028 | LC_CONTROL_ALC, wm8776_ngth_db_scale), |
957 | }; | 1029 | }; |
958 | 1030 | ||
959 | static int xonar_ds_control_filter(struct snd_kcontrol_new *template) | ||
960 | { | ||
961 | if (!strncmp(template->name, "CD Capture ", 11)) | ||
962 | return 1; /* no CD input */ | ||
963 | return 0; | ||
964 | } | ||
965 | |||
966 | static int xonar_ds_mixer_init(struct oxygen *chip) | 1031 | static int xonar_ds_mixer_init(struct oxygen *chip) |
967 | { | 1032 | { |
968 | struct xonar_wm87x6 *data = chip->model_data; | 1033 | struct xonar_wm87x6 *data = chip->model_data; |
@@ -999,10 +1064,9 @@ static int xonar_ds_mixer_init(struct oxygen *chip) | |||
999 | 1064 | ||
1000 | static const struct oxygen_model model_xonar_ds = { | 1065 | static const struct oxygen_model model_xonar_ds = { |
1001 | .shortname = "Xonar DS", | 1066 | .shortname = "Xonar DS", |
1002 | .longname = "Asus Virtuoso 200", | 1067 | .longname = "Asus Virtuoso 66", |
1003 | .chip = "AV200", | 1068 | .chip = "AV200", |
1004 | .init = xonar_ds_init, | 1069 | .init = xonar_ds_init, |
1005 | .control_filter = xonar_ds_control_filter, | ||
1006 | .mixer_init = xonar_ds_mixer_init, | 1070 | .mixer_init = xonar_ds_mixer_init, |
1007 | .cleanup = xonar_ds_cleanup, | 1071 | .cleanup = xonar_ds_cleanup, |
1008 | .suspend = xonar_ds_suspend, | 1072 | .suspend = xonar_ds_suspend, |
@@ -1013,6 +1077,7 @@ static const struct oxygen_model model_xonar_ds = { | |||
1013 | .set_adc_params = set_wm8776_adc_params, | 1077 | .set_adc_params = set_wm8776_adc_params, |
1014 | .update_dac_volume = update_wm87x6_volume, | 1078 | .update_dac_volume = update_wm87x6_volume, |
1015 | .update_dac_mute = update_wm87x6_mute, | 1079 | .update_dac_mute = update_wm87x6_mute, |
1080 | .update_center_lfe_mix = update_wm8766_center_lfe_mix, | ||
1016 | .gpio_changed = xonar_ds_gpio_changed, | 1081 | .gpio_changed = xonar_ds_gpio_changed, |
1017 | .dac_tlv = wm87x6_dac_db_scale, | 1082 | .dac_tlv = wm87x6_dac_db_scale, |
1018 | .model_data_size = sizeof(struct xonar_wm87x6), | 1083 | .model_data_size = sizeof(struct xonar_wm87x6), |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index d19dc052c391..d5f5b440fc40 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -1527,14 +1527,14 @@ snd_rme96_free(void *private_data) | |||
1527 | static void | 1527 | static void |
1528 | snd_rme96_free_spdif_pcm(struct snd_pcm *pcm) | 1528 | snd_rme96_free_spdif_pcm(struct snd_pcm *pcm) |
1529 | { | 1529 | { |
1530 | struct rme96 *rme96 = (struct rme96 *) pcm->private_data; | 1530 | struct rme96 *rme96 = pcm->private_data; |
1531 | rme96->spdif_pcm = NULL; | 1531 | rme96->spdif_pcm = NULL; |
1532 | } | 1532 | } |
1533 | 1533 | ||
1534 | static void | 1534 | static void |
1535 | snd_rme96_free_adat_pcm(struct snd_pcm *pcm) | 1535 | snd_rme96_free_adat_pcm(struct snd_pcm *pcm) |
1536 | { | 1536 | { |
1537 | struct rme96 *rme96 = (struct rme96 *) pcm->private_data; | 1537 | struct rme96 *rme96 = pcm->private_data; |
1538 | rme96->adat_pcm = NULL; | 1538 | rme96->adat_pcm = NULL; |
1539 | } | 1539 | } |
1540 | 1540 | ||
@@ -1661,7 +1661,7 @@ static void | |||
1661 | snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 1661 | snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
1662 | { | 1662 | { |
1663 | int n; | 1663 | int n; |
1664 | struct rme96 *rme96 = (struct rme96 *)entry->private_data; | 1664 | struct rme96 *rme96 = entry->private_data; |
1665 | 1665 | ||
1666 | rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); | 1666 | rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); |
1667 | 1667 | ||
@@ -2348,7 +2348,7 @@ snd_rme96_probe(struct pci_dev *pci, | |||
2348 | if (err < 0) | 2348 | if (err < 0) |
2349 | return err; | 2349 | return err; |
2350 | card->private_free = snd_rme96_card_free; | 2350 | card->private_free = snd_rme96_card_free; |
2351 | rme96 = (struct rme96 *)card->private_data; | 2351 | rme96 = card->private_data; |
2352 | rme96->card = card; | 2352 | rme96->card = card; |
2353 | rme96->pci = pci; | 2353 | rme96->pci = pci; |
2354 | snd_card_set_dev(card, &pci->dev); | 2354 | snd_card_set_dev(card, &pci->dev); |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index d6fa7bfd9aa1..0b720cf7783e 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -3284,7 +3284,7 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) | |||
3284 | static void | 3284 | static void |
3285 | snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 3285 | snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
3286 | { | 3286 | { |
3287 | struct hdsp *hdsp = (struct hdsp *) entry->private_data; | 3287 | struct hdsp *hdsp = entry->private_data; |
3288 | unsigned int status; | 3288 | unsigned int status; |
3289 | unsigned int status2; | 3289 | unsigned int status2; |
3290 | char *pref_sync_ref; | 3290 | char *pref_sync_ref; |
@@ -4566,7 +4566,7 @@ static int hdsp_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rm | |||
4566 | 4566 | ||
4567 | static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) | 4567 | static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) |
4568 | { | 4568 | { |
4569 | struct hdsp *hdsp = (struct hdsp *)hw->private_data; | 4569 | struct hdsp *hdsp = hw->private_data; |
4570 | void __user *argp = (void __user *)arg; | 4570 | void __user *argp = (void __user *)arg; |
4571 | int err; | 4571 | int err; |
4572 | 4572 | ||
@@ -5156,7 +5156,7 @@ static int snd_hdsp_free(struct hdsp *hdsp) | |||
5156 | 5156 | ||
5157 | static void snd_hdsp_card_free(struct snd_card *card) | 5157 | static void snd_hdsp_card_free(struct snd_card *card) |
5158 | { | 5158 | { |
5159 | struct hdsp *hdsp = (struct hdsp *) card->private_data; | 5159 | struct hdsp *hdsp = card->private_data; |
5160 | 5160 | ||
5161 | if (hdsp) | 5161 | if (hdsp) |
5162 | snd_hdsp_free(hdsp); | 5162 | snd_hdsp_free(hdsp); |
@@ -5182,7 +5182,7 @@ static int __devinit snd_hdsp_probe(struct pci_dev *pci, | |||
5182 | if (err < 0) | 5182 | if (err < 0) |
5183 | return err; | 5183 | return err; |
5184 | 5184 | ||
5185 | hdsp = (struct hdsp *) card->private_data; | 5185 | hdsp = card->private_data; |
5186 | card->private_free = snd_hdsp_card_free; | 5186 | card->private_free = snd_hdsp_card_free; |
5187 | hdsp->dev = dev; | 5187 | hdsp->dev = dev; |
5188 | hdsp->pci = pci; | 5188 | hdsp->pci = pci; |