[ALSA] fm801 - Add mute support for FM-only card with FM801 PCI to tuner bridge
authorAndy Shevchenko <andy@smile.org.ua>
Thu, 24 Jan 2008 17:11:53 +0000 (18:11 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 31 Jan 2008 16:30:14 +0000 (17:30 +0100)
This is improvement of the early support of the FM-only cards where the
fm801 chip represents the PCI to tuner bridge.
The tuner initialization isn't included the mute on as well as mute support
via V4L request. Proposed patch should fix this at least for 64-PCR model.

Signed-off-by: Andy Shevchenko <andy@smile.org.ua>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/sound/tea575x-tuner.h
sound/i2c/other/tea575x-tuner.c
sound/pci/fm801.c

index e8eeb3a1ed291fd0aae971cf45d1ced075785bce..b62ce3e077f9176274b80156afdafcd027edfe0c 100644 (file)
@@ -30,6 +30,7 @@ struct snd_tea575x;
 struct snd_tea575x_ops {
        void (*write)(struct snd_tea575x *tea, unsigned int val);
        unsigned int (*read)(struct snd_tea575x *tea);
+       void (*mute)(struct snd_tea575x *tea, unsigned int mute);
 };
 
 struct snd_tea575x {
index 28a4af782f5e43943f199d77626c05f8dd2e4bac..87e3aefeddc39bf73f2b16465b71f5dc95d16795 100644 (file)
@@ -158,6 +158,10 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
                        struct video_audio v;
                        if(copy_from_user(&v, arg, sizeof(v))) 
                                return -EFAULT; 
+                       if (tea->ops->mute)
+                               tea->ops->mute(tea,
+                                              (v.flags &
+                                               VIDEO_AUDIO_MUTE) ? 1 : 0);
                        if(v.audio) 
                                return -EINVAL;
                        return 0;
@@ -205,6 +209,10 @@ void snd_tea575x_init(struct snd_tea575x *tea)
        tea->freq = 90500 * 16;         /* 90.5Mhz default */
 
        snd_tea575x_set_freq(tea);
+
+       /* mute on init */
+       if (tea->ops->mute)
+               tea->ops->mute(tea, 1);
 }
 
 void snd_tea575x_exit(struct snd_tea575x *tea)
index 25c1087d2c006dbc9976b041d94c300f2f1d3b55..4c300e6149fca554891ae85eb2685caf36d0b23b 100644 (file)
@@ -978,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 */
@@ -993,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