[ALSA] fm801 - Add mute support for FM-only card with FM801 PCI to tuner bridge
[safe/jmp/linux-2.6] / sound / pci / fm801.c
index 77e3d5c..4c300e6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  The driver for the ForteMedia FM801 based soundcards
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  *
  *  Support FM only card by Andy Shevchenko <andy@smile.org.ua>
  *
@@ -20,7 +20,6 @@
  *
  */
 
-#include <sound/driver.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -42,7 +41,7 @@
 #define TEA575X_RADIO 1
 #endif
 
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("ForteMedia FM801");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801},"
@@ -979,6 +978,27 @@ static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea)
        return val;
 }
 
+static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea,
+                                         unsigned int mute)
+{
+       struct fm801 *chip = tea->private_data;
+       unsigned short reg;
+
+       spin_lock_irq(&chip->reg_lock);
+
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       if (mute)
+               /* 0xf800 (mute) */
+               reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
+       else
+               /* 0xf802 (unmute) */
+               reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       udelay(1);
+
+       spin_unlock_irq(&chip->reg_lock);
+}
+
 static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
        {
                /* 1 = MediaForte 256-PCS */
@@ -994,6 +1014,7 @@ static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
                /* 3 = MediaForte 64-PCR */
                .write = snd_fm801_tea575x_64pcr_write,
                .read = snd_fm801_tea575x_64pcr_read,
+               .mute = snd_fm801_tea575x_64pcr_mute,
        }
 };
 #endif
@@ -1157,7 +1178,7 @@ static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol,
        return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
 }
 
-static DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0);
 
 #define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls)
 
@@ -1369,7 +1390,6 @@ static int __devinit snd_fm801_create(struct snd_card *card,
                                      struct fm801 ** rchip)
 {
        struct fm801 *chip;
-       unsigned char rev;
        int err;
        static struct snd_device_ops ops = {
                .dev_free =     snd_fm801_dev_free,
@@ -1395,7 +1415,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
        }
        chip->port = pci_resource_start(pci, 0);
        if ((tea575x_tuner & 0x0010) == 0) {
-               if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_DISABLED|IRQF_SHARED,
+               if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
                                "FM801", chip)) {
                        snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
                        snd_fm801_free(chip);
@@ -1405,8 +1425,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
                pci_set_master(pci);
        }
 
-       pci_read_config_byte(pci, PCI_REVISION_ID, &rev);
-       if (rev >= 0xb1)        /* FM801-AU */
+       if (pci->revision >= 0xb1)      /* FM801-AU */
                chip->multichannel = 1;
 
        snd_fm801_chip_init(chip, 0);