aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi/ctmixer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-08 07:50:18 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-08 07:50:18 -0400
commitd436dd063be605dc29f17b2cb0b99a852db89bed (patch)
tree811df221765d5610ae06c59f345a2c21a3d247bf /sound/pci/ctxfi/ctmixer.c
parent54de6bc8b2437f642844cecb8d183df2368ffceb (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.c49
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
27enum CT_SUM_CTL { 28enum 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) */
297static unsigned int uint16_to_float14(unsigned int x) 299static 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
341static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1);
334 342
335static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, 343static 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
400static struct snd_kcontrol_new vol_ctl = { 413static 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
408static void 423static void