mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-03 17:40:04 +00:00
ALSA: ice1724 - aureon - modify WM8770 Master & DAC volume
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>
This commit is contained in:
parent
dd7cdb883b
commit
482e46d4b7
1 changed files with 7 additions and 24 deletions
|
@ -689,32 +689,14 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
|||
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);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
@ -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
|
||||
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);
|
||||
|
@ -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->value.integer.max = 0x7F; /* 0dB */
|
||||
uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
|
||||
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];
|
||||
if (vol > 0x7f)
|
||||
if (vol > WM_VOL_MAX)
|
||||
continue;
|
||||
vol |= spec->vol[ofs+i];
|
||||
if (vol != spec->vol[ofs+i]) {
|
||||
|
|
Loading…
Reference in a new issue