summaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_jack.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-10-27 23:16:55 (GMT)
committerTakashi Iwai <tiwai@suse.de>2011-11-16 10:14:03 (GMT)
commit3a93897ea37cbb8277f8a4232c12c0c18168a7db (patch)
tree1c79df3bb270e86c61bdb13fab0bf66cbd3682ac /sound/pci/hda/hda_jack.c
parent01a61e12b4602c82bde9797d0e153f3e53c95b04 (diff)
downloadlinux-fsl-qoriq-3a93897ea37cbb8277f8a4232c12c0c18168a7db.tar.xz
ALSA: hda - Manage unsol tags in hda_jack.c
Manage the tags assigned for unsolicited events dynamically together with the jack-detection routines. Basically this is almost same as what we've done in patch_sigmatel.c. Assign the new tag number for each new unsol event, associate with the given NID and the action type, etc. With this change, now all pins looked over in snd_hda_jack_add_kctls() are actually enabled for detection now even if the pins aren't used for jack-retasking by the driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_jack.c')
-rw-r--r--sound/pci/hda/hda_jack.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index cee6a00..8829d5c 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -51,6 +51,24 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
/**
+ * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
+ */
+struct hda_jack_tbl *
+snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
+{
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i;
+
+ if (!tag || !jack)
+ return NULL;
+ for (i = 0; i < codec->jacktbl.used; i++, jack++)
+ if (jack->tag == tag)
+ return jack;
+ return NULL;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
+
+/**
* snd_hda_jack_tbl_new - create a jack-table entry for the given NID
*/
struct hda_jack_tbl *
@@ -65,6 +83,7 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
return NULL;
jack->nid = nid;
jack->jack_dirty = 1;
+ jack->tag = codec->jacktbl.used;
return jack;
}
@@ -77,7 +96,7 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
static void jack_detect_update(struct hda_codec *codec,
struct hda_jack_tbl *jack)
{
- if (jack->jack_dirty || !jack->jack_cachable) {
+ if (jack->jack_dirty || !jack->jack_detect) {
unsigned int val = read_pin_sense(codec, jack->nid);
jack->jack_dirty = 0;
if (val != jack->pin_sense) {
@@ -141,17 +160,19 @@ EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
* snd_hda_jack_detect_enable - enable the jack-detection
*/
int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
- unsigned int tag)
+ unsigned char action)
{
struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
if (!jack)
return -ENOMEM;
- if (jack->jack_cachable)
+ if (jack->jack_detect)
return 0; /* already registered */
- jack->jack_cachable = 1;
+ jack->jack_detect = 1;
+ if (action)
+ jack->action = action;
return snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | tag);
+ AC_USRSP_EN | jack->tag);
}
EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
@@ -168,18 +189,6 @@ static void jack_detect_report(struct hda_codec *codec,
}
/**
- * snd_hda_jack_report - notify kctl when the jack state was changed
- */
-void snd_hda_jack_report(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
-
- if (jack)
- jack_detect_report(codec, jack);
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_report);
-
-/**
* 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)
@@ -231,7 +240,7 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
struct hda_jack_tbl *jack;
struct snd_kcontrol *kctl;
- jack = snd_hda_jack_tbl_get(codec, nid);
+ jack = snd_hda_jack_tbl_new(codec, nid);
if (!jack)
return 0;
if (jack->kctl)
@@ -251,20 +260,28 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx,
const struct auto_pin_cfg *cfg)
{
+ unsigned int def_conf, conn;
+ int err;
+
if (!nid)
return 0;
if (!is_jack_detectable(codec, nid))
return 0;
- return snd_hda_jack_add_kctl(codec, nid,
+ def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ conn = get_defcfg_connect(def_conf);
+ if (conn != AC_JACK_PORT_COMPLEX)
+ return 0;
+
+ err = snd_hda_jack_add_kctl(codec, nid,
snd_hda_get_pin_label(codec, nid, cfg),
idx);
+ if (err < 0)
+ return err;
+ return snd_hda_jack_detect_enable(codec, nid, 0);
}
/**
* snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
- *
- * As of now, it assigns only to the pins that enabled the detection.
- * Usually this is called at the end of build_controls callback.
*/
int snd_hda_jack_add_kctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)