diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-08 07:50:18 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-08 07:50:18 -0400 |
commit | d436dd063be605dc29f17b2cb0b99a852db89bed (patch) | |
tree | 811df221765d5610ae06c59f345a2c21a3d247bf /sound/pci/ctxfi/ctmixer.c | |
parent | 54de6bc8b2437f642844cecb8d183df2368ffceb (diff) |
ALSA: ctxfi - Make volume controls more intuitive
Change the volume control to dB scale (as the raw data seems so).
Also added the TLV dB-scale information.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ctxfi/ctmixer.c')
-rw-r--r-- | sound/pci/ctxfi/ctmixer.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index fac783f585fc..796156e4bd38 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c | |||
@@ -18,11 +18,12 @@ | |||
18 | 18 | ||
19 | #include "ctmixer.h" | 19 | #include "ctmixer.h" |
20 | #include "ctamixer.h" | 20 | #include "ctamixer.h" |
21 | #include <linux/slab.h> | ||
21 | #include <sound/core.h> | 22 | #include <sound/core.h> |
22 | #include <sound/control.h> | 23 | #include <sound/control.h> |
23 | #include <sound/asoundef.h> | 24 | #include <sound/asoundef.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
25 | #include <linux/slab.h> | 26 | #include <sound/tlv.h> |
26 | 27 | ||
27 | enum CT_SUM_CTL { | 28 | enum CT_SUM_CTL { |
28 | SUM_IN_F, | 29 | SUM_IN_F, |
@@ -292,6 +293,7 @@ set_switch_state(struct ct_mixer *mixer, | |||
292 | mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START)); | 293 | mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START)); |
293 | } | 294 | } |
294 | 295 | ||
296 | #if 0 /* not used */ | ||
295 | /* Map integer value ranging from 0 to 65535 to 14-bit float value ranging | 297 | /* Map integer value ranging from 0 to 65535 to 14-bit float value ranging |
296 | * from 2^-6 to (1+1023/1024) */ | 298 | * from 2^-6 to (1+1023/1024) */ |
297 | static unsigned int uint16_to_float14(unsigned int x) | 299 | static unsigned int uint16_to_float14(unsigned int x) |
@@ -331,6 +333,12 @@ static unsigned int float14_to_uint16(unsigned int x) | |||
331 | 333 | ||
332 | return x; | 334 | return x; |
333 | } | 335 | } |
336 | #endif /* not used */ | ||
337 | |||
338 | #define VOL_SCALE 0x1c | ||
339 | #define VOL_MAX 0x100 | ||
340 | |||
341 | static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1); | ||
334 | 342 | ||
335 | static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, | 343 | static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, |
336 | struct snd_ctl_elem_info *uinfo) | 344 | struct snd_ctl_elem_info *uinfo) |
@@ -338,8 +346,7 @@ static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, | |||
338 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 346 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
339 | uinfo->count = 2; | 347 | uinfo->count = 2; |
340 | uinfo->value.integer.min = 0; | 348 | uinfo->value.integer.min = 0; |
341 | uinfo->value.integer.max = 43690; | 349 | uinfo->value.integer.max = VOL_MAX; |
342 | uinfo->value.integer.step = 128; | ||
343 | 350 | ||
344 | return 0; | 351 | return 0; |
345 | } | 352 | } |
@@ -349,15 +356,18 @@ static int ct_alsa_mix_volume_get(struct snd_kcontrol *kcontrol, | |||
349 | { | 356 | { |
350 | struct ct_atc *atc = snd_kcontrol_chip(kcontrol); | 357 | struct ct_atc *atc = snd_kcontrol_chip(kcontrol); |
351 | enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); | 358 | enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); |
352 | struct amixer *amixer = NULL; | 359 | struct amixer *amixer; |
353 | int i = 0; | 360 | int i, val; |
354 | 361 | ||
355 | for (i = 0; i < 2; i++) { | 362 | for (i = 0; i < 2; i++) { |
356 | amixer = ((struct ct_mixer *)atc->mixer)-> | 363 | amixer = ((struct ct_mixer *)atc->mixer)-> |
357 | amixers[type*CHN_NUM+i]; | 364 | amixers[type*CHN_NUM+i]; |
358 | /* Convert 14-bit float-point scale to 16-bit integer volume */ | 365 | val = amixer->ops->get_scale(amixer) / VOL_SCALE; |
359 | ucontrol->value.integer.value[i] = | 366 | if (val < 0) |
360 | (float14_to_uint16(amixer->ops->get_scale(amixer)) & 0xffff); | 367 | val = 0; |
368 | else if (val > VOL_MAX) | ||
369 | val = VOL_MAX; | ||
370 | ucontrol->value.integer.value[i] = val; | ||
361 | } | 371 | } |
362 | 372 | ||
363 | return 0; | 373 | return 0; |
@@ -369,16 +379,19 @@ static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol, | |||
369 | struct ct_atc *atc = snd_kcontrol_chip(kcontrol); | 379 | struct ct_atc *atc = snd_kcontrol_chip(kcontrol); |
370 | struct ct_mixer *mixer = atc->mixer; | 380 | struct ct_mixer *mixer = atc->mixer; |
371 | enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); | 381 | enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); |
372 | struct amixer *amixer = NULL; | 382 | struct amixer *amixer; |
373 | int i = 0, j = 0, change = 0, val = 0; | 383 | int i, j, val, oval, change = 0; |
374 | 384 | ||
375 | for (i = 0; i < 2; i++) { | 385 | for (i = 0; i < 2; i++) { |
376 | /* Convert 16-bit integer volume to 14-bit float-point scale */ | 386 | val = ucontrol->value.integer.value[i]; |
377 | val = (ucontrol->value.integer.value[i] & 0xffff); | 387 | if (val < 0) |
388 | val = 0; | ||
389 | else if (val > VOL_MAX) | ||
390 | val = VOL_MAX; | ||
391 | val *= VOL_SCALE; | ||
378 | amixer = mixer->amixers[type*CHN_NUM+i]; | 392 | amixer = mixer->amixers[type*CHN_NUM+i]; |
379 | if ((float14_to_uint16(amixer->ops->get_scale(amixer)) & 0xff80) | 393 | oval = amixer->ops->get_scale(amixer); |
380 | != (val & 0xff80)) { | 394 | if (val != oval) { |
381 | val = uint16_to_float14(val); | ||
382 | amixer->ops->set_scale(amixer, val); | 395 | amixer->ops->set_scale(amixer, val); |
383 | amixer->ops->commit_write(amixer); | 396 | amixer->ops->commit_write(amixer); |
384 | change = 1; | 397 | change = 1; |
@@ -398,11 +411,13 @@ static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol, | |||
398 | } | 411 | } |
399 | 412 | ||
400 | static struct snd_kcontrol_new vol_ctl = { | 413 | static struct snd_kcontrol_new vol_ctl = { |
401 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 414 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
415 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
402 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 416 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
403 | .info = ct_alsa_mix_volume_info, | 417 | .info = ct_alsa_mix_volume_info, |
404 | .get = ct_alsa_mix_volume_get, | 418 | .get = ct_alsa_mix_volume_get, |
405 | .put = ct_alsa_mix_volume_put | 419 | .put = ct_alsa_mix_volume_put, |
420 | .tlv = { .p = ct_vol_db_scale }, | ||
406 | }; | 421 | }; |
407 | 422 | ||
408 | static void | 423 | static void |