V4L/DVB (4872): Saa7134-alsa improvements
authorHartmut Hackmann <hartmut.hackmann@t-online.de>
Tue, 21 Nov 2006 22:59:27 +0000 (19:59 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sun, 10 Dec 2006 11:05:08 +0000 (09:05 -0200)
The change does the following:
- At device open, it sets the recording source to the current
  input instead of LINE2. So it is no longer necessary to set the
  recording source with a mixer application.
- Connects the mixer volume control to the input sensitivity selection
  of the analog sound inputs. This allows only one 6db step.

Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/saa7134/saa7134-alsa.c

index 4abf5c03a740f14c035d771349bd3ea82159772f..ffb0f647a86d6b7b84f873d826a370e19924f75a 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
@@ -614,13 +610,18 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
        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;
 
        mutex_lock(&dev->dmasound.lock);
 
        dev->dmasound.read_count  = 0;
        dev->dmasound.read_offset = 0;
 
+       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);
@@ -713,6 +714,8 @@ 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;
 
@@ -727,10 +730,52 @@ static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
        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;
 }