diff options
Diffstat (limited to 'sound/isa/opti9xx/opti92x-ad1848.c')
-rw-r--r-- | sound/isa/opti9xx/opti92x-ad1848.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index c8a8da0d4036..a4af53b5c1cf 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | #include <asm/dma.h> | 34 | #include <asm/dma.h> |
35 | #include <sound/core.h> | 35 | #include <sound/core.h> |
36 | #include <sound/tlv.h> | ||
36 | #include <sound/wss.h> | 37 | #include <sound/wss.h> |
37 | #include <sound/mpu401.h> | 38 | #include <sound/mpu401.h> |
38 | #include <sound/opl3.h> | 39 | #include <sound/opl3.h> |
@@ -546,6 +547,93 @@ __skip_mpu: | |||
546 | 547 | ||
547 | #ifdef OPTi93X | 548 | #ifdef OPTi93X |
548 | 549 | ||
550 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0); | ||
551 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); | ||
552 | static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0); | ||
553 | |||
554 | static struct snd_kcontrol_new snd_opti93x_controls[] = { | ||
555 | WSS_DOUBLE("Master Playback Switch", 0, | ||
556 | OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), | ||
557 | WSS_DOUBLE_TLV("Master Playback Volume", 0, | ||
558 | OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1, | ||
559 | db_scale_5bit_3db_step), | ||
560 | WSS_DOUBLE_TLV("PCM Playback Volume", 0, | ||
561 | CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1, | ||
562 | db_scale_5bit), | ||
563 | WSS_DOUBLE_TLV("FM Playback Volume", 0, | ||
564 | CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1, | ||
565 | db_scale_4bit_12db_max), | ||
566 | WSS_DOUBLE("Line Playback Switch", 0, | ||
567 | CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), | ||
568 | WSS_DOUBLE_TLV("Line Playback Volume", 0, | ||
569 | CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1, | ||
570 | db_scale_4bit_12db_max), | ||
571 | WSS_DOUBLE("Mic Playback Switch", 0, | ||
572 | OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), | ||
573 | WSS_DOUBLE_TLV("Mic Playback Volume", 0, | ||
574 | OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1, | ||
575 | db_scale_4bit_12db_max), | ||
576 | WSS_DOUBLE_TLV("CD Playback Volume", 0, | ||
577 | CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1, | ||
578 | db_scale_4bit_12db_max), | ||
579 | WSS_DOUBLE("Aux Playback Switch", 0, | ||
580 | OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1), | ||
581 | WSS_DOUBLE_TLV("Aux Playback Volume", 0, | ||
582 | OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1, | ||
583 | db_scale_4bit_12db_max), | ||
584 | }; | ||
585 | |||
586 | static int __devinit snd_opti93x_mixer(struct snd_wss *chip) | ||
587 | { | ||
588 | struct snd_card *card; | ||
589 | unsigned int idx; | ||
590 | struct snd_ctl_elem_id id1, id2; | ||
591 | int err; | ||
592 | |||
593 | if (snd_BUG_ON(!chip || !chip->pcm)) | ||
594 | return -EINVAL; | ||
595 | |||
596 | card = chip->card; | ||
597 | |||
598 | strcpy(card->mixername, chip->pcm->name); | ||
599 | |||
600 | memset(&id1, 0, sizeof(id1)); | ||
601 | memset(&id2, 0, sizeof(id2)); | ||
602 | id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
603 | /* reassign AUX0 switch to CD */ | ||
604 | strcpy(id1.name, "Aux Playback Switch"); | ||
605 | strcpy(id2.name, "CD Playback Switch"); | ||
606 | err = snd_ctl_rename_id(card, &id1, &id2); | ||
607 | if (err < 0) { | ||
608 | snd_printk(KERN_ERR "Cannot rename opti93x control\n"); | ||
609 | return err; | ||
610 | } | ||
611 | /* reassign AUX1 switch to FM */ | ||
612 | strcpy(id1.name, "Aux Playback Switch"); id1.index = 1; | ||
613 | strcpy(id2.name, "FM Playback Switch"); | ||
614 | err = snd_ctl_rename_id(card, &id1, &id2); | ||
615 | if (err < 0) { | ||
616 | snd_printk(KERN_ERR "Cannot rename opti93x control\n"); | ||
617 | return err; | ||
618 | } | ||
619 | /* remove AUX1 volume */ | ||
620 | strcpy(id1.name, "Aux Playback Volume"); id1.index = 1; | ||
621 | snd_ctl_remove_id(card, &id1); | ||
622 | |||
623 | /* Replace WSS volume controls with OPTi93x volume controls */ | ||
624 | id1.index = 0; | ||
625 | for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { | ||
626 | strcpy(id1.name, snd_opti93x_controls[idx].name); | ||
627 | snd_ctl_remove_id(card, &id1); | ||
628 | |||
629 | err = snd_ctl_add(card, | ||
630 | snd_ctl_new1(&snd_opti93x_controls[idx], chip)); | ||
631 | if (err < 0) | ||
632 | return err; | ||
633 | } | ||
634 | return 0; | ||
635 | } | ||
636 | |||
549 | static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) | 637 | static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) |
550 | { | 638 | { |
551 | struct snd_opti9xx *chip = dev_id; | 639 | struct snd_opti9xx *chip = dev_id; |
@@ -754,6 +842,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
754 | error = snd_wss_mixer(codec); | 842 | error = snd_wss_mixer(codec); |
755 | if (error < 0) | 843 | if (error < 0) |
756 | return error; | 844 | return error; |
845 | #ifdef OPTi93X | ||
846 | error = snd_opti93x_mixer(codec); | ||
847 | if (error < 0) | ||
848 | return error; | ||
849 | #endif | ||
757 | #ifdef CS4231 | 850 | #ifdef CS4231 |
758 | error = snd_wss_timer(codec, 0, &timer); | 851 | error = snd_wss_timer(codec, 0, &timer); |
759 | if (error < 0) | 852 | if (error < 0) |