aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c76
1 files changed, 60 insertions, 16 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 23201f3eeb12..9c3d7ac08068 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
@@ -50,8 +51,10 @@ struct hda_vendor_id {
50/* codec vendor labels */ 51/* codec vendor labels */
51static struct hda_vendor_id hda_vendor_ids[] = { 52static struct hda_vendor_id hda_vendor_ids[] = {
52 { 0x10ec, "Realtek" }, 53 { 0x10ec, "Realtek" },
54 { 0x1057, "Motorola" },
53 { 0x11d4, "Analog Devices" }, 55 { 0x11d4, "Analog Devices" },
54 { 0x13f6, "C-Media" }, 56 { 0x13f6, "C-Media" },
57 { 0x14f1, "Conexant" },
55 { 0x434d, "C-Media" }, 58 { 0x434d, "C-Media" },
56 { 0x8384, "SigmaTel" }, 59 { 0x8384, "SigmaTel" },
57 {} /* terminator */ 60 {} /* terminator */
@@ -841,6 +844,31 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
841 return change; 844 return change;
842} 845}
843 846
847int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
848 unsigned int size, unsigned int __user *_tlv)
849{
850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
851 hda_nid_t nid = get_amp_nid(kcontrol);
852 int dir = get_amp_direction(kcontrol);
853 u32 caps, val1, val2;
854
855 if (size < 4 * sizeof(unsigned int))
856 return -ENOMEM;
857 caps = query_amp_caps(codec, nid, dir);
858 val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25;
859 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
860 val1 = ((int)val1) * ((int)val2);
861 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
862 return -EFAULT;
863 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
864 return -EFAULT;
865 if (put_user(val1, _tlv + 2))
866 return -EFAULT;
867 if (put_user(val2, _tlv + 3))
868 return -EFAULT;
869 return 0;
870}
871
844/* switch */ 872/* switch */
845int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 873int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
846{ 874{
@@ -1477,10 +1505,10 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
1477 formats |= SNDRV_PCM_FMTBIT_S32_LE; 1505 formats |= SNDRV_PCM_FMTBIT_S32_LE;
1478 if (val & AC_SUPPCM_BITS_32) 1506 if (val & AC_SUPPCM_BITS_32)
1479 bps = 32; 1507 bps = 32;
1480 else if (val & AC_SUPPCM_BITS_20)
1481 bps = 20;
1482 else if (val & AC_SUPPCM_BITS_24) 1508 else if (val & AC_SUPPCM_BITS_24)
1483 bps = 24; 1509 bps = 24;
1510 else if (val & AC_SUPPCM_BITS_20)
1511 bps = 20;
1484 } 1512 }
1485 } 1513 }
1486 else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */ 1514 else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */
@@ -1916,7 +1944,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
1916 1944
1917 /* front */ 1945 /* front */
1918 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); 1946 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
1919 if (mout->hp_nid) 1947 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
1920 /* headphone out will just decode front left/right (stereo) */ 1948 /* headphone out will just decode front left/right (stereo) */
1921 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); 1949 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
1922 /* extra outputs copied from front */ 1950 /* extra outputs copied from front */
@@ -1984,7 +2012,7 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
1984 * in the order of front, rear, CLFE, side, ... 2012 * in the order of front, rear, CLFE, side, ...
1985 * 2013 *
1986 * If more extra outputs (speaker and headphone) are found, the pins are 2014 * If more extra outputs (speaker and headphone) are found, the pins are
1987 * assisnged to hp_pin and speaker_pins[], respectively. If no line-out jack 2015 * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack
1988 * is detected, one of speaker of HP pins is assigned as the primary 2016 * is detected, one of speaker of HP pins is assigned as the primary
1989 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 2017 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
1990 * if any analog output exists. 2018 * if any analog output exists.
@@ -2046,14 +2074,26 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
2046 cfg->speaker_outs++; 2074 cfg->speaker_outs++;
2047 break; 2075 break;
2048 case AC_JACK_HP_OUT: 2076 case AC_JACK_HP_OUT:
2049 cfg->hp_pin = nid; 2077 if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins))
2078 continue;
2079 cfg->hp_pins[cfg->hp_outs] = nid;
2080 cfg->hp_outs++;
2050 break; 2081 break;
2051 case AC_JACK_MIC_IN: 2082 case AC_JACK_MIC_IN: {
2052 if (loc == AC_JACK_LOC_FRONT) 2083 int preferred, alt;
2053 cfg->input_pins[AUTO_PIN_FRONT_MIC] = nid; 2084 if (loc == AC_JACK_LOC_FRONT) {
2054 else 2085 preferred = AUTO_PIN_FRONT_MIC;
2055 cfg->input_pins[AUTO_PIN_MIC] = nid; 2086 alt = AUTO_PIN_MIC;
2087 } else {
2088 preferred = AUTO_PIN_MIC;
2089 alt = AUTO_PIN_FRONT_MIC;
2090 }
2091 if (!cfg->input_pins[preferred])
2092 cfg->input_pins[preferred] = nid;
2093 else if (!cfg->input_pins[alt])
2094 cfg->input_pins[alt] = nid;
2056 break; 2095 break;
2096 }
2057 case AC_JACK_LINE_IN: 2097 case AC_JACK_LINE_IN:
2058 if (loc == AC_JACK_LOC_FRONT) 2098 if (loc == AC_JACK_LOC_FRONT)
2059 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid; 2099 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid;
@@ -2119,8 +2159,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
2119 cfg->speaker_outs, cfg->speaker_pins[0], 2159 cfg->speaker_outs, cfg->speaker_pins[0],
2120 cfg->speaker_pins[1], cfg->speaker_pins[2], 2160 cfg->speaker_pins[1], cfg->speaker_pins[2],
2121 cfg->speaker_pins[3], cfg->speaker_pins[4]); 2161 cfg->speaker_pins[3], cfg->speaker_pins[4]);
2122 snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n", 2162 snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2123 cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin); 2163 cfg->hp_outs, cfg->hp_pins[0],
2164 cfg->hp_pins[1], cfg->hp_pins[2],
2165 cfg->hp_pins[3], cfg->hp_pins[4]);
2124 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," 2166 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
2125 " cd=0x%x, aux=0x%x\n", 2167 " cd=0x%x, aux=0x%x\n",
2126 cfg->input_pins[AUTO_PIN_MIC], 2168 cfg->input_pins[AUTO_PIN_MIC],
@@ -2141,10 +2183,12 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
2141 sizeof(cfg->speaker_pins)); 2183 sizeof(cfg->speaker_pins));
2142 cfg->speaker_outs = 0; 2184 cfg->speaker_outs = 0;
2143 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); 2185 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
2144 } else if (cfg->hp_pin) { 2186 } else if (cfg->hp_outs) {
2145 cfg->line_outs = 1; 2187 cfg->line_outs = cfg->hp_outs;
2146 cfg->line_out_pins[0] = cfg->hp_pin; 2188 memcpy(cfg->line_out_pins, cfg->hp_pins,
2147 cfg->hp_pin = 0; 2189 sizeof(cfg->hp_pins));
2190 cfg->hp_outs = 0;
2191 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
2148 } 2192 }
2149 } 2193 }
2150 2194