aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-09-22 10:12:16 +0200
committerTakashi Iwai <tiwai@suse.de>2014-09-22 10:12:16 +0200
commit7639913f7298ed23a3f026ebcbb3b4e8850bcc39 (patch)
tree26f08f061535015b748a96106f4869560e3afc63 /sound/pci
parentALSA: oxygen: set fifo_size (diff)
parentALSA: hda - Use standard hda_jack infrastructure for CA0132 driver (diff)
downloadlinux-dev-7639913f7298ed23a3f026ebcbb3b4e8850bcc39.tar.xz
linux-dev-7639913f7298ed23a3f026ebcbb3b4e8850bcc39.zip
Merge branch 'topic/hda-jack-rework' into for-next
This is a merge of rework of HD-audio jack event handling code. It extends the jack table to allow multiple callbacks.
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/ctxfi/ct20k1reg.h4
-rw-r--r--sound/pci/hda/ca0132_regs.h2
-rw-r--r--sound/pci/hda/hda_generic.c23
-rw-r--r--sound/pci/hda/hda_generic.h18
-rw-r--r--sound/pci/hda/hda_jack.c83
-rw-r--r--sound/pci/hda/hda_jack.h42
-rw-r--r--sound/pci/hda/patch_ca0132.c74
-rw-r--r--sound/pci/hda/patch_cirrus.c5
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_hdmi.c18
-rw-r--r--sound/pci/hda/patch_realtek.c41
-rw-r--r--sound/pci/hda/patch_sigmatel.c79
-rw-r--r--sound/pci/hda/patch_via.c30
13 files changed, 199 insertions, 232 deletions
diff --git a/sound/pci/ctxfi/ct20k1reg.h b/sound/pci/ctxfi/ct20k1reg.h
index f2e34e3f27ee..5851249f11d9 100644
--- a/sound/pci/ctxfi/ct20k1reg.h
+++ b/sound/pci/ctxfi/ct20k1reg.h
@@ -7,7 +7,7 @@
*/
#ifndef CT20K1REG_H
-#define CT20k1REG_H
+#define CT20K1REG_H
/* 20k1 registers */
#define DSPXRAM_START 0x000000
@@ -632,5 +632,3 @@
#define I2SD_R 0x19L
#endif /* CT20K1REG_H */
-
-
diff --git a/sound/pci/hda/ca0132_regs.h b/sound/pci/hda/ca0132_regs.h
index 07e760937d3c..8371274aa811 100644
--- a/sound/pci/hda/ca0132_regs.h
+++ b/sound/pci/hda/ca0132_regs.h
@@ -20,7 +20,7 @@
*/
#ifndef __CA0132_REGS_H
-#define __CA0312_REGS_H
+#define __CA0132_REGS_H
#define DSP_CHIP_OFFSET 0x100000
#define DSP_DBGCNTL_MODULE_OFFSET 0xE30
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 95121e818b4d..32a85f9cac4b 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -2032,7 +2032,8 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
* independent HP controls
*/
-static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack);
+static void call_hp_automute(struct hda_codec *codec,
+ struct hda_jack_callback *jack);
static int indep_hp_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -3948,7 +3949,8 @@ static void call_update_outputs(struct hda_codec *codec)
}
/* standard HP-automute helper */
-void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
+void snd_hda_gen_hp_automute(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
struct hda_gen_spec *spec = codec->spec;
hda_nid_t *pins = spec->autocfg.hp_pins;
@@ -3968,7 +3970,8 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute);
/* standard line-out-automute helper */
-void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
+void snd_hda_gen_line_automute(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
struct hda_gen_spec *spec = codec->spec;
@@ -3988,7 +3991,8 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jac
EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute);
/* standard mic auto-switch helper */
-void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack)
+void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
struct hda_gen_spec *spec = codec->spec;
int i;
@@ -4011,7 +4015,8 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch);
/* call appropriate hooks */
-static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
+static void call_hp_automute(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
struct hda_gen_spec *spec = codec->spec;
if (spec->hp_automute_hook)
@@ -4021,7 +4026,7 @@ static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
}
static void call_line_automute(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
+ struct hda_jack_callback *jack)
{
struct hda_gen_spec *spec = codec->spec;
if (spec->line_automute_hook)
@@ -4031,7 +4036,7 @@ static void call_line_automute(struct hda_codec *codec,
}
static void call_mic_autoswitch(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
+ struct hda_jack_callback *jack)
{
struct hda_gen_spec *spec = codec->spec;
if (spec->mic_autoswitch_hook)
@@ -4180,7 +4185,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
if (!is_jack_detectable(codec, nid))
continue;
codec_dbg(codec, "Enable HP auto-muting on NID 0x%x\n", nid);
- snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT,
+ snd_hda_jack_detect_enable_callback(codec, nid,
call_hp_automute);
spec->detect_hp = 1;
}
@@ -4193,7 +4198,6 @@ static int check_auto_mute_availability(struct hda_codec *codec)
continue;
codec_dbg(codec, "Enable Line-Out auto-muting on NID 0x%x\n", nid);
snd_hda_jack_detect_enable_callback(codec, nid,
- HDA_GEN_FRONT_EVENT,
call_line_automute);
spec->detect_lo = 1;
}
@@ -4235,7 +4239,6 @@ static bool auto_mic_check_imux(struct hda_codec *codec)
for (i = 1; i < spec->am_num_entries; i++)
snd_hda_jack_detect_enable_callback(codec,
spec->am_entry[i].pin,
- HDA_GEN_MIC_EVENT,
call_mic_autoswitch);
return true;
}
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 3f95f1d3f1f8..61dd5153f512 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -12,12 +12,6 @@
#ifndef __SOUND_HDA_GENERIC_H
#define __SOUND_HDA_GENERIC_H
-/* unsol event tags */
-enum {
- HDA_GEN_HP_EVENT = 1, HDA_GEN_FRONT_EVENT, HDA_GEN_MIC_EVENT,
- HDA_GEN_LAST_EVENT = HDA_GEN_MIC_EVENT
-};
-
/* table entry for multi-io paths */
struct hda_multi_io {
hda_nid_t pin; /* multi-io widget pin NID */
@@ -290,11 +284,11 @@ struct hda_gen_spec {
/* automute / autoswitch hooks */
void (*hp_automute_hook)(struct hda_codec *codec,
- struct hda_jack_tbl *tbl);
+ struct hda_jack_callback *cb);
void (*line_automute_hook)(struct hda_codec *codec,
- struct hda_jack_tbl *tbl);
+ struct hda_jack_callback *cb);
void (*mic_autoswitch_hook)(struct hda_codec *codec,
- struct hda_jack_tbl *tbl);
+ struct hda_jack_callback *cb);
};
int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
@@ -326,11 +320,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec);
/* standard jack event callbacks */
void snd_hda_gen_hp_automute(struct hda_codec *codec,
- struct hda_jack_tbl *jack);
+ struct hda_jack_callback *jack);
void snd_hda_gen_line_automute(struct hda_codec *codec,
- struct hda_jack_tbl *jack);
+ struct hda_jack_callback *jack);
void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
- struct hda_jack_tbl *jack);
+ struct hda_jack_callback *jack);
void snd_hda_gen_update_outputs(struct hda_codec *codec);
#ifdef CONFIG_PM
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9746d73cec52..f56765ae73a7 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -94,7 +94,7 @@ EXPORT_SYMBOL_GPL(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 *
+static struct hda_jack_tbl *
snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
{
struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
@@ -108,21 +108,24 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
jack->tag = codec->jacktbl.used;
return jack;
}
-EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_new);
void snd_hda_jack_tbl_clear(struct hda_codec *codec)
{
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i;
+
+ for (i = 0; i < codec->jacktbl.used; i++, jack++) {
+ struct hda_jack_callback *cb, *next;
#ifdef CONFIG_SND_HDA_INPUT_JACK
- /* free jack instances manually when clearing/reconfiguring */
- if (!codec->bus->shutdown && codec->jacktbl.list) {
- struct hda_jack_tbl *jack = codec->jacktbl.list;
- int i;
- for (i = 0; i < codec->jacktbl.used; i++, jack++) {
- if (jack->jack)
- snd_device_free(codec->bus->card, jack->jack);
+ /* free jack instances manually when clearing/reconfiguring */
+ if (!codec->bus->shutdown && jack->jack)
+ snd_device_free(codec->bus->card, jack->jack);
+#endif
+ for (cb = jack->callback; cb; cb = next) {
+ next = cb->next;
+ kfree(cb);
}
}
-#endif
snd_array_free(&codec->jacktbl);
}
@@ -215,33 +218,49 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state);
/**
* snd_hda_jack_detect_enable - enable the jack-detection
+ *
+ * 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().
*/
-int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
- unsigned char action,
- hda_jack_callback cb)
+struct hda_jack_callback *
+snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+ hda_jack_callback_fn func)
{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
+ struct hda_jack_tbl *jack;
+ struct hda_jack_callback *callback = NULL;
+ int err;
+
+ jack = snd_hda_jack_tbl_new(codec, nid);
if (!jack)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
+ if (func) {
+ callback = kzalloc(sizeof(*callback), GFP_KERNEL);
+ if (!callback)
+ return ERR_PTR(-ENOMEM);
+ callback->func = func;
+ callback->tbl = jack;
+ callback->next = jack->callback;
+ jack->callback = callback;
+ }
+
if (jack->jack_detect)
- return 0; /* already registered */
+ return callback; /* already registered */
jack->jack_detect = 1;
- if (action)
- jack->action = action;
- if (cb)
- jack->callback = cb;
if (codec->jackpoll_interval > 0)
- return 0; /* No unsol if we're polling instead */
- return snd_hda_codec_write_cache(codec, nid, 0,
+ return callback; /* No unsol if we're polling instead */
+ err = snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | jack->tag);
+ if (err < 0)
+ return ERR_PTR(err);
+ return callback;
}
EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback);
-int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
- unsigned char action)
+int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid)
{
- return snd_hda_jack_detect_enable_callback(codec, nid, action, NULL);
+ return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL));
}
EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable);
@@ -431,7 +450,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, 0);
+ return snd_hda_jack_detect_enable(codec, nid);
return 0;
}
@@ -498,13 +517,17 @@ EXPORT_SYMBOL_GPL(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);
+ struct hda_jack_callback *cb;
+
+ for (cb = jack->callback; cb; cb = cb->next)
+ cb->func(codec, cb);
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);
+ if (gated) {
+ for (cb = gated->callback; cb; cb = cb->next)
+ cb->func(codec, cb);
+ }
}
}
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 46e1ea83ce3c..b41e0a3ea1fb 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -14,15 +14,21 @@
struct auto_pin_cfg;
struct hda_jack_tbl;
+struct hda_jack_callback;
-typedef void (*hda_jack_callback) (struct hda_codec *, struct hda_jack_tbl *);
+typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *);
+
+struct hda_jack_callback {
+ struct hda_jack_tbl *tbl;
+ hda_jack_callback_fn func;
+ unsigned int private_data; /* arbitrary data */
+ struct hda_jack_callback *next;
+};
struct hda_jack_tbl {
hda_nid_t nid;
- unsigned char action; /* event action (0 = none) */
unsigned char tag; /* unsol event tag */
- unsigned int private_data; /* arbitrary data */
- hda_jack_callback callback;
+ struct hda_jack_callback *callback;
/* jack-detection stuff */
unsigned int pin_sense; /* cached pin-sense value */
unsigned int jack_detect:1; /* capable of jack-detection? */
@@ -43,34 +49,14 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
struct hda_jack_tbl *
snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag);
-struct hda_jack_tbl *
-snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid);
void snd_hda_jack_tbl_clear(struct hda_codec *codec);
-/**
- * snd_hda_jack_get_action - get jack-tbl entry for the tag
- *
- * Call this from the unsol event handler to get the assigned action for the
- * event. This will mark the dirty flag for the later reporting, too.
- */
-static inline unsigned char
-snd_hda_jack_get_action(struct hda_codec *codec, unsigned int tag)
-{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
- if (jack) {
- jack->jack_dirty = 1;
- return jack->action;
- }
- return 0;
-}
-
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,
- unsigned char action);
-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_detect_enable(struct hda_codec *codec, hda_nid_t nid);
+struct hda_jack_callback *
+snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+ hda_jack_callback_fn cb);
int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
hda_nid_t gating_nid);
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 5d8455e2dacd..4f7ffa8c4a0d 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -3224,8 +3224,14 @@ static void ca0132_unsol_hp_delayed(struct work_struct *work)
{
struct ca0132_spec *spec = container_of(
to_delayed_work(work), struct ca0132_spec, unsol_hp_work);
+ struct hda_jack_tbl *jack;
+
ca0132_select_out(spec->codec);
- snd_hda_jack_report_sync(spec->codec);
+ jack = snd_hda_jack_tbl_get(spec->codec, UNSOL_TAG_HP);
+ if (jack) {
+ jack->block_report = 0;
+ snd_hda_jack_report_sync(spec->codec);
+ }
}
static void ca0132_set_dmic(struct hda_codec *codec, int enable);
@@ -4114,12 +4120,6 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
}
}
-static void ca0132_init_unsol(struct hda_codec *codec)
-{
- snd_hda_jack_detect_enable(codec, UNSOL_TAG_HP, UNSOL_TAG_HP);
- snd_hda_jack_detect_enable(codec, UNSOL_TAG_AMIC1, UNSOL_TAG_AMIC1);
-}
-
static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir)
{
unsigned int caps;
@@ -4390,7 +4390,8 @@ static void ca0132_download_dsp(struct hda_codec *codec)
ca0132_set_dsp_msr(codec, true);
}
-static void ca0132_process_dsp_response(struct hda_codec *codec)
+static void ca0132_process_dsp_response(struct hda_codec *codec,
+ struct hda_jack_callback *callback)
{
struct ca0132_spec *spec = codec->spec;
@@ -4403,36 +4404,31 @@ static void ca0132_process_dsp_response(struct hda_codec *codec)
dspio_clear_response_queue(codec);
}
-static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
+static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
{
struct ca0132_spec *spec = codec->spec;
- if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) {
- ca0132_process_dsp_response(codec);
- } else {
- res = snd_hda_jack_get_action(codec,
- (res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f);
-
- codec_dbg(codec, "snd_hda_jack_get_action: 0x%x\n", res);
-
- switch (res) {
- case UNSOL_TAG_HP:
- /* Delay enabling the HP amp, to let the mic-detection
- * state machine run.
- */
- cancel_delayed_work_sync(&spec->unsol_hp_work);
- queue_delayed_work(codec->bus->workq,
- &spec->unsol_hp_work,
- msecs_to_jiffies(500));
- break;
- case UNSOL_TAG_AMIC1:
- ca0132_select_mic(codec);
- snd_hda_jack_report_sync(codec);
- break;
- default:
- break;
- }
- }
+ /* Delay enabling the HP amp, to let the mic-detection
+ * state machine run.
+ */
+ cancel_delayed_work_sync(&spec->unsol_hp_work);
+ queue_delayed_work(codec->bus->workq, &spec->unsol_hp_work,
+ msecs_to_jiffies(500));
+ cb->tbl->block_report = 1;
+}
+
+static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
+{
+ ca0132_select_mic(codec);
+}
+
+static void ca0132_init_unsol(struct hda_codec *codec)
+{
+ snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_HP, hp_callback);
+ snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_AMIC1,
+ amic_callback);
+ snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP,
+ ca0132_process_dsp_response);
}
/*
@@ -4443,8 +4439,6 @@ static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
static struct hda_verb ca0132_base_init_verbs[] = {
/*enable ct extension*/
{0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1},
- /*enable DSP node unsol, needed for DSP download*/
- {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_DSP},
{}
};
@@ -4561,6 +4555,8 @@ static int ca0132_init(struct hda_codec *codec)
snd_hda_power_up(codec);
+ ca0132_init_unsol(codec);
+
ca0132_init_params(codec);
ca0132_init_flags(codec);
snd_hda_sequence_write(codec, spec->base_init_verbs);
@@ -4583,8 +4579,6 @@ static int ca0132_init(struct hda_codec *codec)
for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
- ca0132_init_unsol(codec);
-
ca0132_select_out(codec);
ca0132_select_mic(codec);
@@ -4612,7 +4606,7 @@ static struct hda_codec_ops ca0132_patch_ops = {
.build_pcms = ca0132_build_pcms,
.init = ca0132_init,
.free = ca0132_free,
- .unsol_event = ca0132_unsol_event,
+ .unsol_event = snd_hda_jack_unsol_event,
};
static void ca0132_config(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 3db724eaa53c..1589c9bcce3e 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -135,8 +135,6 @@ enum {
#define CS421X_IDX_DAC_CFG 0x03
#define CS421X_IDX_SPK_CTL 0x04
-#define SPDIF_EVENT 0x04
-
/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
#define CS4213_VENDOR_NID 0x09
@@ -984,7 +982,7 @@ static void cs4210_pinmux_init(struct hda_codec *codec)
}
static void cs4210_spdif_automute(struct hda_codec *codec,
- struct hda_jack_tbl *tbl)
+ struct hda_jack_callback *tbl)
{
struct cs_spec *spec = codec->spec;
bool spdif_present = false;
@@ -1019,7 +1017,6 @@ static void parse_cs421x_digital(struct hda_codec *codec)
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
spec->spdif_detect = 1;
snd_hda_jack_detect_enable_callback(codec, nid,
- SPDIF_EVENT,
cs4210_spdif_automute);
}
}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c0b03c112187..d5b0582daaf0 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -216,6 +216,7 @@ enum {
CXT_FIXUP_HEADPHONE_MIC_PIN,
CXT_FIXUP_HEADPHONE_MIC,
CXT_FIXUP_GPIO1,
+ CXT_FIXUP_ASPIRE_DMIC,
CXT_FIXUP_THINKPAD_ACPI,
CXT_FIXUP_OLPC_XO,
CXT_FIXUP_CAP_MIX_AMP,
@@ -392,7 +393,8 @@ static void olpc_xo_update_mic_pins(struct hda_codec *codec)
}
/* mic_autoswitch hook */
-static void olpc_xo_automic(struct hda_codec *codec, struct hda_jack_tbl *jack)
+static void olpc_xo_automic(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
struct conexant_spec *spec = codec->spec;
int saved_cached_write = codec->cached_write;
@@ -663,6 +665,12 @@ static const struct hda_fixup cxt_fixups[] = {
{ }
},
},
+ [CXT_FIXUP_ASPIRE_DMIC] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cxt_fixup_stereo_dmic,
+ .chained = true,
+ .chain_id = CXT_FIXUP_GPIO1,
+ },
[CXT_FIXUP_THINKPAD_ACPI] = {
.type = HDA_FIXUP_FUNC,
.v.func = hda_fixup_thinkpad_acpi,
@@ -743,7 +751,7 @@ static const struct hda_model_fixup cxt5051_fixup_models[] = {
static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
- SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_GPIO1),
+ SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 99d7d7fecaad..39862e98551c 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1163,17 +1163,23 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
-static void jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack)
+static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid)
{
struct hdmi_spec *spec = codec->spec;
- int pin_idx = pin_nid_to_pin_index(codec, jack->nid);
+ int pin_idx = pin_nid_to_pin_index(codec, nid);
+
if (pin_idx < 0)
return;
-
if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
snd_hda_jack_report_sync(codec);
}
+static void jack_callback(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
+{
+ check_presence_and_report(codec, jack->tbl->nid);
+}
+
static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
{
int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
@@ -1190,7 +1196,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
!!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
- jack_callback(codec, jack);
+ check_presence_and_report(codec, jack->nid);
}
static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -2165,7 +2171,7 @@ static int generic_hdmi_init(struct hda_codec *codec)
hda_nid_t pin_nid = per_pin->pin_nid;
hdmi_init_pin(codec, pin_nid);
- snd_hda_jack_detect_enable_callback(codec, pin_nid, pin_nid,
+ snd_hda_jack_detect_enable_callback(codec, pin_nid,
codec->jackpoll_interval > 0 ? jack_callback : NULL);
}
return 0;
@@ -2428,7 +2434,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, pin);
+ snd_hda_jack_detect_enable(codec, pin);
return 0;
}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cbc4d25e4538..a109fdb085f9 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -40,9 +40,6 @@
/* keep halting ALC5505 DSP, for power saving */
#define HALT_REALTEK_ALC5505
-/* unsol event tags */
-#define ALC_DCVOL_EVENT 0x08
-
/* for GPIO Poll */
#define GPIO_MASK 0x03
@@ -267,7 +264,8 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
}
/* update the master volume per volume-knob's unsol event */
-static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
+static void alc_update_knob_master(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
unsigned int val;
struct snd_kcontrol *kctl;
@@ -279,7 +277,7 @@ static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (!uctl)
return;
- val = snd_hda_codec_read(codec, jack->nid, 0,
+ val = snd_hda_codec_read(codec, jack->tbl->nid, 0,
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
val &= HDA_AMP_VOLMASK;
uctl->value.integer.value[0] = val;
@@ -373,6 +371,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
case 0x10ec0885:
case 0x10ec0887:
/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
+ case 0x10ec0900:
alc889_coef_init(codec);
break;
case 0x10ec0888:
@@ -1129,7 +1128,8 @@ static void alc880_fixup_vol_knob(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
if (action == HDA_FIXUP_ACT_PROBE)
- snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
+ snd_hda_jack_detect_enable_callback(codec, 0x21,
+ alc_update_knob_master);
}
static const struct hda_fixup alc880_fixups[] = {
@@ -1592,7 +1592,7 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
spec->gen.detect_hp = 1;
spec->gen.automute_speaker = 1;
spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
- snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT,
+ snd_hda_jack_detect_enable_callback(codec, 0x0f,
snd_hda_gen_hp_automute);
snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
}
@@ -2346,6 +2346,7 @@ static int patch_alc882(struct hda_codec *codec)
switch (codec->vendor_id) {
case 0x10ec0882:
case 0x10ec0885:
+ case 0x10ec0900:
break;
default:
/* ALC883 and variants */
@@ -3272,7 +3273,7 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec,
}
static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
+ struct hda_jack_callback *jack)
{
struct alc_spec *spec = codec->spec;
int vref;
@@ -3926,7 +3927,8 @@ static void alc_update_headset_mode_hook(struct hda_codec *codec,
alc_update_headset_mode(codec);
}
-static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack)
+static void alc_update_headset_jack_cb(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
{
struct alc_spec *spec = codec->spec;
spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
@@ -4166,7 +4168,7 @@ static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
}
static void alc283_hp_automute_hook(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
+ struct hda_jack_callback *jack)
{
struct alc_spec *spec = codec->spec;
int vref;
@@ -4252,7 +4254,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
spec->gen.auto_mute_via_amp = 1;
spec->gen.automute_hook = asus_tx300_automute;
snd_hda_jack_detect_enable_callback(codec, 0x1b,
- HDA_GEN_HP_EVENT,
snd_hda_gen_hp_automute);
break;
case HDA_FIXUP_ACT_BUILD:
@@ -4353,6 +4354,7 @@ enum {
ALC292_FIXUP_TPT440_DOCK,
ALC283_FIXUP_BXBT2807_MIC,
ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
+ ALC282_FIXUP_ASPIRE_V5_PINS,
};
static const struct hda_fixup alc269_fixups[] = {
@@ -4800,6 +4802,22 @@ static const struct hda_fixup alc269_fixups[] = {
.chained_before = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
},
+ [ALC282_FIXUP_ASPIRE_V5_PINS] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x12, 0x90a60130 },
+ { 0x14, 0x90170110 },
+ { 0x17, 0x40000008 },
+ { 0x18, 0x411111f0 },
+ { 0x19, 0x411111f0 },
+ { 0x1a, 0x411111f0 },
+ { 0x1b, 0x411111f0 },
+ { 0x1d, 0x40f89b2d },
+ { 0x1e, 0x411111f0 },
+ { 0x21, 0x0321101f },
+ { },
+ },
+ },
};
@@ -4811,6 +4829,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
+ SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f26ec04a29b5..4f6413e01c13 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -40,11 +40,6 @@
#include "hda_generic.h"
enum {
- STAC_VREF_EVENT = 8,
- STAC_PWR_EVENT,
-};
-
-enum {
STAC_REF,
STAC_9200_OQO,
STAC_9200_DELL_D21,
@@ -486,7 +481,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
/* update power bit per jack plug/unplug */
static void jack_update_power(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
+ struct hda_jack_callback *jack)
{
struct sigmatel_spec *spec = codec->spec;
int i;
@@ -494,9 +489,9 @@ static void jack_update_power(struct hda_codec *codec,
if (!spec->num_pwrs)
return;
- if (jack && jack->nid) {
- stac_toggle_power_map(codec, jack->nid,
- snd_hda_jack_detect(codec, jack->nid),
+ if (jack && jack->tbl->nid) {
+ stac_toggle_power_map(codec, jack->tbl->nid,
+ snd_hda_jack_detect(codec, jack->tbl->nid),
true);
return;
}
@@ -504,42 +499,19 @@ static void jack_update_power(struct hda_codec *codec,
/* update all jacks */
for (i = 0; i < spec->num_pwrs; i++) {
hda_nid_t nid = spec->pwr_nids[i];
- jack = snd_hda_jack_tbl_get(codec, nid);
- if (!jack || !jack->action)
+ if (!snd_hda_jack_tbl_get(codec, nid))
continue;
- if (jack->action == STAC_PWR_EVENT ||
- jack->action <= HDA_GEN_LAST_EVENT)
- stac_toggle_power_map(codec, nid,
- snd_hda_jack_detect(codec, nid),
- false);
+ stac_toggle_power_map(codec, nid,
+ snd_hda_jack_detect(codec, nid),
+ false);
}
snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_IDT_SET_POWER_MAP,
spec->power_map_bits);
}
-static void stac_hp_automute(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
-{
- snd_hda_gen_hp_automute(codec, jack);
- jack_update_power(codec, jack);
-}
-
-static void stac_line_automute(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
-{
- snd_hda_gen_line_automute(codec, jack);
- jack_update_power(codec, jack);
-}
-
-static void stac_mic_autoswitch(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
-{
- snd_hda_gen_mic_autoswitch(codec, jack);
- jack_update_power(codec, jack);
-}
-
-static void stac_vref_event(struct hda_codec *codec, struct hda_jack_tbl *event)
+static void stac_vref_event(struct hda_codec *codec,
+ struct hda_jack_callback *event)
{
unsigned int data;
@@ -562,13 +534,10 @@ static void stac_init_power_map(struct hda_codec *codec)
hda_nid_t nid = spec->pwr_nids[i];
unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
def_conf = get_defcfg_connect(def_conf);
- if (snd_hda_jack_tbl_get(codec, nid))
- continue;
if (def_conf == AC_JACK_PORT_COMPLEX &&
- !(spec->vref_mute_led_nid == nid ||
- is_jack_detectable(codec, nid))) {
+ spec->vref_mute_led_nid != nid &&
+ is_jack_detectable(codec, nid)) {
snd_hda_jack_detect_enable_callback(codec, nid,
- STAC_PWR_EVENT,
jack_update_power);
} else {
if (def_conf == AC_JACK_PORT_NONE)
@@ -3019,7 +2988,7 @@ static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct sigmatel_spec *spec = codec->spec;
- struct hda_jack_tbl *jack;
+ struct hda_jack_callback *jack;
if (action != HDA_FIXUP_ACT_PRE_PROBE)
return;
@@ -3027,11 +2996,9 @@ static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
/* Enable VREF power saving on GPIO1 detect */
snd_hda_codec_write_cache(codec, codec->afg, 0,
AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
- snd_hda_jack_detect_enable_callback(codec, codec->afg,
- STAC_VREF_EVENT,
- stac_vref_event);
- jack = snd_hda_jack_tbl_get(codec, codec->afg);
- if (jack)
+ jack = snd_hda_jack_detect_enable_callback(codec, codec->afg,
+ stac_vref_event);
+ if (!IS_ERR(jack))
jack->private_data = 0x02;
spec->gpio_mask |= 0x02;
@@ -4043,7 +4010,7 @@ static void stac9205_fixup_dell_m43(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct sigmatel_spec *spec = codec->spec;
- struct hda_jack_tbl *jack;
+ struct hda_jack_callback *jack;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
@@ -4051,11 +4018,9 @@ static void stac9205_fixup_dell_m43(struct hda_codec *codec,
/* Enable unsol response for GPIO4/Dock HP connection */
snd_hda_codec_write_cache(codec, codec->afg, 0,
AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
- snd_hda_jack_detect_enable_callback(codec, codec->afg,
- STAC_VREF_EVENT,
- stac_vref_event);
- jack = snd_hda_jack_tbl_get(codec, codec->afg);
- if (jack)
+ jack = snd_hda_jack_detect_enable_callback(codec, codec->afg,
+ stac_vref_event);
+ if (!IS_ERR(jack))
jack->private_data = 0x01;
spec->gpio_dir = 0x0b;
@@ -4218,9 +4183,6 @@ static int stac_parse_auto_config(struct hda_codec *codec)
spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
spec->gen.automute_hook = stac_update_outputs;
- spec->gen.hp_automute_hook = stac_hp_automute;
- spec->gen.line_automute_hook = stac_line_automute;
- spec->gen.mic_autoswitch_hook = stac_mic_autoswitch;
err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
if (err < 0)
@@ -4277,7 +4239,6 @@ static int stac_parse_auto_config(struct hda_codec *codec)
return 0;
}
-
static int stac_init(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 778166259b3e..6c206b6c8d65 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -118,7 +118,6 @@ static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream,
int action);
-static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl);
static struct via_spec *via_new_spec(struct hda_codec *codec)
{
@@ -575,25 +574,12 @@ static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
{} /* terminator */
};
-static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
+static void via_jack_powerstate_event(struct hda_codec *codec,
+ struct hda_jack_callback *tbl)
{
set_widgets_power_state(codec);
- snd_hda_gen_hp_automute(codec, tbl);
}
-static void via_line_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
-{
- set_widgets_power_state(codec);
- snd_hda_gen_line_automute(codec, tbl);
-}
-
-static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
-{
- set_widgets_power_state(codec);
-}
-
-#define VIA_JACK_EVENT (HDA_GEN_LAST_EVENT + 1)
-
static void via_set_jack_unsol_events(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
@@ -601,25 +587,17 @@ static void via_set_jack_unsol_events(struct hda_codec *codec)
hda_nid_t pin;
int i;
- spec->gen.hp_automute_hook = via_hp_automute;
- if (cfg->speaker_pins[0])
- spec->gen.line_automute_hook = via_line_automute;
-
for (i = 0; i < cfg->line_outs; i++) {
pin = cfg->line_out_pins[i];
- if (pin && !snd_hda_jack_tbl_get(codec, pin) &&
- is_jack_detectable(codec, pin))
+ if (pin && is_jack_detectable(codec, pin))
snd_hda_jack_detect_enable_callback(codec, pin,
- VIA_JACK_EVENT,
via_jack_powerstate_event);
}
for (i = 0; i < cfg->num_inputs; i++) {
pin = cfg->line_out_pins[i];
- if (pin && !snd_hda_jack_tbl_get(codec, pin) &&
- is_jack_detectable(codec, pin))
+ if (pin && is_jack_detectable(codec, pin))
snd_hda_jack_detect_enable_callback(codec, pin,
- VIA_JACK_EVENT,
via_jack_powerstate_event);
}
}