From 895c9c056591f05ba3b669cda6c12afb212c6253 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Sat, 20 Jun 2009 11:29:05 -0400 Subject: ASoC: Blackfin: keep better track of SPORT configuration state Do not let the SPORT be reconfigured until there are no more active streams. Then we can let the system reprogram the SPORT state. Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-i2s.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 96482441967..0e8af48650b 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -50,6 +50,7 @@ struct bf5xx_i2s_port { u16 tcr2; u16 rcr2; int counter; + int configured; }; static struct bf5xx_i2s_port bf5xx_i2s; @@ -168,7 +169,7 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, break; } - if (bf5xx_i2s.counter == 1) { + if (!bf5xx_i2s.configured) { /* * TX and RX are not independent,they are enabled at the * same time, even if only one side is running. So, we @@ -177,6 +178,7 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, * * CPU DAI:slave mode. */ + bf5xx_i2s.configured = 1; ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, bf5xx_i2s.rcr2, 0, 0); if (ret) { @@ -200,6 +202,9 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream, { pr_debug("%s enter\n", __func__); bf5xx_i2s.counter--; + /* No active stream, SPORT is allowed to be configured again. */ + if (!bf5xx_i2s.counter) + bf5xx_i2s.configured = 0; } static int bf5xx_i2s_probe(struct platform_device *pdev, -- cgit v1.2.3 From 92a6ad34282f8403c4eb83025a2790af86cdb6bd Mon Sep 17 00:00:00 2001 From: Barry Song Date: Sat, 20 Jun 2009 11:29:57 -0400 Subject: ASoC: Blackfin: update the bf5xx_i2s_resume parameters Latest ASoC only passes snd_soc_dai to the resume function. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-i2s.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 0e8af48650b..af06904bab0 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -249,8 +249,7 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) return 0; } -static int bf5xx_i2s_resume(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int bf5xx_i2s_resume(struct snd_soc_dai *dai) { int ret; struct sport_device *sport = -- cgit v1.2.3 From a8f4310be59a2e7fc80fba945bcb32b18f4ad54f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 07:36:52 +0200 Subject: ALSA: ctxfi - Allow unknown PCI SSIDs Allow unknown PCI SSIDs for emu20k1 and emu20k2 as "unknown" model. Also, add a black-list check in case any device has to be listed as "unsupported". It has a negative value in the pci quirk entry. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 25 +++++++++++++++++++------ sound/pci/ctxfi/cthardware.h | 3 +++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index b0adc809400..32e3c26e969 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -46,8 +46,6 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000, "UAA", CTUAA), - SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE, - "Unknown", CT20K1_UNKNOWN), { } /* terminator */ }; @@ -67,13 +65,16 @@ static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { }; static const char *ct_subsys_name[NUM_CTCARDS] = { + /* 20k1 models */ [CTSB055X] = "SB055x", [CTSB073X] = "SB073x", - [CTSB0760] = "SB076x", [CTUAA] = "UAA", [CT20K1_UNKNOWN] = "Unknown", + /* 20k2 models */ + [CTSB0760] = "SB076x", [CTHENDRIX] = "Hendrix", [CTSB0880] = "SB0880", + [CT20K2_UNKNOWN] = "Unknown", }; static struct { @@ -1240,9 +1241,21 @@ static int __devinit atc_identify_card(struct ct_atc *atc) return -ENOENT; } p = snd_pci_quirk_lookup(atc->pci, list); - if (!p) - return -ENOENT; - atc->model = p->value; + if (p) { + if (p->value < 0) { + printk(KERN_ERR "ctxfi: " + "Device %04x:%04x is black-listed\n", + atc->pci->subsystem_vendor, + atc->pci->subsystem_device); + return -ENOENT; + } + atc->model = p->value; + } else { + if (atc->chip_type == ATC20K1) + atc->model = CT20K1_UNKNOWN; + else + atc->model = CT20K2_UNKNOWN; + } atc->model_name = ct_subsys_name[atc->model]; snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", atc->chip_name, atc->model_name, diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index 4a8e04f090a..a4c2cad80f3 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -30,13 +30,16 @@ enum CHIPTYP { enum CTCARDS { /* 20k1 models */ CTSB055X, + CT20K1_MODEL_FIRST = CTSB055X, CTSB073X, CTUAA, CT20K1_UNKNOWN, /* 20k2 models */ CTSB0760, + CT20K2_MODEL_FIRST = CTSB0760, CTHENDRIX, CTSB0880, + CT20K2_UNKNOWN, NUM_CTCARDS /* This should always be the last */ }; -- cgit v1.2.3 From 8bd9bca3c1a214350e2f2f1e2fd493ed24c06f7e Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sun, 21 Jun 2009 20:26:59 +0200 Subject: sound: fix check for return value in snd_pcm_hw_refine 'params' is a pointer and looking at the code this probably should be a check for ioctl return value. Signed-off-by: Mariusz Kozlowski Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 84da3ba17c8..ac2150e0670 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -320,7 +320,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) { changed = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_FIFO_SIZE, params); - if (params < 0) + if (changed < 0) return changed; } } -- cgit v1.2.3 From 115551d98e4c05bb982bd940f08a489fa9b0a4a1 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Sun, 21 Jun 2009 19:50:48 +0100 Subject: ALSA: via82xx: add option to disable 500ms delay in snd_via82xx_codec_wait There's a large 500ms delay in snd_via82xx_codec_wait() that, at least on my hardware, appears to be unnecessary. The rest of the init of the card works without logging any warnings or errors and both audio and mixer settings work. This adds an "nodelay" parameter to disable this (undocumented in the code) large delay improving bootup time by 489-500ms. [ 1.034217] initcall alsa_card_via82xx_init+0x0/0x16 returned 0 after 505757 usecs vs. [ 0.533136] initcall alsa_card_via82xx_init+0x0/0x16 returned 0 after 15915 usecs Signed-off-by: Simon Arlott Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 1ef58c51c21..949fcaf6b70 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -85,6 +85,7 @@ static int joystick; static int ac97_clock = 48000; static char *ac97_quirk; static int dxs_support; +static int nodelay; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge."); @@ -102,6 +103,8 @@ module_param(ac97_quirk, charp, 0444); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); module_param(dxs_support, int, 0444); MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); +module_param(nodelay, int, 0444); +MODULE_PARM_DESC(nodelay, "Disable 500ms init delay"); /* just for backward compatibility */ static int enable; @@ -549,7 +552,8 @@ static void snd_via82xx_codec_wait(struct snd_ac97 *ac97) int err; err = snd_via82xx_codec_ready(chip, ac97->num); /* here we need to wait fairly for long time.. */ - msleep(500); + if (!nodelay) + msleep(500); } static void snd_via82xx_codec_write(struct snd_ac97 *ac97, -- cgit v1.2.3 From b8621516cc7dd22fe4ad4c2fd8f7d852a33212df Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 08:00:10 +0200 Subject: ALSA: hda - Fix unsigned comparison in patch_sigmatel.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the comparison of unsigned int that causes a compile warning below by changing to the right signed type: patch_sigmatel.c: In function ‘stac92xx_vref_set’: patch_sigmatel.c:658: warning: comparison of unsigned expression < 0 is always false Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 93e47c96a38..090957735e0 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -639,7 +639,7 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, static unsigned int stac92xx_vref_set(struct hda_codec *codec, hda_nid_t nid, unsigned int new_vref) { - unsigned int error; + int error; unsigned int pincfg; pincfg = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); @@ -2703,7 +2703,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int new_vref = 0; - unsigned int error; + int error; hda_nid_t nid = kcontrol->private_value; if (ucontrol->value.enumerated.item[0] == 0) -- cgit v1.2.3 From ae14ef68e8e67ca5b8b29f0eb640f7c106617f4e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 08:16:56 +0200 Subject: ALSA: hda - Get back Input Source for ALC262 toshiba-s06 model The commit f9e336f65b666b8f1764d17e9b7c21c90748a37e ALSA: hda - Unify capture mixer creation in realtek codes removed the "Input Source" mixer element creation for toshiba-s06 model because it contains a digital-mic input. This patch take the control back. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bf4b78a74a8..105fb23398e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11539,6 +11539,7 @@ static struct alc_config_preset alc262_presets[] = { .capsrc_nids = alc262_dmic_capsrc_nids, .dac_nids = alc262_dac_nids, .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ + .num_adc_nids = 1, /* single ADC */ .dig_out_nid = ALC262_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, -- cgit v1.2.3 From 376b508ffde3b17e105265f89b83bdb044b1c1ae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 11:03:13 +0200 Subject: ALSA: hda - Add quirk for Sony VAIO Z21MN It needs model=toshiba-s06 to work with the digital-mic. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 105fb23398e..d20168494dd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11332,6 +11332,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ + SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", -- cgit v1.2.3 From 0169b6b33b2b4d9e66e98afc56272e5fbd350df4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 10:50:19 +0200 Subject: ALSA: hda - Fix check of input source type for realtek codecs Fix the check of the input-source type by checking the widget type of each capture-source item. Since some codecs can have both the mixer and selector types depending on the ADC, alc_mux_enum_put() needs to check each widget. With this change, spec->capture_style gets unneeded, so it's removed, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d20168494dd..28a587353b1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -250,13 +250,6 @@ enum { ALC883_MODEL_LAST, }; -/* styles of capture selection */ -enum { - CAPT_MUX = 0, /* only mux based */ - CAPT_MIX, /* only mixer based */ - CAPT_1MUX_MIX, /* first mux and other mixers */ -}; - /* for GPIO Poll */ #define GPIO_MASK 0x03 @@ -306,7 +299,6 @@ struct alc_spec { hda_nid_t *adc_nids; hda_nid_t *capsrc_nids; hda_nid_t dig_in_nid; /* digital-in NID; optional */ - int capture_style; /* capture style (CAPT_*) */ /* capture source */ unsigned int num_mux_defs; @@ -420,12 +412,13 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, unsigned int mux_idx; hda_nid_t nid = spec->capsrc_nids ? spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; + unsigned int type; mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; imux = &spec->input_mux[mux_idx]; - if (spec->capture_style && - !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) { + type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (type == AC_WID_AUD_MIX) { /* Matrix-mixer style (e.g. ALC882) */ unsigned int *cur_val = &spec->cur_mux[adc_idx]; unsigned int i, idx; @@ -7557,7 +7550,6 @@ static int patch_alc882(struct hda_codec *codec) spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; - spec->capture_style = CAPT_MIX; /* matrix-style capture */ if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); @@ -9781,7 +9773,6 @@ static int patch_alc883(struct hda_codec *codec) } if (!spec->capsrc_nids) spec->capsrc_nids = alc883_capsrc_nids; - spec->capture_style = CAPT_MIX; /* matrix-style capture */ spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ break; case 0x10ec0889: @@ -9791,8 +9782,6 @@ static int patch_alc883(struct hda_codec *codec) } if (!spec->capsrc_nids) spec->capsrc_nids = alc889_capsrc_nids; - spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style - capture */ break; default: if (!spec->num_adc_nids) { @@ -9801,7 +9790,6 @@ static int patch_alc883(struct hda_codec *codec) } if (!spec->capsrc_nids) spec->capsrc_nids = alc883_capsrc_nids; - spec->capture_style = CAPT_MIX; /* matrix-style capture */ break; } @@ -11642,7 +11630,6 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_digital_playback = &alc262_pcm_digital_playback; spec->stream_digital_capture = &alc262_pcm_digital_capture; - spec->capture_style = CAPT_MIX; if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); @@ -15556,7 +15543,6 @@ static int patch_alc861vd(struct hda_codec *codec) spec->adc_nids = alc861vd_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); spec->capsrc_nids = alc861vd_capsrc_nids; - spec->capture_style = CAPT_MIX; set_capture_mixer(spec); set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); @@ -17476,7 +17462,6 @@ static int patch_alc662(struct hda_codec *codec) spec->adc_nids = alc662_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); spec->capsrc_nids = alc662_capsrc_nids; - spec->capture_style = CAPT_MIX; if (!spec->cap_mixer) set_capture_mixer(spec); -- cgit v1.2.3 From 8c927b4acf819ed0170bff991bc9eaec4c85deb8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 10:56:54 +0200 Subject: ALSA: hda - Add digital-mic support to ALC262 auto model Add the digital-mic support with ALC262 auto model. The new ALC262 models have the digital mic at NID 0x12. This widget isn't checked in the current alc262_auto_create_analog_input_ctls() since it's under 0x18. So, just reuse the routine for alc269 to fix the behavior. But, it doesn't suffice: the digital mic is supported only with the ADC0, we have to exclude other ADCs when d-mic is detected. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 86 +++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 28a587353b1..33453319742 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10901,9 +10901,27 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, return 0; } -/* identical with ALC880 */ -#define alc262_auto_create_analog_input_ctls \ - alc880_auto_create_analog_input_ctls +static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + int err; + + err = alc880_auto_create_analog_input_ctls(spec, cfg); + if (err < 0) + return err; + /* digital-mic input pin is excluded in alc880_auto_create..() + * because it's under 0x18 + */ + if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || + cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { + struct hda_input_mux *imux = &spec->private_imux[0]; + imux->items[imux->num_items].label = "Int Mic"; + imux->items[imux->num_items].index = 0x09; + imux->num_items++; + } + return 0; +} + /* * generic initialization of ADC, input mixers and output mixers @@ -11631,19 +11649,35 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_digital_capture = &alc262_pcm_digital_capture; if (!spec->adc_nids && spec->input_mux) { - /* check whether NID 0x07 is valid */ - unsigned int wcap = get_wcaps(codec, 0x07); - - /* get type */ - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; - if (wcap != AC_WID_AUD_IN) { - spec->adc_nids = alc262_adc_nids_alt; - spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); - spec->capsrc_nids = alc262_capsrc_nids_alt; + int i; + /* check whether the digital-mic has to be supported */ + for (i = 0; i < spec->input_mux->num_items; i++) { + if (spec->input_mux->items[i].index >= 9) + break; + } + if (i < spec->input_mux->num_items) { + /* use only ADC0 */ + spec->adc_nids = alc262_dmic_adc_nids; + spec->num_adc_nids = 1; + spec->capsrc_nids = alc262_dmic_capsrc_nids; } else { - spec->adc_nids = alc262_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); - spec->capsrc_nids = alc262_capsrc_nids; + /* all analog inputs */ + /* check whether NID 0x07 is valid */ + unsigned int wcap = get_wcaps(codec, 0x07); + + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wcap != AC_WID_AUD_IN) { + spec->adc_nids = alc262_adc_nids_alt; + spec->num_adc_nids = + ARRAY_SIZE(alc262_adc_nids_alt); + spec->capsrc_nids = alc262_capsrc_nids_alt; + } else { + spec->adc_nids = alc262_adc_nids; + spec->num_adc_nids = + ARRAY_SIZE(alc262_adc_nids); + spec->capsrc_nids = alc262_capsrc_nids; + } } } if (!spec->cap_mixer && !spec->no_analog) @@ -13233,26 +13267,8 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, return 0; } -static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, - const struct auto_pin_cfg *cfg) -{ - int err; - - err = alc880_auto_create_analog_input_ctls(spec, cfg); - if (err < 0) - return err; - /* digital-mic input pin is excluded in alc880_auto_create..() - * because it's under 0x18 - */ - if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || - cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { - struct hda_input_mux *imux = &spec->private_imux[0]; - imux->items[imux->num_items].label = "Int Mic"; - imux->items[imux->num_items].index = 0x05; - imux->num_items++; - } - return 0; -} +#define alc269_auto_create_analog_input_ctls \ + alc262_auto_create_analog_input_ctls #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc269_loopbacks alc880_loopbacks -- cgit v1.2.3 From 6423f9ea8035138d70bae1a278d3b57b743f8b3e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Jun 2009 10:01:59 +0200 Subject: sound: seq_midi_event: fix decoding of (N)RPN events When decoding (N)RPN sequencer events into raw MIDI commands, the extra_decode_xrpn() function had accidentally swapped the MSB and LSB controller values of both the parameter number and the data value. Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai --- sound/core/seq/seq_midi_event.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c index 8284f176a34..b5d6ea4904c 100644 --- a/sound/core/seq/seq_midi_event.c +++ b/sound/core/seq/seq_midi_event.c @@ -504,10 +504,10 @@ static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, if (dev->nostat && count < 12) return -ENOMEM; cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f); - bytes[0] = ev->data.control.param & 0x007f; - bytes[1] = (ev->data.control.param & 0x3f80) >> 7; - bytes[2] = ev->data.control.value & 0x007f; - bytes[3] = (ev->data.control.value & 0x3f80) >> 7; + bytes[0] = (ev->data.control.param & 0x3f80) >> 7; + bytes[1] = ev->data.control.param & 0x007f; + bytes[2] = (ev->data.control.value & 0x3f80) >> 7; + bytes[3] = ev->data.control.value & 0x007f; if (cmd != dev->lastcmd && !dev->nostat) { if (count < 9) return -ENOMEM; -- cgit v1.2.3 From 29959a09cc1aabd2d5f4f03afc0305de6bd29248 Mon Sep 17 00:00:00 2001 From: Wai Yew CHAY Date: Mon, 22 Jun 2009 14:52:34 +0200 Subject: ALSA: ctxfi - Add PM support Added the suspend/resume support to ctxfi driver. The team tested on the following seems ok: AMD Athlon 64 3500+ / ASUS A8N-E / 512MB DDR ATI / Radeon X1300 20k1 & 20k2 cards Signed-off-by: Wai Yew CHAY Singed-off-by: Ryan RICHARDS Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 181 +++++++++++++++++++++++++++++++------------ sound/pci/ctxfi/ctatc.h | 7 ++ sound/pci/ctxfi/cthardware.h | 4 + sound/pci/ctxfi/cthw20k1.c | 83 ++++++++++++++++---- sound/pci/ctxfi/cthw20k2.c | 65 ++++++++++++---- sound/pci/ctxfi/ctmixer.c | 92 +++++++++++++++------- sound/pci/ctxfi/ctmixer.h | 3 + sound/pci/ctxfi/ctpcm.c | 4 + sound/pci/ctxfi/xfi.c | 22 ++++++ 9 files changed, 354 insertions(+), 107 deletions(-) diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 32e3c26e969..a49c7664730 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -261,13 +261,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int device = apcm->substream->pcm->device; unsigned int pitch; - if (NULL != apcm->src) { - /* Prepared pcm playback */ - return 0; - } - /* first release old resources */ - atc->pcm_release_resources(atc, apcm); + atc_pcm_release_resources(atc, apcm); /* Get SRC resource */ desc.multi = apcm->substream->runtime->channels; @@ -661,10 +656,7 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) unsigned int pitch; int mix_base = 0, imp_base = 0; - if (NULL != apcm->src) { - /* Prepared pcm capture */ - return 0; - } + atc_pcm_release_resources(atc, apcm); /* Get needed resources. */ err = atc_pcm_capture_get_resources(atc, apcm); @@ -867,7 +859,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); unsigned int rate = apcm->substream->runtime->rate; unsigned int status; - int err; + int err = 0; unsigned char iec958_con_fs; switch (rate) { @@ -908,8 +900,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int err; int i; - if (NULL != apcm->src) - return 0; + atc_pcm_release_resources(atc, apcm); /* Configure SPDIFOO and PLL to passthrough mode; * determine pll_rate. */ @@ -1116,32 +1107,20 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) return err; } -static int ct_atc_destroy(struct ct_atc *atc) +static int atc_release_resources(struct ct_atc *atc) { - struct daio_mgr *daio_mgr; - struct dao *dao; - struct dai *dai; - struct daio *daio; - struct sum_mgr *sum_mgr; - struct src_mgr *src_mgr; - struct srcimp_mgr *srcimp_mgr; - struct srcimp *srcimp; - struct ct_mixer *mixer; - int i = 0; - - if (NULL == atc) - return 0; - - if (atc->timer) { - ct_timer_free(atc->timer); - atc->timer = NULL; - } - - /* Stop hardware and disable all interrupts */ - if (NULL != atc->hw) - ((struct hw *)atc->hw)->card_stop(atc->hw); - - /* Destroy internal mixer objects */ + int i; + struct daio_mgr *daio_mgr = NULL; + struct dao *dao = NULL; + struct dai *dai = NULL; + struct daio *daio = NULL; + struct sum_mgr *sum_mgr = NULL; + struct src_mgr *src_mgr = NULL; + struct srcimp_mgr *srcimp_mgr = NULL; + struct srcimp *srcimp = NULL; + struct ct_mixer *mixer = NULL; + + /* disconnect internal mixer objects */ if (NULL != atc->mixer) { mixer = atc->mixer; mixer->set_input_left(mixer, MIX_LINE_IN, NULL); @@ -1150,7 +1129,6 @@ static int ct_atc_destroy(struct ct_atc *atc) mixer->set_input_right(mixer, MIX_MIC_IN, NULL); mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL); mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); - ct_mixer_destroy(atc->mixer); } if (NULL != atc->daios) { @@ -1168,6 +1146,7 @@ static int ct_atc_destroy(struct ct_atc *atc) daio_mgr->put_daio(daio_mgr, daio); } kfree(atc->daios); + atc->daios = NULL; } if (NULL != atc->pcm) { @@ -1176,6 +1155,7 @@ static int ct_atc_destroy(struct ct_atc *atc) sum_mgr->put_sum(sum_mgr, atc->pcm[i]); kfree(atc->pcm); + atc->pcm = NULL; } if (NULL != atc->srcs) { @@ -1184,6 +1164,7 @@ static int ct_atc_destroy(struct ct_atc *atc) src_mgr->put_src(src_mgr, atc->srcs[i]); kfree(atc->srcs); + atc->srcs = NULL; } if (NULL != atc->srcimps) { @@ -1194,8 +1175,30 @@ static int ct_atc_destroy(struct ct_atc *atc) srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]); } kfree(atc->srcimps); + atc->srcimps = NULL; + } + + return 0; +} + +static int ct_atc_destroy(struct ct_atc *atc) +{ + int i = 0; + + if (NULL == atc) + return 0; + + if (atc->timer) { + ct_timer_free(atc->timer); + atc->timer = NULL; } + atc_release_resources(atc); + + /* Destroy internal mixer objects */ + if (NULL != atc->mixer) + ct_mixer_destroy(atc->mixer); + for (i = 0; i < NUM_RSCTYP; i++) { if ((NULL != rsc_mgr_funcs[i].destroy) && (NULL != atc->rsc_mgrs[i])) @@ -1323,7 +1326,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc) return 0; } -static int __devinit atc_get_resources(struct ct_atc *atc) +static int atc_get_resources(struct ct_atc *atc) { struct daio_desc da_desc = {0}; struct daio_mgr *daio_mgr; @@ -1420,16 +1423,10 @@ static int __devinit atc_get_resources(struct ct_atc *atc) atc->n_pcm++; } - err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); - if (err) { - printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); - return err; - } - return 0; } -static void __devinit +static void atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, struct src **srcs, struct srcimp **srcimps) { @@ -1468,7 +1465,7 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */ } -static void __devinit atc_connect_resources(struct ct_atc *atc) +static void atc_connect_resources(struct ct_atc *atc) { struct dai *dai; struct dao *dao; @@ -1514,6 +1511,84 @@ static void __devinit atc_connect_resources(struct ct_atc *atc) } } +#ifdef CONFIG_PM +static int atc_suspend(struct ct_atc *atc, pm_message_t state) +{ + int i; + struct hw *hw = atc->hw; + + snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot); + + for (i = FRONT; i < NUM_PCMS; i++) { + if (!atc->pcms[i]) + continue; + + snd_pcm_suspend_all(atc->pcms[i]); + } + + atc_release_resources(atc); + + hw->suspend(hw, state); + + return 0; +} + +static int atc_hw_resume(struct ct_atc *atc) +{ + struct hw *hw = atc->hw; + struct card_conf info = {0}; + + /* Re-initialize card hardware. */ + info.rsr = atc->rsr; + info.msr = atc->msr; + info.vm_pgt_phys = atc_get_ptp_phys(atc, 0); + return hw->resume(hw, &info); +} + +static int atc_resources_resume(struct ct_atc *atc) +{ + struct ct_mixer *mixer; + int err = 0; + + /* Get resources */ + err = atc_get_resources(atc); + if (err < 0) { + atc_release_resources(atc); + return err; + } + + /* Build topology */ + atc_connect_resources(atc); + + mixer = atc->mixer; + mixer->resume(mixer); + + return 0; +} + +static int atc_resume(struct ct_atc *atc) +{ + int err = 0; + + /* Do hardware resume. */ + err = atc_hw_resume(atc); + if (err < 0) { + printk(KERN_ERR "ctxfi: pci_enable_device failed, " + "disabling device\n"); + snd_card_disconnect(atc->card); + return err; + } + + err = atc_resources_resume(atc); + if (err < 0) + return err; + + snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0); + + return 0; +} +#endif + static struct ct_atc atc_preset __devinitdata = { .map_audio_buffer = ct_map_audio_buffer, .unmap_audio_buffer = ct_unmap_audio_buffer, @@ -1542,6 +1617,10 @@ static struct ct_atc atc_preset __devinitdata = { .spdif_out_set_status = atc_spdif_out_set_status, .spdif_out_passthru = atc_spdif_out_passthru, .have_digit_io_switch = atc_have_digit_io_switch, +#ifdef CONFIG_PM + .suspend = atc_suspend, + .resume = atc_resume, +#endif }; /** @@ -1600,6 +1679,12 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, if (err < 0) goto error1; + err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); + if (err) { + printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); + goto error1; + } + /* Get resources */ err = atc_get_resources(atc); if (err < 0) diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index 9fe620ea5f3..9fd8a570894 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -136,6 +136,13 @@ struct ct_atc { unsigned char n_pcm; struct ct_timer *timer; + +#ifdef CONFIG_PM + int (*suspend)(struct ct_atc *atc, pm_message_t state); + int (*resume)(struct ct_atc *atc); +#define NUM_PCMS (NUM_CTALSADEVS - 1) + struct snd_pcm *pcms[NUM_PCMS]; +#endif }; diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index a4c2cad80f3..af55405f5de 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -64,6 +64,10 @@ struct hw { int (*card_init)(struct hw *hw, struct card_conf *info); int (*card_stop)(struct hw *hw); int (*pll_init)(struct hw *hw, unsigned int rsr); +#ifdef CONFIG_PM + int (*suspend)(struct hw *hw, pm_message_t state); + int (*resume)(struct hw *hw, struct card_conf *info); +#endif int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); int (*select_adc_source)(struct hw *hw, enum ADCSRC source); int (*have_digit_io_switch)(struct hw *hw); diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index cb69d9ddfbe..ad3e1d14446 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1911,9 +1911,17 @@ static int hw_card_start(struct hw *hw) goto error1; } - err = pci_request_regions(pci, "XFi"); - if (err < 0) - goto error1; + if (!hw->io_base) { + err = pci_request_regions(pci, "XFi"); + if (err < 0) + goto error1; + + if (hw->model == CTUAA) + hw->io_base = pci_resource_start(pci, 5); + else + hw->io_base = pci_resource_start(pci, 0); + + } /* Switch to X-Fi mode from UAA mode if neeeded */ if (hw->model == CTUAA) { @@ -1921,18 +1929,17 @@ static int hw_card_start(struct hw *hw) if (err) goto error2; - hw->io_base = pci_resource_start(pci, 5); - } else { - hw->io_base = pci_resource_start(pci, 0); } - err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, - "ctxfi", hw); - if (err < 0) { - printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); - goto error2; + if (hw->irq < 0) { + err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, + "ctxfi", hw); + if (err < 0) { + printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); + goto error2; + } + hw->irq = pci->irq; } - hw->irq = pci->irq; pci_set_master(pci); @@ -1948,6 +1955,15 @@ error1: static int hw_card_stop(struct hw *hw) { + unsigned int data; + + /* disable transport bus master and queueing of request */ + hw_write_20kx(hw, TRNCTL, 0x00); + + /* disable pll */ + data = hw_read_20kx(hw, PLLCTL); + hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12)))); + /* TODO: Disable interrupt and so on... */ if (hw->irq >= 0) synchronize_irq(hw->irq); @@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) struct trn_conf trn_info = {0}; /* Get PCI io port base address and do Hendrix switch if needed. */ - if (!hw->io_base) { - err = hw_card_start(hw); - if (err) - return err; - } + err = hw_card_start(hw); + if (err) + return err; /* PLL init */ err = hw_pll_init(hw, info->rsr); @@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) return 0; } +#ifdef CONFIG_PM +static int hw_suspend(struct hw *hw, pm_message_t state) +{ + struct pci_dev *pci = hw->pci; + + hw_card_stop(hw); + + if (hw->model == CTUAA) { + /* Switch to UAA config space. */ + pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); + } + + pci_disable_device(pci); + pci_save_state(pci); + pci_set_power_state(pci, pci_choose_state(pci, state)); + + return 0; +} + +static int hw_resume(struct hw *hw, struct card_conf *info) +{ + struct pci_dev *pci = hw->pci; + + pci_set_power_state(pci, PCI_D0); + pci_restore_state(pci); + + /* Re-initialize card hardware. */ + return hw_card_init(hw, info); +} +#endif + static u32 hw_read_20kx(struct hw *hw, u32 reg) { u32 value; @@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = { .is_adc_source_selected = hw_is_adc_input_selected, .select_adc_source = hw_adc_input_select, .have_digit_io_switch = hw_have_digit_io_switch, +#ifdef CONFIG_PM + .suspend = hw_suspend, + .resume = hw_resume, +#endif .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 4493a51c6b0..dec46d04b04 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -1860,16 +1860,18 @@ static int hw_card_start(struct hw *hw) goto error1; } - err = pci_request_regions(pci, "XFi"); - if (err < 0) - goto error1; + if (!hw->io_base) { + err = pci_request_regions(pci, "XFi"); + if (err < 0) + goto error1; - hw->io_base = pci_resource_start(hw->pci, 2); - hw->mem_base = (unsigned long)ioremap(hw->io_base, + hw->io_base = pci_resource_start(hw->pci, 2); + hw->mem_base = (unsigned long)ioremap(hw->io_base, pci_resource_len(hw->pci, 2)); - if (NULL == (void *)hw->mem_base) { - err = -ENOENT; - goto error2; + if (NULL == (void *)hw->mem_base) { + err = -ENOENT; + goto error2; + } } /* Switch to 20k2 mode from UAA mode. */ @@ -1901,6 +1903,15 @@ error1: static int hw_card_stop(struct hw *hw) { + unsigned int data; + + /* disable transport bus master and queueing of request */ + hw_write_20kx(hw, TRANSPORT_CTL, 0x00); + + /* disable pll */ + data = hw_read_20kx(hw, PLL_ENB); + hw_write_20kx(hw, PLL_ENB, (data & (~0x07))); + /* TODO: Disable interrupt and so on... */ return 0; } @@ -1939,11 +1950,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) /* Get PCI io port/memory base address and * do 20kx core switch if needed. */ - if (!hw->io_base) { - err = hw_card_start(hw); - if (err) - return err; - } + err = hw_card_start(hw); + if (err) + return err; /* PLL init */ err = hw_pll_init(hw, info->rsr); @@ -2006,6 +2015,32 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) return 0; } +#ifdef CONFIG_PM +static int hw_suspend(struct hw *hw, pm_message_t state) +{ + struct pci_dev *pci = hw->pci; + + hw_card_stop(hw); + + pci_disable_device(pci); + pci_save_state(pci); + pci_set_power_state(pci, pci_choose_state(pci, state)); + + return 0; +} + +static int hw_resume(struct hw *hw, struct card_conf *info) +{ + struct pci_dev *pci = hw->pci; + + pci_set_power_state(pci, PCI_D0); + pci_restore_state(pci); + + /* Re-initialize card hardware. */ + return hw_card_init(hw, info); +} +#endif + static u32 hw_read_20kx(struct hw *hw, u32 reg) { return readl((void *)(hw->mem_base + reg)); @@ -2025,6 +2060,10 @@ static struct hw ct20k2_preset __devinitdata = { .is_adc_source_selected = hw_is_adc_input_selected, .select_adc_source = hw_adc_input_select, .have_digit_io_switch = hw_have_digit_io_switch, +#ifdef CONFIG_PM + .suspend = hw_suspend, + .resume = hw_resume, +#endif .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index 666722d9de4..f26d7cd9db9 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -462,6 +462,43 @@ do_digit_io_switch(struct ct_atc *atc, int state) return; } +static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state) +{ + struct ct_mixer *mixer = atc->mixer; + + /* Do changes in mixer. */ + if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) { + if (state) { + ct_mixer_recording_select(mixer, + get_amixer_index(type)); + } else { + ct_mixer_recording_unselect(mixer, + get_amixer_index(type)); + } + } + /* Do changes out of mixer. */ + if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) + do_line_mic_switch(atc, type); + else if (MIXER_WAVEF_P_S == type) + atc->line_front_unmute(atc, state); + else if (MIXER_WAVES_P_S == type) + atc->line_surround_unmute(atc, state); + else if (MIXER_WAVEC_P_S == type) + atc->line_clfe_unmute(atc, state); + else if (MIXER_WAVER_P_S == type) + atc->line_rear_unmute(atc, state); + else if (MIXER_LINEIN_P_S == type) + atc->line_in_unmute(atc, state); + else if (MIXER_SPDIFO_P_S == type) + atc->spdif_out_unmute(atc, state); + else if (MIXER_SPDIFI_P_S == type) + atc->spdif_in_unmute(atc, state); + else if (MIXER_DIGITAL_IO_S == type) + do_digit_io_switch(atc, state); + + return; +} + static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -498,35 +535,7 @@ static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol, return 0; set_switch_state(mixer, type, state); - /* Do changes in mixer. */ - if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) { - if (state) { - ct_mixer_recording_select(mixer, - get_amixer_index(type)); - } else { - ct_mixer_recording_unselect(mixer, - get_amixer_index(type)); - } - } - /* Do changes out of mixer. */ - if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) - do_line_mic_switch(atc, type); - else if (MIXER_WAVEF_P_S == type) - atc->line_front_unmute(atc, state); - else if (MIXER_WAVES_P_S == type) - atc->line_surround_unmute(atc, state); - else if (MIXER_WAVEC_P_S == type) - atc->line_clfe_unmute(atc, state); - else if (MIXER_WAVER_P_S == type) - atc->line_rear_unmute(atc, state); - else if (MIXER_LINEIN_P_S == type) - atc->line_in_unmute(atc, state); - else if (MIXER_SPDIFO_P_S == type) - atc->spdif_out_unmute(atc, state); - else if (MIXER_SPDIFI_P_S == type) - atc->spdif_in_unmute(atc, state); - else if (MIXER_DIGITAL_IO_S == type) - do_digit_io_switch(atc, state); + do_switch(atc, type, state); return 1; } @@ -1039,6 +1048,28 @@ mixer_set_input_right(struct ct_mixer *mixer, return 0; } +#ifdef CONFIG_PM +static int mixer_resume(struct ct_mixer *mixer) +{ + int i, state; + struct amixer *amixer; + + /* resume topology and volume gain. */ + for (i = 0; i < NUM_CT_AMIXERS*CHN_NUM; i++) { + amixer = mixer->amixers[i]; + amixer->ops->commit_write(amixer); + } + + /* resume switch state. */ + for (i = SWH_MIXER_START; i <= SWH_MIXER_END; i++) { + state = get_switch_state(mixer, i); + do_switch(mixer->atc, i, state); + } + + return 0; +} +#endif + int ct_mixer_destroy(struct ct_mixer *mixer) { struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM]; @@ -1087,6 +1118,9 @@ int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer) mixer->get_output_ports = mixer_get_output_ports; mixer->set_input_left = mixer_set_input_left; mixer->set_input_right = mixer_set_input_right; +#ifdef CONFIG_PM + mixer->resume = mixer_resume; +#endif /* Allocate chip resources for mixer obj */ err = ct_mixer_get_resources(mixer); diff --git a/sound/pci/ctxfi/ctmixer.h b/sound/pci/ctxfi/ctmixer.h index e2d96ebde74..b009e989e77 100644 --- a/sound/pci/ctxfi/ctmixer.h +++ b/sound/pci/ctxfi/ctmixer.h @@ -56,6 +56,9 @@ struct ct_mixer { enum MIXER_PORT_T type, struct rsc *rsc); int (*set_input_right)(struct ct_mixer *mixer, enum MIXER_PORT_T type, struct rsc *rsc); +#ifdef CONFIG_PM + int (*resume)(struct ct_mixer *mixer); +#endif }; int ct_alsa_mix_create(struct ct_atc *atc, diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 9e5c0c4da72..60ea23180ac 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -422,5 +422,9 @@ int ct_alsa_pcm_create(struct ct_atc *atc, snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(atc->pci), 128*1024, 128*1024); +#ifdef CONFIG_PM + atc->pcms[device] = pcm; +#endif + return 0; } diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c index 2d3dd89af15..76541748e7b 100644 --- a/sound/pci/ctxfi/xfi.c +++ b/sound/pci/ctxfi/xfi.c @@ -121,11 +121,33 @@ static void __devexit ct_card_remove(struct pci_dev *pci) pci_set_drvdata(pci, NULL); } +#ifdef CONFIG_PM +static int ct_card_suspend(struct pci_dev *pci, pm_message_t state) +{ + struct snd_card *card = pci_get_drvdata(pci); + struct ct_atc *atc = card->private_data; + + return atc->suspend(atc, state); +} + +static int ct_card_resume(struct pci_dev *pci) +{ + struct snd_card *card = pci_get_drvdata(pci); + struct ct_atc *atc = card->private_data; + + return atc->resume(atc); +} +#endif + static struct pci_driver ct_driver = { .name = "SB-XFi", .id_table = ct_pci_dev_ids, .probe = ct_card_probe, .remove = __devexit_p(ct_card_remove), +#ifdef CONFIG_PM + .suspend = ct_card_suspend, + .resume = ct_card_resume, +#endif }; static int __init ct_card_init(void) -- cgit v1.2.3 From 8c8145b8734028f6deb487f7d64748da4c6c39ac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Jun 2009 17:00:38 +0200 Subject: ALSA: hda - Make jack-plug notification selectable Make the jack-plug notification via input layer selectable via Kconfig. This is often unnecessary, and the similr function will be provided using the ALSA control API in near future anyway. Signed-off-by: Takashi Iwai --- sound/pci/hda/Kconfig | 9 ++++++++- sound/pci/hda/patch_conexant.c | 4 ++-- sound/pci/hda/patch_sigmatel.c | 6 +++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index c710150d506..04438f1d682 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -2,7 +2,6 @@ menuconfig SND_HDA_INTEL tristate "Intel HD Audio" select SND_PCM select SND_VMASTER - select SND_JACK if INPUT=y || INPUT=SND help Say Y here to include support for Intel "High Definition Audio" (Azalia) and its compatible devices. @@ -39,6 +38,14 @@ config SND_HDA_INPUT_BEEP Say Y here to build a digital beep interface for HD-audio driver. This interface is used to generate digital beeps. +config SND_HDA_INPUT_JACK + bool "Support jack plugging notification via input layer" + depends on INPUT=y || INPUT=SND_HDA_INTEL + select SND_JACK + help + Say Y here to enable the jack plugging notification via + input layer. + config SND_HDA_CODEC_REALTEK bool "Build Realtek HD-audio codec support" default y diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4fcbe21829a..ac868c59f9e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -349,7 +349,7 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } -#ifdef CONFIG_SND_JACK +#ifdef CONFIG_SND_HDA_INPUT_JACK static void conexant_free_jack_priv(struct snd_jack *jack) { struct conexant_jack *jacks = jack->private_data; @@ -463,7 +463,7 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { -#ifdef CONFIG_SND_JACK +#ifdef CONFIG_SND_HDA_INPUT_JACK struct conexant_spec *spec = codec->spec; if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 090957735e0..14f3c3e0f62 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4035,7 +4035,7 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ } -#ifdef CONFIG_SND_JACK +#ifdef CONFIG_SND_HDA_INPUT_JACK static void stac92xx_free_jack_priv(struct snd_jack *jack) { struct sigmatel_jack *jacks = jack->private_data; @@ -4047,7 +4047,7 @@ static void stac92xx_free_jack_priv(struct snd_jack *jack) static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { -#ifdef CONFIG_SND_JACK +#ifdef CONFIG_SND_HDA_INPUT_JACK struct sigmatel_spec *spec = codec->spec; struct sigmatel_jack *jack; int def_conf = snd_hda_codec_get_pincfg(codec, nid); @@ -4336,7 +4336,7 @@ static int stac92xx_init(struct hda_codec *codec) static void stac92xx_free_jacks(struct hda_codec *codec) { -#ifdef CONFIG_SND_JACK +#ifdef CONFIG_SND_HDA_INPUT_JACK /* free jack instances manually when clearing/reconfiguring */ struct sigmatel_spec *spec = codec->spec; if (!codec->bus->shutdown && spec->jacks.list) { -- cgit v1.2.3