diff options
Diffstat (limited to 'sound')
32 files changed, 391 insertions, 80 deletions
diff --git a/sound/core/jack.c b/sound/core/jack.c index 4902ae568730..53b53e97c896 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -141,6 +141,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, fail_input: input_free_device(jack->input_dev); + kfree(jack->id); kfree(jack); return err; } diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 23f49f356e0f..16c0bdfbb164 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -1252,11 +1252,19 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) { static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) { stream_t *dma = &vortex->dma_adb[adbdma]; - int temp; + int temp, page, delta; temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)); - temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1)); - return temp; + page = (temp & ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT; + if (dma->nr_periods >= 4) + delta = (page - dma->period_real) & 3; + else { + delta = (page - dma->period_real); + if (delta < 0) + delta += dma->nr_periods; + } + return (dma->period_virt + delta) * dma->period_bytes + + (temp & (dma->period_bytes - 1)); } static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 0baffcdee8f9..fcedad9a5fef 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2308,6 +2308,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB), SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index a07b031090d8..067982f4f182 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -1039,9 +1039,11 @@ static struct hda_verb cs_errata_init_verbs[] = { {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, {0x11, AC_VERB_SET_PROC_STATE, 0x00}, +#if 0 /* Don't to set to D3 as we are in power-up sequence */ {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ +#endif {} /* terminator */ }; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index fbe97d32140d..4d5004e693f0 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3114,6 +3114,8 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS), SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS), @@ -3410,7 +3412,7 @@ static void cx_auto_parse_output(struct hda_codec *codec) } } spec->multiout.dac_nids = spec->private_dac_nids; - spec->multiout.max_channels = nums * 2; + spec->multiout.max_channels = spec->multiout.num_dacs * 2; if (cfg->hp_outs > 0) spec->auto_mute = 1; @@ -3729,9 +3731,9 @@ static int cx_auto_init(struct hda_codec *codec) return 0; } -static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, +static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, const char *dir, int cidx, - hda_nid_t nid, int hda_dir) + hda_nid_t nid, int hda_dir, int amp_idx) { static char name[32]; static struct snd_kcontrol_new knew[] = { @@ -3743,7 +3745,8 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, for (i = 0; i < 2; i++) { struct snd_kcontrol *kctl; - knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, hda_dir); + knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx, + hda_dir); knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; knew[i].index = cidx; snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); @@ -3759,6 +3762,9 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, return 0; } +#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \ + cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0) + #define cx_auto_add_pb_volume(codec, nid, str, idx) \ cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) @@ -3808,29 +3814,60 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; static const char *prev_label; - int i, err, cidx; + int i, err, cidx, conn_len; + hda_nid_t conn[HDA_MAX_CONNECTIONS]; + + int multi_adc_volume = 0; /* If the ADC nid has several input volumes */ + int adc_nid = spec->adc_nids[0]; + + conn_len = snd_hda_get_connections(codec, adc_nid, conn, + HDA_MAX_CONNECTIONS); + if (conn_len < 0) + return conn_len; + + multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1; + if (!multi_adc_volume) { + err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid, + HDA_INPUT); + if (err < 0) + return err; + } - err = cx_auto_add_volume(codec, "Capture", "", 0, spec->adc_nids[0], - HDA_INPUT); - if (err < 0) - return err; prev_label = NULL; cidx = 0; for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; const char *label; - if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) + int j; + int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP; + if (!pin_amp && !multi_adc_volume) continue; + label = hda_get_autocfg_input_label(codec, cfg, i); if (label == prev_label) cidx++; else cidx = 0; prev_label = label; - err = cx_auto_add_volume(codec, label, " Capture", cidx, - nid, HDA_INPUT); - if (err < 0) - return err; + + if (pin_amp) { + err = cx_auto_add_volume(codec, label, " Boost", cidx, + nid, HDA_INPUT); + if (err < 0) + return err; + } + + if (!multi_adc_volume) + continue; + for (j = 0; j < conn_len; j++) { + if (conn[j] == nid) { + err = cx_auto_add_volume_idx(codec, label, + " Capture", cidx, adc_nid, HDA_INPUT, j); + if (err < 0) + return err; + break; + } + } } return 0; } @@ -3902,6 +3939,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { .patch = patch_cxt5066 }, { .id = 0x14f15069, .name = "CX20585", .patch = patch_cxt5066 }, + { .id = 0x14f1506e, .name = "CX20590", + .patch = patch_cxt5066 }, { .id = 0x14f15097, .name = "CX20631", .patch = patch_conexant_auto }, { .id = 0x14f15098, .name = "CX20632", @@ -3928,6 +3967,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15066"); MODULE_ALIAS("snd-hda-codec-id:14f15067"); MODULE_ALIAS("snd-hda-codec-id:14f15068"); MODULE_ALIAS("snd-hda-codec-id:14f15069"); +MODULE_ALIAS("snd-hda-codec-id:14f1506e"); MODULE_ALIAS("snd-hda-codec-id:14f15097"); MODULE_ALIAS("snd-hda-codec-id:14f15098"); MODULE_ALIAS("snd-hda-codec-id:14f150a1"); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index a58767736727..ec0fa2dd0a27 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1634,6 +1634,9 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +/* 17 is known to be absent */ { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, @@ -1676,6 +1679,8 @@ MODULE_ALIAS("snd-hda-codec-id:10de0011"); MODULE_ALIAS("snd-hda-codec-id:10de0012"); MODULE_ALIAS("snd-hda-codec-id:10de0013"); MODULE_ALIAS("snd-hda-codec-id:10de0014"); +MODULE_ALIAS("snd-hda-codec-id:10de0015"); +MODULE_ALIAS("snd-hda-codec-id:10de0016"); MODULE_ALIAS("snd-hda-codec-id:10de0018"); MODULE_ALIAS("snd-hda-codec-id:10de0019"); MODULE_ALIAS("snd-hda-codec-id:10de001a"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3328a259a242..4261bb8eec1d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1133,11 +1133,8 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl) nid = spec->autocfg.hp_pins[i]; if (!nid) break; - if (snd_hda_jack_detect(codec, nid)) { - spec->jack_present = 1; - break; - } - alc_report_jack(codec, spec->autocfg.hp_pins[i]); + alc_report_jack(codec, nid); + spec->jack_present |= snd_hda_jack_detect(codec, nid); } mute = spec->jack_present ? HDA_AMP_MUTE : 0; @@ -15015,7 +15012,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), - SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), + SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9ea48b425d0b..bd7b123f6440 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -586,7 +586,12 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = { 0x0f, 0x10, 0x11, 0x1f, 0x20, }; -static hda_nid_t stac92hd88xxx_pin_nids[10] = { +static hda_nid_t stac92hd87xxx_pin_nids[6] = { + 0x0a, 0x0b, 0x0c, 0x0d, + 0x0f, 0x11, +}; + +static hda_nid_t stac92hd88xxx_pin_nids[8] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0f, 0x11, 0x1f, 0x20, }; @@ -5430,12 +5435,13 @@ again: switch (codec->vendor_id) { case 0x111d76d1: case 0x111d76d9: + case 0x111d76e5: spec->dmic_nids = stac92hd87b_dmic_nids; spec->num_dmics = stac92xx_connected_ports(codec, stac92hd87b_dmic_nids, STAC92HD87B_NUM_DMICS); - spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); - spec->pin_nids = stac92hd88xxx_pin_nids; + spec->num_pins = ARRAY_SIZE(stac92hd87xxx_pin_nids); + spec->pin_nids = stac92hd87xxx_pin_nids; spec->mono_nid = 0; spec->num_pwrs = 0; break; @@ -5443,6 +5449,7 @@ again: case 0x111d7667: case 0x111d7668: case 0x111d7669: + case 0x111d76e3: spec->num_dmics = stac92xx_connected_ports(codec, stac92hd88xxx_dmic_nids, STAC92HD88XXX_NUM_DMICS); @@ -6387,6 +6394,8 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, {} /* terminator */ }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index a76c3260d941..63b0054200a8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -567,7 +567,7 @@ static void via_auto_init_analog_input(struct hda_codec *codec) hda_nid_t nid = cfg->inputs[i].pin; if (spec->smart51_enabled && is_smart51_pins(spec, nid)) ctl = PIN_OUT; - else if (i == AUTO_PIN_MIC) + else if (cfg->inputs[i].type == AUTO_PIN_MIC) ctl = PIN_VREF50; else ctl = PIN_IN; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index bb4bf65b9e7e..0bb424af956f 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -367,7 +367,7 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) return 0; } -static const u8 cx20442_reg = CX20442_TELOUT | CX20442_MIC; +static const u8 cx20442_reg; static struct snd_soc_codec_driver cx20442_codec_dev = { .probe = cx20442_codec_probe, diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 987476a5895f..017d99ceb42e 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1482,7 +1482,7 @@ int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, irq_mask); - if (det && shrt) { + if (det || shrt) { /* Enable mic detection, this may not have been set through * platform data (eg, if the defaults are OK). */ snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h index e8490f3edd03..e3ec2433b215 100644 --- a/sound/soc/codecs/wm8903.h +++ b/sound/soc/codecs/wm8903.h @@ -165,7 +165,7 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec, #define WM8903_VMID_RES_50K 2 #define WM8903_VMID_RES_250K 3 -#define WM8903_VMID_RES_5K 4 +#define WM8903_VMID_RES_5K 6 /* * R8 (0x08) - Analogue DAC 0 diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 4bbc3442703f..8dfb0a0da673 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -145,18 +145,18 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = { SOC_SINGLE("DAC Playback Limiter Threshold", WM8978_DAC_LIMITER_2, 4, 7, 0), SOC_SINGLE("DAC Playback Limiter Boost", - WM8978_DAC_LIMITER_2, 0, 15, 0), + WM8978_DAC_LIMITER_2, 0, 12, 0), SOC_ENUM("ALC Enable Switch", alc1), SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0), SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0), - SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0), + SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 10, 0), SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0), SOC_ENUM("ALC Capture Mode", alc3), - SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0), - SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0), + SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 10, 0), + SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 10, 0), SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0), SOC_SINGLE("ALC Capture Noise Gate Threshold", @@ -211,8 +211,10 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = { WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1), /* DAC / ADC oversampling */ - SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0), - SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0), + SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, + 5, 1, 0), + SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, + 5, 1, 0), }; /* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 37b8aa8a680f..c6c958ee5d59 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -107,6 +107,12 @@ struct wm8994_priv { int revision; struct wm8994_pdata *pdata; + + unsigned int aif1clk_enable:1; + unsigned int aif2clk_enable:1; + + unsigned int aif1clk_disable:1; + unsigned int aif2clk_disable:1; }; static int wm8994_readable(unsigned int reg) @@ -1004,6 +1010,110 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) } } +static int late_enable_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (wm8994->aif1clk_enable) { + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA_MASK, + WM8994_AIF1CLK_ENA); + wm8994->aif1clk_enable = 0; + } + if (wm8994->aif2clk_enable) { + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA_MASK, + WM8994_AIF2CLK_ENA); + wm8994->aif2clk_enable = 0; + } + break; + } + + return 0; +} + +static int late_disable_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMD: + if (wm8994->aif1clk_disable) { + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA_MASK, 0); + wm8994->aif1clk_disable = 0; + } + if (wm8994->aif2clk_disable) { + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA_MASK, 0); + wm8994->aif2clk_disable = 0; + } + break; + } + + return 0; +} + +static int aif1clk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wm8994->aif1clk_enable = 1; + break; + case SND_SOC_DAPM_POST_PMD: + wm8994->aif1clk_disable = 1; + break; + } + + return 0; +} + +static int aif2clk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wm8994->aif2clk_enable = 1; + break; + case SND_SOC_DAPM_POST_PMD: + wm8994->aif2clk_disable = 1; + break; + } + + return 0; +} + +static int adc_mux_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + late_enable_ev(w, kcontrol, event); + return 0; +} + +static int dac_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + unsigned int mask = 1 << w->shift; + + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, + mask, mask); + return 0; +} + static const char *hp_mux_text[] = { "Mixer", "DAC", @@ -1272,6 +1382,59 @@ static const struct soc_enum aif2dacr_src_enum = static const struct snd_kcontrol_new aif2dacr_src_mux = SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); +static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = { +SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + +SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + late_enable_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_PGA_E("Late DAC1R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + late_enable_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + late_enable_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + late_enable_ev, SND_SOC_DAPM_PRE_PMU), + +SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) +}; + +static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { +SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0) +}; + +static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { +SND_SOC_DAPM_DAC_E("DAC2L", NULL, SND_SOC_NOPM, 3, 0, + dac_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_DAC_E("DAC2R", NULL, SND_SOC_NOPM, 2, 0, + dac_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_DAC_E("DAC1L", NULL, SND_SOC_NOPM, 1, 0, + dac_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_DAC_E("DAC1R", NULL, SND_SOC_NOPM, 0, 0, + dac_ev, SND_SOC_DAPM_PRE_PMU), +}; + +static const struct snd_soc_dapm_widget wm8994_dac_widgets[] = { +SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0), +SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0), +SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0), +SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), +}; + +static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { +SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +}; + +static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { +SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), +}; + static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { SND_SOC_DAPM_INPUT("DMIC1DAT"), SND_SOC_DAPM_INPUT("DMIC2DAT"), @@ -1284,9 +1447,6 @@ SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), - SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, 0, WM8994_POWER_MANAGEMENT_4, 9, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, @@ -1369,14 +1529,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0), SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), -SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), - -SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0), -SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0), -SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0), -SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), - SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), @@ -1516,14 +1668,12 @@ static const struct snd_soc_dapm_route intercon[] = { { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, /* DAC1 inputs */ - { "DAC1L", NULL, "DAC1L Mixer" }, { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, - { "DAC1R", NULL, "DAC1R Mixer" }, { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, @@ -1532,7 +1682,6 @@ static const struct snd_soc_dapm_route intercon[] = { /* DAC2/AIF2 outputs */ { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, - { "DAC2L", NULL, "AIF2DAC2L Mixer" }, { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, @@ -1540,7 +1689,6 @@ static const struct snd_soc_dapm_route intercon[] = { { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, - { "DAC2R", NULL, "AIF2DAC2R Mixer" }, { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, @@ -1584,6 +1732,24 @@ static const struct snd_soc_dapm_route intercon[] = { { "Right Headphone Mux", "DAC", "DAC1R" }, }; +static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = { + { "DAC1L", NULL, "Late DAC1L Enable PGA" }, + { "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" }, + { "DAC1R", NULL, "Late DAC1R Enable PGA" }, + { "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" }, + { "DAC2L", NULL, "Late DAC2L Enable PGA" }, + { "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" }, + { "DAC2R", NULL, "Late DAC2R Enable PGA" }, + { "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" } +}; + +static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = { + { "DAC1L", NULL, "DAC1L Mixer" }, + { "DAC1R", NULL, "DAC1R Mixer" }, + { "DAC2L", NULL, "AIF2DAC2L Mixer" }, + { "DAC2R", NULL, "AIF2DAC2R Mixer" }, +}; + static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { { "AIF1DACDAT", NULL, "AIF2DACDAT" }, { "AIF2DACDAT", NULL, "AIF1DACDAT" }, @@ -2514,6 +2680,22 @@ static int wm8994_resume(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int i, ret; + unsigned int val, mask; + + if (wm8994->revision < 4) { + /* force a HW read */ + val = wm8994_reg_read(codec->control_data, + WM8994_POWER_MANAGEMENT_5); + + /* modify the cache only */ + codec->cache_only = 1; + mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA | + WM8994_DAC2R_ENA | WM8994_DAC2L_ENA; + val &= mask; + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, + mask, val); + codec->cache_only = 0; + } /* Restore the registers */ ret = snd_soc_cache_sync(codec); @@ -2847,11 +3029,10 @@ static void wm8958_default_micdet(u16 status, void *data) report |= SND_JACK_BTN_5; done: - snd_soc_jack_report(wm8994->micdet[0].jack, + snd_soc_jack_report(wm8994->micdet[0].jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 | - SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT, - report); + SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT); } /** @@ -3125,10 +3306,31 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) case WM8994: snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, ARRAY_SIZE(wm8994_specific_dapm_widgets)); + if (wm8994->revision < 4) { + snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, + ARRAY_SIZE(wm8994_lateclk_revd_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, + ARRAY_SIZE(wm8994_adc_revd_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets, + ARRAY_SIZE(wm8994_dac_revd_widgets)); + } else { + snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, + ARRAY_SIZE(wm8994_lateclk_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, + ARRAY_SIZE(wm8994_adc_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, + ARRAY_SIZE(wm8994_dac_widgets)); + } break; case WM8958: snd_soc_add_controls(codec, wm8958_snd_controls, ARRAY_SIZE(wm8958_snd_controls)); + snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, + ARRAY_SIZE(wm8994_lateclk_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, + ARRAY_SIZE(wm8994_adc_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, + ARRAY_SIZE(wm8994_dac_widgets)); snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, ARRAY_SIZE(wm8958_dapm_widgets)); break; @@ -3143,12 +3345,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(dapm, wm8994_intercon, ARRAY_SIZE(wm8994_intercon)); - if (wm8994->revision < 4) + if (wm8994->revision < 4) { snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, ARRAY_SIZE(wm8994_revd_intercon)); - + snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, + ARRAY_SIZE(wm8994_lateclk_revd_intercon)); + } else { + snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, + ARRAY_SIZE(wm8994_lateclk_intercon)); + } break; case WM8958: + snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, + ARRAY_SIZE(wm8994_lateclk_intercon)); snd_soc_dapm_add_routes(dapm, wm8958_intercon, ARRAY_SIZE(wm8958_intercon)); break; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 43825b2102a5..cce704c275c6 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -15,6 +15,7 @@ #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/device.h> #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> @@ -1341,6 +1342,10 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, wm9081->control_type = SND_SOC_I2C; wm9081->control_data = i2c; + if (dev_get_platdata(&i2c->dev)) + memcpy(&wm9081->retune, dev_get_platdata(&i2c->dev), + sizeof(wm9081->retune)); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9081, &wm9081_dai, 1); if (ret < 0) diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 613df5db0b32..516892706063 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -674,6 +674,9 @@ SND_SOC_DAPM_OUTPUT("LINEOUT2N"), }; static const struct snd_soc_dapm_route analogue_routes[] = { + { "MICBIAS1", NULL, "CLK_SYS" }, + { "MICBIAS2", NULL, "CLK_SYS" }, + { "IN1L PGA", "IN1LP Switch", "IN1LP" }, { "IN1L PGA", "IN1LN Switch", "IN1LN" }, diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index e20c9e1457c0..1e9bccae4e80 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c @@ -79,7 +79,7 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = { .name = "tlv320aic23", .stream_name = "TLV320AIC23", .codec_dai_name = "tlv320aic23-hifi", - .platform_name = "imx-pcm-audio.0", + .platform_name = "imx-fiq-pcm-audio.0", .codec_name = "tlv320aic23-codec.0-001a", .cpu_dai_name = "imx-ssi.0", .ops = &eukrea_tlv320_snd_ops, diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 161750443ebc..73dde4a1adc3 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -139,7 +139,7 @@ static struct snd_soc_dai_link am3517evm_dai = { .cpu_dai_name ="omap-mcbsp-dai.0", .codec_dai_name = "tlv320aic23-hifi", .platform_name = "omap-pcm-audio", - .codec_name = "tlv320aic23-codec", + .codec_name = "tlv320aic23-codec.2-001a", .init = am3517evm_aic23_init, .ops = &am3517evm_ops, }; diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index 28333e7d9c50..dc65650a6fa1 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -117,7 +117,7 @@ static struct snd_soc_dai_link e740_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9705-hifi", .platform_name = "pxa-pcm-audio", .codec_name = "wm9705-codec", @@ -126,7 +126,7 @@ static struct snd_soc_dai_link e740_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name = "wm9705-aux", .platform_name = "pxa-pcm-audio", .codec_name = "wm9705-codec", diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 01bf31675c55..51897fcd911b 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -99,7 +99,7 @@ static struct snd_soc_dai_link e750_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9705-hifi", .platform_name = "pxa-pcm-audio", .codec_name = "wm9705-codec", @@ -109,7 +109,7 @@ static struct snd_soc_dai_link e750_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name ="wm9705-aux", .platform_name = "pxa-pcm-audio", .codec_name = "wm9705-codec", diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index c6a37c6ef23b..053ed208e59f 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -89,7 +89,7 @@ static struct snd_soc_dai_link e800_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9712-hifi", .platform_name = "pxa-pcm-audio", .codec_name = "wm9712-codec", @@ -98,7 +98,7 @@ static struct snd_soc_dai_link e800_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name ="wm9712-aux", .platform_name = "pxa-pcm-audio", .codec_name = "wm9712-codec", diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index fc22e6eefc98..b13a4252812d 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -37,7 +37,7 @@ static struct snd_soc_dai_link em_x270_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9712-hifi", .platform_name = "pxa-pcm-audio", .codec_name = "wm9712-codec", @@ -45,7 +45,7 @@ static struct snd_soc_dai_link em_x270_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name ="wm9712-aux", .platform_name = "pxa-pcm-audio", .codec_name = "wm9712-codec", diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 0d70fc8c12bd..38ca6759907e 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -162,7 +162,7 @@ static struct snd_soc_dai_link mioa701_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9713-hifi", .codec_name = "wm9713-codec", .init = mioa701_wm9713_init, @@ -172,7 +172,7 @@ static struct snd_soc_dai_link mioa701_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name ="wm9713-aux", .codec_name = "wm9713-codec", .platform_name = "pxa-pcm-audio", diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 857db96d4a4f..504e4004f004 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -132,7 +132,7 @@ static struct snd_soc_dai_link palm27x_dai[] = { { .name = "AC97 HiFi", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9712-hifi", .codec_name = "wm9712-codec", .platform_name = "pxa-pcm-audio", @@ -141,7 +141,7 @@ static struct snd_soc_dai_link palm27x_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name = "wm9712-aux", .codec_name = "wm9712-codec", .platform_name = "pxa-pcm-audio", diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index f75804ef0897..4b6e5d608b42 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -219,7 +219,7 @@ static struct snd_soc_dai_link tosa_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_dai_name = "wm9712-hifi", .platform_name = "pxa-pcm-audio", .codec_name = "wm9712-codec", @@ -229,7 +229,7 @@ static struct snd_soc_dai_link tosa_dai[] = { { .name = "AC97 Aux", .stream_name = "AC97 Aux", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_dai_name = "wm9712-aux", .platform_name = "pxa-pcm-audio", .codec_name = "wm9712-codec", diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index b222a7d72027..25bba108fea3 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c @@ -166,7 +166,7 @@ static struct snd_soc_dai_link zylonite_dai[] = { .stream_name = "AC97 HiFi", .codec_name = "wm9713-codec", .platform_name = "pxa-pcm-audio", - .cpu_dai_name = "pxa-ac97.0", + .cpu_dai_name = "pxa2xx-ac97", .codec_name = "wm9713-hifi", .init = zylonite_wm9713_init, }, @@ -175,7 +175,7 @@ static struct snd_soc_dai_link zylonite_dai[] = { .stream_name = "AC97 Aux", .codec_name = "wm9713-codec", .platform_name = "pxa-pcm-audio", - .cpu_dai_name = "pxa-ac97.1", + .cpu_dai_name = "pxa2xx-ac97-aux", .codec_name = "wm9713-aux", }, { diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8194f150bab7..1790f83ee665 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -712,7 +712,15 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) !path->connected(path->source, path->sink)) continue; - if (path->sink && path->sink->power_check && + if (!path->sink) + continue; + + if (path->sink->force) { + power = 1; + break; + } + + if (path->sink->power_check && path->sink->power_check(path->sink)) { power = 1; break; @@ -933,7 +941,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, } if (!list_empty(&pending)) - dapm_seq_run_coalesced(dapm, &pending); + dapm_seq_run_coalesced(cur_dapm, &pending); } static void dapm_widget_update(struct snd_soc_dapm_context *dapm) @@ -1627,6 +1635,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; + unsigned int val; list_for_each_entry(w, &dapm->card->widgets, list) { @@ -1675,6 +1684,18 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) case snd_soc_dapm_post: break; } + + /* Read the initial power state from the device */ + if (w->reg >= 0) { + val = snd_soc_read(w->codec, w->reg); + val &= 1 << w->shift; + if (w->invert) + val = !val; + + if (val) + w->power = 1; + } + w->new = 1; } diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 68b97477577b..66eabafb1c24 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -785,7 +785,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) } dev->pcm->private_data = dev; - strcpy(dev->pcm->name, dev->product_name); + strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name)); memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c index 2f218c77fff2..a1a47088fd0c 100644 --- a/sound/usb/caiaq/midi.c +++ b/sound/usb/caiaq/midi.c @@ -136,7 +136,7 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) if (ret < 0) return ret; - strcpy(rmidi->name, device->product_name); + strlcpy(rmidi->name, device->product_name, sizeof(rmidi->name)); rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; rmidi->private_data = device; diff --git a/sound/usb/card.c b/sound/usb/card.c index 800f7cb4f251..c0f8270bc199 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -323,6 +323,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, return -ENOMEM; } + mutex_init(&chip->shutdown_mutex); chip->index = idx; chip->dev = dev; chip->card = card; @@ -531,6 +532,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) chip = ptr; card = chip->card; mutex_lock(®ister_mutex); + mutex_lock(&chip->shutdown_mutex); chip->shutdown = 1; chip->num_interfaces--; if (chip->num_interfaces <= 0) { @@ -548,9 +550,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; + mutex_unlock(&chip->shutdown_mutex); mutex_unlock(®ister_mutex); snd_card_free_when_closed(card); } else { + mutex_unlock(&chip->shutdown_mutex); mutex_unlock(®ister_mutex); } } diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 4132522ac90f..e3f680526cb5 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -361,6 +361,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, } if (changed) { + mutex_lock(&subs->stream->chip->shutdown_mutex); /* format changed */ snd_usb_release_substream_urbs(subs, 0); /* influenced: period_bytes, channels, rate, format, */ @@ -368,6 +369,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, params_rate(hw_params), snd_pcm_format_physical_width(params_format(hw_params)) * params_channels(hw_params)); + mutex_unlock(&subs->stream->chip->shutdown_mutex); } return ret; @@ -385,8 +387,9 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) subs->cur_audiofmt = NULL; subs->cur_rate = 0; subs->period_bytes = 0; - if (!subs->stream->chip->shutdown) - snd_usb_release_substream_urbs(subs, 0); + mutex_lock(&subs->stream->chip->shutdown_mutex); + snd_usb_release_substream_urbs(subs, 0); + mutex_unlock(&subs->stream->chip->shutdown_mutex); return snd_pcm_lib_free_vmalloc_buffer(substream); } diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index db3eb21627ee..6e66fffe87f5 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -36,6 +36,7 @@ struct snd_usb_audio { struct snd_card *card; u32 usb_id; int shutdown; + struct mutex shutdown_mutex; unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ int num_interfaces; int num_suspended_intf; |