aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-10-27 11:06:43 -0400
committerTakashi Iwai <tiwai@suse.de>2011-10-27 11:06:43 -0400
commit8128c9f21509f9a8b6da94ac432d845dda458406 (patch)
tree587b5e785571ac7630c7f2b31cbbca6e70cc0d4b /sound
parentbb14eb0da72afb69be261b28ec858cbd5a35e089 (diff)
parent6b45214277bec2193ad3ccb8d7aa6100b5a0f1a9 (diff)
Merge branch 'topic/hda' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_local.h3
-rw-r--r--sound/pci/hda/patch_conexant.c72
-rw-r--r--sound/pci/hda/patch_realtek.c42
3 files changed, 88 insertions, 29 deletions
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 46c581c3fa84..81e12c0ed0a2 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -600,7 +600,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
600#define get_amp_nid_(pv) ((pv) & 0xffff) 600#define get_amp_nid_(pv) ((pv) & 0xffff)
601#define get_amp_nid(kc) get_amp_nid_((kc)->private_value) 601#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
602#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) 602#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
603#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) 603#define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
604#define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
604#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) 605#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
605#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) 606#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
606#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) 607#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 686ec6d75c64..0c8b5a1993ed 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -136,6 +136,8 @@ struct conexant_spec {
136 unsigned int thinkpad:1; 136 unsigned int thinkpad:1;
137 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
138 unsigned int asus:1; 138 unsigned int asus:1;
139 unsigned int pin_eapd_ctrls:1;
140 unsigned int single_adc_amp:1;
139 141
140 unsigned int adc_switching:1; 142 unsigned int adc_switching:1;
141 143
@@ -3430,12 +3432,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3430static void do_automute(struct hda_codec *codec, int num_pins, 3432static void do_automute(struct hda_codec *codec, int num_pins,
3431 hda_nid_t *pins, bool on) 3433 hda_nid_t *pins, bool on)
3432{ 3434{
3435 struct conexant_spec *spec = codec->spec;
3433 int i; 3436 int i;
3434 for (i = 0; i < num_pins; i++) 3437 for (i = 0; i < num_pins; i++)
3435 snd_hda_codec_write(codec, pins[i], 0, 3438 snd_hda_codec_write(codec, pins[i], 0,
3436 AC_VERB_SET_PIN_WIDGET_CONTROL, 3439 AC_VERB_SET_PIN_WIDGET_CONTROL,
3437 on ? PIN_OUT : 0); 3440 on ? PIN_OUT : 0);
3438 cx_auto_turn_eapd(codec, num_pins, pins, on); 3441 if (spec->pin_eapd_ctrls)
3442 cx_auto_turn_eapd(codec, num_pins, pins, on);
3439} 3443}
3440 3444
3441static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3445static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
@@ -3460,9 +3464,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
3460 int on = 1; 3464 int on = 1;
3461 3465
3462 /* turn on HP EAPD when HP jacks are present */ 3466 /* turn on HP EAPD when HP jacks are present */
3463 if (spec->auto_mute) 3467 if (spec->pin_eapd_ctrls) {
3464 on = spec->hp_present; 3468 if (spec->auto_mute)
3465 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); 3469 on = spec->hp_present;
3470 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3471 }
3472
3466 /* mute speakers in auto-mode if HP or LO jacks are plugged */ 3473 /* mute speakers in auto-mode if HP or LO jacks are plugged */
3467 if (spec->auto_mute) 3474 if (spec->auto_mute)
3468 on = !(spec->hp_present || 3475 on = !(spec->hp_present ||
@@ -3889,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3889#define cx_auto_parse_beep(codec) 3896#define cx_auto_parse_beep(codec)
3890#endif 3897#endif
3891 3898
3892static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 3899/* parse EAPDs */
3893{
3894 int i;
3895 for (i = 0; i < nums; i++)
3896 if (list[i] == nid)
3897 return true;
3898 return false;
3899}
3900
3901/* parse extra-EAPD that aren't assigned to any pins */
3902static void cx_auto_parse_eapd(struct hda_codec *codec) 3900static void cx_auto_parse_eapd(struct hda_codec *codec)
3903{ 3901{
3904 struct conexant_spec *spec = codec->spec; 3902 struct conexant_spec *spec = codec->spec;
3905 struct auto_pin_cfg *cfg = &spec->autocfg;
3906 hda_nid_t nid, end_nid; 3903 hda_nid_t nid, end_nid;
3907 3904
3908 end_nid = codec->start_nid + codec->num_nodes; 3905 end_nid = codec->start_nid + codec->num_nodes;
@@ -3911,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
3911 continue; 3908 continue;
3912 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) 3909 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3913 continue; 3910 continue;
3914 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3915 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3916 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3917 continue;
3918 spec->eapds[spec->num_eapds++] = nid; 3911 spec->eapds[spec->num_eapds++] = nid;
3919 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) 3912 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3920 break; 3913 break;
3921 } 3914 }
3915
3916 /* NOTE: below is a wild guess; if we have more than two EAPDs,
3917 * it's a new chip, where EAPDs are supposed to be associated to
3918 * pins, and we can control EAPD per pin.
3919 * OTOH, if only one or two EAPDs are found, it's an old chip,
3920 * thus it might control over all pins.
3921 */
3922 spec->pin_eapd_ctrls = spec->num_eapds > 2;
3922} 3923}
3923 3924
3924static int cx_auto_parse_auto_config(struct hda_codec *codec) 3925static int cx_auto_parse_auto_config(struct hda_codec *codec)
@@ -4024,8 +4025,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
4024 } 4025 }
4025 } 4026 }
4026 cx_auto_update_speakers(codec); 4027 cx_auto_update_speakers(codec);
4027 /* turn on/off extra EAPDs, too */ 4028 /* turn on all EAPDs if no individual EAPD control is available */
4028 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4029 if (!spec->pin_eapd_ctrls)
4030 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4029} 4031}
4030 4032
4031static void cx_auto_init_input(struct hda_codec *codec) 4033static void cx_auto_init_input(struct hda_codec *codec)
@@ -4212,6 +4214,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4212 int idx = get_input_connection(codec, adc_nid, nid); 4214 int idx = get_input_connection(codec, adc_nid, nid);
4213 if (idx < 0) 4215 if (idx < 0)
4214 continue; 4216 continue;
4217 if (spec->single_adc_amp)
4218 idx = 0;
4215 return cx_auto_add_volume_idx(codec, label, pfx, 4219 return cx_auto_add_volume_idx(codec, label, pfx,
4216 cidx, adc_nid, HDA_INPUT, idx); 4220 cidx, adc_nid, HDA_INPUT, idx);
4217 } 4221 }
@@ -4252,14 +4256,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4252 struct hda_input_mux *imux = &spec->private_imux; 4256 struct hda_input_mux *imux = &spec->private_imux;
4253 const char *prev_label; 4257 const char *prev_label;
4254 int input_conn[HDA_MAX_NUM_INPUTS]; 4258 int input_conn[HDA_MAX_NUM_INPUTS];
4255 int i, err, cidx; 4259 int i, j, err, cidx;
4256 int multi_connection; 4260 int multi_connection;
4257 4261
4262 if (!imux->num_items)
4263 return 0;
4264
4258 multi_connection = 0; 4265 multi_connection = 0;
4259 for (i = 0; i < imux->num_items; i++) { 4266 for (i = 0; i < imux->num_items; i++) {
4260 cidx = get_input_connection(codec, spec->imux_info[i].adc, 4267 cidx = get_input_connection(codec, spec->imux_info[i].adc,
4261 spec->imux_info[i].pin); 4268 spec->imux_info[i].pin);
4262 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; 4269 if (cidx < 0)
4270 continue;
4271 input_conn[i] = spec->imux_info[i].adc;
4272 if (!spec->single_adc_amp)
4273 input_conn[i] |= cidx << 8;
4263 if (i > 0 && input_conn[i] != input_conn[0]) 4274 if (i > 0 && input_conn[i] != input_conn[0])
4264 multi_connection = 1; 4275 multi_connection = 1;
4265 } 4276 }
@@ -4288,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4288 err = cx_auto_add_capture_volume(codec, nid, 4299 err = cx_auto_add_capture_volume(codec, nid,
4289 "Capture", "", cidx); 4300 "Capture", "", cidx);
4290 } else { 4301 } else {
4302 bool dup_found = false;
4303 for (j = 0; j < i; j++) {
4304 if (input_conn[j] == input_conn[i]) {
4305 dup_found = true;
4306 break;
4307 }
4308 }
4309 if (dup_found)
4310 continue;
4291 err = cx_auto_add_capture_volume(codec, nid, 4311 err = cx_auto_add_capture_volume(codec, nid,
4292 label, " Capture", cidx); 4312 label, " Capture", cidx);
4293 } 4313 }
@@ -4412,6 +4432,12 @@ static int patch_conexant_auto(struct hda_codec *codec)
4412 codec->spec = spec; 4432 codec->spec = spec;
4413 codec->pin_amp_workaround = 1; 4433 codec->pin_amp_workaround = 1;
4414 4434
4435 switch (codec->vendor_id) {
4436 case 0x14f15045:
4437 spec->single_adc_amp = 1;
4438 break;
4439 }
4440
4415 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); 4441 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4416 4442
4417 err = cx_auto_search_adcs(codec); 4443 err = cx_auto_search_adcs(codec);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 011644b7c2d1..8f93b97559a5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -116,6 +116,8 @@ struct alc_spec {
116 const hda_nid_t *capsrc_nids; 116 const hda_nid_t *capsrc_nids;
117 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 117 hda_nid_t dig_in_nid; /* digital-in NID; optional */
118 hda_nid_t mixer_nid; /* analog-mixer NID */ 118 hda_nid_t mixer_nid; /* analog-mixer NID */
119 DECLARE_BITMAP(vol_ctls, 0x20 << 1);
120 DECLARE_BITMAP(sw_ctls, 0x20 << 1);
119 121
120 /* capture setup for dynamic dual-adc switch */ 122 /* capture setup for dynamic dual-adc switch */
121 hda_nid_t cur_adc; 123 hda_nid_t cur_adc;
@@ -3006,14 +3008,32 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3006 return 0; 3008 return 0;
3007} 3009}
3008 3010
3011static inline unsigned int get_ctl_pos(unsigned int data)
3012{
3013 hda_nid_t nid = get_amp_nid_(data);
3014 unsigned int dir = get_amp_direction_(data);
3015 return (nid << 1) | dir;
3016}
3017
3018#define is_ctl_used(bits, data) \
3019 test_bit(get_ctl_pos(data), bits)
3020#define mark_ctl_usage(bits, data) \
3021 set_bit(get_ctl_pos(data), bits)
3022
3009static int alc_auto_add_vol_ctl(struct hda_codec *codec, 3023static int alc_auto_add_vol_ctl(struct hda_codec *codec,
3010 const char *pfx, int cidx, 3024 const char *pfx, int cidx,
3011 hda_nid_t nid, unsigned int chs) 3025 hda_nid_t nid, unsigned int chs)
3012{ 3026{
3027 struct alc_spec *spec = codec->spec;
3028 unsigned int val;
3013 if (!nid) 3029 if (!nid)
3014 return 0; 3030 return 0;
3031 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
3032 if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */
3033 return 0;
3034 mark_ctl_usage(spec->vol_ctls, val);
3015 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, 3035 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
3016 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 3036 val);
3017} 3037}
3018 3038
3019#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ 3039#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
@@ -3026,6 +3046,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
3026 const char *pfx, int cidx, 3046 const char *pfx, int cidx,
3027 hda_nid_t nid, unsigned int chs) 3047 hda_nid_t nid, unsigned int chs)
3028{ 3048{
3049 struct alc_spec *spec = codec->spec;
3029 int wid_type; 3050 int wid_type;
3030 int type; 3051 int type;
3031 unsigned long val; 3052 unsigned long val;
@@ -3042,6 +3063,9 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
3042 type = ALC_CTL_BIND_MUTE; 3063 type = ALC_CTL_BIND_MUTE;
3043 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); 3064 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
3044 } 3065 }
3066 if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */
3067 return 0;
3068 mark_ctl_usage(spec->sw_ctls, val);
3045 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); 3069 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
3046} 3070}
3047 3071
@@ -3136,12 +3160,16 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3136 int err; 3160 int err;
3137 3161
3138 if (!dac) { 3162 if (!dac) {
3163 unsigned int val;
3139 /* the corresponding DAC is already occupied */ 3164 /* the corresponding DAC is already occupied */
3140 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 3165 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
3141 return 0; /* no way */ 3166 return 0; /* no way */
3142 /* create a switch only */ 3167 /* create a switch only */
3143 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 3168 val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
3144 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3169 if (is_ctl_used(spec->sw_ctls, val))
3170 return 0; /* already created */
3171 mark_ctl_usage(spec->sw_ctls, val);
3172 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
3145 } 3173 }
3146 3174
3147 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3175 sw = alc_look_for_out_mute_nid(codec, pin, dac);
@@ -3186,8 +3214,12 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3186 if (!num_pins || !pins[0]) 3214 if (!num_pins || !pins[0])
3187 return 0; 3215 return 0;
3188 3216
3189 if (num_pins == 1) 3217 if (num_pins == 1) {
3190 return alc_auto_create_extra_out(codec, *pins, *dacs, pfx); 3218 hda_nid_t dac = *dacs;
3219 if (!dac)
3220 dac = spec->multiout.dac_nids[0];
3221 return alc_auto_create_extra_out(codec, *pins, dac, pfx);
3222 }
3191 3223
3192 if (dacs[num_pins - 1]) { 3224 if (dacs[num_pins - 1]) {
3193 /* OK, we have a multi-output system with individual volumes */ 3225 /* OK, we have a multi-output system with individual volumes */