Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 342591
b: refs/heads/master
c: 0619ba8
h: refs/heads/master
i:
  342589: 1a37c1c
  342587: 3c74561
  342583: 2206a77
  342575: 5d33b1f
  342559: a14ec5f
  342527: 90b7387
v: v3
  • Loading branch information
Dylan Reid authored and Takashi Iwai committed Nov 19, 2012
1 parent 6ad7472 commit b0720d7
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 379170a42c84cee5f95fac536a4b5b76843baf90
refs/heads/master: 0619ba8c17b121ef0273be181198659b17d84247
72 changes: 63 additions & 9 deletions trunk/sound/pci/hda/hda_jack.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
snd_array_free(&codec->jacktbl);
}

#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)

/* update the cached value and notification flag if needed */
static void jack_detect_update(struct hda_codec *codec,
struct hda_jack_tbl *jack)
Expand All @@ -134,7 +136,21 @@ static void jack_detect_update(struct hda_codec *codec,
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);
}
}
}

/**
Expand Down Expand Up @@ -173,8 +189,6 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
}
EXPORT_SYMBOL_HDA(snd_hda_pin_sense);

#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)

/**
* snd_hda_jack_detect - query pin Presence Detect status
* @codec: the CODEC to sense
Expand Down Expand Up @@ -221,17 +235,47 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
}
EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);

/**
* 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;
}
EXPORT_SYMBOL_HDA(snd_hda_jack_set_gating_jack);

/**
* 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;
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) {
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)
continue;
state = get_jack_plug_state(jack->pin_sense);
Expand Down Expand Up @@ -424,6 +468,19 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);

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);
}
}

void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
{
struct hda_jack_tbl *event;
Expand All @@ -434,9 +491,7 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
return;
event->jack_dirty = 1;

if (event->callback)
event->callback(codec, event);

call_jack_callback(codec, event);
snd_hda_jack_report_sync(codec);
}
EXPORT_SYMBOL_HDA(snd_hda_jack_unsol_event);
Expand All @@ -455,8 +510,7 @@ void snd_hda_jack_poll_all(struct hda_codec *codec)
if (old_sense == get_jack_plug_state(jack->pin_sense))
continue;
changes = 1;
if (jack->callback)
jack->callback(codec, jack);
call_jack_callback(codec, jack);
}
if (changes)
snd_hda_jack_report_sync(codec);
Expand Down
4 changes: 4 additions & 0 deletions trunk/sound/pci/hda/hda_jack.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ struct hda_jack_tbl {
unsigned int jack_detect:1; /* capable of jack-detection? */
unsigned int jack_dirty:1; /* needs to update? */
unsigned int phantom_jack:1; /* a fixed, always present port? */
hda_nid_t gating_jack; /* valid when gating jack plugged */
hda_nid_t gated_jack; /* gated is dependent on this jack */
struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
#ifdef CONFIG_SND_HDA_INPUT_JACK
int type;
Expand Down Expand Up @@ -69,6 +71,8 @@ int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
unsigned char action,
hda_jack_callback 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_pin_sense(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
Expand Down

0 comments on commit b0720d7

Please sign in to comment.