/** * snd_hda_jack_report_sync - sync the states of all jacks and report if changed */ void snd_hda_jack_report_sync(struct hda_codec *codec) { struct hda_jack_tbl *jack; int i, state; /* update all jacks at first */ jack = codec->jacktbl.list; for (i = 0; i < codec->jacktbl.used; i++, jack++) if (jack->nid) jack_detect_update(codec, jack); /* report the updated jacks; it's done after updating all jacks * to make sure that all gating jacks properly have been set */ jack = codec->jacktbl.list; for (i = 0; i < codec->jacktbl.used; i++, jack++) if (jack->nid) { if (!jack->kctl || jack->block_report) continue; state = get_jack_plug_state(jack->pin_sense); snd_kctl_jack_report(codec->bus->card, jack->kctl, state); #ifdef CONFIG_SND_HDA_INPUT_JACK if (jack->jack) snd_jack_report(jack->jack, state ? jack->type : 0); #endif } }
/* 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_jack_report_sync - sync the states of all jacks and report if changed * @codec: the HDA codec */ void snd_hda_jack_report_sync(struct hda_codec *codec) { struct hda_jack_tbl *jack; int i, state; /* update all jacks at first */ jack = codec->jacktbl.list; for (i = 0; i < codec->jacktbl.used; i++, jack++) if (jack->nid) jack_detect_update(codec, jack); /* report the updated jacks; it's done after updating all jacks * to make sure that all gating jacks properly have been set */ jack = codec->jacktbl.list; for (i = 0; i < codec->jacktbl.used; i++, jack++) if (jack->nid) { if (!jack->jack || jack->block_report) continue; state = jack->button_state; if (get_jack_plug_state(jack->pin_sense)) state |= jack->type; snd_jack_report(jack->jack, state); if (jack->button_state) { snd_jack_report(jack->jack, state & ~jack->button_state); jack->button_state = 0; /* button released */ } } }
/** * 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); }
void snd_hda_jack_poll_all(struct hda_codec *codec) { struct hda_jack_tbl *jack = codec->jacktbl.list; int i, changes = 0; for (i = 0; i < codec->jacktbl.used; i++, jack++) { unsigned int old_sense; if (!jack->nid || !jack->jack_dirty || jack->phantom_jack) continue; old_sense = get_jack_plug_state(jack->pin_sense); jack_detect_update(codec, jack); if (old_sense == get_jack_plug_state(jack->pin_sense)) continue; changes = 1; call_jack_callback(codec, jack); } if (changes) snd_hda_jack_report_sync(codec); }
/** * snd_hda_jack_report_sync - sync the states of all jacks and report if changed */ void snd_hda_jack_report_sync(struct hda_codec *codec) { struct hda_jack_tbl *jack = codec->jacktbl.list; int i, state; for (i = 0; i < codec->jacktbl.used; i++, jack++) if (jack->nid) { jack_detect_update(codec, jack); if (!jack->kctl) continue; state = get_jack_plug_state(jack->pin_sense); snd_kctl_jack_report(codec->bus->card, jack->kctl, state); #ifdef CONFIG_SND_HDA_INPUT_JACK if (jack->jack) snd_jack_report(jack->jack, state ? jack->type : 0); #endif } }