diff options
-rw-r--r-- | sound/pci/hda/hda_jack.c | 147 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.h | 107 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 70 |
3 files changed, 244 insertions, 80 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 1ea42447278f..bf0255cb0515 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -43,7 +43,7 @@ bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) EXPORT_SYMBOL_GPL(is_jack_detectable); /* execute pin sense measurement */ -static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) +static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id) { u32 pincap; u32 val; @@ -55,19 +55,20 @@ static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) AC_VERB_SET_PIN_SENSE, 0); } val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_SENSE, 0); + AC_VERB_GET_PIN_SENSE, dev_id); if (codec->inv_jack_detect) val ^= AC_PINSENSE_PRESENCE; return val; } /** - * snd_hda_jack_tbl_get - query the jack-table entry for the given NID + * snd_hda_jack_tbl_get_mst - query the jack-table entry for the given NID * @codec: the HDA codec * @nid: pin NID to refer to + * @dev_id: pin device entry id */ struct hda_jack_tbl * -snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) +snd_hda_jack_tbl_get_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id) { struct hda_jack_tbl *jack = codec->jacktbl.list; int i; @@ -75,19 +76,21 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) if (!nid || !jack) return NULL; for (i = 0; i < codec->jacktbl.used; i++, jack++) - if (jack->nid == nid) + if (jack->nid == nid && jack->dev_id == dev_id) return jack; return NULL; } -EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get); +EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_mst); /** * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag * @codec: the HDA codec * @tag: tag value to refer to + * @dev_id: pin device entry id */ struct hda_jack_tbl * -snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) +snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, + unsigned char tag, int dev_id) { struct hda_jack_tbl *jack = codec->jacktbl.list; int i; @@ -95,29 +98,62 @@ snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) if (!tag || !jack) return NULL; for (i = 0; i < codec->jacktbl.used; i++, jack++) - if (jack->tag == tag) + if (jack->tag == tag && jack->dev_id == dev_id) return jack; return NULL; } EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag); +static struct hda_jack_tbl * +any_jack_tbl_get_from_nid(struct hda_codec *codec, hda_nid_t nid) +{ + struct hda_jack_tbl *jack = codec->jacktbl.list; + int i; + + if (!nid || !jack) + return NULL; + for (i = 0; i < codec->jacktbl.used; i++, jack++) + if (jack->nid == nid) + return jack; + return NULL; +} + /** * snd_hda_jack_tbl_new - create a jack-table entry for the given NID * @codec: the HDA codec * @nid: pin NID to assign */ static struct hda_jack_tbl * -snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) +snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid, int dev_id) { - struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); + struct hda_jack_tbl *jack = + snd_hda_jack_tbl_get_mst(codec, nid, dev_id); + struct hda_jack_tbl *existing_nid_jack = + any_jack_tbl_get_from_nid(codec, nid); + + WARN_ON(dev_id != 0 && !codec->dp_mst); + if (jack) return jack; jack = snd_array_new(&codec->jacktbl); if (!jack) return NULL; jack->nid = nid; + jack->dev_id = dev_id; jack->jack_dirty = 1; - jack->tag = codec->jacktbl.used; + if (existing_nid_jack) { + jack->tag = existing_nid_jack->tag; + + /* + * Copy jack_detect from existing_nid_jack to avoid + * snd_hda_jack_detect_enable_callback_mst() making multiple + * SET_UNSOLICITED_ENABLE calls on the same pin. + */ + jack->jack_detect = existing_nid_jack->jack_detect; + } else { + jack->tag = codec->jacktbl.used; + } + return jack; } @@ -153,10 +189,12 @@ static void jack_detect_update(struct hda_codec *codec, if (jack->phantom_jack) jack->pin_sense = AC_PINSENSE_PRESENCE; else - jack->pin_sense = read_pin_sense(codec, jack->nid); + jack->pin_sense = read_pin_sense(codec, jack->nid, + jack->dev_id); /* A gating jack indicates the jack is invalid if gating is unplugged */ - if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack)) + if (jack->gating_jack && + !snd_hda_jack_detect_mst(codec, jack->gating_jack, jack->dev_id)) jack->pin_sense &= ~AC_PINSENSE_PRESENCE; jack->jack_dirty = 0; @@ -164,7 +202,8 @@ static void jack_detect_update(struct hda_codec *codec, /* 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); + snd_hda_jack_tbl_get_mst(codec, jack->gated_jack, + jack->dev_id); if (gated) { gated->jack_dirty = 1; jack_detect_update(codec, gated); @@ -198,56 +237,62 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all); * Execute necessary pin sense measurement and return its Presence Detect, * Impedance, ELD Valid etc. status bits. */ -u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid) +u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id) { - struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); + struct hda_jack_tbl *jack = + snd_hda_jack_tbl_get_mst(codec, nid, dev_id); if (jack) { jack_detect_update(codec, jack); return jack->pin_sense; } - return read_pin_sense(codec, nid); + return read_pin_sense(codec, nid, dev_id); } EXPORT_SYMBOL_GPL(snd_hda_jack_pin_sense); /** - * snd_hda_jack_detect_state - query pin Presence Detect status + * snd_hda_jack_detect_state_mst - query pin Presence Detect status * @codec: the CODEC to sense * @nid: the pin NID to sense + * @dev_id: pin device entry id * * 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) +int snd_hda_jack_detect_state_mst(struct hda_codec *codec, + hda_nid_t nid, int dev_id) { - struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); + struct hda_jack_tbl *jack = + snd_hda_jack_tbl_get_mst(codec, nid, dev_id); if (jack && jack->phantom_jack) return HDA_JACK_PHANTOM; - else if (snd_hda_jack_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE) + else if (snd_hda_jack_pin_sense(codec, nid, dev_id) & + AC_PINSENSE_PRESENCE) return HDA_JACK_PRESENT; else return HDA_JACK_NOT_PRESENT; } -EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state); +EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state_mst); /** - * snd_hda_jack_detect_enable - enable the jack-detection + * snd_hda_jack_detect_enable_mst - enable the jack-detection * @codec: the HDA codec * @nid: pin NID to enable * @func: callback function to register + * @dev_id: pin device entry id * * In the case of error, the return value will be a pointer embedded with * errno. Check and handle the return value appropriately with standard * macros such as @IS_ERR() and @PTR_ERR(). */ struct hda_jack_callback * -snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, - hda_jack_callback_fn func) +snd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid, + int dev_id, hda_jack_callback_fn func) { struct hda_jack_tbl *jack; struct hda_jack_callback *callback = NULL; int err; - jack = snd_hda_jack_tbl_new(codec, nid); + jack = snd_hda_jack_tbl_new(codec, nid, dev_id); if (!jack) return ERR_PTR(-ENOMEM); if (func) { @@ -256,6 +301,7 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, return ERR_PTR(-ENOMEM); callback->func = func; callback->nid = jack->nid; + callback->dev_id = jack->dev_id; callback->next = jack->callback; jack->callback = callback; } @@ -272,19 +318,24 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, return ERR_PTR(err); return callback; } -EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); +EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback_mst); /** * snd_hda_jack_detect_enable - Enable the jack detection on the given pin * @codec: the HDA codec * @nid: pin NID to enable jack detection + * @dev_id: pin device entry id * * Enable the jack detection with the default callback. Returns zero if * successful or a negative error code. */ -int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid) +int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, + int dev_id) { - return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL)); + return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback_mst(codec, + nid, + dev_id, + NULL)); } EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); @@ -299,8 +350,11 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); 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_new(codec, gated_nid); - struct hda_jack_tbl *gating = snd_hda_jack_tbl_new(codec, gating_nid); + struct hda_jack_tbl *gated = snd_hda_jack_tbl_new(codec, gated_nid, 0); + struct hda_jack_tbl *gating = + snd_hda_jack_tbl_new(codec, gating_nid, 0); + + WARN_ON(codec->dp_mst); if (!gated || !gating) return -EINVAL; @@ -376,9 +430,10 @@ static void hda_free_jack_priv(struct snd_jack *jack) } /** - * snd_hda_jack_add_kctl - Add a kctl for the given pin + * snd_hda_jack_add_kctl_mst - Add a kctl for the given pin * @codec: the HDA codec * @nid: pin NID to assign + * @dev_id : pin device entry id * @name: string name for the jack * @phantom_jack: flag to deal as a phantom jack * @type: jack type bits to be reported, 0 for guessing from pincfg @@ -387,15 +442,15 @@ static void hda_free_jack_priv(struct snd_jack *jack) * This assigns a jack-detection kctl to the given pin. The kcontrol * will have the given name and index. */ -int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, - const char *name, bool phantom_jack, - int type, const struct hda_jack_keymap *keymap) +int snd_hda_jack_add_kctl_mst(struct hda_codec *codec, hda_nid_t nid, + int dev_id, const char *name, bool phantom_jack, + int type, const struct hda_jack_keymap *keymap) { struct hda_jack_tbl *jack; const struct hda_jack_keymap *map; int err, state, buttons; - jack = snd_hda_jack_tbl_new(codec, nid); + jack = snd_hda_jack_tbl_new(codec, nid, dev_id); if (!jack) return 0; if (jack->jack) @@ -425,12 +480,12 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, snd_jack_set_key(jack->jack, map->type, map->key); } - state = snd_hda_jack_detect(codec, nid); + state = snd_hda_jack_detect_mst(codec, nid, dev_id); snd_jack_report(jack->jack, state ? jack->type : 0); return 0; } -EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl); +EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl_mst); static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, const struct auto_pin_cfg *cfg, @@ -441,6 +496,8 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int err; bool phantom_jack; + WARN_ON(codec->dp_mst); + if (!nid) return 0; def_conf = snd_hda_codec_get_pincfg(codec, nid); @@ -462,7 +519,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, return err; if (!phantom_jack) - return snd_hda_jack_detect_enable(codec, nid); + return snd_hda_jack_detect_enable(codec, nid, 0); return 0; } @@ -540,7 +597,8 @@ static void call_jack_callback(struct hda_codec *codec, unsigned int res, } if (jack->gated_jack) { struct hda_jack_tbl *gated = - snd_hda_jack_tbl_get(codec, jack->gated_jack); + snd_hda_jack_tbl_get_mst(codec, jack->gated_jack, + jack->dev_id); if (gated) { for (cb = gated->callback; cb; cb = cb->next) { cb->jack = gated; @@ -561,7 +619,14 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) struct hda_jack_tbl *event; int tag = (res & AC_UNSOL_RES_TAG) >> AC_UNSOL_RES_TAG_SHIFT; - event = snd_hda_jack_tbl_get_from_tag(codec, tag); + if (codec->dp_mst) { + int dev_entry = + (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; + + event = snd_hda_jack_tbl_get_from_tag(codec, tag, dev_entry); + } else { + event = snd_hda_jack_tbl_get_from_tag(codec, tag, 0); + } if (!event) return; event->jack_dirty = 1; diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index cd9b47f51fab..727b6d3ba454 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -19,6 +19,7 @@ typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callba struct hda_jack_callback { hda_nid_t nid; + int dev_id; hda_jack_callback_fn func; unsigned int private_data; /* arbitrary data */ unsigned int unsol_res; /* unsolicited event bits */ @@ -28,6 +29,7 @@ struct hda_jack_callback { struct hda_jack_tbl { hda_nid_t nid; + int dev_id; unsigned char tag; /* unsol event tag */ struct hda_jack_callback *callback; /* jack-detection stuff */ @@ -49,46 +51,129 @@ struct hda_jack_keymap { }; struct hda_jack_tbl * -snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid); +snd_hda_jack_tbl_get_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id); + +/** + * snd_hda_jack_tbl_get - query the jack-table entry for the given NID + * @codec: the HDA codec + * @nid: pin NID to refer to + */ +static inline struct hda_jack_tbl * +snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) +{ + return snd_hda_jack_tbl_get_mst(codec, nid, 0); +} + struct hda_jack_tbl * -snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag); +snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, + unsigned char tag, int dev_id); void snd_hda_jack_tbl_clear(struct hda_codec *codec); void snd_hda_jack_set_dirty_all(struct hda_codec *codec); -int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid); +int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, + int dev_id); + struct hda_jack_callback * +snd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid, + int dev_id, hda_jack_callback_fn cb); + +/** + * snd_hda_jack_detect_enable - enable the jack-detection + * @codec: the HDA codec + * @nid: pin NID to enable + * @func: callback function to register + * + * In the case of error, the return value will be a pointer embedded with + * errno. Check and handle the return value appropriately with standard + * macros such as @IS_ERR() and @PTR_ERR(). + */ +static inline struct hda_jack_callback * snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, - hda_jack_callback_fn cb); + hda_jack_callback_fn cb) +{ + return snd_hda_jack_detect_enable_callback_mst(codec, nid, 0, cb); +} int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, hda_nid_t gating_nid); -u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid); +u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id); /* the jack state returned from snd_hda_jack_detect_state() */ enum { HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM, }; -int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid); +int snd_hda_jack_detect_state_mst(struct hda_codec *codec, hda_nid_t nid, + int dev_id); + +/** + * 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. + */ +static inline int +snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid) +{ + return snd_hda_jack_detect_state_mst(codec, nid, 0); +} + +/** + * snd_hda_jack_detect_mst - Detect the jack + * @codec: the HDA codec + * @nid: pin NID to check jack detection + * @dev_id: pin device entry id + */ +static inline bool +snd_hda_jack_detect_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id) +{ + return snd_hda_jack_detect_state_mst(codec, nid, dev_id) != + HDA_JACK_NOT_PRESENT; +} /** * snd_hda_jack_detect - Detect the jack * @codec: the HDA codec * @nid: pin NID to check jack detection */ -static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) +static inline bool +snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) { - return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT; + return snd_hda_jack_detect_mst(codec, nid, 0); } bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); -int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, - const char *name, bool phantom_jack, - int type, const struct hda_jack_keymap *keymap); +int snd_hda_jack_add_kctl_mst(struct hda_codec *codec, hda_nid_t nid, + int dev_id, const char *name, bool phantom_jack, + int type, const struct hda_jack_keymap *keymap); + +/** + * snd_hda_jack_add_kctl - Add a kctl for the given pin + * @codec: the HDA codec + * @nid: pin NID to assign + * @name: string name for the jack + * @phantom_jack: flag to deal as a phantom jack + * @type: jack type bits to be reported, 0 for guessing from pincfg + * @keymap: optional jack / key mapping + * + * This assigns a jack-detection kctl to the given pin. The kcontrol + * will have the given name and index. + */ +static inline int +snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, + const char *name, bool phantom_jack, + int type, const struct hda_jack_keymap *keymap) +{ + return snd_hda_jack_add_kctl_mst(codec, nid, 0, + name, phantom_jack, type, keymap); +} + int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 3b1b978201a9..37b4345afdde 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -758,34 +758,32 @@ static void jack_callback(struct hda_codec *codec, if (codec_has_acomp(codec)) return; - /* hda_jack don't support DP MST */ - check_presence_and_report(codec, jack->nid, 0); + check_presence_and_report(codec, jack->nid, jack->dev_id); } static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) { int tag = res >> AC_UNSOL_RES_TAG_SHIFT; struct hda_jack_tbl *jack; - int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; - /* - * assume DP MST uses dyn_pcm_assign and acomp and - * never comes here - * if DP MST supports unsol event, below code need - * consider dev_entry - */ - jack = snd_hda_jack_tbl_get_from_tag(codec, tag); + if (codec->dp_mst) { + int dev_entry = + (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; + + jack = snd_hda_jack_tbl_get_from_tag(codec, tag, dev_entry); + } else { + jack = snd_hda_jack_tbl_get_from_tag(codec, tag, 0); + } if (!jack) return; jack->jack_dirty = 1; codec_dbg(codec, "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA), + codec->addr, jack->nid, jack->dev_id, !!(res & AC_UNSOL_RES_IA), !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); - /* hda_jack don't support DP MST */ - check_presence_and_report(codec, jack->nid, 0); + check_presence_and_report(codec, jack->nid, jack->dev_id); } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -815,11 +813,21 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) { int tag = res >> AC_UNSOL_RES_TAG_SHIFT; int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; + struct hda_jack_tbl *jack; if (codec_has_acomp(codec)) return; - if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) { + if (codec->dp_mst) { + int dev_entry = + (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; + + jack = snd_hda_jack_tbl_get_from_tag(codec, tag, dev_entry); + } else { + jack = snd_hda_jack_tbl_get_from_tag(codec, tag, 0); + } + + if (!jack) { codec_dbg(codec, "Unexpected HDMI event tag 0x%x\n", tag); return; } @@ -1505,7 +1513,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, bool ret; bool do_repoll = false; - present = snd_hda_jack_pin_sense(codec, pin_nid); + present = snd_hda_jack_pin_sense(codec, pin_nid, per_pin->dev_id); mutex_lock(&per_pin->lock); eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); @@ -1538,7 +1546,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, ret = !repoll || !eld->monitor_present || eld->eld_valid; - jack = snd_hda_jack_tbl_get(codec, pin_nid); + jack = snd_hda_jack_tbl_get_mst(codec, pin_nid, per_pin->dev_id); if (jack) { jack->block_report = !ret; jack->pin_sense = (eld->monitor_present && eld->eld_valid) ? @@ -1569,7 +1577,8 @@ static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec, * DP MST will use dyn_pcm_assign, * so DP MST will never come here */ - jack_tbl = snd_hda_jack_tbl_get(codec, per_pin->pin_nid); + jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, + per_pin->dev_id); if (jack_tbl) jack = jack_tbl->jack; } @@ -1650,7 +1659,8 @@ static void hdmi_repoll_eld(struct work_struct *work) struct hdmi_spec *spec = codec->spec; struct hda_jack_tbl *jack; - jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid); + jack = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, + per_pin->dev_id); if (jack) jack->jack_dirty = 1; @@ -2151,11 +2161,13 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx) if (phantom_jack) strncat(hdmi_str, " Phantom", sizeof(hdmi_str) - strlen(hdmi_str) - 1); - ret = snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, - phantom_jack, 0, NULL); + ret = snd_hda_jack_add_kctl_mst(codec, per_pin->pin_nid, + per_pin->dev_id, hdmi_str, phantom_jack, + 0, NULL); if (ret < 0) return ret; - jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid); + jack = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, + per_pin->dev_id); if (jack == NULL) return 0; /* assign jack->jack to pcm_rec[].jack to @@ -2264,10 +2276,11 @@ static int generic_hdmi_init(struct hda_codec *codec) if (codec_has_acomp(codec)) continue; if (spec->use_jack_detect) - snd_hda_jack_detect_enable(codec, pin_nid); + snd_hda_jack_detect_enable(codec, pin_nid, dev_id); else - snd_hda_jack_detect_enable_callback(codec, pin_nid, - jack_callback); + snd_hda_jack_detect_enable_callback_mst(codec, pin_nid, + dev_id, + jack_callback); } mutex_unlock(&spec->bind_lock); return 0; @@ -2417,11 +2430,11 @@ static int patch_generic_hdmi(struct hda_codec *codec) /* turn on / off the unsol event jack detection dynamically */ static void reprogram_jack_detect(struct hda_codec *codec, hda_nid_t nid, - bool use_acomp) + int dev_id, bool use_acomp) { struct hda_jack_tbl *tbl; - tbl = snd_hda_jack_tbl_get(codec, nid); + tbl = snd_hda_jack_tbl_get_mst(codec, nid, dev_id); if (tbl) { /* clear unsol even if component notifier is used, or re-enable * if notifier is cleared @@ -2434,7 +2447,7 @@ static void reprogram_jack_detect(struct hda_codec *codec, hda_nid_t nid, * at need (i.e. only when notifier is cleared) */ if (!use_acomp) - snd_hda_jack_detect_enable(codec, nid); + snd_hda_jack_detect_enable(codec, nid, dev_id); } } @@ -2454,6 +2467,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp, for (i = 0; i < spec->num_pins; i++) reprogram_jack_detect(spec->codec, get_pin(spec, i)->pin_nid, + get_pin(spec, i)->dev_id, use_acomp); } mutex_unlock(&spec->bind_lock); @@ -2959,7 +2973,7 @@ static int simple_playback_init(struct hda_codec *codec) if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); - snd_hda_jack_detect_enable(codec, pin); + snd_hda_jack_detect_enable(codec, pin, per_pin->dev_id); return 0; } |