Skip to content

Commit 911761c

Browse files
committed
ALSA: hda - Add jack button support
Extend some structs to add the support for jack button changes. Now snd_hda_jack_add_kctl() receives two more arguments: the jack type and the jack keymaps. Both are optional, and when zero are passed, the function behaves just like before. For reporting button state changes, you'd need to update jack->button_state bits accordingly, typically in the jack callback. Then the value OR'ed with button_state and the jack plug state is passed to snd_jack_report(). Note that currently the code assumes only the one-shot button events, i.e. it tries to send the button release soon after sending the button event. If a driver really supports the button release handling by itself, we may need to introduce some flag to control this behavior in future. Signed-off-by: Takashi Iwai <[email protected]>
1 parent e6ce180 commit 911761c

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

sound/pci/hda/hda_jack.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,15 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
339339
if (jack->nid) {
340340
if (!jack->jack || jack->block_report)
341341
continue;
342-
state = get_jack_plug_state(jack->pin_sense);
343-
snd_jack_report(jack->jack,
344-
state ? jack->type : 0);
342+
state = jack->button_state;
343+
if (get_jack_plug_state(jack->pin_sense))
344+
state |= jack->type;
345+
snd_jack_report(jack->jack, state);
346+
if (jack->button_state) {
347+
snd_jack_report(jack->jack,
348+
state & ~jack->button_state);
349+
jack->button_state = 0; /* button released */
350+
}
345351
}
346352
}
347353
EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
@@ -379,32 +385,50 @@ static void hda_free_jack_priv(struct snd_jack *jack)
379385
* @nid: pin NID to assign
380386
* @name: string name for the jack
381387
* @phantom_jack: flag to deal as a phantom jack
388+
* @type: jack type bits to be reported, 0 for guessing from pincfg
389+
* @keymap: optional jack / key mapping
382390
*
383391
* This assigns a jack-detection kctl to the given pin. The kcontrol
384392
* will have the given name and index.
385393
*/
386394
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
387-
const char *name, bool phantom_jack)
395+
const char *name, bool phantom_jack,
396+
int type, const struct hda_jack_keymap *keymap)
388397
{
389398
struct hda_jack_tbl *jack;
390-
int err, state, type;
399+
const struct hda_jack_keymap *map;
400+
int err, state, buttons;
391401

392402
jack = snd_hda_jack_tbl_new(codec, nid);
393403
if (!jack)
394404
return 0;
395405
if (jack->jack)
396406
return 0; /* already created */
397407

398-
type = get_input_jack_type(codec, nid);
399-
err = snd_jack_new(codec->card, name, type,
408+
if (!type)
409+
type = get_input_jack_type(codec, nid);
410+
411+
buttons = 0;
412+
if (keymap) {
413+
for (map = keymap; map->type; map++)
414+
buttons |= map->type;
415+
}
416+
417+
err = snd_jack_new(codec->card, name, type | buttons,
400418
&jack->jack, true, phantom_jack);
401419
if (err < 0)
402420
return err;
403421

404422
jack->phantom_jack = !!phantom_jack;
405423
jack->type = type;
424+
jack->button_state = 0;
406425
jack->jack->private_data = jack;
407426
jack->jack->private_free = hda_free_jack_priv;
427+
if (keymap) {
428+
for (map = keymap; map->type; map++)
429+
snd_jack_set_key(jack->jack, map->type, map->key);
430+
}
431+
408432
state = snd_hda_jack_detect(codec, nid);
409433
snd_jack_report(jack->jack, state ? jack->type : 0);
410434

@@ -437,7 +461,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
437461
if (phantom_jack)
438462
/* Example final name: "Internal Mic Phantom Jack" */
439463
strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
440-
err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
464+
err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack, 0, NULL);
441465
if (err < 0)
442466
return err;
443467

sound/pci/hda/hda_jack.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define __SOUND_HDA_JACK_H
1414

1515
#include <linux/err.h>
16+
#include <sound/jack.h>
1617

1718
struct auto_pin_cfg;
1819
struct hda_jack_tbl;
@@ -42,9 +43,15 @@ struct hda_jack_tbl {
4243
hda_nid_t gating_jack; /* valid when gating jack plugged */
4344
hda_nid_t gated_jack; /* gated is dependent on this jack */
4445
int type;
46+
int button_state;
4547
struct snd_jack *jack;
4648
};
4749

50+
struct hda_jack_keymap {
51+
enum snd_jack_types type;
52+
int key;
53+
};
54+
4855
struct hda_jack_tbl *
4956
snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
5057
struct hda_jack_tbl *
@@ -84,7 +91,8 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
8491
bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
8592

8693
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
87-
const char *name, bool phantom_jack);
94+
const char *name, bool phantom_jack,
95+
int type, const struct hda_jack_keymap *keymap);
8896
int snd_hda_jack_add_kctls(struct hda_codec *codec,
8997
const struct auto_pin_cfg *cfg);
9098

sound/pci/hda/patch_hdmi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2142,7 +2142,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
21422142
strncat(hdmi_str, " Phantom",
21432143
sizeof(hdmi_str) - strlen(hdmi_str) - 1);
21442144
ret = snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,
2145-
phantom_jack);
2145+
phantom_jack, 0, NULL);
21462146
if (ret < 0)
21472147
return ret;
21482148
jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);

0 commit comments

Comments
 (0)