Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=82896f29d47d945e331873c7295da9e3a47d709d
Commit:     82896f29d47d945e331873c7295da9e3a47d709d
Parent:     6fcecce7e1a5223be450031fa446323b08d1ec41
Author:     Trent Piepho <[EMAIL PROTECTED]>
AuthorDate: Thu Sep 6 23:02:23 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 22:08:31 2007 -0300

    V4L/DVB (6184): cx88-alsa: Make volume control stereo
    
    Use the balance control to make the mono volume control stereo.
    
    Note that full range isn't supported.  The balance control attenuates one
    channel by 0 to -63 dB, and the volume control provides additional 
attenuation
    to both channels by another 0 to -63 dB.
    
    So the channel with the most attenuation has a range of 0 to -126 dB, while
    the other channel only has a range of 0 to -63 dB.  ALSA volume controls 
don't
    appear to support this concept.  I just limited the range to 0 to -63 total.
    Once you get to -63 dB, you're already at silence, so additional attenuation
    is pretty much pointless anyway.
    
    Signed-off-by: Trent Piepho <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/cx88/cx88-alsa.c |   61 ++++++++++++++++++++-------------
 1 files changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/media/video/cx88/cx88-alsa.c 
b/drivers/media/video/cx88/cx88-alsa.c
index 85d6322..25de25f 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -552,7 +552,7 @@ static int snd_cx88_capture_volume_info(struct snd_kcontrol 
*kcontrol,
                                        struct snd_ctl_elem_info *info)
 {
        info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-       info->count = 1;
+       info->count = 2;
        info->value.integer.min = 0;
        info->value.integer.max = 0x3f;
 
@@ -565,8 +565,12 @@ static int snd_cx88_capture_volume_get(struct snd_kcontrol 
*kcontrol,
 {
        snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
        struct cx88_core *core=chip->core;
+       int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f),
+           bal = cx_read(AUD_BAL_CTL);
 
-       value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
+       value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol;
+       vol -= (bal & 0x3f);
+       value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol;
 
        return 0;
 }
@@ -577,19 +581,31 @@ static int snd_cx88_capture_volume_put(struct 
snd_kcontrol *kcontrol,
 {
        snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
        struct cx88_core *core=chip->core;
-       int v;
-       u32 old_control;
-
+       int v, b;
+       int changed = 0;
+       u32 old;
+
+       b = value->value.integer.value[1] - value->value.integer.value[0];
+       if (b < 0) {
+           v = 0x3f - value->value.integer.value[0];
+           b = (-b) | 0x40;
+       } else {
+           v = 0x3f - value->value.integer.value[1];
+       }
        /* Do we really know this will always be called with IRQs on? */
        spin_lock_irq(&chip->reg_lock);
-
-       old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
-       v = 0x3f - (value->value.integer.value[0] & 0x3f);
-       cx_andor(AUD_VOL_CTL, 0x3f, v);
-
+       old = cx_read(AUD_VOL_CTL);
+       if (v != (old & 0x3f)) {
+           cx_write(AUD_VOL_CTL, (old & ~0x3f) | v);
+           changed = 1;
+       }
+       if (cx_read(AUD_BAL_CTL) != b) {
+           cx_write(AUD_BAL_CTL, b);
+           changed = 1;
+       }
        spin_unlock_irq(&chip->reg_lock);
 
-       return v != old_control;
+       return changed;
 }
 
 static struct snd_kcontrol_new snd_cx88_capture_volume = {
@@ -746,17 +762,12 @@ static int __devinit cx88_audio_initdev(struct pci_dev 
*pci,
                return (err);
 
        err = snd_cx88_pcm(chip, 0, "CX88 Digital");
-
-       if (err < 0) {
-               snd_card_free(card);
-               return (err);
-       }
+       if (err < 0)
+               goto error;
 
        err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
-       if (err < 0) {
-               snd_card_free(card);
-               return (err);
-       }
+       if (err < 0)
+               goto error;
 
        strcpy (card->driver, "CX88x");
        sprintf(card->shortname, "Conexant CX%x", pci->device);
@@ -768,14 +779,16 @@ static int __devinit cx88_audio_initdev(struct pci_dev 
*pci,
               card->driver,devno);
 
        err = snd_card_register(card);
-       if (err < 0) {
-               snd_card_free(card);
-               return (err);
-       }
+       if (err < 0)
+               goto error;
        pci_set_drvdata(pci,card);
 
        devno++;
        return 0;
+
+error:
+       snd_card_free(card);
+       return err;
 }
 /*
  * ALSA destructor
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to