11835a0f9STakashi Iwai /* 21835a0f9STakashi Iwai * Jack-detection handling for HD-audio 31835a0f9STakashi Iwai * 41835a0f9STakashi Iwai * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> 51835a0f9STakashi Iwai * 61835a0f9STakashi Iwai * This driver is free software; you can redistribute it and/or modify 71835a0f9STakashi Iwai * it under the terms of the GNU General Public License as published by 81835a0f9STakashi Iwai * the Free Software Foundation; either version 2 of the License, or 91835a0f9STakashi Iwai * (at your option) any later version. 101835a0f9STakashi Iwai */ 111835a0f9STakashi Iwai 121835a0f9STakashi Iwai #include <linux/init.h> 131835a0f9STakashi Iwai #include <linux/slab.h> 141835a0f9STakashi Iwai #include <sound/core.h> 1501a61e12STakashi Iwai #include <sound/control.h> 16*aad37dbdSTakashi Iwai #include <sound/jack.h> 171835a0f9STakashi Iwai #include "hda_codec.h" 181835a0f9STakashi Iwai #include "hda_local.h" 191835a0f9STakashi Iwai #include "hda_jack.h" 201835a0f9STakashi Iwai 211835a0f9STakashi Iwai /* execute pin sense measurement */ 221835a0f9STakashi Iwai static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) 231835a0f9STakashi Iwai { 241835a0f9STakashi Iwai u32 pincap; 251835a0f9STakashi Iwai 261835a0f9STakashi Iwai if (!codec->no_trigger_sense) { 271835a0f9STakashi Iwai pincap = snd_hda_query_pin_caps(codec, nid); 281835a0f9STakashi Iwai if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ 291835a0f9STakashi Iwai snd_hda_codec_read(codec, nid, 0, 301835a0f9STakashi Iwai AC_VERB_SET_PIN_SENSE, 0); 311835a0f9STakashi Iwai } 321835a0f9STakashi Iwai return snd_hda_codec_read(codec, nid, 0, 331835a0f9STakashi Iwai AC_VERB_GET_PIN_SENSE, 0); 341835a0f9STakashi Iwai } 351835a0f9STakashi Iwai 361835a0f9STakashi Iwai /** 371835a0f9STakashi Iwai * snd_hda_jack_tbl_get - query the jack-table entry for the given NID 381835a0f9STakashi Iwai */ 391835a0f9STakashi Iwai struct hda_jack_tbl * 401835a0f9STakashi Iwai snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) 411835a0f9STakashi Iwai { 421835a0f9STakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 431835a0f9STakashi Iwai int i; 441835a0f9STakashi Iwai 451835a0f9STakashi Iwai if (!nid || !jack) 461835a0f9STakashi Iwai return NULL; 471835a0f9STakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 481835a0f9STakashi Iwai if (jack->nid == nid) 491835a0f9STakashi Iwai return jack; 501835a0f9STakashi Iwai return NULL; 511835a0f9STakashi Iwai } 521835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); 531835a0f9STakashi Iwai 541835a0f9STakashi Iwai /** 553a93897eSTakashi Iwai * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag 563a93897eSTakashi Iwai */ 573a93897eSTakashi Iwai struct hda_jack_tbl * 583a93897eSTakashi Iwai snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) 593a93897eSTakashi Iwai { 603a93897eSTakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 613a93897eSTakashi Iwai int i; 623a93897eSTakashi Iwai 633a93897eSTakashi Iwai if (!tag || !jack) 643a93897eSTakashi Iwai return NULL; 653a93897eSTakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 663a93897eSTakashi Iwai if (jack->tag == tag) 673a93897eSTakashi Iwai return jack; 683a93897eSTakashi Iwai return NULL; 693a93897eSTakashi Iwai } 703a93897eSTakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag); 713a93897eSTakashi Iwai 723a93897eSTakashi Iwai /** 731835a0f9STakashi Iwai * snd_hda_jack_tbl_new - create a jack-table entry for the given NID 741835a0f9STakashi Iwai */ 751835a0f9STakashi Iwai struct hda_jack_tbl * 761835a0f9STakashi Iwai snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) 771835a0f9STakashi Iwai { 781835a0f9STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 791835a0f9STakashi Iwai if (jack) 801835a0f9STakashi Iwai return jack; 811835a0f9STakashi Iwai snd_array_init(&codec->jacktbl, sizeof(*jack), 16); 821835a0f9STakashi Iwai jack = snd_array_new(&codec->jacktbl); 831835a0f9STakashi Iwai if (!jack) 841835a0f9STakashi Iwai return NULL; 851835a0f9STakashi Iwai jack->nid = nid; 861835a0f9STakashi Iwai jack->jack_dirty = 1; 873a93897eSTakashi Iwai jack->tag = codec->jacktbl.used; 881835a0f9STakashi Iwai return jack; 891835a0f9STakashi Iwai } 901835a0f9STakashi Iwai 91*aad37dbdSTakashi Iwai #ifdef CONFIG_SND_HDA_INPUT_JACK 92*aad37dbdSTakashi Iwai static void snd_hda_input_jack_free(struct hda_codec *codec); 93*aad37dbdSTakashi Iwai #else 94*aad37dbdSTakashi Iwai #define snd_hda_input_jack_free(codec) 95*aad37dbdSTakashi Iwai #endif 96*aad37dbdSTakashi Iwai 971835a0f9STakashi Iwai void snd_hda_jack_tbl_clear(struct hda_codec *codec) 981835a0f9STakashi Iwai { 99*aad37dbdSTakashi Iwai snd_hda_input_jack_free(codec); 1001835a0f9STakashi Iwai snd_array_free(&codec->jacktbl); 1011835a0f9STakashi Iwai } 1021835a0f9STakashi Iwai 1031835a0f9STakashi Iwai /* update the cached value and notification flag if needed */ 1041835a0f9STakashi Iwai static void jack_detect_update(struct hda_codec *codec, 1051835a0f9STakashi Iwai struct hda_jack_tbl *jack) 1061835a0f9STakashi Iwai { 1073a93897eSTakashi Iwai if (jack->jack_dirty || !jack->jack_detect) { 10835be544aSTakashi Iwai jack->pin_sense = read_pin_sense(codec, jack->nid); 1091835a0f9STakashi Iwai jack->jack_dirty = 0; 1101835a0f9STakashi Iwai } 1111835a0f9STakashi Iwai } 1121835a0f9STakashi Iwai 1131835a0f9STakashi Iwai /** 1141835a0f9STakashi Iwai * snd_hda_set_dirty_all - Mark all the cached as dirty 1151835a0f9STakashi Iwai * 1161835a0f9STakashi Iwai * This function sets the dirty flag to all entries of jack table. 1171835a0f9STakashi Iwai * It's called from the resume path in hda_codec.c. 1181835a0f9STakashi Iwai */ 1191835a0f9STakashi Iwai void snd_hda_jack_set_dirty_all(struct hda_codec *codec) 1201835a0f9STakashi Iwai { 1211835a0f9STakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 1221835a0f9STakashi Iwai int i; 1231835a0f9STakashi Iwai 1241835a0f9STakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 1251835a0f9STakashi Iwai if (jack->nid) 1261835a0f9STakashi Iwai jack->jack_dirty = 1; 1271835a0f9STakashi Iwai } 1281835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all); 1291835a0f9STakashi Iwai 1301835a0f9STakashi Iwai /** 1311835a0f9STakashi Iwai * snd_hda_pin_sense - execute pin sense measurement 1321835a0f9STakashi Iwai * @codec: the CODEC to sense 1331835a0f9STakashi Iwai * @nid: the pin NID to sense 1341835a0f9STakashi Iwai * 1351835a0f9STakashi Iwai * Execute necessary pin sense measurement and return its Presence Detect, 1361835a0f9STakashi Iwai * Impedance, ELD Valid etc. status bits. 1371835a0f9STakashi Iwai */ 1381835a0f9STakashi Iwai u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) 1391835a0f9STakashi Iwai { 1401835a0f9STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 1411835a0f9STakashi Iwai if (jack) { 1421835a0f9STakashi Iwai jack_detect_update(codec, jack); 1431835a0f9STakashi Iwai return jack->pin_sense; 1441835a0f9STakashi Iwai } 1451835a0f9STakashi Iwai return read_pin_sense(codec, nid); 1461835a0f9STakashi Iwai } 1471835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_pin_sense); 1481835a0f9STakashi Iwai 14935be544aSTakashi Iwai #define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE) 15035be544aSTakashi Iwai 1511835a0f9STakashi Iwai /** 1521835a0f9STakashi Iwai * snd_hda_jack_detect - query pin Presence Detect status 1531835a0f9STakashi Iwai * @codec: the CODEC to sense 1541835a0f9STakashi Iwai * @nid: the pin NID to sense 1551835a0f9STakashi Iwai * 1561835a0f9STakashi Iwai * Query and return the pin's Presence Detect status. 1571835a0f9STakashi Iwai */ 1581835a0f9STakashi Iwai int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 1591835a0f9STakashi Iwai { 1601835a0f9STakashi Iwai u32 sense = snd_hda_pin_sense(codec, nid); 16135be544aSTakashi Iwai return get_jack_plug_state(sense); 1621835a0f9STakashi Iwai } 1631835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 1641835a0f9STakashi Iwai 1651835a0f9STakashi Iwai /** 1661835a0f9STakashi Iwai * snd_hda_jack_detect_enable - enable the jack-detection 1671835a0f9STakashi Iwai */ 1681835a0f9STakashi Iwai int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 1693a93897eSTakashi Iwai unsigned char action) 1701835a0f9STakashi Iwai { 1711835a0f9STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); 1721835a0f9STakashi Iwai if (!jack) 1731835a0f9STakashi Iwai return -ENOMEM; 1743a93897eSTakashi Iwai if (jack->jack_detect) 17501a61e12STakashi Iwai return 0; /* already registered */ 1763a93897eSTakashi Iwai jack->jack_detect = 1; 1773a93897eSTakashi Iwai if (action) 1783a93897eSTakashi Iwai jack->action = action; 1791835a0f9STakashi Iwai return snd_hda_codec_write_cache(codec, nid, 0, 1801835a0f9STakashi Iwai AC_VERB_SET_UNSOLICITED_ENABLE, 1813a93897eSTakashi Iwai AC_USRSP_EN | jack->tag); 1821835a0f9STakashi Iwai } 1831835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); 18401a61e12STakashi Iwai 18501a61e12STakashi Iwai /** 18601a61e12STakashi Iwai * snd_hda_jack_report_sync - sync the states of all jacks and report if changed 18701a61e12STakashi Iwai */ 18801a61e12STakashi Iwai void snd_hda_jack_report_sync(struct hda_codec *codec) 18901a61e12STakashi Iwai { 19001a61e12STakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 19135be544aSTakashi Iwai int i, state; 19201a61e12STakashi Iwai 19301a61e12STakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 19401a61e12STakashi Iwai if (jack->nid) { 19501a61e12STakashi Iwai jack_detect_update(codec, jack); 19635be544aSTakashi Iwai state = get_jack_plug_state(jack->pin_sense); 197*aad37dbdSTakashi Iwai snd_kctl_jack_report(codec->bus->card, jack->kctl, state); 19801a61e12STakashi Iwai } 19901a61e12STakashi Iwai } 20001a61e12STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync); 20101a61e12STakashi Iwai 20201a61e12STakashi Iwai /** 20301a61e12STakashi Iwai * snd_hda_jack_add_kctl - Add a kctl for the given pin 20401a61e12STakashi Iwai * 20501a61e12STakashi Iwai * This assigns a jack-detection kctl to the given pin. The kcontrol 20601a61e12STakashi Iwai * will have the given name and index. 20701a61e12STakashi Iwai */ 20801a61e12STakashi Iwai int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 20901a61e12STakashi Iwai const char *name, int idx) 21001a61e12STakashi Iwai { 21101a61e12STakashi Iwai struct hda_jack_tbl *jack; 21201a61e12STakashi Iwai struct snd_kcontrol *kctl; 21301a61e12STakashi Iwai 2143a93897eSTakashi Iwai jack = snd_hda_jack_tbl_new(codec, nid); 21501a61e12STakashi Iwai if (!jack) 21601a61e12STakashi Iwai return 0; 21701a61e12STakashi Iwai if (jack->kctl) 21801a61e12STakashi Iwai return 0; /* already created */ 21935be544aSTakashi Iwai kctl = snd_kctl_jack_new(name, idx, codec); 22001a61e12STakashi Iwai if (!kctl) 22101a61e12STakashi Iwai return -ENOMEM; 22201a61e12STakashi Iwai if (snd_hda_ctl_add(codec, nid, kctl) < 0) 22301a61e12STakashi Iwai return -ENOMEM; 22401a61e12STakashi Iwai jack->kctl = kctl; 22501a61e12STakashi Iwai return 0; 22601a61e12STakashi Iwai } 22701a61e12STakashi Iwai 22801a61e12STakashi Iwai static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, 22901a61e12STakashi Iwai const struct auto_pin_cfg *cfg) 23001a61e12STakashi Iwai { 2313a93897eSTakashi Iwai unsigned int def_conf, conn; 2323a93897eSTakashi Iwai int err; 2333a93897eSTakashi Iwai 23401a61e12STakashi Iwai if (!nid) 23501a61e12STakashi Iwai return 0; 23601a61e12STakashi Iwai if (!is_jack_detectable(codec, nid)) 23701a61e12STakashi Iwai return 0; 2383a93897eSTakashi Iwai def_conf = snd_hda_codec_get_pincfg(codec, nid); 2393a93897eSTakashi Iwai conn = get_defcfg_connect(def_conf); 2403a93897eSTakashi Iwai if (conn != AC_JACK_PORT_COMPLEX) 2413a93897eSTakashi Iwai return 0; 2423a93897eSTakashi Iwai 2433a93897eSTakashi Iwai err = snd_hda_jack_add_kctl(codec, nid, 24401a61e12STakashi Iwai snd_hda_get_pin_label(codec, nid, cfg), 24501a61e12STakashi Iwai idx); 2463a93897eSTakashi Iwai if (err < 0) 2473a93897eSTakashi Iwai return err; 2483a93897eSTakashi Iwai return snd_hda_jack_detect_enable(codec, nid, 0); 24901a61e12STakashi Iwai } 25001a61e12STakashi Iwai 25101a61e12STakashi Iwai /** 25201a61e12STakashi Iwai * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg 25301a61e12STakashi Iwai */ 25401a61e12STakashi Iwai int snd_hda_jack_add_kctls(struct hda_codec *codec, 25501a61e12STakashi Iwai const struct auto_pin_cfg *cfg) 25601a61e12STakashi Iwai { 25701a61e12STakashi Iwai const hda_nid_t *p; 25801a61e12STakashi Iwai int i, err; 25901a61e12STakashi Iwai 26001a61e12STakashi Iwai for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 26101a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 26201a61e12STakashi Iwai if (err < 0) 26301a61e12STakashi Iwai return err; 26401a61e12STakashi Iwai } 26501a61e12STakashi Iwai for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 26601a61e12STakashi Iwai if (*p == *cfg->line_out_pins) /* might be duplicated */ 26701a61e12STakashi Iwai break; 26801a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 26901a61e12STakashi Iwai if (err < 0) 27001a61e12STakashi Iwai return err; 27101a61e12STakashi Iwai } 27201a61e12STakashi Iwai for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 27301a61e12STakashi Iwai if (*p == *cfg->line_out_pins) /* might be duplicated */ 27401a61e12STakashi Iwai break; 27501a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 27601a61e12STakashi Iwai if (err < 0) 27701a61e12STakashi Iwai return err; 27801a61e12STakashi Iwai } 27901a61e12STakashi Iwai for (i = 0; i < cfg->num_inputs; i++) { 28001a61e12STakashi Iwai err = add_jack_kctl(codec, cfg->inputs[i].pin, 0, cfg); 28101a61e12STakashi Iwai if (err < 0) 28201a61e12STakashi Iwai return err; 28301a61e12STakashi Iwai } 28401a61e12STakashi Iwai for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 28501a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 28601a61e12STakashi Iwai if (err < 0) 28701a61e12STakashi Iwai return err; 28801a61e12STakashi Iwai } 28901a61e12STakashi Iwai err = add_jack_kctl(codec, cfg->dig_in_pin, 0, cfg); 29001a61e12STakashi Iwai if (err < 0) 29101a61e12STakashi Iwai return err; 29201a61e12STakashi Iwai err = add_jack_kctl(codec, cfg->mono_out_pin, 0, cfg); 29301a61e12STakashi Iwai if (err < 0) 29401a61e12STakashi Iwai return err; 29501a61e12STakashi Iwai return 0; 29601a61e12STakashi Iwai } 29701a61e12STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls); 298*aad37dbdSTakashi Iwai 299*aad37dbdSTakashi Iwai #ifdef CONFIG_SND_HDA_INPUT_JACK 300*aad37dbdSTakashi Iwai /* 301*aad37dbdSTakashi Iwai * Input-jack notification support 302*aad37dbdSTakashi Iwai */ 303*aad37dbdSTakashi Iwai static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, 304*aad37dbdSTakashi Iwai int type) 305*aad37dbdSTakashi Iwai { 306*aad37dbdSTakashi Iwai switch (type) { 307*aad37dbdSTakashi Iwai case SND_JACK_HEADPHONE: 308*aad37dbdSTakashi Iwai return "Headphone"; 309*aad37dbdSTakashi Iwai case SND_JACK_MICROPHONE: 310*aad37dbdSTakashi Iwai return "Mic"; 311*aad37dbdSTakashi Iwai case SND_JACK_LINEOUT: 312*aad37dbdSTakashi Iwai return "Line-out"; 313*aad37dbdSTakashi Iwai case SND_JACK_LINEIN: 314*aad37dbdSTakashi Iwai return "Line-in"; 315*aad37dbdSTakashi Iwai case SND_JACK_HEADSET: 316*aad37dbdSTakashi Iwai return "Headset"; 317*aad37dbdSTakashi Iwai case SND_JACK_VIDEOOUT: 318*aad37dbdSTakashi Iwai return "HDMI/DP"; 319*aad37dbdSTakashi Iwai default: 320*aad37dbdSTakashi Iwai return "Misc"; 321*aad37dbdSTakashi Iwai } 322*aad37dbdSTakashi Iwai } 323*aad37dbdSTakashi Iwai 324*aad37dbdSTakashi Iwai static void hda_free_jack_priv(struct snd_jack *jack) 325*aad37dbdSTakashi Iwai { 326*aad37dbdSTakashi Iwai struct hda_jack_tbl *jacks = jack->private_data; 327*aad37dbdSTakashi Iwai jacks->nid = 0; 328*aad37dbdSTakashi Iwai jacks->jack = NULL; 329*aad37dbdSTakashi Iwai } 330*aad37dbdSTakashi Iwai 331*aad37dbdSTakashi Iwai int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, 332*aad37dbdSTakashi Iwai const char *name) 333*aad37dbdSTakashi Iwai { 334*aad37dbdSTakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); 335*aad37dbdSTakashi Iwai int err; 336*aad37dbdSTakashi Iwai 337*aad37dbdSTakashi Iwai if (!jack) 338*aad37dbdSTakashi Iwai return -ENOMEM; 339*aad37dbdSTakashi Iwai if (!name) 340*aad37dbdSTakashi Iwai name = get_jack_default_name(codec, nid, type); 341*aad37dbdSTakashi Iwai err = snd_jack_new(codec->bus->card, name, type, &jack->jack); 342*aad37dbdSTakashi Iwai if (err < 0) 343*aad37dbdSTakashi Iwai return err; 344*aad37dbdSTakashi Iwai jack->jack->private_data = jack; 345*aad37dbdSTakashi Iwai jack->jack->private_free = hda_free_jack_priv; 346*aad37dbdSTakashi Iwai return 0; 347*aad37dbdSTakashi Iwai } 348*aad37dbdSTakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); 349*aad37dbdSTakashi Iwai 350*aad37dbdSTakashi Iwai void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) 351*aad37dbdSTakashi Iwai { 352*aad37dbdSTakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 353*aad37dbdSTakashi Iwai unsigned int pin_ctl; 354*aad37dbdSTakashi Iwai unsigned int present; 355*aad37dbdSTakashi Iwai int type; 356*aad37dbdSTakashi Iwai 357*aad37dbdSTakashi Iwai if (!jack) 358*aad37dbdSTakashi Iwai return; 359*aad37dbdSTakashi Iwai 360*aad37dbdSTakashi Iwai present = snd_hda_jack_detect(codec, nid); 361*aad37dbdSTakashi Iwai type = jack->type; 362*aad37dbdSTakashi Iwai if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { 363*aad37dbdSTakashi Iwai pin_ctl = snd_hda_codec_read(codec, nid, 0, 364*aad37dbdSTakashi Iwai AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 365*aad37dbdSTakashi Iwai type = (pin_ctl & AC_PINCTL_HP_EN) ? 366*aad37dbdSTakashi Iwai SND_JACK_HEADPHONE : SND_JACK_LINEOUT; 367*aad37dbdSTakashi Iwai } 368*aad37dbdSTakashi Iwai snd_jack_report(jack->jack, present ? type : 0); 369*aad37dbdSTakashi Iwai } 370*aad37dbdSTakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); 371*aad37dbdSTakashi Iwai 372*aad37dbdSTakashi Iwai /* free jack instances manually when clearing/reconfiguring */ 373*aad37dbdSTakashi Iwai static void snd_hda_input_jack_free(struct hda_codec *codec) 374*aad37dbdSTakashi Iwai { 375*aad37dbdSTakashi Iwai if (!codec->bus->shutdown && codec->jacktbl.list) { 376*aad37dbdSTakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 377*aad37dbdSTakashi Iwai int i; 378*aad37dbdSTakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) { 379*aad37dbdSTakashi Iwai if (jack->jack) 380*aad37dbdSTakashi Iwai snd_device_free(codec->bus->card, jack->jack); 381*aad37dbdSTakashi Iwai } 382*aad37dbdSTakashi Iwai } 383*aad37dbdSTakashi Iwai } 384*aad37dbdSTakashi Iwai #endif /* CONFIG_SND_HDA_INPUT_JACK */ 385