diff options
author | Jaroslav Kysela <perex@suse.cz> | 2006-07-05 11:39:49 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 04:37:36 -0400 |
commit | 302e9c5af4fb3ea258917ee6a32e9e45f578b231 (patch) | |
tree | 2f3c5f8c48c198fc3a7c7b1460d094549cd7d313 /sound/pci/hda/hda_codec.c | |
parent | 7f0e2f8bb851f5e0a2e0fef465b7b6f36c7aa7be (diff) |
[ALSA] HDA codec & CA0106 - add/fix TLV support
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 23201f3eeb12..78ff4575699d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <sound/core.h> | 29 | #include <sound/core.h> |
30 | #include "hda_codec.h" | 30 | #include "hda_codec.h" |
31 | #include <sound/asoundef.h> | 31 | #include <sound/asoundef.h> |
32 | #include <sound/tlv.h> | ||
32 | #include <sound/initval.h> | 33 | #include <sound/initval.h> |
33 | #include "hda_local.h" | 34 | #include "hda_local.h" |
34 | 35 | ||
@@ -841,6 +842,38 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
841 | return change; | 842 | return change; |
842 | } | 843 | } |
843 | 844 | ||
845 | int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
846 | unsigned int size, unsigned int __user *_tlv) | ||
847 | { | ||
848 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
849 | hda_nid_t nid = get_amp_nid(kcontrol); | ||
850 | int dir = get_amp_direction(kcontrol); | ||
851 | u32 caps, val1, val2; | ||
852 | |||
853 | if (size < 4 * sizeof(unsigned int)) | ||
854 | return -ENOMEM; | ||
855 | caps = query_amp_caps(codec, nid, dir); | ||
856 | val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25; | ||
857 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); | ||
858 | val1 = ((int)val1) * ((int)val2); | ||
859 | if (caps & AC_AMPCAP_MUTE) | ||
860 | val2 |= 0x10000; | ||
861 | if ((val2 & 0x10000) == 0 && dir == HDA_OUTPUT) { | ||
862 | caps = query_amp_caps(codec, nid, HDA_INPUT); | ||
863 | if (caps & AC_AMPCAP_MUTE) | ||
864 | val2 |= 0x10000; | ||
865 | } | ||
866 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | ||
867 | return -EFAULT; | ||
868 | if (put_user(2 * sizeof(unsigned int), _tlv + 1)) | ||
869 | return -EFAULT; | ||
870 | if (put_user(val1, _tlv + 2)) | ||
871 | return -EFAULT; | ||
872 | if (put_user(val2, _tlv + 3)) | ||
873 | return -EFAULT; | ||
874 | return 0; | ||
875 | } | ||
876 | |||
844 | /* switch */ | 877 | /* switch */ |
845 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 878 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
846 | { | 879 | { |