^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Jack-detection handling for HD-audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sound/jack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/hda_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "hda_local.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "hda_auto_parser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "hda_jack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * is_jack_detectable - Check whether the given pin is jack-detectable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @nid: pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Check whether the given pin is capable to report the jack detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * The jack detection might not work by various reasons, e.g. the jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * detection is prohibited in the codec level, the pin config has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * AC_DEFCFG_MISC_NO_PRESENCE bit, no unsol support, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (codec->no_jack_detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) AC_DEFCFG_MISC_NO_PRESENCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) !codec->jackpoll_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) EXPORT_SYMBOL_GPL(is_jack_detectable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* execute pin sense measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 pincap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (!codec->no_trigger_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) pincap = snd_hda_query_pin_caps(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) AC_VERB_SET_PIN_SENSE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) val = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) AC_VERB_GET_PIN_SENSE, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (codec->inv_jack_detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) val ^= AC_PINSENSE_PRESENCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * snd_hda_jack_tbl_get_mst - query the jack-table entry for the given NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @nid: pin NID to refer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) snd_hda_jack_tbl_get_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct hda_jack_tbl *jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (!nid || !jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) for (i = 0; i < codec->jacktbl.used; i++, jack++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (jack->nid == nid && jack->dev_id == dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @tag: tag value to refer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned char tag, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct hda_jack_tbl *jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!tag || !jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) for (i = 0; i < codec->jacktbl.used; i++, jack++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (jack->tag == tag && jack->dev_id == dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) any_jack_tbl_get_from_nid(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct hda_jack_tbl *jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!nid || !jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for (i = 0; i < codec->jacktbl.used; i++, jack++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (jack->nid == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @nid: pin NID to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct hda_jack_tbl *jack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) snd_hda_jack_tbl_get_mst(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct hda_jack_tbl *existing_nid_jack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) any_jack_tbl_get_from_nid(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) WARN_ON(dev_id != 0 && !codec->dp_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) jack = snd_array_new(&codec->jacktbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) jack->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) jack->dev_id = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) jack->jack_dirty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (existing_nid_jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) jack->tag = existing_nid_jack->tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Copy jack_detect from existing_nid_jack to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * snd_hda_jack_detect_enable_callback_mst() making multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * SET_UNSOLICITED_ENABLE calls on the same pin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) jack->jack_detect = existing_nid_jack->jack_detect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) jack->tag = codec->jacktbl.used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) void snd_hda_jack_tbl_clear(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct hda_jack_tbl *jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for (i = 0; i < codec->jacktbl.used; i++, jack++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct hda_jack_callback *cb, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* free jack instances manually when clearing/reconfiguring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!codec->bus->shutdown && jack->jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) snd_device_free(codec->card, jack->jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) for (cb = jack->callback; cb; cb = next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) next = cb->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) kfree(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) snd_array_free(&codec->jacktbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* update the cached value and notification flag if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void jack_detect_update(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct hda_jack_tbl *jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!jack->jack_dirty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (jack->phantom_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) jack->pin_sense = AC_PINSENSE_PRESENCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) jack->pin_sense = read_pin_sense(codec, jack->nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) jack->dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* A gating jack indicates the jack is invalid if gating is unplugged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (jack->gating_jack &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) !snd_hda_jack_detect_mst(codec, jack->gating_jack, jack->dev_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) jack->pin_sense &= ~AC_PINSENSE_PRESENCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) jack->jack_dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* If a jack is gated by this one update it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (jack->gated_jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct hda_jack_tbl *gated =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) snd_hda_jack_tbl_get_mst(codec, jack->gated_jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) jack->dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (gated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) gated->jack_dirty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) jack_detect_update(codec, gated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * snd_hda_set_dirty_all - Mark all the cached as dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * This function sets the dirty flag to all entries of jack table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * It's called from the resume path in hda_codec.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct hda_jack_tbl *jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) for (i = 0; i < codec->jacktbl.used; i++, jack++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (jack->nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) jack->jack_dirty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * snd_hda_jack_pin_sense - execute pin sense measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @codec: the CODEC to sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @nid: the pin NID to sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * Execute necessary pin sense measurement and return its Presence Detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * Impedance, ELD Valid etc. status bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct hda_jack_tbl *jack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) snd_hda_jack_tbl_get_mst(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) jack_detect_update(codec, jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return jack->pin_sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return read_pin_sense(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) EXPORT_SYMBOL_GPL(snd_hda_jack_pin_sense);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * snd_hda_jack_detect_state_mst - query pin Presence Detect status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @codec: the CODEC to sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @nid: the pin NID to sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Query and return the pin's Presence Detect status, as either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int snd_hda_jack_detect_state_mst(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct hda_jack_tbl *jack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) snd_hda_jack_tbl_get_mst(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (jack && jack->phantom_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return HDA_JACK_PHANTOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) else if (snd_hda_jack_pin_sense(codec, nid, dev_id) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) AC_PINSENSE_PRESENCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return HDA_JACK_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return HDA_JACK_NOT_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static struct hda_jack_callback *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) find_callback_from_list(struct hda_jack_tbl *jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) hda_jack_callback_fn func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct hda_jack_callback *cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (!func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) for (cb = jack->callback; cb; cb = cb->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (cb->func == func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * snd_hda_jack_detect_enable_mst - enable the jack-detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * @nid: pin NID to enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * @func: callback function to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * In the case of error, the return value will be a pointer embedded with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * errno. Check and handle the return value appropriately with standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * macros such as @IS_ERR() and @PTR_ERR().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct hda_jack_callback *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) snd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int dev_id, hda_jack_callback_fn func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct hda_jack_tbl *jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct hda_jack_callback *callback = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) jack = snd_hda_jack_tbl_new(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) callback = find_callback_from_list(jack, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (func && !callback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) callback = kzalloc(sizeof(*callback), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) callback->func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) callback->nid = jack->nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) callback->dev_id = jack->dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) callback->next = jack->callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) jack->callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (jack->jack_detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return callback; /* already registered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) jack->jack_detect = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (codec->jackpoll_interval > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return callback; /* No unsol if we're polling instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) err = snd_hda_codec_write_cache(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) AC_VERB_SET_UNSOLICITED_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) AC_USRSP_EN | jack->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * snd_hda_jack_detect_enable - Enable the jack detection on the given pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * @nid: pin NID to enable jack detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * Enable the jack detection with the default callback. Returns zero if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * successful or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback_mst(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * snd_hda_jack_set_gating_jack - Set gating jack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * @gated_nid: gated pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @gating_nid: gating pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Indicates the gated jack is only valid when the gating jack is plugged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) hda_nid_t gating_nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct hda_jack_tbl *gated = snd_hda_jack_tbl_new(codec, gated_nid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct hda_jack_tbl *gating =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) snd_hda_jack_tbl_new(codec, gating_nid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) WARN_ON(codec->dp_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!gated || !gating)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) gated->gating_jack = gating_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) gating->gated_jack = gated_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) void snd_hda_jack_report_sync(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct hda_jack_tbl *jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int i, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* update all jacks at first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) for (i = 0; i < codec->jacktbl.used; i++, jack++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (jack->nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) jack_detect_update(codec, jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* report the updated jacks; it's done after updating all jacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * to make sure that all gating jacks properly have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) for (i = 0; i < codec->jacktbl.used; i++, jack++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (jack->nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (!jack->jack || jack->block_report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) state = jack->button_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (get_jack_plug_state(jack->pin_sense))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) state |= jack->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) snd_jack_report(jack->jack, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (jack->button_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) snd_jack_report(jack->jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) state & ~jack->button_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) jack->button_state = 0; /* button released */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* guess the jack type from the pin-config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) switch (get_defcfg_device(def_conf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) case AC_JACK_LINE_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case AC_JACK_SPEAKER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return SND_JACK_LINEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) case AC_JACK_HP_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return SND_JACK_HEADPHONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case AC_JACK_SPDIF_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case AC_JACK_DIG_OTHER_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return SND_JACK_AVOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case AC_JACK_MIC_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return SND_JACK_MICROPHONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return SND_JACK_LINEIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static void hda_free_jack_priv(struct snd_jack *jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct hda_jack_tbl *jacks = jack->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) jacks->nid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) jacks->jack = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * snd_hda_jack_add_kctl_mst - Add a kctl for the given pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @nid: pin NID to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * @dev_id : pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * @name: string name for the jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * @phantom_jack: flag to deal as a phantom jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * @type: jack type bits to be reported, 0 for guessing from pincfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * @keymap: optional jack / key mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * This assigns a jack-detection kctl to the given pin. The kcontrol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * will have the given name and index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int snd_hda_jack_add_kctl_mst(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int dev_id, const char *name, bool phantom_jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int type, const struct hda_jack_keymap *keymap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct hda_jack_tbl *jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) const struct hda_jack_keymap *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int err, state, buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) jack = snd_hda_jack_tbl_new(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (!jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (jack->jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0; /* already created */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) type = get_input_jack_type(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) buttons = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (keymap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) for (map = keymap; map->type; map++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) buttons |= map->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) err = snd_jack_new(codec->card, name, type | buttons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) &jack->jack, true, phantom_jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) jack->phantom_jack = !!phantom_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) jack->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) jack->button_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) jack->jack->private_data = jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) jack->jack->private_free = hda_free_jack_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (keymap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) for (map = keymap; map->type; map++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) snd_jack_set_key(jack->jack, map->type, map->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) state = snd_hda_jack_detect_mst(codec, nid, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) snd_jack_report(jack->jack, state ? jack->type : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) const struct auto_pin_cfg *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) const char *base_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) unsigned int def_conf, conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) bool phantom_jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) WARN_ON(codec->dp_mst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) def_conf = snd_hda_codec_get_pincfg(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) conn = get_defcfg_connect(def_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (conn == AC_JACK_PORT_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) !is_jack_detectable(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (base_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) strlcpy(name, base_name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (phantom_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* Example final name: "Internal Mic Phantom Jack" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!phantom_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return snd_hda_jack_detect_enable(codec, nid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * @cfg: pin config table to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) int snd_hda_jack_add_kctls(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) const struct auto_pin_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) const hda_nid_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) for (i = 0; i < cfg->num_inputs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* If we have headphone mics; make sure they get the right name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) before grabbed by output pins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (cfg->inputs[i].is_headphone_mic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (auto_cfg_hp_outs(cfg) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) err = add_jack_kctl(codec, auto_cfg_hp_pins(cfg)[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) cfg, "Headphone Mic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) err = add_jack_kctl(codec, cfg->inputs[i].pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) cfg, "Headphone Mic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) err = add_jack_kctl(codec, *p, cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (*p == *cfg->line_out_pins) /* might be duplicated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) err = add_jack_kctl(codec, *p, cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (*p == *cfg->line_out_pins) /* might be duplicated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) err = add_jack_kctl(codec, *p, cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) err = add_jack_kctl(codec, *p, cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static void call_jack_callback(struct hda_codec *codec, unsigned int res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct hda_jack_tbl *jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct hda_jack_callback *cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) for (cb = jack->callback; cb; cb = cb->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) cb->jack = jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) cb->unsol_res = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cb->func(codec, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (jack->gated_jack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct hda_jack_tbl *gated =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) snd_hda_jack_tbl_get_mst(codec, jack->gated_jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) jack->dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (gated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for (cb = gated->callback; cb; cb = cb->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) cb->jack = gated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) cb->unsol_res = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) cb->func(codec, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * snd_hda_jack_unsol_event - Handle an unsolicited event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * @res: the unsolicited event data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct hda_jack_tbl *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int tag = (res & AC_UNSOL_RES_TAG) >> AC_UNSOL_RES_TAG_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (codec->dp_mst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) int dev_entry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) event = snd_hda_jack_tbl_get_from_tag(codec, tag, dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) event = snd_hda_jack_tbl_get_from_tag(codec, tag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) event->jack_dirty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) call_jack_callback(codec, res, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) snd_hda_jack_report_sync(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * snd_hda_jack_poll_all - Poll all jacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * Poll all detectable jacks with dirty flag, update the status, call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * callbacks and call snd_hda_jack_report_sync() if any changes are found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) void snd_hda_jack_poll_all(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct hda_jack_tbl *jack = codec->jacktbl.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int i, changes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) for (i = 0; i < codec->jacktbl.used; i++, jack++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) unsigned int old_sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (!jack->nid || !jack->jack_dirty || jack->phantom_jack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) old_sense = get_jack_plug_state(jack->pin_sense);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) jack_detect_update(codec, jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (old_sense == get_jack_plug_state(jack->pin_sense))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) changes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) call_jack_callback(codec, 0, jack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (changes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) snd_hda_jack_report_sync(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) EXPORT_SYMBOL_GPL(snd_hda_jack_poll_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)