V4L/DVB (6079): Cleanup: remove linux/moduleparam.h from drivers/media files
[linux-2.6.git] / drivers / media / video / saa7134 / saa7134-alsa.c
index ade05f7..eb5e77d 100644 (file)
@@ -1,10 +1,6 @@
 /*
  *   SAA713x ALSA support for V4L
  *
- *
- *   Caveats:
- *        - Volume doesn't work (it's always at max)
- *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, version 2
  *
  */
 
-#include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
 #include <linux/module.h>
+#include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
@@ -54,10 +49,12 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
 
 module_param_array(index, int, NULL, 0444);
+module_param_array(enable, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
+MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");
 
 #define dprintk(fmt, arg...)    if (debug) \
        printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg)
@@ -69,7 +66,7 @@ MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
  */
 
 typedef struct snd_card_saa7134 {
-       snd_card_t *card;
+       struct snd_card *card;
        spinlock_t mixer_lock;
        int mixer_volume[MIXER_ADDR_LAST+1][2];
        int capture_source[MIXER_ADDR_LAST+1][2];
@@ -77,7 +74,8 @@ typedef struct snd_card_saa7134 {
        struct saa7134_dev *dev;
 
        unsigned long iobase;
-       int irq;
+       s16 irq;
+       u16 mute_was_on;
 
        spinlock_t lock;
 } snd_card_saa7134_t;
@@ -93,10 +91,10 @@ typedef struct snd_card_saa7134_pcm {
 
        spinlock_t lock;
 
-       snd_pcm_substream_t *substream;
+       struct snd_pcm_substream *substream;
 } snd_card_saa7134_pcm_t;
 
-static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
+static struct snd_card *snd_saa7134_cards[SNDRV_CARDS];
 
 
 /*
@@ -210,7 +208,7 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
  *
  */
 
-static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id)
 {
        struct saa7134_dmasound *dmasound = dev_id;
        struct saa7134_dev *dev = dmasound->priv_data;
@@ -249,10 +247,10 @@ out:
  *
  */
 
-static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream,
                                          int cmd)
 {
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime = substream->runtime;
        snd_card_saa7134_pcm_t *pcm = runtime->private_data;
        struct saa7134_dev *dev=pcm->dev;
        int err = 0;
@@ -306,8 +304,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
 
 static int dsp_buffer_free(struct saa7134_dev *dev)
 {
-       if (!dev->dmasound.blksize)
-               BUG();
+       BUG_ON(!dev->dmasound.blksize);
 
        videobuf_dma_free(&dev->dmasound.dma);
 
@@ -331,9 +328,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
  *
  */
 
-static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream)
 {
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime = substream->runtime;
        int bswap, sign;
        u32 fmt, control;
        snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
@@ -420,9 +417,10 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
  *
  */
 
-static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
 {
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime = substream->runtime;
        snd_card_saa7134_pcm_t *pcm = runtime->private_data;
        struct saa7134_dev *dev=pcm->dev;
 
@@ -440,7 +438,7 @@ static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t *
  * ALSA hardware capabilities definition
  */
 
-static snd_pcm_hardware_t snd_card_saa7134_capture =
+static struct snd_pcm_hardware snd_card_saa7134_capture =
 {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -463,7 +461,7 @@ static snd_pcm_hardware_t snd_card_saa7134_capture =
        .periods_max =          1024,
 };
 
-static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
+static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime)
 {
        snd_card_saa7134_pcm_t *pcm = runtime->private_data;
 
@@ -480,8 +478,8 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
  *
  */
 
-static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
-                                   snd_pcm_hw_params_t * hw_params)
+static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
+                                     struct snd_pcm_hw_params * hw_params)
 {
        snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
        struct saa7134_dev *dev;
@@ -505,7 +503,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
        /* release the old buffer */
        if (substream->runtime->dma_area) {
                saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
-               videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+               videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
                dsp_buffer_free(dev);
                substream->runtime->dma_area = NULL;
        }
@@ -521,12 +519,12 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
                return err;
        }
 
-       if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) {
+       if (0 != (err = videobuf_pci_dma_map(dev->pci, &dev->dmasound.dma))) {
                dsp_buffer_free(dev);
                return err;
        }
        if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
-               videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+               videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
                dsp_buffer_free(dev);
                return err;
        }
@@ -535,7 +533,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
                                                dev->dmasound.dma.sglen,
                                                0))) {
                saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
-               videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+               videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
                dsp_buffer_free(dev);
                return err;
        }
@@ -560,7 +558,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
  *
  */
 
-static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
+static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
 {
        snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
        struct saa7134_dev *dev;
@@ -569,7 +567,7 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
 
        if (substream->runtime->dma_area) {
                saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
-               videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+               videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
                dsp_buffer_free(dev);
                substream->runtime->dma_area = NULL;
        }
@@ -586,8 +584,15 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
  *
  */
 
-static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
+static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
 {
+       snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+       struct saa7134_dev *dev = saa7134->dev;
+
+       if (saa7134->mute_was_on) {
+               dev->ctl_mute = 1;
+               saa7134_tvaudio_setmute(dev);
+       }
        return 0;
 }
 
@@ -601,20 +606,25 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
  *
  */
 
-static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
+static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
 {
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime = substream->runtime;
        snd_card_saa7134_pcm_t *pcm;
        snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
        struct saa7134_dev *dev = saa7134->dev;
-       int err;
+       int amux, err;
 
-       down(&dev->dmasound.lock);
+       mutex_lock(&dev->dmasound.lock);
 
        dev->dmasound.read_count  = 0;
        dev->dmasound.read_offset = 0;
 
-       up(&dev->dmasound.lock);
+       amux = dev->input->amux;
+       if ((amux < 1) || (amux > 3))
+               amux = 1;
+       dev->dmasound.input  =  amux - 1;
+
+       mutex_unlock(&dev->dmasound.lock);
 
        pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
        if (pcm == NULL)
@@ -629,6 +639,12 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
        runtime->private_free = snd_card_saa7134_runtime_free;
        runtime->hw = snd_card_saa7134_capture;
 
+       if (dev->ctl_mute != 0) {
+               saa7134->mute_was_on = 1;
+               dev->ctl_mute = 0;
+               saa7134_tvaudio_setmute(dev);
+       }
+
        if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
                return err;
 
@@ -639,7 +655,7 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
  * ALSA capture callbacks definition
  */
 
-static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
+static struct snd_pcm_ops snd_card_saa7134_capture_ops = {
        .open =                 snd_card_saa7134_capture_open,
        .close =                snd_card_saa7134_capture_close,
        .ioctl =                snd_pcm_lib_ioctl,
@@ -660,7 +676,7 @@ static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
 
 static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
 {
-       snd_pcm_t *pcm;
+       struct snd_pcm *pcm;
        int err;
 
        if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
@@ -678,7 +694,8 @@ static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
   .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
   .private_value = addr }
 
-static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol,
+                                  struct snd_ctl_elem_info * uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->count = 2;
@@ -687,7 +704,8 @@ static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
        return 0;
 }
 
-static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol,
+                                 struct snd_ctl_elem_value * ucontrol)
 {
        snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
        int addr = kcontrol->private_value;
@@ -697,9 +715,12 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
        return 0;
 }
 
-static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
+                                 struct snd_ctl_elem_value * ucontrol)
 {
        snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+       struct saa7134_dev *dev = chip->dev;
+
        int change, addr = kcontrol->private_value;
        int left, right;
 
@@ -714,10 +735,52 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
        if (right > 20)
                right = 20;
        spin_lock_irq(&chip->mixer_lock);
-       change = chip->mixer_volume[addr][0] != left ||
-                chip->mixer_volume[addr][1] != right;
-       chip->mixer_volume[addr][0] = left;
-       chip->mixer_volume[addr][1] = right;
+       change = 0;
+       if (chip->mixer_volume[addr][0] != left) {
+               change = 1;
+               right = left;
+       }
+       if (chip->mixer_volume[addr][1] != right) {
+               change = 1;
+               left = right;
+       }
+       if (change) {
+               switch (dev->pci->device) {
+                       case PCI_DEVICE_ID_PHILIPS_SAA7134:
+                               switch (addr) {
+                                       case MIXER_ADDR_TVTUNER:
+                                               left = 20;
+                                               break;
+                                       case MIXER_ADDR_LINE1:
+                                               saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
+                                                          (left > 10) ? 0x00 : 0x10);
+                                               break;
+                                       case MIXER_ADDR_LINE2:
+                                               saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
+                                                          (left > 10) ? 0x00 : 0x20);
+                                               break;
+                               }
+                               break;
+                       case PCI_DEVICE_ID_PHILIPS_SAA7133:
+                       case PCI_DEVICE_ID_PHILIPS_SAA7135:
+                               switch (addr) {
+                                       case MIXER_ADDR_TVTUNER:
+                                               left = 20;
+                                               break;
+                                       case MIXER_ADDR_LINE1:
+                                               saa_andorb(0x0594,  0x10,
+                                                          (left > 10) ? 0x00 : 0x10);
+                                               break;
+                                       case MIXER_ADDR_LINE2:
+                                               saa_andorb(0x0594,  0x20,
+                                                          (left > 10) ? 0x00 : 0x20);
+                                               break;
+                               }
+                               break;
+               }
+               chip->mixer_volume[addr][0] = left;
+               chip->mixer_volume[addr][1] = right;
+       }
        spin_unlock_irq(&chip->mixer_lock);
        return change;
 }
@@ -728,7 +791,8 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
   .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
   .private_value = addr }
 
-static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol,
+                                  struct snd_ctl_elem_info * uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
        uinfo->count = 2;
@@ -737,7 +801,8 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
        return 0;
 }
 
-static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
+                                 struct snd_ctl_elem_value * ucontrol)
 {
        snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
        int addr = kcontrol->private_value;
@@ -750,7 +815,8 @@ static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
        return 0;
 }
 
-static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
+                                 struct snd_ctl_elem_value * ucontrol)
 {
        snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
        int change, addr = kcontrol->private_value;
@@ -810,7 +876,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
                                break;
                }
 
-               /* output xbar always main channel */
+               /* output xbar always main channel */
                saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
 
                if (left || right) { // We've got data, turn the input on
@@ -827,7 +893,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
        return change;
 }
 
-static snd_kcontrol_new_t snd_saa7134_controls[] = {
+static struct snd_kcontrol_new snd_saa7134_controls[] = {
 SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
 SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
 SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
@@ -846,7 +912,7 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
 
 static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
 {
-       snd_card_t *card = chip->card;
+       struct snd_card *card = chip->card;
        unsigned int idx;
        int err;
 
@@ -860,7 +926,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
        return 0;
 }
 
-static void snd_saa7134_free(snd_card_t * card)
+static void snd_saa7134_free(struct snd_card * card)
 {
        snd_card_saa7134_t *chip = card->private_data;
 
@@ -887,7 +953,7 @@ static void snd_saa7134_free(snd_card_t * card)
 static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 {
 
-       snd_card_t *card;
+       struct snd_card *card;
        snd_card_saa7134_t *chip;
        int err;
 
@@ -921,7 +987,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 
 
        err = request_irq(dev->pci->irq, saa7134_alsa_irq,
-                               SA_SHIRQ | SA_INTERRUPT, dev->name,
+                               IRQF_SHARED | IRQF_DISABLED, dev->name,
                                (void*) &dev->dmasound);
 
        if (err < 0) {
@@ -932,7 +998,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 
        chip->irq = dev->pci->irq;
 
-       init_MUTEX(&dev->dmasound.lock);
+       mutex_init(&dev->dmasound.lock);
 
        if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
                goto __nodev;
@@ -989,9 +1055,9 @@ static int saa7134_alsa_init(void)
        struct saa7134_dev *dev = NULL;
        struct list_head *list;
 
-       if (!dmasound_init && !dmasound_exit) {
-               dmasound_init = alsa_device_init;
-               dmasound_exit = alsa_device_exit;
+       if (!saa7134_dmasound_init && !saa7134_dmasound_exit) {
+               saa7134_dmasound_init = alsa_device_init;
+               saa7134_dmasound_exit = alsa_device_exit;
        } else {
                printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n");
                return -EBUSY;
@@ -1028,8 +1094,8 @@ static void saa7134_alsa_exit(void)
                snd_card_free(snd_saa7134_cards[idx]);
        }
 
-       dmasound_init = NULL;
-       dmasound_exit = NULL;
+       saa7134_dmasound_init = NULL;
+       saa7134_dmasound_exit = NULL;
        printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
 
        return;