diff options
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 264 |
1 files changed, 235 insertions, 29 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9da0724cd47a..e84a1177f350 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -62,6 +62,12 @@ static int wm8994_retune_mobile_base[] = { | |||
62 | 62 | ||
63 | #define WM8994_REG_CACHE_SIZE 0x621 | 63 | #define WM8994_REG_CACHE_SIZE 0x621 |
64 | 64 | ||
65 | struct wm8994_micdet { | ||
66 | struct snd_soc_jack *jack; | ||
67 | int det; | ||
68 | int shrt; | ||
69 | }; | ||
70 | |||
65 | /* codec private data */ | 71 | /* codec private data */ |
66 | struct wm8994_priv { | 72 | struct wm8994_priv { |
67 | struct wm_hubs_data hubs; | 73 | struct wm_hubs_data hubs; |
@@ -87,6 +93,8 @@ struct wm8994_priv { | |||
87 | int retune_mobile_cfg[WM8994_NUM_EQ]; | 93 | int retune_mobile_cfg[WM8994_NUM_EQ]; |
88 | struct soc_enum retune_mobile_enum; | 94 | struct soc_enum retune_mobile_enum; |
89 | 95 | ||
96 | struct wm8994_micdet micdet[2]; | ||
97 | |||
90 | struct wm8994_pdata *pdata; | 98 | struct wm8994_pdata *pdata; |
91 | }; | 99 | }; |
92 | 100 | ||
@@ -1696,13 +1704,15 @@ static int wm8994_volatile(unsigned int reg) | |||
1696 | static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, | 1704 | static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, |
1697 | unsigned int value) | 1705 | unsigned int value) |
1698 | { | 1706 | { |
1699 | struct wm8994_priv *wm8994 = codec->private_data; | 1707 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1700 | 1708 | ||
1701 | BUG_ON(reg > WM8994_MAX_REGISTER); | 1709 | BUG_ON(reg > WM8994_MAX_REGISTER); |
1702 | 1710 | ||
1703 | if (!wm8994_volatile(reg)) | 1711 | if (!wm8994_volatile(reg)) |
1704 | wm8994->reg_cache[reg] = value; | 1712 | wm8994->reg_cache[reg] = value; |
1705 | 1713 | ||
1714 | dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); | ||
1715 | |||
1706 | return wm8994_reg_write(codec->control_data, reg, value); | 1716 | return wm8994_reg_write(codec->control_data, reg, value); |
1707 | } | 1717 | } |
1708 | 1718 | ||
@@ -1721,7 +1731,7 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec, | |||
1721 | 1731 | ||
1722 | static int configure_aif_clock(struct snd_soc_codec *codec, int aif) | 1732 | static int configure_aif_clock(struct snd_soc_codec *codec, int aif) |
1723 | { | 1733 | { |
1724 | struct wm8994_priv *wm8994 = codec->private_data; | 1734 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1725 | int rate; | 1735 | int rate; |
1726 | int reg1 = 0; | 1736 | int reg1 = 0; |
1727 | int offset; | 1737 | int offset; |
@@ -1762,6 +1772,11 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif) | |||
1762 | dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n", | 1772 | dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n", |
1763 | aif + 1, rate); | 1773 | aif + 1, rate); |
1764 | } | 1774 | } |
1775 | |||
1776 | if (rate && rate < 3000000) | ||
1777 | dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n", | ||
1778 | aif + 1, rate); | ||
1779 | |||
1765 | wm8994->aifclk[aif] = rate; | 1780 | wm8994->aifclk[aif] = rate; |
1766 | 1781 | ||
1767 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, | 1782 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, |
@@ -1773,7 +1788,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif) | |||
1773 | 1788 | ||
1774 | static int configure_clock(struct snd_soc_codec *codec) | 1789 | static int configure_clock(struct snd_soc_codec *codec) |
1775 | { | 1790 | { |
1776 | struct wm8994_priv *wm8994 = codec->private_data; | 1791 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1777 | int old, new; | 1792 | int old, new; |
1778 | 1793 | ||
1779 | /* Bring up the AIF clocks first */ | 1794 | /* Bring up the AIF clocks first */ |
@@ -1870,7 +1885,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, | |||
1870 | 1885 | ||
1871 | static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) | 1886 | static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) |
1872 | { | 1887 | { |
1873 | struct wm8994_priv *wm8994 = codec->private_data; | 1888 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1874 | struct wm8994_pdata *pdata = wm8994->pdata; | 1889 | struct wm8994_pdata *pdata = wm8994->pdata; |
1875 | int base = wm8994_drc_base[drc]; | 1890 | int base = wm8994_drc_base[drc]; |
1876 | int cfg = wm8994->drc_cfg[drc]; | 1891 | int cfg = wm8994->drc_cfg[drc]; |
@@ -1906,7 +1921,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, | |||
1906 | struct snd_ctl_elem_value *ucontrol) | 1921 | struct snd_ctl_elem_value *ucontrol) |
1907 | { | 1922 | { |
1908 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1923 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1909 | struct wm8994_priv *wm8994 = codec->private_data; | 1924 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1910 | struct wm8994_pdata *pdata = wm8994->pdata; | 1925 | struct wm8994_pdata *pdata = wm8994->pdata; |
1911 | int drc = wm8994_get_drc(kcontrol->id.name); | 1926 | int drc = wm8994_get_drc(kcontrol->id.name); |
1912 | int value = ucontrol->value.integer.value[0]; | 1927 | int value = ucontrol->value.integer.value[0]; |
@@ -1928,7 +1943,7 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, | |||
1928 | struct snd_ctl_elem_value *ucontrol) | 1943 | struct snd_ctl_elem_value *ucontrol) |
1929 | { | 1944 | { |
1930 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1945 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1931 | struct wm8994_priv *wm8994 = codec->private_data; | 1946 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1932 | int drc = wm8994_get_drc(kcontrol->id.name); | 1947 | int drc = wm8994_get_drc(kcontrol->id.name); |
1933 | 1948 | ||
1934 | ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc]; | 1949 | ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc]; |
@@ -1938,7 +1953,7 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, | |||
1938 | 1953 | ||
1939 | static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) | 1954 | static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) |
1940 | { | 1955 | { |
1941 | struct wm8994_priv *wm8994 = codec->private_data; | 1956 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1942 | struct wm8994_pdata *pdata = wm8994->pdata; | 1957 | struct wm8994_pdata *pdata = wm8994->pdata; |
1943 | int base = wm8994_retune_mobile_base[block]; | 1958 | int base = wm8994_retune_mobile_base[block]; |
1944 | int iface, best, best_val, save, i, cfg; | 1959 | int iface, best, best_val, save, i, cfg; |
@@ -2009,7 +2024,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
2009 | struct snd_ctl_elem_value *ucontrol) | 2024 | struct snd_ctl_elem_value *ucontrol) |
2010 | { | 2025 | { |
2011 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2026 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2012 | struct wm8994_priv *wm8994 = codec->private_data; | 2027 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2013 | struct wm8994_pdata *pdata = wm8994->pdata; | 2028 | struct wm8994_pdata *pdata = wm8994->pdata; |
2014 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); | 2029 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); |
2015 | int value = ucontrol->value.integer.value[0]; | 2030 | int value = ucontrol->value.integer.value[0]; |
@@ -2031,7 +2046,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
2031 | struct snd_ctl_elem_value *ucontrol) | 2046 | struct snd_ctl_elem_value *ucontrol) |
2032 | { | 2047 | { |
2033 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2048 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2034 | struct wm8994_priv *wm8994 = codec->private_data; | 2049 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2035 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); | 2050 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); |
2036 | 2051 | ||
2037 | ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; | 2052 | ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; |
@@ -2182,13 +2197,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) | |||
2182 | /* Only support direct DAC->headphone paths */ | 2197 | /* Only support direct DAC->headphone paths */ |
2183 | reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1); | 2198 | reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1); |
2184 | if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) { | 2199 | if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) { |
2185 | dev_dbg(codec->dev, "HPL connected to output mixer\n"); | 2200 | dev_vdbg(codec->dev, "HPL connected to output mixer\n"); |
2186 | enable = 0; | 2201 | enable = 0; |
2187 | } | 2202 | } |
2188 | 2203 | ||
2189 | reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2); | 2204 | reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2); |
2190 | if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) { | 2205 | if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) { |
2191 | dev_dbg(codec->dev, "HPR connected to output mixer\n"); | 2206 | dev_vdbg(codec->dev, "HPR connected to output mixer\n"); |
2192 | enable = 0; | 2207 | enable = 0; |
2193 | } | 2208 | } |
2194 | 2209 | ||
@@ -2196,26 +2211,26 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) | |||
2196 | reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); | 2211 | reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); |
2197 | switch (reg) { | 2212 | switch (reg) { |
2198 | case WM8994_AIF2DACL_TO_DAC1L: | 2213 | case WM8994_AIF2DACL_TO_DAC1L: |
2199 | dev_dbg(codec->dev, "Class W source AIF2DAC\n"); | 2214 | dev_vdbg(codec->dev, "Class W source AIF2DAC\n"); |
2200 | source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT; | 2215 | source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT; |
2201 | break; | 2216 | break; |
2202 | case WM8994_AIF1DAC2L_TO_DAC1L: | 2217 | case WM8994_AIF1DAC2L_TO_DAC1L: |
2203 | dev_dbg(codec->dev, "Class W source AIF1DAC2\n"); | 2218 | dev_vdbg(codec->dev, "Class W source AIF1DAC2\n"); |
2204 | source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT; | 2219 | source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT; |
2205 | break; | 2220 | break; |
2206 | case WM8994_AIF1DAC1L_TO_DAC1L: | 2221 | case WM8994_AIF1DAC1L_TO_DAC1L: |
2207 | dev_dbg(codec->dev, "Class W source AIF1DAC1\n"); | 2222 | dev_vdbg(codec->dev, "Class W source AIF1DAC1\n"); |
2208 | source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT; | 2223 | source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT; |
2209 | break; | 2224 | break; |
2210 | default: | 2225 | default: |
2211 | dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg); | 2226 | dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg); |
2212 | enable = 0; | 2227 | enable = 0; |
2213 | break; | 2228 | break; |
2214 | } | 2229 | } |
2215 | 2230 | ||
2216 | reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); | 2231 | reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); |
2217 | if (reg_r != reg) { | 2232 | if (reg_r != reg) { |
2218 | dev_dbg(codec->dev, "Left and right DAC mixers different\n"); | 2233 | dev_vdbg(codec->dev, "Left and right DAC mixers different\n"); |
2219 | enable = 0; | 2234 | enable = 0; |
2220 | } | 2235 | } |
2221 | 2236 | ||
@@ -2777,9 +2792,18 @@ static int wm8994_get_fll_config(struct fll_div *fll, | |||
2777 | 2792 | ||
2778 | if (freq_in > 1000000) { | 2793 | if (freq_in > 1000000) { |
2779 | fll->fll_fratio = 0; | 2794 | fll->fll_fratio = 0; |
2780 | } else { | 2795 | } else if (freq_in > 256000) { |
2796 | fll->fll_fratio = 1; | ||
2797 | freq_in *= 2; | ||
2798 | } else if (freq_in > 128000) { | ||
2799 | fll->fll_fratio = 2; | ||
2800 | freq_in *= 4; | ||
2801 | } else if (freq_in > 64000) { | ||
2781 | fll->fll_fratio = 3; | 2802 | fll->fll_fratio = 3; |
2782 | freq_in *= 8; | 2803 | freq_in *= 8; |
2804 | } else { | ||
2805 | fll->fll_fratio = 4; | ||
2806 | freq_in *= 16; | ||
2783 | } | 2807 | } |
2784 | pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); | 2808 | pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); |
2785 | 2809 | ||
@@ -2812,7 +2836,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, | |||
2812 | unsigned int freq_in, unsigned int freq_out) | 2836 | unsigned int freq_in, unsigned int freq_out) |
2813 | { | 2837 | { |
2814 | struct snd_soc_codec *codec = dai->codec; | 2838 | struct snd_soc_codec *codec = dai->codec; |
2815 | struct wm8994_priv *wm8994 = codec->private_data; | 2839 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2816 | int reg_offset, ret; | 2840 | int reg_offset, ret; |
2817 | struct fll_div fll; | 2841 | struct fll_div fll; |
2818 | u16 reg, aif1, aif2; | 2842 | u16 reg, aif1, aif2; |
@@ -2836,6 +2860,21 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, | |||
2836 | return -EINVAL; | 2860 | return -EINVAL; |
2837 | } | 2861 | } |
2838 | 2862 | ||
2863 | switch (src) { | ||
2864 | case 0: | ||
2865 | /* Allow no source specification when stopping */ | ||
2866 | if (freq_out) | ||
2867 | return -EINVAL; | ||
2868 | break; | ||
2869 | case WM8994_FLL_SRC_MCLK1: | ||
2870 | case WM8994_FLL_SRC_MCLK2: | ||
2871 | case WM8994_FLL_SRC_LRCLK: | ||
2872 | case WM8994_FLL_SRC_BCLK: | ||
2873 | break; | ||
2874 | default: | ||
2875 | return -EINVAL; | ||
2876 | } | ||
2877 | |||
2839 | /* Are we changing anything? */ | 2878 | /* Are we changing anything? */ |
2840 | if (wm8994->fll[id].src == src && | 2879 | if (wm8994->fll[id].src == src && |
2841 | wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out) | 2880 | wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out) |
@@ -2876,8 +2915,10 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, | |||
2876 | fll.n << WM8994_FLL1_N_SHIFT); | 2915 | fll.n << WM8994_FLL1_N_SHIFT); |
2877 | 2916 | ||
2878 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, | 2917 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, |
2879 | WM8994_FLL1_REFCLK_DIV_MASK, | 2918 | WM8994_FLL1_REFCLK_DIV_MASK | |
2880 | fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT); | 2919 | WM8994_FLL1_REFCLK_SRC_MASK, |
2920 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | | ||
2921 | (src - 1)); | ||
2881 | 2922 | ||
2882 | /* Enable (with fractional mode if required) */ | 2923 | /* Enable (with fractional mode if required) */ |
2883 | if (freq_out) { | 2924 | if (freq_out) { |
@@ -2892,6 +2933,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, | |||
2892 | 2933 | ||
2893 | wm8994->fll[id].in = freq_in; | 2934 | wm8994->fll[id].in = freq_in; |
2894 | wm8994->fll[id].out = freq_out; | 2935 | wm8994->fll[id].out = freq_out; |
2936 | wm8994->fll[id].src = src; | ||
2895 | 2937 | ||
2896 | /* Enable any gated AIF clocks */ | 2938 | /* Enable any gated AIF clocks */ |
2897 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | 2939 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, |
@@ -2908,7 +2950,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2908 | int clk_id, unsigned int freq, int dir) | 2950 | int clk_id, unsigned int freq, int dir) |
2909 | { | 2951 | { |
2910 | struct snd_soc_codec *codec = dai->codec; | 2952 | struct snd_soc_codec *codec = dai->codec; |
2911 | struct wm8994_priv *wm8994 = codec->private_data; | 2953 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2912 | 2954 | ||
2913 | switch (dai->id) { | 2955 | switch (dai->id) { |
2914 | case 1: | 2956 | case 1: |
@@ -3174,7 +3216,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
3174 | struct snd_soc_dai *dai) | 3216 | struct snd_soc_dai *dai) |
3175 | { | 3217 | { |
3176 | struct snd_soc_codec *codec = dai->codec; | 3218 | struct snd_soc_codec *codec = dai->codec; |
3177 | struct wm8994_priv *wm8994 = codec->private_data; | 3219 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3178 | int aif1_reg; | 3220 | int aif1_reg; |
3179 | int bclk_reg; | 3221 | int bclk_reg; |
3180 | int lrclk_reg; | 3222 | int lrclk_reg; |
@@ -3338,6 +3380,36 @@ static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) | |||
3338 | return 0; | 3380 | return 0; |
3339 | } | 3381 | } |
3340 | 3382 | ||
3383 | static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate) | ||
3384 | { | ||
3385 | struct snd_soc_codec *codec = codec_dai->codec; | ||
3386 | int reg, val, mask; | ||
3387 | |||
3388 | switch (codec_dai->id) { | ||
3389 | case 1: | ||
3390 | reg = WM8994_AIF1_MASTER_SLAVE; | ||
3391 | mask = WM8994_AIF1_TRI; | ||
3392 | break; | ||
3393 | case 2: | ||
3394 | reg = WM8994_AIF2_MASTER_SLAVE; | ||
3395 | mask = WM8994_AIF2_TRI; | ||
3396 | break; | ||
3397 | case 3: | ||
3398 | reg = WM8994_POWER_MANAGEMENT_6; | ||
3399 | mask = WM8994_AIF3_TRI; | ||
3400 | break; | ||
3401 | default: | ||
3402 | return -EINVAL; | ||
3403 | } | ||
3404 | |||
3405 | if (tristate) | ||
3406 | val = mask; | ||
3407 | else | ||
3408 | val = 0; | ||
3409 | |||
3410 | return snd_soc_update_bits(codec, reg, mask, reg); | ||
3411 | } | ||
3412 | |||
3341 | #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 | 3413 | #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 |
3342 | 3414 | ||
3343 | #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 3415 | #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
@@ -3349,6 +3421,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { | |||
3349 | .hw_params = wm8994_hw_params, | 3421 | .hw_params = wm8994_hw_params, |
3350 | .digital_mute = wm8994_aif_mute, | 3422 | .digital_mute = wm8994_aif_mute, |
3351 | .set_pll = wm8994_set_fll, | 3423 | .set_pll = wm8994_set_fll, |
3424 | .set_tristate = wm8994_set_tristate, | ||
3352 | }; | 3425 | }; |
3353 | 3426 | ||
3354 | static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { | 3427 | static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { |
@@ -3357,6 +3430,11 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { | |||
3357 | .hw_params = wm8994_hw_params, | 3430 | .hw_params = wm8994_hw_params, |
3358 | .digital_mute = wm8994_aif_mute, | 3431 | .digital_mute = wm8994_aif_mute, |
3359 | .set_pll = wm8994_set_fll, | 3432 | .set_pll = wm8994_set_fll, |
3433 | .set_tristate = wm8994_set_tristate, | ||
3434 | }; | ||
3435 | |||
3436 | static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { | ||
3437 | .set_tristate = wm8994_set_tristate, | ||
3360 | }; | 3438 | }; |
3361 | 3439 | ||
3362 | struct snd_soc_dai wm8994_dai[] = { | 3440 | struct snd_soc_dai wm8994_dai[] = { |
@@ -3400,6 +3478,7 @@ struct snd_soc_dai wm8994_dai[] = { | |||
3400 | }, | 3478 | }, |
3401 | { | 3479 | { |
3402 | .name = "WM8994 AIF3", | 3480 | .name = "WM8994 AIF3", |
3481 | .id = 3, | ||
3403 | .playback = { | 3482 | .playback = { |
3404 | .stream_name = "AIF3 Playback", | 3483 | .stream_name = "AIF3 Playback", |
3405 | .channels_min = 2, | 3484 | .channels_min = 2, |
@@ -3414,6 +3493,7 @@ struct snd_soc_dai wm8994_dai[] = { | |||
3414 | .rates = WM8994_RATES, | 3493 | .rates = WM8994_RATES, |
3415 | .formats = WM8994_FORMATS, | 3494 | .formats = WM8994_FORMATS, |
3416 | }, | 3495 | }, |
3496 | .ops = &wm8994_aif3_dai_ops, | ||
3417 | } | 3497 | } |
3418 | }; | 3498 | }; |
3419 | EXPORT_SYMBOL_GPL(wm8994_dai); | 3499 | EXPORT_SYMBOL_GPL(wm8994_dai); |
@@ -3423,7 +3503,7 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t state) | |||
3423 | { | 3503 | { |
3424 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 3504 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
3425 | struct snd_soc_codec *codec = socdev->card->codec; | 3505 | struct snd_soc_codec *codec = socdev->card->codec; |
3426 | struct wm8994_priv *wm8994 = codec->private_data; | 3506 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3427 | int i, ret; | 3507 | int i, ret; |
3428 | 3508 | ||
3429 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { | 3509 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { |
@@ -3444,7 +3524,7 @@ static int wm8994_resume(struct platform_device *pdev) | |||
3444 | { | 3524 | { |
3445 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 3525 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
3446 | struct snd_soc_codec *codec = socdev->card->codec; | 3526 | struct snd_soc_codec *codec = socdev->card->codec; |
3447 | struct wm8994_priv *wm8994 = codec->private_data; | 3527 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3448 | u16 *reg_cache = codec->reg_cache; | 3528 | u16 *reg_cache = codec->reg_cache; |
3449 | int i, ret; | 3529 | int i, ret; |
3450 | 3530 | ||
@@ -3469,6 +3549,9 @@ static int wm8994_resume(struct platform_device *pdev) | |||
3469 | wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 3549 | wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
3470 | 3550 | ||
3471 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { | 3551 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { |
3552 | if (!wm8994->fll_suspend[i].out) | ||
3553 | continue; | ||
3554 | |||
3472 | ret = wm8994_set_fll(&codec->dai[0], i + 1, | 3555 | ret = wm8994_set_fll(&codec->dai[0], i + 1, |
3473 | wm8994->fll_suspend[i].src, | 3556 | wm8994->fll_suspend[i].src, |
3474 | wm8994->fll_suspend[i].in, | 3557 | wm8994->fll_suspend[i].in, |
@@ -3639,7 +3722,7 @@ static int wm8994_probe(struct platform_device *pdev) | |||
3639 | return ret; | 3722 | return ret; |
3640 | } | 3723 | } |
3641 | 3724 | ||
3642 | wm8994_handle_pdata(codec->private_data); | 3725 | wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec)); |
3643 | 3726 | ||
3644 | wm_hubs_add_analogue_controls(codec); | 3727 | wm_hubs_add_analogue_controls(codec); |
3645 | snd_soc_add_controls(codec, wm8994_snd_controls, | 3728 | snd_soc_add_controls(codec, wm8994_snd_controls, |
@@ -3670,6 +3753,96 @@ struct snd_soc_codec_device soc_codec_dev_wm8994 = { | |||
3670 | }; | 3753 | }; |
3671 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994); | 3754 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994); |
3672 | 3755 | ||
3756 | /** | ||
3757 | * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ | ||
3758 | * | ||
3759 | * @codec: WM8994 codec | ||
3760 | * @jack: jack to report detection events on | ||
3761 | * @micbias: microphone bias to detect on | ||
3762 | * @det: value to report for presence detection | ||
3763 | * @shrt: value to report for short detection | ||
3764 | * | ||
3765 | * Enable microphone detection via IRQ on the WM8994. If GPIOs are | ||
3766 | * being used to bring out signals to the processor then only platform | ||
3767 | * data configuration is needed for WM8903 and processor GPIOs should | ||
3768 | * be configured using snd_soc_jack_add_gpios() instead. | ||
3769 | * | ||
3770 | * Configuration of detection levels is available via the micbias1_lvl | ||
3771 | * and micbias2_lvl platform data members. | ||
3772 | */ | ||
3773 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | ||
3774 | int micbias, int det, int shrt) | ||
3775 | { | ||
3776 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
3777 | struct wm8994_micdet *micdet; | ||
3778 | int reg; | ||
3779 | |||
3780 | switch (micbias) { | ||
3781 | case 1: | ||
3782 | micdet = &wm8994->micdet[0]; | ||
3783 | break; | ||
3784 | case 2: | ||
3785 | micdet = &wm8994->micdet[1]; | ||
3786 | break; | ||
3787 | default: | ||
3788 | return -EINVAL; | ||
3789 | } | ||
3790 | |||
3791 | dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", | ||
3792 | micbias, det, shrt); | ||
3793 | |||
3794 | /* Store the configuration */ | ||
3795 | micdet->jack = jack; | ||
3796 | micdet->det = det; | ||
3797 | micdet->shrt = shrt; | ||
3798 | |||
3799 | /* If either of the jacks is set up then enable detection */ | ||
3800 | if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) | ||
3801 | reg = WM8994_MICD_ENA; | ||
3802 | else | ||
3803 | reg = 0; | ||
3804 | |||
3805 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); | ||
3806 | |||
3807 | return 0; | ||
3808 | } | ||
3809 | EXPORT_SYMBOL_GPL(wm8994_mic_detect); | ||
3810 | |||
3811 | static irqreturn_t wm8994_mic_irq(int irq, void *data) | ||
3812 | { | ||
3813 | struct wm8994_priv *priv = data; | ||
3814 | struct snd_soc_codec *codec = &priv->codec; | ||
3815 | int reg; | ||
3816 | int report; | ||
3817 | |||
3818 | reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); | ||
3819 | if (reg < 0) { | ||
3820 | dev_err(codec->dev, "Failed to read microphone status: %d\n", | ||
3821 | reg); | ||
3822 | return IRQ_HANDLED; | ||
3823 | } | ||
3824 | |||
3825 | dev_dbg(codec->dev, "Microphone status: %x\n", reg); | ||
3826 | |||
3827 | report = 0; | ||
3828 | if (reg & WM8994_MIC1_DET_STS) | ||
3829 | report |= priv->micdet[0].det; | ||
3830 | if (reg & WM8994_MIC1_SHRT_STS) | ||
3831 | report |= priv->micdet[0].shrt; | ||
3832 | snd_soc_jack_report(priv->micdet[0].jack, report, | ||
3833 | priv->micdet[0].det | priv->micdet[0].shrt); | ||
3834 | |||
3835 | report = 0; | ||
3836 | if (reg & WM8994_MIC2_DET_STS) | ||
3837 | report |= priv->micdet[1].det; | ||
3838 | if (reg & WM8994_MIC2_SHRT_STS) | ||
3839 | report |= priv->micdet[1].shrt; | ||
3840 | snd_soc_jack_report(priv->micdet[1].jack, report, | ||
3841 | priv->micdet[1].det | priv->micdet[1].shrt); | ||
3842 | |||
3843 | return IRQ_HANDLED; | ||
3844 | } | ||
3845 | |||
3673 | static int wm8994_codec_probe(struct platform_device *pdev) | 3846 | static int wm8994_codec_probe(struct platform_device *pdev) |
3674 | { | 3847 | { |
3675 | int ret; | 3848 | int ret; |
@@ -3695,7 +3868,7 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3695 | INIT_LIST_HEAD(&codec->dapm_widgets); | 3868 | INIT_LIST_HEAD(&codec->dapm_widgets); |
3696 | INIT_LIST_HEAD(&codec->dapm_paths); | 3869 | INIT_LIST_HEAD(&codec->dapm_paths); |
3697 | 3870 | ||
3698 | codec->private_data = wm8994; | 3871 | snd_soc_codec_set_drvdata(codec, wm8994); |
3699 | codec->control_data = dev_get_drvdata(pdev->dev.parent); | 3872 | codec->control_data = dev_get_drvdata(pdev->dev.parent); |
3700 | codec->name = "WM8994"; | 3873 | codec->name = "WM8994"; |
3701 | codec->owner = THIS_MODULE; | 3874 | codec->owner = THIS_MODULE; |
@@ -3743,6 +3916,30 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3743 | break; | 3916 | break; |
3744 | } | 3917 | } |
3745 | 3918 | ||
3919 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, | ||
3920 | wm8994_mic_irq, "Mic 1 detect", wm8994); | ||
3921 | if (ret != 0) | ||
3922 | dev_warn(&pdev->dev, | ||
3923 | "Failed to request Mic1 detect IRQ: %d\n", ret); | ||
3924 | |||
3925 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, | ||
3926 | wm8994_mic_irq, "Mic 1 short", wm8994); | ||
3927 | if (ret != 0) | ||
3928 | dev_warn(&pdev->dev, | ||
3929 | "Failed to request Mic1 short IRQ: %d\n", ret); | ||
3930 | |||
3931 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, | ||
3932 | wm8994_mic_irq, "Mic 2 detect", wm8994); | ||
3933 | if (ret != 0) | ||
3934 | dev_warn(&pdev->dev, | ||
3935 | "Failed to request Mic2 detect IRQ: %d\n", ret); | ||
3936 | |||
3937 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, | ||
3938 | wm8994_mic_irq, "Mic 2 short", wm8994); | ||
3939 | if (ret != 0) | ||
3940 | dev_warn(&pdev->dev, | ||
3941 | "Failed to request Mic2 short IRQ: %d\n", ret); | ||
3942 | |||
3746 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be | 3943 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be |
3747 | * configured on init - if a system wants to do this dynamically | 3944 | * configured on init - if a system wants to do this dynamically |
3748 | * at runtime we can deal with that then. | 3945 | * at runtime we can deal with that then. |
@@ -3750,7 +3947,7 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3750 | ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); | 3947 | ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); |
3751 | if (ret < 0) { | 3948 | if (ret < 0) { |
3752 | dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); | 3949 | dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); |
3753 | goto err; | 3950 | goto err_irq; |
3754 | } | 3951 | } |
3755 | if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { | 3952 | if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
3756 | wm8994->lrclk_shared[0] = 1; | 3953 | wm8994->lrclk_shared[0] = 1; |
@@ -3762,7 +3959,7 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3762 | ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); | 3959 | ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); |
3763 | if (ret < 0) { | 3960 | if (ret < 0) { |
3764 | dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); | 3961 | dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); |
3765 | goto err; | 3962 | goto err_irq; |
3766 | } | 3963 | } |
3767 | if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { | 3964 | if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
3768 | wm8994->lrclk_shared[1] = 1; | 3965 | wm8994->lrclk_shared[1] = 1; |
@@ -3812,7 +4009,7 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3812 | ret = snd_soc_register_codec(codec); | 4009 | ret = snd_soc_register_codec(codec); |
3813 | if (ret != 0) { | 4010 | if (ret != 0) { |
3814 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | 4011 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); |
3815 | goto err; | 4012 | goto err_irq; |
3816 | } | 4013 | } |
3817 | 4014 | ||
3818 | ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); | 4015 | ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); |
@@ -3827,6 +4024,11 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3827 | 4024 | ||
3828 | err_codec: | 4025 | err_codec: |
3829 | snd_soc_unregister_codec(codec); | 4026 | snd_soc_unregister_codec(codec); |
4027 | err_irq: | ||
4028 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); | ||
4029 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); | ||
4030 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); | ||
4031 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); | ||
3830 | err: | 4032 | err: |
3831 | kfree(wm8994); | 4033 | kfree(wm8994); |
3832 | return ret; | 4034 | return ret; |
@@ -3840,6 +4042,10 @@ static int __devexit wm8994_codec_remove(struct platform_device *pdev) | |||
3840 | wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); | 4042 | wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); |
3841 | snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); | 4043 | snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); |
3842 | snd_soc_unregister_codec(&wm8994->codec); | 4044 | snd_soc_unregister_codec(&wm8994->codec); |
4045 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); | ||
4046 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); | ||
4047 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); | ||
4048 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); | ||
3843 | kfree(wm8994); | 4049 | kfree(wm8994); |
3844 | wm8994_codec = NULL; | 4050 | wm8994_codec = NULL; |
3845 | 4051 | ||