diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-11-15 09:54:38 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:24 -0500 |
commit | 68ea7b2f2d8c1effd662fded04e9a589cb640da6 (patch) | |
tree | e104282748345692c2a71572a260bf926501ebde /sound/pci/hda/patch_sigmatel.c | |
parent | 7e39e2273a9b8182ed1b21af5444e29843fc06ca (diff) |
[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 'sound/pci/hda/patch_sigmatel.c')
-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, | |||
349 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 349 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
350 | struct sigmatel_spec *spec = codec->spec; | 350 | struct sigmatel_spec *spec = codec->spec; |
351 | unsigned int dac_mode; | 351 | unsigned int dac_mode; |
352 | unsigned int val; | ||
352 | 353 | ||
353 | if (spec->aloopback == ucontrol->value.integer.value[0]) | 354 | val = !!ucontrol->value.integer.value[0]; |
355 | if (spec->aloopback == val) | ||
354 | return 0; | 356 | return 0; |
355 | 357 | ||
356 | spec->aloopback = ucontrol->value.integer.value[0]; | 358 | spec->aloopback = val; |
357 | |||
358 | 359 | ||
359 | dac_mode = snd_hda_codec_read(codec, codec->afg, 0, | 360 | dac_mode = snd_hda_codec_read(codec, codec->afg, 0, |
360 | kcontrol->private_value & 0xFFFF, 0x0); | 361 | kcontrol->private_value & 0xFFFF, 0x0); |
@@ -373,6 +374,42 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, | |||
373 | return 1; | 374 | return 1; |
374 | } | 375 | } |
375 | 376 | ||
377 | static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol, | ||
378 | struct snd_ctl_elem_info *uinfo) | ||
379 | { | ||
380 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
381 | uinfo->count = 1; | ||
382 | uinfo->value.integer.min = 0; | ||
383 | uinfo->value.integer.max = 127; | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol, | ||
388 | struct snd_ctl_elem_value *ucontrol) | ||
389 | { | ||
390 | ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff; | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol, | ||
395 | struct snd_ctl_elem_value *ucontrol) | ||
396 | { | ||
397 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
398 | unsigned int oval = kcontrol->private_value & 0xff; | ||
399 | unsigned int val; | ||
400 | |||
401 | val = ucontrol->value.integer.value[0] & 0xff; | ||
402 | if (val == oval) | ||
403 | return 0; | ||
404 | |||
405 | kcontrol->private_value &= ~0xff; | ||
406 | kcontrol->private_value |= val; | ||
407 | |||
408 | snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0, | ||
409 | AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80); | ||
410 | return 1; | ||
411 | } | ||
412 | |||
376 | static struct hda_verb stac9200_core_init[] = { | 413 | static struct hda_verb stac9200_core_init[] = { |
377 | /* set dac0mux for dac converter */ | 414 | /* set dac0mux for dac converter */ |
378 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 415 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -1588,7 +1625,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1588 | struct sigmatel_spec *spec = codec->spec; | 1625 | struct sigmatel_spec *spec = codec->spec; |
1589 | hda_nid_t nid = kcontrol->private_value >> 8; | 1626 | hda_nid_t nid = kcontrol->private_value >> 8; |
1590 | int io_idx = kcontrol-> private_value & 0xff; | 1627 | int io_idx = kcontrol-> private_value & 0xff; |
1591 | unsigned short val = ucontrol->value.integer.value[0]; | 1628 | unsigned short val = !!ucontrol->value.integer.value[0]; |
1592 | 1629 | ||
1593 | spec->io_switch[io_idx] = val; | 1630 | spec->io_switch[io_idx] = val; |
1594 | 1631 | ||
@@ -1628,11 +1665,12 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, | |||
1628 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1665 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1629 | struct sigmatel_spec *spec = codec->spec; | 1666 | struct sigmatel_spec *spec = codec->spec; |
1630 | hda_nid_t nid = kcontrol->private_value & 0xff; | 1667 | hda_nid_t nid = kcontrol->private_value & 0xff; |
1668 | unsigned int val = !!ucontrol->value.integer.value[0]; | ||
1631 | 1669 | ||
1632 | if (spec->clfe_swap == ucontrol->value.integer.value[0]) | 1670 | if (spec->clfe_swap == val) |
1633 | return 0; | 1671 | return 0; |
1634 | 1672 | ||
1635 | spec->clfe_swap = ucontrol->value.integer.value[0]; | 1673 | spec->clfe_swap = val; |
1636 | 1674 | ||
1637 | snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, | 1675 | snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, |
1638 | spec->clfe_swap ? 0x4 : 0x0); | 1676 | spec->clfe_swap ? 0x4 : 0x0); |