asoc: codecs: Add Headset detect support for ALC5639/40
Manoj Gangwal [Tue, 28 Feb 2012 13:21:55 +0000 (18:21 +0530)]
Add support for headset detection for ALC5639/40
codec for kai board.

Bug 937914

Change-Id: I0bb9e913601c37a1cc8f7094fbdd3885aeec92b3
Signed-off-by: Manoj Gangwal <mgangwal@nvidia.com>
Reviewed-on: http://git-master/r/86348
Reviewed-by: Chandler Zhang <chazhang@nvidia.com>
Tested-by: Chandler Zhang <chazhang@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>

sound/soc/codecs/rt5639.c
sound/soc/codecs/rt5639.h
sound/soc/codecs/rt5640.c
sound/soc/codecs/rt5640.h

index e51c1f0..74d8a31 100644 (file)
@@ -418,6 +418,41 @@ static int rt5639_readable_register(
        }
 }
 
+int rt5639_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+{
+       int jack_type;
+
+       if (jack_insert) {
+               snd_soc_update_bits(codec, RT5639_PWR_ANLG1,
+                       RT5639_PWR_LDO2, RT5639_PWR_LDO2);
+               snd_soc_update_bits(codec, RT5639_PWR_ANLG2,
+                       RT5639_PWR_MB1, RT5639_PWR_MB1);
+               snd_soc_update_bits(codec, RT5639_MICBIAS,
+                       RT5639_MIC1_OVCD_MASK | RT5639_MIC1_OVTH_MASK |
+                       RT5639_PWR_CLK25M_MASK | RT5639_PWR_MB_MASK,
+                       RT5639_MIC1_OVCD_EN | RT5639_MIC1_OVTH_600UA |
+                       RT5639_PWR_MB_PU | RT5639_PWR_CLK25M_PU);
+               snd_soc_update_bits(codec, RT5639_DUMMY1,
+                       0x1, 0x1);
+               msleep(50);
+               if (snd_soc_read(codec, RT5639_IRQ_CTRL2) & 0x8)
+                       jack_type = RT5639_HEADPHO_DET;
+               else
+                       jack_type = RT5639_HEADSET_DET;
+               snd_soc_update_bits(codec, RT5639_IRQ_CTRL2,
+                       RT5639_MB1_OC_CLR, 0);
+       } else {
+               snd_soc_update_bits(codec, RT5639_MICBIAS,
+                       RT5639_MIC1_OVCD_MASK,
+                       RT5639_MIC1_OVCD_DIS);
+
+               jack_type = RT5639_NO_JACK;
+       }
+
+       return jack_type;
+}
+EXPORT_SYMBOL(rt5639_headset_detect);
+
 static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
 static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
index 163db7a..f75ddad 100644 (file)
@@ -2025,6 +2025,12 @@ enum {
 /* Debug String Length */
 #define RT5639_REG_DISP_LEN 10
 
+#define RT5639_NO_JACK         BIT(0)
+#define RT5639_HEADSET_DET     BIT(1)
+#define RT5639_HEADPHO_DET     BIT(2)
+
+int rt5639_headset_detect(struct snd_soc_codec *codec, int jack_insert);
+
 /* System Clock Source */
 enum {
        RT5639_SCLK_S_MCLK,
index fdfa6b5..dfeb1dc 100644 (file)
@@ -419,6 +419,41 @@ static int rt5640_readable_register(
        }
 }
 
+int rt5640_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+{
+       int jack_type;
+
+       if (jack_insert) {
+               snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+                       RT5640_PWR_LDO2, RT5640_PWR_LDO2);
+               snd_soc_update_bits(codec, RT5640_PWR_ANLG2,
+                       RT5640_PWR_MB1, RT5640_PWR_MB1);
+               snd_soc_update_bits(codec, RT5640_MICBIAS,
+                       RT5640_MIC1_OVCD_MASK | RT5640_MIC1_OVTH_MASK |
+                       RT5640_PWR_CLK25M_MASK | RT5640_PWR_MB_MASK,
+                       RT5640_MIC1_OVCD_EN | RT5640_MIC1_OVTH_600UA |
+                       RT5640_PWR_MB_PU | RT5640_PWR_CLK25M_PU);
+               snd_soc_update_bits(codec, RT5640_DUMMY1,
+                       0x1, 0x1);
+               msleep(50);
+               if (snd_soc_read(codec, RT5640_IRQ_CTRL2) & 0x8)
+                       jack_type = RT5640_HEADPHO_DET;
+               else
+                       jack_type = RT5640_HEADSET_DET;
+               snd_soc_update_bits(codec, RT5640_IRQ_CTRL2,
+                       RT5640_MB1_OC_CLR, 0);
+       } else {
+               snd_soc_update_bits(codec, RT5640_MICBIAS,
+                       RT5640_MIC1_OVCD_MASK,
+                       RT5640_MIC1_OVCD_DIS);
+
+               jack_type = RT5640_NO_JACK;
+       }
+
+       return jack_type;
+}
+EXPORT_SYMBOL(rt5640_headset_detect);
+
 static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
 static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
index ba9ac7f..d6920f0 100644 (file)
@@ -2019,7 +2019,11 @@ enum {
 #define RT5640_EQ_PST_VOL_MASK         (0xffff)
 #define RT5640_EQ_PST_VOL_SFT                  0
 
+#define RT5640_NO_JACK         BIT(0)
+#define RT5640_HEADSET_DET     BIT(1)
+#define RT5640_HEADPHO_DET     BIT(2)
 
+int rt5640_headset_detect(struct snd_soc_codec *codec, int jack_insert);
 
 /* System Clock Source */
 #define RT5640_SCLK_S_MCLK 0