@@ -136,6 +136,8 @@ struct conexant_spec {
136
136
unsigned int thinkpad :1 ;
137
137
unsigned int hp_laptop :1 ;
138
138
unsigned int asus :1 ;
139
+ unsigned int pin_eapd_ctrls :1 ;
140
+ unsigned int single_adc_amp :1 ;
139
141
140
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,
3430
3432
static void do_automute (struct hda_codec * codec , int num_pins ,
3431
3433
hda_nid_t * pins , bool on )
3432
3434
{
3435
+ struct conexant_spec * spec = codec -> spec ;
3433
3436
int i ;
3434
3437
for (i = 0 ; i < num_pins ; i ++ )
3435
3438
snd_hda_codec_write (codec , pins [i ], 0 ,
3436
3439
AC_VERB_SET_PIN_WIDGET_CONTROL ,
3437
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
3441
3445
static 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
3464
int on = 1 ;
3461
3465
3462
3466
/* turn on HP EAPD when HP jacks are present */
3463
- if (spec -> auto_mute )
3464
- on = spec -> hp_present ;
3465
- cx_auto_turn_eapd (codec , cfg -> hp_outs , cfg -> hp_pins , on );
3467
+ if (spec -> pin_eapd_ctrls ) {
3468
+ if (spec -> auto_mute )
3469
+ on = spec -> hp_present ;
3470
+ cx_auto_turn_eapd (codec , cfg -> hp_outs , cfg -> hp_pins , on );
3471
+ }
3472
+
3466
3473
/* mute speakers in auto-mode if HP or LO jacks are plugged */
3467
3474
if (spec -> auto_mute )
3468
3475
on = !(spec -> hp_present ||
@@ -3889,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3889
3896
#define cx_auto_parse_beep (codec )
3890
3897
#endif
3891
3898
3892
- static bool found_in_nid_list (hda_nid_t nid , const hda_nid_t * list , int nums )
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 */
3899
+ /* parse EAPDs */
3902
3900
static void cx_auto_parse_eapd (struct hda_codec * codec )
3903
3901
{
3904
3902
struct conexant_spec * spec = codec -> spec ;
3905
- struct auto_pin_cfg * cfg = & spec -> autocfg ;
3906
3903
hda_nid_t nid , end_nid ;
3907
3904
3908
3905
end_nid = codec -> start_nid + codec -> num_nodes ;
@@ -3911,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
3911
3908
continue ;
3912
3909
if (!(snd_hda_query_pin_caps (codec , nid ) & AC_PINCAP_EAPD ))
3913
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
3911
spec -> eapds [spec -> num_eapds ++ ] = nid ;
3919
3912
if (spec -> num_eapds >= ARRAY_SIZE (spec -> eapds ))
3920
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
3924
3925
static 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
4027
cx_auto_update_speakers (codec );
4027
- /* turn on/off extra EAPDs, too */
4028
- cx_auto_turn_eapd (codec , spec -> num_eapds , spec -> eapds , true);
4028
+ /* turn on all EAPDs if no individual EAPD control is available */
4029
+ if (!spec -> pin_eapd_ctrls )
4030
+ cx_auto_turn_eapd (codec , spec -> num_eapds , spec -> eapds , true);
4029
4031
}
4030
4032
4031
4033
static 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
4214
int idx = get_input_connection (codec , adc_nid , nid );
4213
4215
if (idx < 0 )
4214
4216
continue ;
4217
+ if (spec -> single_adc_amp )
4218
+ idx = 0 ;
4215
4219
return cx_auto_add_volume_idx (codec , label , pfx ,
4216
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
4256
struct hda_input_mux * imux = & spec -> private_imux ;
4253
4257
const char * prev_label ;
4254
4258
int input_conn [HDA_MAX_NUM_INPUTS ];
4255
- int i , err , cidx ;
4259
+ int i , j , err , cidx ;
4256
4260
int multi_connection ;
4257
4261
4262
+ if (!imux -> num_items )
4263
+ return 0 ;
4264
+
4258
4265
multi_connection = 0 ;
4259
4266
for (i = 0 ; i < imux -> num_items ; i ++ ) {
4260
4267
cidx = get_input_connection (codec , spec -> imux_info [i ].adc ,
4261
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
4274
if (i > 0 && input_conn [i ] != input_conn [0 ])
4264
4275
multi_connection = 1 ;
4265
4276
}
@@ -4288,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4288
4299
err = cx_auto_add_capture_volume (codec , nid ,
4289
4300
"Capture" , "" , cidx );
4290
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
4311
err = cx_auto_add_capture_volume (codec , nid ,
4292
4312
label , " Capture" , cidx );
4293
4313
}
@@ -4412,6 +4432,12 @@ static int patch_conexant_auto(struct hda_codec *codec)
4412
4432
codec -> spec = spec ;
4413
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
4441
apply_pin_fixup (codec , cxt_fixups , cxt_pincfg_tbl );
4416
4442
4417
4443
err = cx_auto_search_adcs (codec );
0 commit comments