162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Jack-detection handling for HD-audio 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef __SOUND_HDA_JACK_H 962306a36Sopenharmony_ci#define __SOUND_HDA_JACK_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/err.h> 1262306a36Sopenharmony_ci#include <sound/jack.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct auto_pin_cfg; 1562306a36Sopenharmony_cistruct hda_jack_tbl; 1662306a36Sopenharmony_cistruct hda_jack_callback; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_citypedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *); 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct hda_jack_callback { 2162306a36Sopenharmony_ci hda_nid_t nid; 2262306a36Sopenharmony_ci int dev_id; 2362306a36Sopenharmony_ci hda_jack_callback_fn func; 2462306a36Sopenharmony_ci unsigned int private_data; /* arbitrary data */ 2562306a36Sopenharmony_ci unsigned int unsol_res; /* unsolicited event bits */ 2662306a36Sopenharmony_ci struct hda_jack_tbl *jack; /* associated jack entry */ 2762306a36Sopenharmony_ci struct hda_jack_callback *next; 2862306a36Sopenharmony_ci}; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistruct hda_jack_tbl { 3162306a36Sopenharmony_ci hda_nid_t nid; 3262306a36Sopenharmony_ci int dev_id; 3362306a36Sopenharmony_ci unsigned char tag; /* unsol event tag */ 3462306a36Sopenharmony_ci struct hda_jack_callback *callback; 3562306a36Sopenharmony_ci /* jack-detection stuff */ 3662306a36Sopenharmony_ci unsigned int pin_sense; /* cached pin-sense value */ 3762306a36Sopenharmony_ci unsigned int jack_detect:1; /* capable of jack-detection? */ 3862306a36Sopenharmony_ci unsigned int jack_dirty:1; /* needs to update? */ 3962306a36Sopenharmony_ci unsigned int phantom_jack:1; /* a fixed, always present port? */ 4062306a36Sopenharmony_ci unsigned int block_report:1; /* in a transitional state - do not report to userspace */ 4162306a36Sopenharmony_ci hda_nid_t gating_jack; /* valid when gating jack plugged */ 4262306a36Sopenharmony_ci hda_nid_t gated_jack; /* gated is dependent on this jack */ 4362306a36Sopenharmony_ci hda_nid_t key_report_jack; /* key reports to this jack */ 4462306a36Sopenharmony_ci int type; 4562306a36Sopenharmony_ci int button_state; 4662306a36Sopenharmony_ci struct snd_jack *jack; 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistruct hda_jack_keymap { 5062306a36Sopenharmony_ci enum snd_jack_types type; 5162306a36Sopenharmony_ci int key; 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistruct hda_jack_tbl * 5562306a36Sopenharmony_cisnd_hda_jack_tbl_get_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/** 5862306a36Sopenharmony_ci * snd_hda_jack_tbl_get - query the jack-table entry for the given NID 5962306a36Sopenharmony_ci * @codec: the HDA codec 6062306a36Sopenharmony_ci * @nid: pin NID to refer to 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_cistatic inline struct hda_jack_tbl * 6362306a36Sopenharmony_cisnd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci return snd_hda_jack_tbl_get_mst(codec, nid, 0); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistruct hda_jack_tbl * 6962306a36Sopenharmony_cisnd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, 7062306a36Sopenharmony_ci unsigned char tag, int dev_id); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_civoid snd_hda_jack_tbl_disconnect(struct hda_codec *codec); 7362306a36Sopenharmony_civoid snd_hda_jack_tbl_clear(struct hda_codec *codec); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_civoid snd_hda_jack_set_dirty_all(struct hda_codec *codec); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciint snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 7862306a36Sopenharmony_ci int dev_id); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistruct hda_jack_callback * 8162306a36Sopenharmony_cisnd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid, 8262306a36Sopenharmony_ci int dev_id, hda_jack_callback_fn func); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/** 8562306a36Sopenharmony_ci * snd_hda_jack_detect_enable - enable the jack-detection 8662306a36Sopenharmony_ci * @codec: the HDA codec 8762306a36Sopenharmony_ci * @nid: pin NID to enable 8862306a36Sopenharmony_ci * @func: callback function to register 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * In the case of error, the return value will be a pointer embedded with 9162306a36Sopenharmony_ci * errno. Check and handle the return value appropriately with standard 9262306a36Sopenharmony_ci * macros such as @IS_ERR() and @PTR_ERR(). 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_cistatic inline struct hda_jack_callback * 9562306a36Sopenharmony_cisnd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, 9662306a36Sopenharmony_ci hda_jack_callback_fn cb) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci return snd_hda_jack_detect_enable_callback_mst(codec, nid, 0, cb); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ciint snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, 10262306a36Sopenharmony_ci hda_nid_t gating_nid); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciint snd_hda_jack_bind_keymap(struct hda_codec *codec, hda_nid_t key_nid, 10562306a36Sopenharmony_ci const struct hda_jack_keymap *keymap, 10662306a36Sopenharmony_ci hda_nid_t jack_nid); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_civoid snd_hda_jack_set_button_state(struct hda_codec *codec, hda_nid_t jack_nid, 10962306a36Sopenharmony_ci int button_state); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciu32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/* the jack state returned from snd_hda_jack_detect_state() */ 11462306a36Sopenharmony_cienum { 11562306a36Sopenharmony_ci HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM, 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint snd_hda_jack_detect_state_mst(struct hda_codec *codec, hda_nid_t nid, 11962306a36Sopenharmony_ci int dev_id); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/** 12262306a36Sopenharmony_ci * snd_hda_jack_detect_state - query pin Presence Detect status 12362306a36Sopenharmony_ci * @codec: the CODEC to sense 12462306a36Sopenharmony_ci * @nid: the pin NID to sense 12562306a36Sopenharmony_ci * 12662306a36Sopenharmony_ci * Query and return the pin's Presence Detect status, as either 12762306a36Sopenharmony_ci * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM. 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_cistatic inline int 13062306a36Sopenharmony_cisnd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci return snd_hda_jack_detect_state_mst(codec, nid, 0); 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci/** 13662306a36Sopenharmony_ci * snd_hda_jack_detect_mst - Detect the jack 13762306a36Sopenharmony_ci * @codec: the HDA codec 13862306a36Sopenharmony_ci * @nid: pin NID to check jack detection 13962306a36Sopenharmony_ci * @dev_id: pin device entry id 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_cistatic inline bool 14262306a36Sopenharmony_cisnd_hda_jack_detect_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci return snd_hda_jack_detect_state_mst(codec, nid, dev_id) != 14562306a36Sopenharmony_ci HDA_JACK_NOT_PRESENT; 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/** 14962306a36Sopenharmony_ci * snd_hda_jack_detect - Detect the jack 15062306a36Sopenharmony_ci * @codec: the HDA codec 15162306a36Sopenharmony_ci * @nid: pin NID to check jack detection 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_cistatic inline bool 15462306a36Sopenharmony_cisnd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci return snd_hda_jack_detect_mst(codec, nid, 0); 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cibool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ciint snd_hda_jack_add_kctl_mst(struct hda_codec *codec, hda_nid_t nid, 16262306a36Sopenharmony_ci int dev_id, const char *name, bool phantom_jack, 16362306a36Sopenharmony_ci int type, const struct hda_jack_keymap *keymap); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci/** 16662306a36Sopenharmony_ci * snd_hda_jack_add_kctl - Add a kctl for the given pin 16762306a36Sopenharmony_ci * @codec: the HDA codec 16862306a36Sopenharmony_ci * @nid: pin NID to assign 16962306a36Sopenharmony_ci * @name: string name for the jack 17062306a36Sopenharmony_ci * @phantom_jack: flag to deal as a phantom jack 17162306a36Sopenharmony_ci * @type: jack type bits to be reported, 0 for guessing from pincfg 17262306a36Sopenharmony_ci * @keymap: optional jack / key mapping 17362306a36Sopenharmony_ci * 17462306a36Sopenharmony_ci * This assigns a jack-detection kctl to the given pin. The kcontrol 17562306a36Sopenharmony_ci * will have the given name and index. 17662306a36Sopenharmony_ci */ 17762306a36Sopenharmony_cistatic inline int 17862306a36Sopenharmony_cisnd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 17962306a36Sopenharmony_ci const char *name, bool phantom_jack, 18062306a36Sopenharmony_ci int type, const struct hda_jack_keymap *keymap) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci return snd_hda_jack_add_kctl_mst(codec, nid, 0, 18362306a36Sopenharmony_ci name, phantom_jack, type, keymap); 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ciint snd_hda_jack_add_kctls(struct hda_codec *codec, 18762306a36Sopenharmony_ci const struct auto_pin_cfg *cfg); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_civoid snd_hda_jack_report_sync(struct hda_codec *codec); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_civoid snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_civoid snd_hda_jack_poll_all(struct hda_codec *codec); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci#endif /* __SOUND_HDA_JACK_H */ 196