diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/arm/pxa2xx-ac97-lib.c | 26 | ||||
-rw-r--r-- | sound/oss/pas2_card.c | 5 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0_synth.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 30 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.c | 9 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.h | 18 | ||||
-rw-r--r-- | sound/soc/codecs/cs4271.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l52.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/lm49453.c | 106 | ||||
-rw-r--r-- | sound/soc/codecs/wm5102.c | 48 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 35 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 1 | ||||
-rw-r--r-- | sound/usb/midi.c | 4 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 24 | ||||
-rw-r--r-- | sound/usb/quirks.c | 16 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 |
17 files changed, 224 insertions, 113 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c index 6fc0ae90e5b1..fff7753e35c1 100644 --- a/sound/arm/pxa2xx-ac97-lib.c +++ b/sound/arm/pxa2xx-ac97-lib.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/gpio.h> #include <sound/ac97_codec.h> #include <sound/pxa2xx-lib.h> @@ -148,6 +149,8 @@ static inline void pxa_ac97_warm_pxa27x(void) static inline void pxa_ac97_cold_pxa27x(void) { + unsigned int timeout; + GCR &= GCR_COLD_RST; /* clear everything but nCRST */ GCR &= ~GCR_COLD_RST; /* then assert nCRST */ @@ -157,8 +160,10 @@ static inline void pxa_ac97_cold_pxa27x(void) clk_enable(ac97conf_clk); udelay(5); clk_disable(ac97conf_clk); - GCR = GCR_COLD_RST; - udelay(50); + GCR = GCR_COLD_RST | GCR_WARM_RST; + timeout = 100; /* wait for the codec-ready bit to be set */ + while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) + mdelay(1); } #endif @@ -340,8 +345,21 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev) } if (cpu_is_pxa27x()) { - /* Use GPIO 113 as AC97 Reset on Bulverde */ + /* + * This gpio is needed for a work-around to a bug in the ac97 + * controller during warm reset. The direction and level is set + * here so that it is an output driven high when switching from + * AC97_nRESET alt function to generic gpio. + */ + ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH, + "pxa27x ac97 reset"); + if (ret < 0) { + pr_err("%s: gpio_request_one() failed: %d\n", + __func__, ret); + goto err_conf; + } pxa27x_assert_ac97reset(reset_gpio, 0); + ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); if (IS_ERR(ac97conf_clk)) { ret = PTR_ERR(ac97conf_clk); @@ -384,6 +402,8 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); void pxa2xx_ac97_hw_remove(struct platform_device *dev) { + if (cpu_is_pxa27x()) + gpio_free(reset_gpio); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); if (ac97conf_clk) { diff --git a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c index dabf8a871dcc..7004e24d209f 100644 --- a/sound/oss/pas2_card.c +++ b/sound/oss/pas2_card.c @@ -333,6 +333,11 @@ static void __init attach_pas_card(struct address_info *hw_config) { char temp[100]; + if (pas_model < 0 || + pas_model >= ARRAY_SIZE(pas_model_names)) { + printk(KERN_ERR "pas2 unrecognized model.\n"); + return; + } sprintf(temp, "%s rev %d", pas_model_names[(int) pas_model], pas_read(0x2789)); diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index 2805e34bd41d..8bef47311e45 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c @@ -58,7 +58,7 @@ static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en) if (en) temp |= (1 << (wt & 0x1f)); else - temp &= (1 << ~(wt & 0x1f)); + temp &= ~(1 << (wt & 0x1f)); hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp); } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8353c77536ac..b8fb0a5adb9b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2531,7 +2531,7 @@ static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static const char * const texts[] = { - "Off", "On", "Follow Master" + "On", "Off", "Follow Master" }; unsigned int index; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6ee34593774a..71ae23dd7103 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5992,6 +5992,30 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec, spec->automute_hook = alc269_quanta_automute; } +/* update mute-LED according to the speaker mute state via mic1 VREF pin */ +static void alc269_fixup_mic1_mute_hook(void *private_data, int enabled) +{ + struct hda_codec *codec = private_data; + unsigned int pinval = AC_PINCTL_IN_EN + (enabled ? + AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); + snd_hda_set_pin_ctl_cache(codec, 0x18, pinval); +} + +static void alc269_fixup_mic1_mute(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + switch (action) { + case ALC_FIXUP_ACT_BUILD: + spec->vmaster_mute.hook = alc269_fixup_mic1_mute_hook; + snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); + /* fallthru */ + case ALC_FIXUP_ACT_INIT: + snd_hda_sync_vmaster_hook(&spec->vmaster_mute); + break; + } +} + /* update mute-LED according to the speaker mute state via mic2 VREF pin */ static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled) { @@ -6043,6 +6067,7 @@ enum { ALC269_FIXUP_DMIC, ALC269VB_FIXUP_AMIC, ALC269VB_FIXUP_DMIC, + ALC269_FIXUP_MIC1_MUTE_LED, ALC269_FIXUP_MIC2_MUTE_LED, ALC269_FIXUP_INV_DMIC, ALC269_FIXUP_LENOVO_DOCK, @@ -6171,6 +6196,10 @@ static const struct alc_fixup alc269_fixups[] = { { } }, }, + [ALC269_FIXUP_MIC1_MUTE_LED] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc269_fixup_mic1_mute, + }, [ALC269_FIXUP_MIC2_MUTE_LED] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_mic2_mute, @@ -6215,6 +6244,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x1972, "HP Pavilion 17", ALC269_FIXUP_MIC1_MUTE_LED), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index adf397b9d0e6..1d8bb5917594 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -446,15 +446,9 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_DSP_A: mode = 0; break; - case SND_SOC_DAIFMT_DSP_B: - mode = 1; - break; case SND_SOC_DAIFMT_I2S: mode = 2; break; - case SND_SOC_DAIFMT_LEFT_J: - mode = 3; - break; default: arizona_aif_err(dai, "Unsupported DAI format %d\n", fmt & SND_SOC_DAIFMT_FORMAT_MASK); @@ -714,7 +708,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1, ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val); snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, - ARIZONA_AIF1_RATE_MASK, 8); + ARIZONA_AIF1_RATE_MASK, + 8 << ARIZONA_AIF1_RATE_SHIFT); break; default: arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 41dae1ed3b71..4deebeb07177 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -34,15 +34,15 @@ #define ARIZONA_FLL_SRC_MCLK1 0 #define ARIZONA_FLL_SRC_MCLK2 1 -#define ARIZONA_FLL_SRC_SLIMCLK 2 -#define ARIZONA_FLL_SRC_FLL1 3 -#define ARIZONA_FLL_SRC_FLL2 4 -#define ARIZONA_FLL_SRC_AIF1BCLK 5 -#define ARIZONA_FLL_SRC_AIF2BCLK 6 -#define ARIZONA_FLL_SRC_AIF3BCLK 7 -#define ARIZONA_FLL_SRC_AIF1LRCLK 8 -#define ARIZONA_FLL_SRC_AIF2LRCLK 9 -#define ARIZONA_FLL_SRC_AIF3LRCLK 10 +#define ARIZONA_FLL_SRC_SLIMCLK 3 +#define ARIZONA_FLL_SRC_FLL1 4 +#define ARIZONA_FLL_SRC_FLL2 5 +#define ARIZONA_FLL_SRC_AIF1BCLK 8 +#define ARIZONA_FLL_SRC_AIF2BCLK 9 +#define ARIZONA_FLL_SRC_AIF3BCLK 10 +#define ARIZONA_FLL_SRC_AIF1LRCLK 12 +#define ARIZONA_FLL_SRC_AIF2LRCLK 13 +#define ARIZONA_FLL_SRC_AIF3LRCLK 14 #define ARIZONA_MIXER_VOL_MASK 0x00FE #define ARIZONA_MIXER_VOL_SHIFT 1 diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 4f1127935fdf..ac8742a1f25a 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -474,16 +474,16 @@ static int cs4271_probe(struct snd_soc_codec *codec) struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; int ret; int gpio_nreset = -EINVAL; - int amutec_eq_bmutec = 0; + bool amutec_eq_bmutec = false; #ifdef CONFIG_OF if (of_match_device(cs4271_dt_ids, codec->dev)) { gpio_nreset = of_get_named_gpio(codec->dev->of_node, "reset-gpio", 0); - if (!of_get_property(codec->dev->of_node, + if (of_get_property(codec->dev->of_node, "cirrus,amutec-eq-bmutec", NULL)) - amutec_eq_bmutec = 1; + amutec_eq_bmutec = true; } #endif diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 99bb1c69499e..9811a5478c87 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -737,7 +737,7 @@ static const struct cs42l52_clk_para clk_map_table[] = { static int cs42l52_get_clk(int mclk, int rate) { - int i, ret = 0; + int i, ret = -EINVAL; u_int mclk1, mclk2 = 0; for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) { @@ -749,8 +749,6 @@ static int cs42l52_get_clk(int mclk, int rate) } } } - if (ret > ARRAY_SIZE(clk_map_table)) - return -EINVAL; return ret; } diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index d75257d40a49..e19490cfb3a8 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -111,9 +111,9 @@ static struct reg_default lm49453_reg_defs[] = { { 101, 0x00 }, { 102, 0x00 }, { 103, 0x01 }, - { 105, 0x01 }, - { 106, 0x00 }, - { 107, 0x01 }, + { 104, 0x01 }, + { 105, 0x00 }, + { 106, 0x01 }, { 107, 0x00 }, { 108, 0x00 }, { 109, 0x00 }, @@ -163,56 +163,25 @@ static struct reg_default lm49453_reg_defs[] = { { 184, 0x00 }, { 185, 0x00 }, { 186, 0x00 }, - { 189, 0x00 }, + { 187, 0x00 }, { 188, 0x00 }, - { 194, 0x00 }, - { 195, 0x00 }, - { 196, 0x00 }, - { 197, 0x00 }, - { 200, 0x00 }, - { 201, 0x00 }, - { 202, 0x00 }, - { 203, 0x00 }, - { 204, 0x00 }, - { 205, 0x00 }, - { 208, 0x00 }, + { 189, 0x00 }, + { 208, 0x06 }, { 209, 0x00 }, - { 210, 0x00 }, - { 211, 0x00 }, - { 213, 0x00 }, - { 214, 0x00 }, - { 215, 0x00 }, - { 216, 0x00 }, - { 217, 0x00 }, - { 218, 0x00 }, - { 219, 0x00 }, + { 210, 0x08 }, + { 211, 0x54 }, + { 212, 0x14 }, + { 213, 0x0d }, + { 214, 0x0d }, + { 215, 0x14 }, + { 216, 0x60 }, { 221, 0x00 }, { 222, 0x00 }, + { 223, 0x00 }, { 224, 0x00 }, - { 225, 0x00 }, - { 226, 0x00 }, - { 227, 0x00 }, - { 228, 0x00 }, - { 229, 0x00 }, - { 230, 0x13 }, - { 231, 0x00 }, - { 232, 0x80 }, - { 233, 0x0C }, - { 234, 0xDD }, - { 235, 0x00 }, - { 236, 0x04 }, - { 237, 0x00 }, - { 238, 0x00 }, - { 239, 0x00 }, - { 240, 0x00 }, - { 241, 0x00 }, - { 242, 0x00 }, - { 243, 0x00 }, - { 244, 0x00 }, - { 245, 0x00 }, { 248, 0x00 }, { 249, 0x00 }, - { 254, 0x00 }, + { 250, 0x00 }, { 255, 0x00 }, }; @@ -525,36 +494,41 @@ SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_PORT2_TX2_REG, 7, 1, 0), }; /* TLV Declarations */ -static const DECLARE_TLV_DB_SCALE(digital_tlv, -7650, 150, 1); -static const DECLARE_TLV_DB_SCALE(port_tlv, 0, 600, 0); +static const DECLARE_TLV_DB_SCALE(adc_dac_tlv, -7650, 150, 1); +static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 200, 1); +static const DECLARE_TLV_DB_SCALE(port_tlv, -1800, 600, 0); +static const DECLARE_TLV_DB_SCALE(stn_tlv, -7200, 150, 0); static const struct snd_kcontrol_new lm49453_sidetone_mixer_controls[] = { /* Sidetone supports mono only */ SOC_DAPM_SINGLE_TLV("Sidetone ADCL Volume", LM49453_P0_STN_VOL_ADCL_REG, - 0, 0x3F, 0, digital_tlv), + 0, 0x3F, 0, stn_tlv), SOC_DAPM_SINGLE_TLV("Sidetone ADCR Volume", LM49453_P0_STN_VOL_ADCR_REG, - 0, 0x3F, 0, digital_tlv), + 0, 0x3F, 0, stn_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC1L Volume", LM49453_P0_STN_VOL_DMIC1L_REG, - 0, 0x3F, 0, digital_tlv), + 0, 0x3F, 0, stn_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC1R Volume", LM49453_P0_STN_VOL_DMIC1R_REG, - 0, 0x3F, 0, digital_tlv), + 0, 0x3F, 0, stn_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC2L Volume", LM49453_P0_STN_VOL_DMIC2L_REG, - 0, 0x3F, 0, digital_tlv), + 0, 0x3F, 0, stn_tlv), SOC_DAPM_SINGLE_TLV("Sidetone DMIC2R Volume", LM49453_P0_STN_VOL_DMIC2R_REG, - 0, 0x3F, 0, digital_tlv), + 0, 0x3F, 0, stn_tlv), }; static const struct snd_kcontrol_new lm49453_snd_controls[] = { /* mic1 and mic2 supports mono only */ - SOC_SINGLE_TLV("Mic1 Volume", LM49453_P0_ADC_LEVELL_REG, 0, 6, - 0, digital_tlv), - SOC_SINGLE_TLV("Mic2 Volume", LM49453_P0_ADC_LEVELR_REG, 0, 6, - 0, digital_tlv), + SOC_SINGLE_TLV("Mic1 Volume", LM49453_P0_MICL_REG, 0, 15, 0, mic_tlv), + SOC_SINGLE_TLV("Mic2 Volume", LM49453_P0_MICR_REG, 0, 15, 0, mic_tlv), + + SOC_SINGLE_TLV("ADCL Volume", LM49453_P0_ADC_LEVELL_REG, 0, 63, + 0, adc_dac_tlv), + SOC_SINGLE_TLV("ADCR Volume", LM49453_P0_ADC_LEVELR_REG, 0, 63, + 0, adc_dac_tlv), SOC_DOUBLE_R_TLV("DMIC1 Volume", LM49453_P0_DMIC1_LEVELL_REG, - LM49453_P0_DMIC1_LEVELR_REG, 0, 6, 0, digital_tlv), + LM49453_P0_DMIC1_LEVELR_REG, 0, 63, 0, adc_dac_tlv), SOC_DOUBLE_R_TLV("DMIC2 Volume", LM49453_P0_DMIC2_LEVELL_REG, - LM49453_P0_DMIC2_LEVELR_REG, 0, 6, 0, digital_tlv), + LM49453_P0_DMIC2_LEVELR_REG, 0, 63, 0, adc_dac_tlv), SOC_DAPM_ENUM("Mic2Mode", lm49453_mic2mode_enum), SOC_DAPM_ENUM("DMIC12 SRC", lm49453_dmic12_cfg_enum), @@ -569,16 +543,16 @@ static const struct snd_kcontrol_new lm49453_snd_controls[] = { 2, 1, 0), SOC_DOUBLE_R_TLV("DAC HP Volume", LM49453_P0_DAC_HP_LEVELL_REG, - LM49453_P0_DAC_HP_LEVELR_REG, 0, 6, 0, digital_tlv), + LM49453_P0_DAC_HP_LEVELR_REG, 0, 63, 0, adc_dac_tlv), SOC_DOUBLE_R_TLV("DAC LO Volume", LM49453_P0_DAC_LO_LEVELL_REG, - LM49453_P0_DAC_LO_LEVELR_REG, 0, 6, 0, digital_tlv), + LM49453_P0_DAC_LO_LEVELR_REG, 0, 63, 0, adc_dac_tlv), SOC_DOUBLE_R_TLV("DAC LS Volume", LM49453_P0_DAC_LS_LEVELL_REG, - LM49453_P0_DAC_LS_LEVELR_REG, 0, 6, 0, digital_tlv), + LM49453_P0_DAC_LS_LEVELR_REG, 0, 63, 0, adc_dac_tlv), SOC_DOUBLE_R_TLV("DAC HA Volume", LM49453_P0_DAC_HA_LEVELL_REG, - LM49453_P0_DAC_HA_LEVELR_REG, 0, 6, 0, digital_tlv), + LM49453_P0_DAC_HA_LEVELR_REG, 0, 63, 0, adc_dac_tlv), SOC_SINGLE_TLV("EP Volume", LM49453_P0_DAC_LS_LEVELL_REG, - 0, 6, 0, digital_tlv), + 0, 63, 0, adc_dac_tlv), SOC_SINGLE_TLV("PORT1_1_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG, 0, 3, 0, port_tlv), @@ -1218,7 +1192,7 @@ static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) } snd_soc_update_bits(codec, LM49453_P0_AUDIO_PORT1_BASIC_REG, - LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(1)|BIT(5), + LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(0)|BIT(5), (aif_val | mode | clk_phase)); snd_soc_write(codec, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift); diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 688ade080589..7a9048dad1cd 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -36,6 +36,9 @@ struct wm5102_priv { struct arizona_priv core; struct arizona_fll fll[2]; + + unsigned int spk_ena:2; + unsigned int spk_ena_pending:1; }; static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); @@ -787,6 +790,47 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), }; +static int wm5102_spk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = w->codec; + struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec); + + if (arizona->rev < 1) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!wm5102->spk_ena) { + snd_soc_write(codec, 0x4f5, 0x25a); + wm5102->spk_ena_pending = true; + } + break; + case SND_SOC_DAPM_POST_PMU: + if (wm5102->spk_ena_pending) { + msleep(75); + snd_soc_write(codec, 0x4f5, 0xda); + wm5102->spk_ena_pending = false; + wm5102->spk_ena++; + } + break; + case SND_SOC_DAPM_PRE_PMD: + wm5102->spk_ena--; + if (!wm5102->spk_ena) + snd_soc_write(codec, 0x4f5, 0x25a); + break; + case SND_SOC_DAPM_POST_PMD: + if (!wm5102->spk_ena) + snd_soc_write(codec, 0x4f5, 0x0da); + break; + } + + return 0; +} + + ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); @@ -1034,10 +1078,10 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 91d592ff67b7..2370063b5824 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1255,6 +1255,8 @@ static int soc_post_component_init(struct snd_soc_card *card, INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); ret = device_add(rtd->dev); if (ret < 0) { + /* calling put_device() here to free the rtd->dev */ + put_device(rtd->dev); dev_err(card->dev, "ASoC: failed to register runtime device: %d\n", ret); return ret; @@ -1554,7 +1556,7 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) /* unregister the rtd device */ if (rtd->dev_registered) { device_remove_file(rtd->dev, &dev_attr_codec_reg); - device_del(rtd->dev); + device_unregister(rtd->dev); rtd->dev_registered = 0; } @@ -2917,7 +2919,7 @@ int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, platform_max = mc->platform_max; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; + uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = platform_max - min; @@ -2941,12 +2943,14 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int reg = mc->reg; + unsigned int rreg = mc->rreg; unsigned int shift = mc->shift; int min = mc->min; int max = mc->max; unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = mc->invert; unsigned int val, val_mask; + int ret; val = ((ucontrol->value.integer.value[0] + min) & mask); if (invert) @@ -2954,7 +2958,21 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, val_mask = mask << shift; val = val << shift; - return snd_soc_update_bits_locked(codec, reg, val_mask, val); + ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); + if (ret != 0) + return ret; + + if (snd_soc_volsw_is_stereo(mc)) { + val = ((ucontrol->value.integer.value[1] + min) & mask); + if (invert) + val = max - val; + val_mask = mask << shift; + val = val << shift; + + ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val); + } + + return ret; } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); @@ -2974,6 +2992,7 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int reg = mc->reg; + unsigned int rreg = mc->rreg; unsigned int shift = mc->shift; int min = mc->min; int max = mc->max; @@ -2988,6 +3007,16 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] - min; + if (snd_soc_volsw_is_stereo(mc)) { + ucontrol->value.integer.value[1] = + (snd_soc_read(codec, rreg) >> shift) & mask; + if (invert) + ucontrol->value.integer.value[1] = + max - ucontrol->value.integer.value[1]; + ucontrol->value.integer.value[1] = + ucontrol->value.integer.value[1] - min; + } + return 0; } EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index d7711fce119b..cf191e6aebbe 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1243,6 +1243,7 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) continue; diff --git a/sound/usb/midi.c b/sound/usb/midi.c index c183d34842ac..34b9bb7fe87c 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -2181,10 +2181,6 @@ int snd_usbmidi_create(struct snd_card *card, umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; - case QUIRK_MIDI_MBOX2: - umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops; - err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); - break; case QUIRK_MIDI_RAW_BYTES: umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; /* diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index cdcf6b45e8a8..78e845ec65da 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -50,6 +50,28 @@ } }, +{ + /* Creative BT-D1 */ + USB_DEVICE(0x041e, 0x0005), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels = 2, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x03, + .ep_attr = USB_ENDPOINT_XFER_ISOC, + .attributes = 0, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 48000, + .rate_max = 48000, + } + } +}, + /* Creative/Toshiba Multimedia Center SB-0500 */ { USB_DEVICE(0x041e, 0x3048), @@ -2993,7 +3015,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, { .ifnum = 6, - .type = QUIRK_MIDI_MBOX2, + .type = QUIRK_MIDI_MIDIMAN, .data = &(const struct snd_usb_midi_endpoint_info) { .out_ep = 0x02, .out_cables = 0x0001, diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index f104c68fe1e0..acc12f004c23 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -306,7 +306,6 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, - [QUIRK_MIDI_MBOX2] = create_any_midi_quirk, [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk, [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, [QUIRK_MIDI_CME] = create_any_midi_quirk, @@ -528,11 +527,11 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev) #define MBOX2_BOOT_LOADING 0x01 /* Hard coded into the device */ #define MBOX2_BOOT_READY 0x02 /* Hard coded into the device */ -int snd_usb_mbox2_boot_quirk(struct usb_device *dev) +static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) { struct usb_host_config *config = dev->actconfig; int err; - u8 bootresponse; + u8 bootresponse[12]; int fwsize; int count; @@ -546,20 +545,20 @@ int snd_usb_mbox2_boot_quirk(struct usb_device *dev) snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n"); count = 0; - bootresponse = MBOX2_BOOT_LOADING; - while ((bootresponse == MBOX2_BOOT_LOADING) && (count < 10)) { + bootresponse[0] = MBOX2_BOOT_LOADING; + while ((bootresponse[0] == MBOX2_BOOT_LOADING) && (count < 10)) { msleep(500); /* 0.5 second delay */ snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), /* Control magic - load onboard firmware */ 0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012); - if (bootresponse == MBOX2_BOOT_READY) + if (bootresponse[0] == MBOX2_BOOT_READY) break; snd_printd("usb-audio: device not ready, resending boot sequence...\n"); count++; } - if (bootresponse != MBOX2_BOOT_READY) { - snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse); + if (bootresponse[0] != MBOX2_BOOT_READY) { + snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse[0]); return -ENODEV; } @@ -660,7 +659,6 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, return 0; /* keep this altsetting */ } - static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip, int iface, int altno) { diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index a8172c119796..1ac3fd9cc5a6 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -76,7 +76,6 @@ enum quirk_type { QUIRK_MIDI_YAMAHA, QUIRK_MIDI_MIDIMAN, QUIRK_MIDI_NOVATION, - QUIRK_MIDI_MBOX2, QUIRK_MIDI_RAW_BYTES, QUIRK_MIDI_EMAGIC, QUIRK_MIDI_CME, |