Skip to content

Commit

Permalink
ALSA: ctxfi - Make volume controls more intuitive
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Takashi Iwai committed Jun 8, 2009
1 parent 54de6bc commit d436dd0
Showing 1 changed file with 32 additions and 17 deletions.
49 changes: 32 additions & 17 deletions sound/pci/ctxfi/ctmixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

#include "ctmixer.h"
#include "ctamixer.h"
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/asoundef.h>
#include <sound/pcm.h>
#include <linux/slab.h>
#include <sound/tlv.h>

enum CT_SUM_CTL {
SUM_IN_F,
Expand Down Expand Up @@ -292,6 +293,7 @@ set_switch_state(struct ct_mixer *mixer,
mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START));
}

#if 0 /* not used */
/* Map integer value ranging from 0 to 65535 to 14-bit float value ranging
* from 2^-6 to (1+1023/1024) */
static unsigned int uint16_to_float14(unsigned int x)
Expand Down Expand Up @@ -331,15 +333,20 @@ static unsigned int float14_to_uint16(unsigned int x)

return x;
}
#endif /* not used */

#define VOL_SCALE 0x1c
#define VOL_MAX 0x100

static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1);

static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 43690;
uinfo->value.integer.step = 128;
uinfo->value.integer.max = VOL_MAX;

return 0;
}
Expand All @@ -349,15 +356,18 @@ static int ct_alsa_mix_volume_get(struct snd_kcontrol *kcontrol,
{
struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value);
struct amixer *amixer = NULL;
int i = 0;
struct amixer *amixer;
int i, val;

for (i = 0; i < 2; i++) {
amixer = ((struct ct_mixer *)atc->mixer)->
amixers[type*CHN_NUM+i];
/* Convert 14-bit float-point scale to 16-bit integer volume */
ucontrol->value.integer.value[i] =
(float14_to_uint16(amixer->ops->get_scale(amixer)) & 0xffff);
val = amixer->ops->get_scale(amixer) / VOL_SCALE;
if (val < 0)
val = 0;
else if (val > VOL_MAX)
val = VOL_MAX;
ucontrol->value.integer.value[i] = val;
}

return 0;
Expand All @@ -369,16 +379,19 @@ static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol,
struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
struct ct_mixer *mixer = atc->mixer;
enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value);
struct amixer *amixer = NULL;
int i = 0, j = 0, change = 0, val = 0;
struct amixer *amixer;
int i, j, val, oval, change = 0;

for (i = 0; i < 2; i++) {
/* Convert 16-bit integer volume to 14-bit float-point scale */
val = (ucontrol->value.integer.value[i] & 0xffff);
val = ucontrol->value.integer.value[i];
if (val < 0)
val = 0;
else if (val > VOL_MAX)
val = VOL_MAX;
val *= VOL_SCALE;
amixer = mixer->amixers[type*CHN_NUM+i];
if ((float14_to_uint16(amixer->ops->get_scale(amixer)) & 0xff80)
!= (val & 0xff80)) {
val = uint16_to_float14(val);
oval = amixer->ops->get_scale(amixer);
if (val != oval) {
amixer->ops->set_scale(amixer, val);
amixer->ops->commit_write(amixer);
change = 1;
Expand All @@ -398,11 +411,13 @@ static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol,
}

static struct snd_kcontrol_new vol_ctl = {
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.info = ct_alsa_mix_volume_info,
.get = ct_alsa_mix_volume_get,
.put = ct_alsa_mix_volume_put
.put = ct_alsa_mix_volume_put,
.tlv = { .p = ct_vol_db_scale },
};

static void
Expand Down

0 comments on commit d436dd0

Please sign in to comment.