aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8962.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8962.c')
-rw-r--r--sound/soc/codecs/wm8962.c222
1 files changed, 202 insertions, 20 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index d2c315fa1b9..f60dfa16545 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -63,6 +63,8 @@ struct wm8962_priv {
63 int fll_fref; 63 int fll_fref;
64 int fll_fout; 64 int fll_fout;
65 65
66 u16 dsp2_ena;
67
66 struct delayed_work mic_work; 68 struct delayed_work mic_work;
67 struct snd_soc_jack *jack; 69 struct snd_soc_jack *jack;
68 70
@@ -837,7 +839,7 @@ static const struct wm8962_reg_access {
837 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ 839 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */
838 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ 840 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */
839 841
840 [47] = { 0x000F, 0x0000, 0x0000 }, /* R47 - Thermal Shutdown Status */ 842 [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */
841 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ 843 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */
842 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ 844 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */
843 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ 845 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */
@@ -965,7 +967,7 @@ static const struct wm8962_reg_access {
965 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ 967 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */
966 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ 968 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */
967 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ 969 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */
968 [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037 - DSP2_ExecControl */ 970 [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */
969 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ 971 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */
970 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ 972 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */
971 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ 973 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */
@@ -1986,6 +1988,122 @@ static const unsigned int classd_tlv[] = {
1986}; 1988};
1987static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 1989static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1988 1990
1991static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
1992{
1993 return 0;
1994}
1995
1996static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
1997{
1998 u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
1999 u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
2000 u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
2001
2002 /* Mute the ADCs and DACs */
2003 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
2004 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
2005 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2006 WM8962_DAC_MUTE, WM8962_DAC_MUTE);
2007
2008 snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
2009
2010 /* Restore the ADCs and DACs */
2011 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
2012 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
2013 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2014 WM8962_DAC_MUTE, dac);
2015
2016 return 0;
2017}
2018
2019static int wm8962_dsp2_start(struct snd_soc_codec *codec)
2020{
2021 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2022
2023 wm8962_dsp2_write_config(codec);
2024
2025 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
2026
2027 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2028
2029 return 0;
2030}
2031
2032static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
2033{
2034 wm8962_dsp2_set_enable(codec, 0);
2035
2036 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
2037
2038 return 0;
2039}
2040
2041#define WM8962_DSP2_ENABLE(xname, xshift) \
2042{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2043 .info = wm8962_dsp2_ena_info, \
2044 .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \
2045 .private_value = xshift }
2046
2047static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol,
2048 struct snd_ctl_elem_info *uinfo)
2049{
2050 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2051
2052 uinfo->count = 1;
2053 uinfo->value.integer.min = 0;
2054 uinfo->value.integer.max = 1;
2055
2056 return 0;
2057}
2058
2059static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
2062 int shift = kcontrol->private_value;
2063 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2064 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2065
2066 ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
2067
2068 return 0;
2069}
2070
2071static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
2072 struct snd_ctl_elem_value *ucontrol)
2073{
2074 int shift = kcontrol->private_value;
2075 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2077 int old = wm8962->dsp2_ena;
2078 int ret = 0;
2079 int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
2080 WM8962_DSP2_ENA;
2081
2082 mutex_lock(&codec->mutex);
2083
2084 if (ucontrol->value.integer.value[0])
2085 wm8962->dsp2_ena |= 1 << shift;
2086 else
2087 wm8962->dsp2_ena &= ~(1 << shift);
2088
2089 if (wm8962->dsp2_ena == old)
2090 goto out;
2091
2092 ret = 1;
2093
2094 if (dsp2_running) {
2095 if (wm8962->dsp2_ena)
2096 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2097 else
2098 wm8962_dsp2_stop(codec);
2099 }
2100
2101out:
2102 mutex_unlock(&codec->mutex);
2103
2104 return ret;
2105}
2106
1989/* The VU bits for the headphones are in a different register to the mute 2107/* The VU bits for the headphones are in a different register to the mute
1990 * bits and only take effect on the PGA if it is actually powered. 2108 * bits and only take effect on the PGA if it is actually powered.
1991 */ 2109 */
@@ -2021,7 +2139,6 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2021 struct snd_ctl_elem_value *ucontrol) 2139 struct snd_ctl_elem_value *ucontrol)
2022{ 2140{
2023 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2141 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2024 u16 *reg_cache = codec->reg_cache;
2025 int ret; 2142 int ret;
2026 2143
2027 /* Apply the update (if any) */ 2144 /* Apply the update (if any) */
@@ -2030,16 +2147,19 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2030 return 0; 2147 return 0;
2031 2148
2032 /* If the left PGA is enabled hit that VU bit... */ 2149 /* If the left PGA is enabled hit that VU bit... */
2033 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTL_PGA_ENA) 2150 ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
2034 return snd_soc_write(codec, WM8962_SPKOUTL_VOLUME, 2151 if (ret & WM8962_SPKOUTL_PGA_ENA) {
2035 reg_cache[WM8962_SPKOUTL_VOLUME]); 2152 snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
2153 snd_soc_read(codec, WM8962_SPKOUTL_VOLUME));
2154 return 1;
2155 }
2036 2156
2037 /* ...otherwise the right. The VU is stereo. */ 2157 /* ...otherwise the right. The VU is stereo. */
2038 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTR_PGA_ENA) 2158 if (ret & WM8962_SPKOUTR_PGA_ENA)
2039 return snd_soc_write(codec, WM8962_SPKOUTR_VOLUME, 2159 snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
2040 reg_cache[WM8962_SPKOUTR_VOLUME]); 2160 snd_soc_read(codec, WM8962_SPKOUTR_VOLUME));
2041 2161
2042 return 0; 2162 return 1;
2043} 2163}
2044 2164
2045static const char *cap_hpf_mode_text[] = { 2165static const char *cap_hpf_mode_text[] = {
@@ -2049,6 +2169,14 @@ static const char *cap_hpf_mode_text[] = {
2049static const struct soc_enum cap_hpf_mode = 2169static const struct soc_enum cap_hpf_mode =
2050 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); 2170 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2051 2171
2172
2173static const char *cap_lhpf_mode_text[] = {
2174 "LPF", "HPF"
2175};
2176
2177static const struct soc_enum cap_lhpf_mode =
2178 SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text);
2179
2052static const struct snd_kcontrol_new wm8962_snd_controls[] = { 2180static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2053SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), 2181SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2054 2182
@@ -2077,6 +2205,8 @@ SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2077SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1), 2205SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2078SOC_ENUM("Capture HPF Mode", cap_hpf_mode), 2206SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2079SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0), 2207SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2208SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0),
2209SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
2080 2210
2081SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, 2211SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2082 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), 2212 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2134,6 +2264,11 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
2134 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv), 2264 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
2135SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, 2265SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
2136 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), 2266 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
2267
2268WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
2269WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
2270WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
2271WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
2137}; 2272};
2138 2273
2139static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 2274static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2365,7 +2500,6 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2365 struct snd_kcontrol *kcontrol, int event) 2500 struct snd_kcontrol *kcontrol, int event)
2366{ 2501{
2367 struct snd_soc_codec *codec = w->codec; 2502 struct snd_soc_codec *codec = w->codec;
2368 u16 *reg_cache = codec->reg_cache;
2369 int reg; 2503 int reg;
2370 2504
2371 switch (w->shift) { 2505 switch (w->shift) {
@@ -2388,11 +2522,36 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2388 2522
2389 switch (event) { 2523 switch (event) {
2390 case SND_SOC_DAPM_POST_PMU: 2524 case SND_SOC_DAPM_POST_PMU:
2391 return snd_soc_write(codec, reg, reg_cache[reg]); 2525 return snd_soc_write(codec, reg, snd_soc_read(codec, reg));
2526 default:
2527 BUG();
2528 return -EINVAL;
2529 }
2530}
2531
2532static int dsp2_event(struct snd_soc_dapm_widget *w,
2533 struct snd_kcontrol *kcontrol, int event)
2534{
2535 struct snd_soc_codec *codec = w->codec;
2536 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2537
2538 switch (event) {
2539 case SND_SOC_DAPM_POST_PMU:
2540 if (wm8962->dsp2_ena)
2541 wm8962_dsp2_start(codec);
2542 break;
2543
2544 case SND_SOC_DAPM_PRE_PMD:
2545 if (wm8962->dsp2_ena)
2546 wm8962_dsp2_stop(codec);
2547 break;
2548
2392 default: 2549 default:
2393 BUG(); 2550 BUG();
2394 return -EINVAL; 2551 return -EINVAL;
2395 } 2552 }
2553
2554 return 0;
2396} 2555}
2397 2556
2398static const char *st_text[] = { "None", "Right", "Left" }; 2557static const char *st_text[] = { "None", "Right", "Left" };
@@ -2509,7 +2668,7 @@ SND_SOC_DAPM_INPUT("IN4R"),
2509SND_SOC_DAPM_INPUT("Beep"), 2668SND_SOC_DAPM_INPUT("Beep"),
2510SND_SOC_DAPM_INPUT("DMICDAT"), 2669SND_SOC_DAPM_INPUT("DMICDAT"),
2511 2670
2512SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0), 2671SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
2513 2672
2514SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), 2673SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2515SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, 2674SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
@@ -2517,6 +2676,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
2517SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2676SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2518 SND_SOC_DAPM_POST_PMU), 2677 SND_SOC_DAPM_POST_PMU),
2519SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2678SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
2679SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
2680 WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
2681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2520 2682
2521SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, 2683SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
2522 inpgal, ARRAY_SIZE(inpgal)), 2684 inpgal, ARRAY_SIZE(inpgal)),
@@ -2527,7 +2689,7 @@ SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
2527SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, 2689SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
2528 mixinr, ARRAY_SIZE(mixinr)), 2690 mixinr, ARRAY_SIZE(mixinr)),
2529 2691
2530SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0), 2692SND_SOC_DAPM_AIF_IN("DMIC_ENA", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
2531 2693
2532SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), 2694SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
2533SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), 2695SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
@@ -2606,17 +2768,19 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2606 2768
2607 { "MICBIAS", NULL, "SYSCLK" }, 2769 { "MICBIAS", NULL, "SYSCLK" },
2608 2770
2609 { "DMIC", NULL, "DMICDAT" }, 2771 { "DMIC_ENA", NULL, "DMICDAT" },
2610 2772
2611 { "ADCL", NULL, "SYSCLK" }, 2773 { "ADCL", NULL, "SYSCLK" },
2612 { "ADCL", NULL, "TOCLK" }, 2774 { "ADCL", NULL, "TOCLK" },
2613 { "ADCL", NULL, "MIXINL" }, 2775 { "ADCL", NULL, "MIXINL" },
2614 { "ADCL", NULL, "DMIC" }, 2776 { "ADCL", NULL, "DMIC_ENA" },
2777 { "ADCL", NULL, "DSP2" },
2615 2778
2616 { "ADCR", NULL, "SYSCLK" }, 2779 { "ADCR", NULL, "SYSCLK" },
2617 { "ADCR", NULL, "TOCLK" }, 2780 { "ADCR", NULL, "TOCLK" },
2618 { "ADCR", NULL, "MIXINR" }, 2781 { "ADCR", NULL, "MIXINR" },
2619 { "ADCR", NULL, "DMIC" }, 2782 { "ADCR", NULL, "DMIC_ENA" },
2783 { "ADCR", NULL, "DSP2" },
2620 2784
2621 { "STL", "Left", "ADCL" }, 2785 { "STL", "Left", "ADCL" },
2622 { "STL", "Right", "ADCR" }, 2786 { "STL", "Right", "ADCR" },
@@ -2628,11 +2792,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2628 { "DACL", NULL, "TOCLK" }, 2792 { "DACL", NULL, "TOCLK" },
2629 { "DACL", NULL, "Beep" }, 2793 { "DACL", NULL, "Beep" },
2630 { "DACL", NULL, "STL" }, 2794 { "DACL", NULL, "STL" },
2795 { "DACL", NULL, "DSP2" },
2631 2796
2632 { "DACR", NULL, "SYSCLK" }, 2797 { "DACR", NULL, "SYSCLK" },
2633 { "DACR", NULL, "TOCLK" }, 2798 { "DACR", NULL, "TOCLK" },
2634 { "DACR", NULL, "Beep" }, 2799 { "DACR", NULL, "Beep" },
2635 { "DACR", NULL, "STR" }, 2800 { "DACR", NULL, "STR" },
2801 { "DACR", NULL, "DSP2" },
2636 2802
2637 { "HPMIXL", "IN4L Switch", "IN4L" }, 2803 { "HPMIXL", "IN4L Switch", "IN4L" },
2638 { "HPMIXL", "IN4R Switch", "IN4R" }, 2804 { "HPMIXL", "IN4R Switch", "IN4R" },
@@ -3058,9 +3224,9 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3058 int aif0 = 0; 3224 int aif0 = 0;
3059 3225
3060 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 3226 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3061 case SND_SOC_DAIFMT_DSP_A:
3062 aif0 |= WM8962_LRCLK_INV;
3063 case SND_SOC_DAIFMT_DSP_B: 3227 case SND_SOC_DAIFMT_DSP_B:
3228 aif0 |= WM8962_LRCLK_INV | 3;
3229 case SND_SOC_DAIFMT_DSP_A:
3064 aif0 |= 3; 3230 aif0 |= 3;
3065 3231
3066 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 3232 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -3403,12 +3569,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3403 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3569 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3404 int mask; 3570 int mask;
3405 int active; 3571 int active;
3572 int reg;
3406 3573
3407 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); 3574 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
3408 3575
3409 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); 3576 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3410 active &= ~mask; 3577 active &= ~mask;
3411 3578
3579 if (!active)
3580 return IRQ_NONE;
3581
3412 /* Acknowledge the interrupts */ 3582 /* Acknowledge the interrupts */
3413 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); 3583 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
3414 3584
@@ -3420,9 +3590,21 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3420 if (active & WM8962_FIFOS_ERR_EINT) 3590 if (active & WM8962_FIFOS_ERR_EINT)
3421 dev_err(codec->dev, "FIFO error\n"); 3591 dev_err(codec->dev, "FIFO error\n");
3422 3592
3423 if (active & WM8962_TEMP_SHUT_EINT) 3593 if (active & WM8962_TEMP_SHUT_EINT) {
3424 dev_crit(codec->dev, "Thermal shutdown\n"); 3594 dev_crit(codec->dev, "Thermal shutdown\n");
3425 3595
3596 reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS);
3597
3598 if (reg & WM8962_TEMP_ERR_HP)
3599 dev_crit(codec->dev, "Headphone thermal error\n");
3600 if (reg & WM8962_TEMP_WARN_HP)
3601 dev_crit(codec->dev, "Headphone thermal warning\n");
3602 if (reg & WM8962_TEMP_ERR_SPK)
3603 dev_crit(codec->dev, "Speaker thermal error\n");
3604 if (reg & WM8962_TEMP_WARN_SPK)
3605 dev_crit(codec->dev, "Speaker thermal warning\n");
3606 }
3607
3426 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3608 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3427 dev_dbg(codec->dev, "Microphone event detected\n"); 3609 dev_dbg(codec->dev, "Microphone event detected\n");
3428 3610