aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8994.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-06 13:50:39 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-06 14:06:19 -0500
commit87092e3ca4ff7b2c2d7723b3402fe2f74b249bc4 (patch)
treedf6e8a54dc9dd10dd5869735dd0095a41fba5ade /sound/soc/codecs/wm8994.c
parent27060b3c64a1b9bc0b60c27da6153cf78919fa72 (diff)
ASoC: wm8994: Bring WM8994 accessory detection up to date
Make the mechanism used for WM8994 more like that for WM1811 and WM8958: provide the logic to distinguish between headphone and headset and hard code the reporting of sensible SND_JACK values. Should integration with other detection mechanisms be required we can add appropriate callbacks (though some integrations should be able to use the subsystem ones). Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r--sound/soc/codecs/wm8994.c82
1 files changed, 61 insertions, 21 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 6a47c75119bd..8aed0e3c6131 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2946,8 +2946,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2946 * @codec: WM8994 codec 2946 * @codec: WM8994 codec
2947 * @jack: jack to report detection events on 2947 * @jack: jack to report detection events on
2948 * @micbias: microphone bias to detect on 2948 * @micbias: microphone bias to detect on
2949 * @det: value to report for presence detection
2950 * @shrt: value to report for short detection
2951 * 2949 *
2952 * Enable microphone detection via IRQ on the WM8994. If GPIOs are 2950 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
2953 * being used to bring out signals to the processor then only platform 2951 * being used to bring out signals to the processor then only platform
@@ -2958,43 +2956,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2958 * and micbias2_lvl platform data members. 2956 * and micbias2_lvl platform data members.
2959 */ 2957 */
2960int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 2958int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2961 int micbias, int det, int shrt) 2959 int micbias)
2962{ 2960{
2963 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2961 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2964 struct wm8994_micdet *micdet; 2962 struct wm8994_micdet *micdet;
2965 struct wm8994 *control = wm8994->wm8994; 2963 struct wm8994 *control = wm8994->wm8994;
2966 int reg; 2964 int reg, ret;
2967 2965
2968 if (control->type != WM8994) 2966 if (control->type != WM8994) {
2967 dev_warn(codec->dev, "Not a WM8994\n");
2969 return -EINVAL; 2968 return -EINVAL;
2969 }
2970 2970
2971 switch (micbias) { 2971 switch (micbias) {
2972 case 1: 2972 case 1:
2973 micdet = &wm8994->micdet[0]; 2973 micdet = &wm8994->micdet[0];
2974 if (jack)
2975 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
2976 "MICBIAS1");
2977 else
2978 ret = snd_soc_dapm_disable_pin(&codec->dapm,
2979 "MICBIAS1");
2974 break; 2980 break;
2975 case 2: 2981 case 2:
2976 micdet = &wm8994->micdet[1]; 2982 micdet = &wm8994->micdet[1];
2983 if (jack)
2984 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
2985 "MICBIAS1");
2986 else
2987 ret = snd_soc_dapm_disable_pin(&codec->dapm,
2988 "MICBIAS1");
2977 break; 2989 break;
2978 default: 2990 default:
2991 dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
2979 return -EINVAL; 2992 return -EINVAL;
2980 } 2993 }
2981 2994
2982 dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", 2995 if (ret != 0)
2983 micbias, det, shrt); 2996 dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
2997 micbias, ret);
2998
2999 dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
3000 micbias, jack);
2984 3001
2985 /* Store the configuration */ 3002 /* Store the configuration */
2986 micdet->jack = jack; 3003 micdet->jack = jack;
2987 micdet->det = det; 3004 micdet->detecting = true;
2988 micdet->shrt = shrt;
2989 3005
2990 /* If either of the jacks is set up then enable detection */ 3006 /* If either of the jacks is set up then enable detection */
2991 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) 3007 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2992 reg = WM8994_MICD_ENA; 3008 reg = WM8994_MICD_ENA;
2993 else 3009 else
2994 reg = 0; 3010 reg = 0;
2995 3011
2996 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); 3012 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
2997 3013
3014 snd_soc_dapm_sync(&codec->dapm);
3015
2998 return 0; 3016 return 0;
2999} 3017}
3000EXPORT_SYMBOL_GPL(wm8994_mic_detect); 3018EXPORT_SYMBOL_GPL(wm8994_mic_detect);
@@ -3020,20 +3038,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3020 dev_dbg(codec->dev, "Microphone status: %x\n", reg); 3038 dev_dbg(codec->dev, "Microphone status: %x\n", reg);
3021 3039
3022 report = 0; 3040 report = 0;
3023 if (reg & WM8994_MIC1_DET_STS) 3041 if (reg & WM8994_MIC1_DET_STS) {
3024 report |= priv->micdet[0].det; 3042 if (priv->micdet[0].detecting)
3025 if (reg & WM8994_MIC1_SHRT_STS) 3043 report = SND_JACK_HEADSET;
3026 report |= priv->micdet[0].shrt; 3044 }
3045 if (reg & WM8994_MIC1_SHRT_STS) {
3046 if (priv->micdet[0].detecting)
3047 report = SND_JACK_HEADPHONE;
3048 else
3049 report |= SND_JACK_BTN_0;
3050 }
3051 if (report)
3052 priv->micdet[0].detecting = false;
3053 else
3054 priv->micdet[0].detecting = true;
3055
3027 snd_soc_jack_report(priv->micdet[0].jack, report, 3056 snd_soc_jack_report(priv->micdet[0].jack, report,
3028 priv->micdet[0].det | priv->micdet[0].shrt); 3057 SND_JACK_HEADSET | SND_JACK_BTN_0);
3029 3058
3030 report = 0; 3059 report = 0;
3031 if (reg & WM8994_MIC2_DET_STS) 3060 if (reg & WM8994_MIC2_DET_STS) {
3032 report |= priv->micdet[1].det; 3061 if (priv->micdet[1].detecting)
3033 if (reg & WM8994_MIC2_SHRT_STS) 3062 report = SND_JACK_HEADSET;
3034 report |= priv->micdet[1].shrt; 3063 }
3064 if (reg & WM8994_MIC2_SHRT_STS) {
3065 if (priv->micdet[1].detecting)
3066 report = SND_JACK_HEADPHONE;
3067 else
3068 report |= SND_JACK_BTN_0;
3069 }
3070 if (report)
3071 priv->micdet[1].detecting = false;
3072 else
3073 priv->micdet[1].detecting = true;
3074
3035 snd_soc_jack_report(priv->micdet[1].jack, report, 3075 snd_soc_jack_report(priv->micdet[1].jack, report,
3036 priv->micdet[1].det | priv->micdet[1].shrt); 3076 SND_JACK_HEADSET | SND_JACK_BTN_0);
3037 3077
3038 return IRQ_HANDLED; 3078 return IRQ_HANDLED;
3039} 3079}