From 04f5ade6afc4326dc6cd10d235500972fba548eb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 27 Oct 2011 20:47:07 +0200 Subject: ALSA: hda - Introduce snd_hda_get_pin_label() Create a new helper function snd_hda_get_pin_label() for getting a label string for both input and output pins. hda_get_input_pin_label() is obsoleted by this function, and the callers are replaced appropriately now by this patch. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 470f6f286e8..3b4ef0cba0e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2872,7 +2872,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, } if (control) { - strcpy(name, hda_get_input_pin_label(codec, nid, 1)); + strcpy(name, snd_hda_get_pin_label(codec, nid, NULL)); return stac92xx_add_control(codec->spec, control, strcat(name, " Jack Mode"), nid); } @@ -3563,7 +3563,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, if (index < 0) continue; - label = hda_get_input_pin_label(codec, nid, 1); + label = snd_hda_get_pin_label(codec, nid, NULL); snd_hda_add_imux_item(dimux, label, index, &type_idx); if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) snd_hda_add_imux_item(imux, label, index, &type_idx); -- cgit v1.2.3 From 1835a0f9a2121ce3198dab67507d4d3e960cc09e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 27 Oct 2011 22:12:46 +0200 Subject: ALSA: hda - Cache the jack-detection value Introduce a table containing the pins and their jack-detection states for avoiding the unnecessary verbs to check the pin status at each time. When the unsol event is enabled via snd_hda_jack_detect_enable(), it automatically adds the given NID to the table. Then the driver supposes that the codec driver will set the dirty flag appropariately when an unsolicited event is invoked for that pin. The behavior for reading other pins that aren't registered in the table doesn't change. Only the pins assigned to the table are cached, so far. In near futre, this table can be extended to use the central place for the unsolicited events of all pins, etc, and eventually include the jack-detect kcontrols that replace the current input-jack stuff. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 46 +++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3b4ef0cba0e..97c6df9db5e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -37,6 +37,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" enum { STAC_VREF_EVENT = 1, @@ -4244,9 +4245,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, if (tag < 0) return 0; } - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | tag); + snd_hda_jack_detect_enable(codec, nid, tag); return 1; } @@ -4795,24 +4794,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec) mic->mux_idx); } -static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) -{ - struct sigmatel_event *event = stac_get_event(codec, nid); - if (!event) - return; - codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); -} - -static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +static void handle_unsol_event(struct hda_codec *codec, + struct sigmatel_event *event) { struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event; - int tag, data; - - tag = (res >> 26) & 0x7f; - event = stac_get_event_from_tag(codec, tag); - if (!event) - return; + int data; switch (event->type) { case STAC_HP_EVENT: @@ -4862,6 +4848,28 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } +static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) +{ + struct sigmatel_event *event = stac_get_event(codec, nid); + if (!event) + return; + handle_unsol_event(codec, event); +} + +static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct sigmatel_spec *spec = codec->spec; + struct sigmatel_event *event; + int tag; + + tag = (res >> 26) & 0x7f; + event = stac_get_event_from_tag(codec, tag); + if (!event) + return; + snd_hda_jack_set_dirty(codec, event->nid); + handle_unsol_event(codec, event); +} + static int hp_blike_system(u32 subsystem_id); static void set_hp_led_gpio(struct hda_codec *codec) -- cgit v1.2.3 From 01a61e12b4602c82bde9797d0e153f3e53c95b04 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 28 Oct 2011 00:03:22 +0200 Subject: ALSA: hda - Create jack-detection kcontrols Create kcontrols for pin jack-detections, which work similarly like jack-input layer. Each control will notify when the jack is plugged or unplugged, and also user can read the value at any time via the normal control API. The control elements are created with iface=CARD, so that they won't appear in the mixer apps. So far, only the pins that enabled the jack-detection are registered. For covering all pins, the transition of the common unsol-tag handling would be needed. Stay tuned. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 97c6df9db5e..90954b8269c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1212,6 +1212,10 @@ static int stac92xx_build_controls(struct hda_codec *codec) return err; } + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + return 0; } @@ -4473,6 +4477,8 @@ static int stac92xx_init(struct hda_codec *codec) stac_toggle_power_map(codec, nid, 0); } + snd_hda_jack_report_sync(codec); + /* sync mute LED */ if (spec->gpio_led) hda_call_check_power_status(codec, 0x01); @@ -4868,6 +4874,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) return; snd_hda_jack_set_dirty(codec, event->nid); handle_unsol_event(codec, event); + snd_hda_jack_report_sync(codec); } static int hp_blike_system(u32 subsystem_id); -- cgit v1.2.3 From 3a93897ea37cbb8277f8a4232c12c0c18168a7db Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 28 Oct 2011 01:16:55 +0200 Subject: 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 --- sound/pci/hda/patch_sigmatel.c | 104 +++++++++++------------------------------ 1 file changed, 26 insertions(+), 78 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 90954b8269c..dd6569ffcff 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -177,13 +177,6 @@ enum { STAC_9872_MODELS }; -struct sigmatel_event { - hda_nid_t nid; - unsigned char type; - unsigned char tag; - int data; -}; - struct sigmatel_mic_route { hda_nid_t pin; signed char mux_idx; @@ -231,9 +224,6 @@ struct sigmatel_spec { const hda_nid_t *pwr_nids; const hda_nid_t *dac_list; - /* events */ - struct snd_array events; - /* playback */ struct hda_input_mux *mono_mux; unsigned int cur_mmux; @@ -4182,49 +4172,18 @@ static int stac92xx_add_jack(struct hda_codec *codec, #endif /* CONFIG_SND_HDA_INPUT_JACK */ } -static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, +static int stac_add_event(struct hda_codec *codec, hda_nid_t nid, unsigned char type, int data) { - struct sigmatel_event *event; + struct hda_jack_tbl *event; - snd_array_init(&spec->events, sizeof(*event), 32); - event = snd_array_new(&spec->events); + event = snd_hda_jack_tbl_new(codec, nid); if (!event) return -ENOMEM; - event->nid = nid; - event->type = type; - event->tag = spec->events.used; - event->data = data; - - return event->tag; -} - -static struct sigmatel_event *stac_get_event(struct hda_codec *codec, - hda_nid_t nid) -{ - struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event = spec->events.list; - int i; - - for (i = 0; i < spec->events.used; i++, event++) { - if (event->nid == nid) - return event; - } - return NULL; -} + event->action = type; + event->private_data = data; -static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, - unsigned char tag) -{ - struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event = spec->events.list; - int i; - - for (i = 0; i < spec->events.used; i++, event++) { - if (event->tag == tag) - return event; - } - return NULL; + return 0; } /* check if given nid is a valid pin and no other events are assigned @@ -4234,22 +4193,17 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, unsigned int type) { - struct sigmatel_event *event; - int tag; + struct hda_jack_tbl *event; if (!is_jack_detectable(codec, nid)) return 0; - event = stac_get_event(codec, nid); - if (event) { - if (event->type != type) - return 0; - tag = event->tag; - } else { - tag = stac_add_event(codec->spec, nid, type, 0); - if (tag < 0) - return 0; - } - snd_hda_jack_detect_enable(codec, nid, tag); + event = snd_hda_jack_tbl_new(codec, nid); + if (!event) + return -ENOMEM; + if (event->action && event->action != type) + return 0; + event->action = type; + snd_hda_jack_detect_enable(codec, nid, 0); return 1; } @@ -4536,7 +4490,6 @@ static void stac92xx_free(struct hda_codec *codec) stac92xx_shutup(codec); snd_hda_input_jack_free(codec); - snd_array_free(&spec->events); kfree(spec); snd_hda_detach_beep_device(codec); @@ -4801,12 +4754,12 @@ static void stac92xx_mic_detect(struct hda_codec *codec) } static void handle_unsol_event(struct hda_codec *codec, - struct sigmatel_event *event) + struct hda_jack_tbl *event) { struct sigmatel_spec *spec = codec->spec; int data; - switch (event->type) { + switch (event->action) { case STAC_HP_EVENT: case STAC_LO_EVENT: stac92xx_hp_detect(codec); @@ -4816,7 +4769,7 @@ static void handle_unsol_event(struct hda_codec *codec, break; } - switch (event->type) { + switch (event->action) { case STAC_HP_EVENT: case STAC_LO_EVENT: case STAC_MIC_EVENT: @@ -4849,14 +4802,14 @@ static void handle_unsol_event(struct hda_codec *codec, AC_VERB_GET_GPIO_DATA, 0); /* toggle VREF state based on GPIOx status */ snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, - !!(data & (1 << event->data))); + !!(data & (1 << event->private_data))); break; } } static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) { - struct sigmatel_event *event = stac_get_event(codec, nid); + struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid); if (!event) return; handle_unsol_event(codec, event); @@ -4864,15 +4817,14 @@ static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) { - struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event; + struct hda_jack_tbl *event; int tag; tag = (res >> 26) & 0x7f; - event = stac_get_event_from_tag(codec, tag); + event = snd_hda_jack_tbl_get_from_tag(codec, tag); if (!event) return; - snd_hda_jack_set_dirty(codec, event->nid); + event->jack_dirty = 1; handle_unsol_event(codec, event); snd_hda_jack_report_sync(codec); } @@ -5857,15 +5809,13 @@ again: switch (spec->board_config) { case STAC_HP_M4: /* Enable VREF power saving on GPIO1 detect */ - err = stac_add_event(spec, codec->afg, + err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x02); if (err < 0) return err; snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); - snd_hda_codec_write_cache(codec, codec->afg, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | err); + snd_hda_jack_detect_enable(codec, codec->afg, 0); spec->gpio_mask |= 0x02; break; } @@ -6338,14 +6288,12 @@ static int patch_stac9205(struct hda_codec *codec) snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); /* Enable unsol response for GPIO4/Dock HP connection */ - err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); + err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01); if (err < 0) return err; snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); - snd_hda_codec_write_cache(codec, codec->afg, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | err); + snd_hda_jack_detect_enable(codec, codec->afg, 0); spec->gpio_dir = 0x0b; spec->eapd_mask = 0x01; -- cgit v1.2.3 From aad37dbd563010252e1bedb6dad6cddb867b9235 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Nov 2011 08:54:51 +0100 Subject: ALSA: hda - Merge input-jack helpers to hda_jack.c We can use the very same table in hda_jack.c for managing the list for input-jack elements, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index dd6569ffcff..73bf7cd0a6e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4489,7 +4489,6 @@ static void stac92xx_free(struct hda_codec *codec) return; stac92xx_shutup(codec); - snd_hda_input_jack_free(codec); kfree(spec); snd_hda_detach_beep_device(codec); -- cgit v1.2.3 From 201e06ffa9ef9b5265e636617f4fa20cd1490343 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 16 Nov 2011 15:33:26 +0100 Subject: ALSA: hda - Give more unique names by snd_hda_get_pin_label() The function now gives more unique names for the output pins by adding some prefix and suffix for the location and the channels. Otherwise, it can pass the index number. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 73bf7cd0a6e..0988dc4890a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2867,7 +2867,8 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, } if (control) { - strcpy(name, snd_hda_get_pin_label(codec, nid, NULL)); + snd_hda_get_pin_label(codec, nid, &spec->autocfg, + name, sizeof(name), NULL); return stac92xx_add_control(codec->spec, control, strcat(name, " Jack Mode"), nid); } @@ -3545,7 +3546,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, for (i = 0; i < spec->num_dmics; i++) { hda_nid_t nid; int index, type_idx; - const char *label; + char label[32]; nid = spec->dmic_nids[i]; if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) @@ -3558,7 +3559,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, if (index < 0) continue; - label = snd_hda_get_pin_label(codec, nid, NULL); + snd_hda_get_pin_label(codec, nid, &spec->autocfg, + label, sizeof(label), NULL); snd_hda_add_imux_item(dimux, label, index, &type_idx); if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) snd_hda_add_imux_item(imux, label, index, &type_idx); -- cgit v1.2.3 From 31ef22579302ac42054bebecb528710f46580925 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 1 Dec 2011 17:41:36 +0100 Subject: ALSA: hda - Integrate input-jack stuff into kctl-jack Instead of managing input-jack stuff separately, call all stuff inside the kctl-jack creation, deletion and report. The caller no longer needs to care about input-jack. The better integration between input-jack and kctl-jack should be done in the upper layer in near future, but for now, it's implemented locally for more tests. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 46 ------------------------------------------ 1 file changed, 46 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 0988dc4890a..2d4156c583c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1084,13 +1084,10 @@ static const char * const slave_sws[] = { }; static void stac92xx_free_kctls(struct hda_codec *codec); -static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type); static int stac92xx_build_controls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; - hda_nid_t nid; int err; int i; @@ -1176,32 +1173,6 @@ static int stac92xx_build_controls(struct hda_codec *codec) stac92xx_free_kctls(codec); /* no longer needed */ - /* create jack input elements */ - if (spec->hp_detect) { - for (i = 0; i < cfg->hp_outs; i++) { - int type = SND_JACK_HEADPHONE; - nid = cfg->hp_pins[i]; - /* jack detection */ - if (cfg->hp_outs == i) - type |= SND_JACK_LINEOUT; - err = stac92xx_add_jack(codec, nid, type); - if (err < 0) - return err; - } - } - for (i = 0; i < cfg->line_outs; i++) { - err = stac92xx_add_jack(codec, cfg->line_out_pins[i], - SND_JACK_LINEOUT); - if (err < 0) - return err; - } - for (i = 0; i < cfg->num_inputs; i++) { - nid = cfg->inputs[i].pin; - err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE); - if (err < 0) - return err; - } - err = snd_hda_jack_add_kctls(codec, &spec->autocfg); if (err < 0) return err; @@ -4158,22 +4129,6 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ } -static int stac92xx_add_jack(struct hda_codec *codec, - hda_nid_t nid, int type) -{ -#ifdef CONFIG_SND_HDA_INPUT_JACK - int def_conf = snd_hda_codec_get_pincfg(codec, nid); - int connectivity = get_defcfg_connect(def_conf); - - if (connectivity && connectivity != AC_JACK_PORT_FIXED) - return 0; - - return snd_hda_input_jack_add(codec, nid, type, NULL); -#else - return 0; -#endif /* CONFIG_SND_HDA_INPUT_JACK */ -} - static int stac_add_event(struct hda_codec *codec, hda_nid_t nid, unsigned char type, int data) { @@ -4778,7 +4733,6 @@ static void handle_unsol_event(struct hda_codec *codec, case STAC_PWR_EVENT: if (spec->num_pwrs > 0) stac92xx_pin_sense(codec, event->nid); - snd_hda_input_jack_report(codec, event->nid); switch (codec->subsystem_id) { case 0x103c308f: -- cgit v1.2.3