aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c4
-rw-r--r--sound/pci/hda/hda_codec.c33
-rw-r--r--sound/pci/hda/hda_local.h5
-rw-r--r--sound/pci/hda/patch_analog.c17
4 files changed, 58 insertions, 1 deletions
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 35309b3ed8c0..df75270939ac 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -472,10 +472,12 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
472#define CA_VOLUME(xname,chid,reg) \ 472#define CA_VOLUME(xname,chid,reg) \
473{ \ 473{ \
474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
475 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
476 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
475 .info = snd_ca0106_volume_info, \ 477 .info = snd_ca0106_volume_info, \
476 .get = snd_ca0106_volume_get, \ 478 .get = snd_ca0106_volume_get, \
477 .put = snd_ca0106_volume_put, \ 479 .put = snd_ca0106_volume_put, \
478 .tlv = snd_ca0106_db_scale, \ 480 .tlv.p = snd_ca0106_db_scale, \
479 .private_value = ((chid) << 8) | (reg) \ 481 .private_value = ((chid) << 8) | (reg) \
480} 482}
481 483
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
845int 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 */
845int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 878int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
846{ 879{
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 14e8aa2806ed..0f0ae685a9c1 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -30,9 +30,13 @@
30/* mono volume with index (index=0,1,...) (channel=1,2) */ 30/* mono volume with index (index=0,1,...) (channel=1,2) */
31#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 31#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
32 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 32 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
33 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
34 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
35 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
33 .info = snd_hda_mixer_amp_volume_info, \ 36 .info = snd_hda_mixer_amp_volume_info, \
34 .get = snd_hda_mixer_amp_volume_get, \ 37 .get = snd_hda_mixer_amp_volume_get, \
35 .put = snd_hda_mixer_amp_volume_put, \ 38 .put = snd_hda_mixer_amp_volume_put, \
39 .tlv.c = snd_hda_mixer_amp_tlv, \
36 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } 40 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
37/* stereo volume with index */ 41/* stereo volume with index */
38#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ 42#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
@@ -63,6 +67,7 @@
63int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); 67int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
64int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 68int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
65int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 69int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
70int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv);
66int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); 71int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
67int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 72int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
68int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 73int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 6823f2bc10b3..54506d4e57d5 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -452,6 +452,19 @@ static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl
452 return change; 452 return change;
453} 453}
454 454
455static int ad1986a_pcm_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
456 unsigned int size, unsigned int __user *_tlv)
457{
458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
459 struct ad198x_spec *ad = codec->spec;
460
461 mutex_lock(&ad->amp_mutex);
462 snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, _tlv);
463 mutex_unlock(&ad->amp_mutex);
464 return 0;
465}
466
467
455#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info 468#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
456 469
457static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 470static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
@@ -488,9 +501,13 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
488 { 501 {
489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
490 .name = "PCM Playback Volume", 503 .name = "PCM Playback Volume",
504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
505 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
506 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
491 .info = ad1986a_pcm_amp_vol_info, 507 .info = ad1986a_pcm_amp_vol_info,
492 .get = ad1986a_pcm_amp_vol_get, 508 .get = ad1986a_pcm_amp_vol_get,
493 .put = ad1986a_pcm_amp_vol_put, 509 .put = ad1986a_pcm_amp_vol_put,
510 .tlv.c = ad1986a_pcm_amp_tlv,
494 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) 511 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
495 }, 512 },
496 { 513 {