3535#include <sound/core.h>
3636#include <sound/dmaengine_pcm.h>
3737#include <sound/initval.h>
38+ #include <sound/jack.h>
3839#include <sound/pcm.h>
3940#include <sound/pcm_params.h>
41+ #include <sound/simple_card.h>
4042#include <sound/soc.h>
4143#include <sound/tlv.h>
4244
5355#define ADC_LR_GROUP_MAX 4
5456#define DEBUG_POP_ALWAYS 0
5557#define ENABLE_AGC 0
58+ #define HPDET_POLL_MS 2000
5659
5760enum {
5861 ADC_GRP0_MICIN = 0 ,
@@ -75,6 +78,7 @@ struct rk3308_codec_priv {
7578 struct clk * mclk_tx ;
7679 struct gpio_desc * hp_ctl_gpio ;
7780 struct gpio_desc * spk_ctl_gpio ;
81+ int irq ;
7882 /*
7983 * To select ADCs for groups:
8084 *
@@ -89,6 +93,9 @@ struct rk3308_codec_priv {
8993 /* 0: line out, 1: hp out, 11: lineout and hpout */
9094 int dac_output ;
9195
96+ bool hp_plugged ;
97+ struct delayed_work hpdet_work ;
98+
9299#if defined(CONFIG_DEBUG_FS )
93100 struct dentry * dbg_codec ;
94101#endif
@@ -1201,9 +1208,6 @@ static int rk3308_codec_power_off(struct snd_soc_codec *codec)
12011208
12021209static int rk3308_codec_headset_detect_enable (struct rk3308_codec_priv * rk3308 )
12031210{
1204- /* HACK: headset_detect bypass */
1205- return 0 ;
1206-
12071211 /*
12081212 * Set ACODEC_DAC_ANA_CON0[1] to 0x1, to enable the headset insert
12091213 * detection
@@ -1220,9 +1224,6 @@ static int rk3308_codec_headset_detect_enable(struct rk3308_codec_priv *rk3308)
12201224
12211225static int rk3308_codec_headset_detect_disable (struct rk3308_codec_priv * rk3308 )
12221226{
1223- /* HACK: headset_detect bypass */
1224- return 0 ;
1225-
12261227 /*
12271228 * Set ACODEC_DAC_ANA_CON0[1] to 0x0, to disable the headset insert
12281229 * detection
@@ -1570,7 +1571,6 @@ static int rk3308_codec_adc_ana_enable(struct rk3308_codec_priv *rk3308)
15701571 RK3308_ADC_CH2_MIC_UNMUTE ,
15711572 RK3308_ADC_CH1_MIC_UNMUTE |
15721573 RK3308_ADC_CH2_MIC_UNMUTE );
1573-
15741574 /*
15751575 * 3. Set ACODEC_ADC_ANA_CON6[0] to 0x1, to enable the current source
15761576 * of audio
@@ -2009,8 +2009,56 @@ static bool rk3308_codec_volatile_reg(struct device *dev, unsigned int reg)
20092009 return true;
20102010}
20112011
2012- static irqreturn_t rk3308_codec_headset_isr (int irq , void * dev_id )
2012+ static void rk3308_codec_hpdetect_work (struct work_struct * work )
2013+ {
2014+ struct rk3308_codec_priv * rk3308 =
2015+ container_of (work , struct rk3308_codec_priv , hpdet_work .work );
2016+ unsigned int val ;
2017+ int need_poll = 0 , need_irq = 0 ;
2018+ int need_report = 0 , report_type = 0 ;
2019+
2020+ regmap_read (rk3308 -> regmap , RK3308_DAC_DIG_CON14 , & val );
2021+ if (!val ) {
2022+ rk3308 -> hp_plugged = false;
2023+
2024+ report_type = 0 ;
2025+ need_report = 1 ;
2026+ need_irq = 1 ;
2027+ } else {
2028+ if (!rk3308 -> hp_plugged ) {
2029+ rk3308 -> hp_plugged = true;
2030+ report_type = SND_JACK_HEADPHONE ;
2031+ need_report = 1 ;
2032+ }
2033+ need_poll = 1 ;
2034+ }
2035+
2036+ if (need_poll )
2037+ queue_delayed_work (system_power_efficient_wq ,
2038+ & rk3308 -> hpdet_work ,
2039+ msecs_to_jiffies (HPDET_POLL_MS ));
2040+
2041+ if (need_report )
2042+ snd_soc_jack_report (asoc_simple_card_get_hp_jack (),
2043+ report_type ,
2044+ SND_JACK_HEADPHONE );
2045+
2046+ if (need_irq )
2047+ enable_irq (rk3308 -> irq );
2048+ }
2049+
2050+ static irqreturn_t rk3308_codec_hpdet_isr (int irq , void * data )
20132051{
2052+ struct rk3308_codec_priv * rk3308 = data ;
2053+
2054+ /*
2055+ * For the high level irq trigger, disable irq and avoid a lot of
2056+ * repeated irq handlers entry.
2057+ */
2058+ disable_irq_nosync (rk3308 -> irq );
2059+ queue_delayed_work (system_power_efficient_wq ,
2060+ & rk3308 -> hpdet_work , msecs_to_jiffies (10 ));
2061+
20142062 return IRQ_HANDLED ;
20152063}
20162064
@@ -2306,7 +2354,6 @@ static int rk3308_platform_probe(struct platform_device *pdev)
23062354 struct resource * res ;
23072355 struct regmap * grf ;
23082356 void __iomem * base ;
2309- int irq ;
23102357 int ret ;
23112358
23122359 grf = syscon_regmap_lookup_by_phandle (np , "rockchip,grf" );
@@ -2430,14 +2477,19 @@ static int rk3308_platform_probe(struct platform_device *pdev)
24302477 goto failed ;
24312478 }
24322479
2433- irq = platform_get_irq (pdev , 0 );
2434- if (irq < 0 ) {
2480+ rk3308 -> irq = platform_get_irq (pdev , 0 );
2481+ if (rk3308 -> irq < 0 ) {
24352482 dev_err (& pdev -> dev , "Can not get codec irq\n" );
24362483 goto failed ;
24372484 }
24382485
2439- ret = devm_request_irq (& pdev -> dev , irq , rk3308_codec_headset_isr ,
2440- 0 , "headset-irq" , rk3308 );
2486+ INIT_DELAYED_WORK (& rk3308 -> hpdet_work , rk3308_codec_hpdetect_work );
2487+
2488+ ret = devm_request_irq (& pdev -> dev , rk3308 -> irq ,
2489+ rk3308_codec_hpdet_isr ,
2490+ 0 ,
2491+ "acodec-hpdet" ,
2492+ rk3308 );
24412493 if (ret < 0 ) {
24422494 dev_err (& pdev -> dev , "Failed to request IRQ: %d\n" , ret );
24432495 goto failed ;
0 commit comments