diff options
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 100 |
1 files changed, 3 insertions, 97 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 3fbf2883e06e..4e0ec146553d 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3240,102 +3240,8 @@ enum { | |||
3240 | CXT_FIXUP_THINKPAD_ACPI, | 3240 | CXT_FIXUP_THINKPAD_ACPI, |
3241 | }; | 3241 | }; |
3242 | 3242 | ||
3243 | #if IS_ENABLED(CONFIG_THINKPAD_ACPI) | 3243 | /* for hda_fixup_thinkpad_acpi() */ |
3244 | 3244 | #include "thinkpad_helper.c" | |
3245 | #include <linux/thinkpad_acpi.h> | ||
3246 | #include <acpi/acpi.h> | ||
3247 | |||
3248 | static int (*led_set_func)(int, bool); | ||
3249 | |||
3250 | static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context, | ||
3251 | void **rv) | ||
3252 | { | ||
3253 | bool *found = context; | ||
3254 | *found = true; | ||
3255 | return AE_OK; | ||
3256 | } | ||
3257 | |||
3258 | static bool is_thinkpad(struct hda_codec *codec) | ||
3259 | { | ||
3260 | bool found = false; | ||
3261 | if (codec->subsystem_id >> 16 != 0x17aa) | ||
3262 | return false; | ||
3263 | if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found) | ||
3264 | return true; | ||
3265 | found = false; | ||
3266 | return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found; | ||
3267 | } | ||
3268 | |||
3269 | static void update_tpacpi_mute_led(void *private_data, int enabled) | ||
3270 | { | ||
3271 | struct hda_codec *codec = private_data; | ||
3272 | struct conexant_spec *spec = codec->spec; | ||
3273 | |||
3274 | if (spec->dynamic_eapd) | ||
3275 | cx_auto_vmaster_hook(private_data, enabled); | ||
3276 | |||
3277 | if (led_set_func) | ||
3278 | led_set_func(TPACPI_LED_MUTE, !enabled); | ||
3279 | } | ||
3280 | |||
3281 | static void update_tpacpi_micmute_led(struct hda_codec *codec, | ||
3282 | struct snd_ctl_elem_value *ucontrol) | ||
3283 | { | ||
3284 | if (!ucontrol || !led_set_func) | ||
3285 | return; | ||
3286 | if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { | ||
3287 | /* TODO: How do I verify if it's a mono or stereo here? */ | ||
3288 | bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; | ||
3289 | led_set_func(TPACPI_LED_MICMUTE, !val); | ||
3290 | } | ||
3291 | } | ||
3292 | |||
3293 | static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, | ||
3294 | const struct hda_fixup *fix, int action) | ||
3295 | { | ||
3296 | struct conexant_spec *spec = codec->spec; | ||
3297 | |||
3298 | bool removefunc = false; | ||
3299 | |||
3300 | if (action == HDA_FIXUP_ACT_PROBE) { | ||
3301 | if (!is_thinkpad(codec)) | ||
3302 | return; | ||
3303 | if (!led_set_func) | ||
3304 | led_set_func = symbol_request(tpacpi_led_set); | ||
3305 | if (!led_set_func) { | ||
3306 | snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n"); | ||
3307 | return; | ||
3308 | } | ||
3309 | |||
3310 | removefunc = true; | ||
3311 | if (led_set_func(TPACPI_LED_MUTE, false) >= 0) { | ||
3312 | spec->gen.vmaster_mute.hook = update_tpacpi_mute_led; | ||
3313 | removefunc = false; | ||
3314 | } | ||
3315 | if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { | ||
3316 | if (spec->gen.num_adc_nids > 1) | ||
3317 | snd_printdd("Skipping micmute LED control due to several ADCs"); | ||
3318 | else { | ||
3319 | spec->gen.cap_sync_hook = update_tpacpi_micmute_led; | ||
3320 | removefunc = false; | ||
3321 | } | ||
3322 | } | ||
3323 | } | ||
3324 | |||
3325 | if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { | ||
3326 | symbol_put(tpacpi_led_set); | ||
3327 | led_set_func = NULL; | ||
3328 | } | ||
3329 | } | ||
3330 | |||
3331 | #else | ||
3332 | |||
3333 | static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, | ||
3334 | const struct hda_fixup *fix, int action) | ||
3335 | { | ||
3336 | } | ||
3337 | |||
3338 | #endif | ||
3339 | 3245 | ||
3340 | static void cxt_fixup_stereo_dmic(struct hda_codec *codec, | 3246 | static void cxt_fixup_stereo_dmic(struct hda_codec *codec, |
3341 | const struct hda_fixup *fix, int action) | 3247 | const struct hda_fixup *fix, int action) |
@@ -3492,7 +3398,7 @@ static const struct hda_fixup cxt_fixups[] = { | |||
3492 | }, | 3398 | }, |
3493 | [CXT_FIXUP_THINKPAD_ACPI] = { | 3399 | [CXT_FIXUP_THINKPAD_ACPI] = { |
3494 | .type = HDA_FIXUP_FUNC, | 3400 | .type = HDA_FIXUP_FUNC, |
3495 | .v.func = cxt_fixup_thinkpad_acpi, | 3401 | .v.func = hda_fixup_thinkpad_acpi, |
3496 | }, | 3402 | }, |
3497 | }; | 3403 | }; |
3498 | 3404 | ||