/** * snd_hda_jack_set_gating_jack - Set gating jack. * * Indicates the gated jack is only valid when the gating jack is plugged. */ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, hda_nid_t gating_nid) { struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, gated_nid); struct hda_jack_tbl *gating = snd_hda_jack_tbl_get(codec, gating_nid); if (!gated || !gating) return -EINVAL; gated->gating_jack = gating_nid; gating->gated_jack = gated_nid; return 0; }
/* update the cached value and notification flag if needed */ static void jack_detect_update(struct hda_codec *codec, struct hda_jack_tbl *jack) { if (!jack->jack_dirty) return; if (jack->phantom_jack) jack->pin_sense = AC_PINSENSE_PRESENCE; else jack->pin_sense = read_pin_sense(codec, jack->nid); /* A gating jack indicates the jack is invalid if gating is unplugged */ if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack)) jack->pin_sense &= ~AC_PINSENSE_PRESENCE; jack->jack_dirty = 0; /* If a jack is gated by this one update it. */ if (jack->gated_jack) { struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, jack->gated_jack); if (gated) { gated->jack_dirty = 1; jack_detect_update(codec, gated); } } }
/** * snd_hda_pin_sense - execute pin sense measurement * @codec: the CODEC to sense * @nid: the pin NID to sense * * Execute necessary pin sense measurement and return its Presence Detect, * Impedance, ELD Valid etc. status bits. */ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); if (jack) { jack_detect_update(codec, jack); return jack->pin_sense; } return read_pin_sense(codec, nid); }
/** * snd_hda_jack_detect_state - query pin Presence Detect status * @codec: the CODEC to sense * @nid: the pin NID to sense * * Query and return the pin's Presence Detect status, as either * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM. */ int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); if (jack && jack->phantom_jack) return HDA_JACK_PHANTOM; else if (snd_hda_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE) return HDA_JACK_PRESENT; else return HDA_JACK_NOT_PRESENT; }
static void call_jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack) { if (jack->callback) jack->callback(codec, jack); if (jack->gated_jack) { struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, jack->gated_jack); if (gated && gated->callback) gated->callback(codec, gated); } }
/** * snd_hda_jack_tbl_new - create a jack-table entry for the given NID */ static struct hda_jack_tbl * snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); if (jack) return jack; jack = snd_array_new(&codec->jacktbl); if (!jack) return NULL; jack->nid = nid; jack->jack_dirty = 1; jack->tag = codec->jacktbl.used; return jack; }
static void call_jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack) { struct hda_jack_callback *cb; for (cb = jack->callback; cb; cb = cb->next) cb->func(codec, cb); if (jack->gated_jack) { struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, jack->gated_jack); if (gated) { for (cb = gated->callback; cb; cb = cb->next) cb->func(codec, cb); } } }
static void call_jack_callback(struct hda_codec *codec, unsigned int res, struct hda_jack_tbl *jack) { struct hda_jack_callback *cb; for (cb = jack->callback; cb; cb = cb->next) { cb->jack = jack; cb->unsol_res = res; cb->func(codec, cb); } if (jack->gated_jack) { struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, jack->gated_jack); if (gated) { for (cb = gated->callback; cb; cb = cb->next) { cb->jack = gated; cb->unsol_res = res; cb->func(codec, cb); } } } }