diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-11-15 15:54:38 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 17:29:24 +0100 |
commit | 68ea7b2f2d8c1effd662fded04e9a589cb640da6 (patch) | |
tree | e104282748345692c2a71572a260bf926501ebde /sound/pci/hda/patch_sigmatel.c | |
parent | [ALSA] emu10k1 - Check value ranges in ctl callbacks (diff) | |
download | linux-68ea7b2f2d8c1effd662fded04e9a589cb640da6.tar.xz linux-68ea7b2f2d8c1effd662fded04e9a589cb640da6.zip |
[ALSA] hda-codec - Check value range in ctl callbacks
Check the value ranges in ctl put callbacks properly so that
invalid values won't be stored or written to registers.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to '')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c4447b160a5a..0817f42a7c86 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -349,12 +349,13 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; unsigned int dac_mode; + unsigned int val; - if (spec->aloopback == ucontrol->value.integer.value[0]) + val = !!ucontrol->value.integer.value[0]; + if (spec->aloopback == val) return 0; - spec->aloopback = ucontrol->value.integer.value[0]; - + spec->aloopback = val; dac_mode = snd_hda_codec_read(codec, codec->afg, 0, kcontrol->private_value & 0xFFFF, 0x0); @@ -373,6 +374,42 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, return 1; } +static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 127; + return 0; +} + +static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff; + return 0; +} + +static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + unsigned int oval = kcontrol->private_value & 0xff; + unsigned int val; + + val = ucontrol->value.integer.value[0] & 0xff; + if (val == oval) + return 0; + + kcontrol->private_value &= ~0xff; + kcontrol->private_value |= val; + + snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0, + AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80); + return 1; +} + static struct hda_verb stac9200_core_init[] = { /* set dac0mux for dac converter */ { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -1588,7 +1625,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ struct sigmatel_spec *spec = codec->spec; hda_nid_t nid = kcontrol->private_value >> 8; int io_idx = kcontrol-> private_value & 0xff; - unsigned short val = ucontrol->value.integer.value[0]; + unsigned short val = !!ucontrol->value.integer.value[0]; spec->io_switch[io_idx] = val; @@ -1628,11 +1665,12 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; hda_nid_t nid = kcontrol->private_value & 0xff; + unsigned int val = !!ucontrol->value.integer.value[0]; - if (spec->clfe_swap == ucontrol->value.integer.value[0]) + if (spec->clfe_swap == val) return 0; - spec->clfe_swap = ucontrol->value.integer.value[0]; + spec->clfe_swap = val; snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, spec->clfe_swap ? 0x4 : 0x0); |