From ac0547dc62e67a3e0b0c1628b6e49efba8f517db Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 5 Jul 2010 16:50:13 +0200 Subject: ALSA: hda - Restore cleared pin controls on resume Many codecs now clear the pin controls at suspend via snd_hda_shutup_pins() for reducing the click noise at power-off. But this leaves some pins uninitialized, and they'll be never recovered after resume. This patch adds the proper recovery of cleared pin controls on resume. Also it adds a check of bus->shutdown so that pins won't be cleared at module unloading. Reference: Kernel bug 16339 http://bugzilla.kernel.org/show_bug.cgi?id=16339 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 27 +++++++++++++++++++++++++++ sound/pci/hda/hda_codec.h | 5 ++++- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a3d638c8c1fd..ba2098d20ccc 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -784,6 +784,9 @@ static int read_pin_defaults(struct hda_codec *codec) pin->nid = nid; pin->cfg = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + pin->ctrl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, + 0); } return 0; } @@ -912,15 +915,38 @@ static void restore_pincfgs(struct hda_codec *codec) void snd_hda_shutup_pins(struct hda_codec *codec) { int i; + /* don't shut up pins when unloading the driver; otherwise it breaks + * the default pin setup at the next load of the driver + */ + if (codec->bus->shutdown) + return; for (i = 0; i < codec->init_pins.used; i++) { struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); /* use read here for syncing after issuing each verb */ snd_hda_codec_read(codec, pin->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0); } + codec->pins_shutup = 1; } EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); +/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ +static void restore_shutup_pins(struct hda_codec *codec) +{ + int i; + if (!codec->pins_shutup) + return; + if (codec->bus->shutdown) + return; + for (i = 0; i < codec->init_pins.used; i++) { + struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); + snd_hda_codec_write(codec, pin->nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + pin->ctrl); + } + codec->pins_shutup = 0; +} + static void init_hda_cache(struct hda_cache_rec *cache, unsigned int record_size); static void free_hda_cache(struct hda_cache_rec *cache); @@ -2907,6 +2933,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); restore_pincfgs(codec); /* restore all current pin configs */ + restore_shutup_pins(codec); hda_exec_init_verbs(codec); if (codec->patch_ops.resume) codec->patch_ops.resume(codec); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 49e939e7e5cd..5991d14e1ec0 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -821,6 +821,7 @@ struct hda_codec { unsigned int pin_amp_workaround:1; /* pin out-amp takes index * (e.g. Conexant codecs) */ + unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ @@ -897,7 +898,9 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec); /* the struct for codec->pin_configs */ struct hda_pincfg { hda_nid_t nid; - unsigned int cfg; + unsigned char ctrl; /* current pin control value */ + unsigned char pad; /* reserved */ + unsigned int cfg; /* default configuration */ }; unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); -- cgit From b427b44cc8793af521b0dc3a9fdd9fcc275c3bd7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 13 Jul 2010 12:01:15 +0900 Subject: ASoC: fsi: fixup clock inversion operation Clock inversion should be specified by each flags bit. Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'sound') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3396a0db06ba..4fa75087c45b 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -683,20 +683,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, /* clock inversion (CKG2) */ data = 0; - switch (SH_FSI_INVERSION_MASK & flags) { - case SH_FSI_LRM_INV: - data = 1 << 12; - break; - case SH_FSI_BRM_INV: - data = 1 << 8; - break; - case SH_FSI_LRS_INV: - data = 1 << 4; - break; - case SH_FSI_BRS_INV: - data = 1 << 0; - break; - } + if (SH_FSI_LRM_INV & flags) + data |= 1 << 12; + if (SH_FSI_BRM_INV & flags) + data |= 1 << 8; + if (SH_FSI_LRS_INV & flags) + data |= 1 << 4; + if (SH_FSI_BRS_INV & flags) + data |= 1 << 0; + fsi_reg_write(fsi, CKG2, data); /* do fmt, di fmt */ -- cgit From 637727838a5e82bc9285ab078a793eaae590bacb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 13 Jul 2010 12:01:25 +0900 Subject: ASoC: fsi: fixup wrong value setting order of TDM channel size should be set before setting register value Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 4fa75087c45b..ec4acac49ebd 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -721,15 +721,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, break; case SH_FSI_FMT_TDM: msg = "TDM"; - data = CR_FMT(CR_TDM) | (fsi->chan - 1); fsi->chan = is_play ? SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); + data = CR_FMT(CR_TDM) | (fsi->chan - 1); break; case SH_FSI_FMT_TDM_DELAY: msg = "TDM Delay"; - data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); fsi->chan = is_play ? SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); + data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); break; default: dev_err(dai->dev, "unknown format.\n"); -- cgit From c555b028f12e92c1de9cf5de0ef5886779590222 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 14 Jul 2010 18:57:31 +0800 Subject: ASoC: wm8727: add a missing return in wm8727_platform_probe otherwise the error path will always be executed. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8727.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 1072621e93fd..9d1df2628136 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -127,6 +127,8 @@ static __devinit int wm8727_platform_probe(struct platform_device *pdev) goto err_codec; } + return 0; + err_codec: snd_soc_unregister_codec(codec); err: -- cgit From cecb66fddf2a3deb44da1f741b6734a785df7957 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 14 Jul 2010 19:06:07 +0800 Subject: ASoC:: remove a redundant snd_soc_unregister_codec call in wm8988_register snd_soc_unregister_codec is called twice if snd_soc_register_dai fail. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8988.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 0417dae32e6f..19ad590ca0b3 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -885,7 +885,6 @@ static int wm8988_register(struct wm8988_priv *wm8988, ret = snd_soc_register_dai(&wm8988_dai); if (ret != 0) { dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); goto err_codec; } -- cgit From 3c0709396df0869786f83e4b2d2d687c70ee886d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 17 Jul 2010 14:20:17 +0100 Subject: ASoC: Remove duplicate AUX definition from WM8776 Signed-off-by: Mark Brown Acked-by: Liam Girdwood Cc: stable@kernel.org --- sound/soc/codecs/wm8776.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 7e4a627b4c7e..4e212ed62ea6 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -94,7 +94,6 @@ SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0), static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AUX"), -SND_SOC_DAPM_INPUT("AUX"), SND_SOC_DAPM_INPUT("AIN1"), SND_SOC_DAPM_INPUT("AIN2"), -- cgit From 41f9a314af9c1f24b595f73ae73ee23db6d5e6a8 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 20 Jul 2010 14:28:33 +0900 Subject: ASoC: Select wm_hubs automatically for WM8994 Otherwise all machine drivers need to do so. Signed-off-by: Chanwoo Choi Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 31ac5538fe7e..5da30eb6ad00 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -83,8 +83,8 @@ config SND_SOC_ALL_CODECS config SND_SOC_WM_HUBS tristate - default y if SND_SOC_WM8993=y - default m if SND_SOC_WM8993=m + default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y + default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m config SND_SOC_AC97_CODEC tristate -- cgit