ALSA: ice1724 - aureon - modify WM8770 Master & DAC volume
authorJaroslav Kysela <perex@perex.cz>
Wed, 9 Dec 2009 11:43:44 +0000 (12:43 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 9 Dec 2009 13:09:11 +0000 (14:09 +0100)
The volume levels in original implementation are incorrect and does
not match the dB scale. The real range is linear (in the sense of
the dB scale) from 0dB to -100dB. Remove logaritmic table and make
all volumes from range 0dB..100dB.

The tests are in RedHat's bugzilla #540817.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/ice1712/aureon.c

index 110d16e..765d7bd 100644 (file)
@@ -689,32 +689,14 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
        return change;
 }
 
        return change;
 }
 
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
+static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
 
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
 
-/*
- * Logarithmic volume values for WM8770
- * Computed as 20 * Log10(255 / x)
- */
-static const unsigned char wm_vol[256] = {
-       127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
-       23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
-       17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
-       13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
-       11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
-       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
-       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-       5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
-       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0
-};
-
-#define WM_VOL_MAX     (sizeof(wm_vol) - 1)
+#define WM_VOL_MAX     100
+#define WM_VOL_CNT     101     /* 0dB .. -100dB */
 #define WM_VOL_MUTE    0x8000
 
 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
 #define WM_VOL_MUTE    0x8000
 
 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
@@ -724,7 +706,8 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
        if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
                nvol = 0;
        else
        if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
                nvol = 0;
        else
-               nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
+               nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
+                                                               WM_VOL_MAX;
 
        wm_put(ice, index, nvol);
        wm_put_nocache(ice, index, 0x180 | nvol);
 
        wm_put(ice, index, nvol);
        wm_put_nocache(ice, index, 0x180 | nvol);
@@ -820,7 +803,7 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->count = voices;
        uinfo->value.integer.min = 0;           /* mute (-101dB) */
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->count = voices;
        uinfo->value.integer.min = 0;           /* mute (-101dB) */
-       uinfo->value.integer.max = 0x7F;        /* 0dB */
+       uinfo->value.integer.max = WM_VOL_MAX;  /* 0dB */
        return 0;
 }
 
        return 0;
 }
 
@@ -850,7 +833,7 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
        snd_ice1712_save_gpio_status(ice);
        for (i = 0; i < voices; i++) {
                unsigned int vol = ucontrol->value.integer.value[i];
        snd_ice1712_save_gpio_status(ice);
        for (i = 0; i < voices; i++) {
                unsigned int vol = ucontrol->value.integer.value[i];
-               if (vol > 0x7f)
+               if (vol > WM_VOL_MAX)
                        continue;
                vol |= spec->vol[ofs+i];
                if (vol != spec->vol[ofs+i]) {
                        continue;
                vol |= spec->vol[ofs+i];
                if (vol != spec->vol[ofs+i]) {