aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/opti9xx/opti92x-ad1848.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/opti9xx/opti92x-ad1848.c')
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index d8eac3f28947..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>
@@ -179,7 +180,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
179#endif 180#endif
180 181
181static char * snd_opti9xx_names[] = { 182static char * snd_opti9xx_names[] = {
182 "unkown", 183 "unknown",
183 "82C928", "82C929", 184 "82C928", "82C929",
184 "82C924", "82C925", 185 "82C924", "82C925",
185 "82C930", "82C931", "82C933" 186 "82C930", "82C931", "82C933"
@@ -546,6 +547,93 @@ __skip_mpu:
546 547
547#ifdef OPTi93X 548#ifdef OPTi93X
548 549
550static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
551static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
552static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
553
554static struct snd_kcontrol_new snd_opti93x_controls[] = {
555WSS_DOUBLE("Master Playback Switch", 0,
556 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
557WSS_DOUBLE_TLV("Master Playback Volume", 0,
558 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
559 db_scale_5bit_3db_step),
560WSS_DOUBLE_TLV("PCM Playback Volume", 0,
561 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
562 db_scale_5bit),
563WSS_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),
566WSS_DOUBLE("Line Playback Switch", 0,
567 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
568WSS_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),
571WSS_DOUBLE("Mic Playback Switch", 0,
572 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
573WSS_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),
576WSS_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),
579WSS_DOUBLE("Aux Playback Switch", 0,
580 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
581WSS_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
586static 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
549static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 637static 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)