@@ -195,6 +195,7 @@ static bool rt5640_volatile_register(struct device *dev, unsigned int reg)
195195 case RT5640_PRIV_DATA :
196196 case RT5640_PGM_REG_ARR1 :
197197 case RT5640_PGM_REG_ARR3 :
198+ case RT5640_DUMMY2 :
198199 case RT5640_VENDOR_ID :
199200 case RT5640_VENDOR_ID1 :
200201 case RT5640_VENDOR_ID2 :
@@ -2301,6 +2302,38 @@ static void rt5640_jack_work(struct work_struct *work)
23012302 struct snd_soc_component * component = rt5640 -> component ;
23022303 int status ;
23032304
2305+ if (rt5640 -> jd_src == RT5640_JD_SRC_HDA_HEADER ) {
2306+ int val , jack_type = 0 , hda_mic_plugged , hda_hp_plugged ;
2307+
2308+ /* mic jack */
2309+ val = snd_soc_component_read (component , RT5640_INT_IRQ_ST );
2310+ hda_mic_plugged = !(val & RT5640_JD_STATUS );
2311+ dev_dbg (component -> dev , "mic jack status %d\n" ,
2312+ hda_mic_plugged );
2313+
2314+ snd_soc_component_update_bits (component , RT5640_IRQ_CTRL1 ,
2315+ RT5640_JD_P_MASK , !hda_mic_plugged << RT5640_JD_P_SFT );
2316+
2317+ if (hda_mic_plugged )
2318+ jack_type |= SND_JACK_MICROPHONE ;
2319+
2320+ /* headphone jack */
2321+ val = snd_soc_component_read (component , RT5640_DUMMY2 );
2322+ hda_hp_plugged = !(val & (0x1 << 11 ));
2323+ dev_dbg (component -> dev , "headphone jack status %d\n" ,
2324+ hda_hp_plugged );
2325+
2326+ snd_soc_component_update_bits (component , RT5640_DUMMY2 ,
2327+ (0x1 << 10 ), !hda_hp_plugged << 10 );
2328+
2329+ if (hda_hp_plugged )
2330+ jack_type |= SND_JACK_HEADPHONE ;
2331+
2332+ snd_soc_jack_report (rt5640 -> jack , jack_type , SND_JACK_HEADSET );
2333+
2334+ return ;
2335+ }
2336+
23042337 if (!rt5640_jack_inserted (component )) {
23052338 /* Jack removed, or spurious IRQ? */
23062339 if (rt5640 -> jack -> status & SND_JACK_HEADPHONE ) {
@@ -2478,13 +2511,57 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
24782511 queue_work (system_long_wq , & rt5640 -> jack_work );
24792512}
24802513
2514+ static void rt5640_enable_hda_jack_detect (
2515+ struct snd_soc_component * component , struct snd_soc_jack * jack )
2516+ {
2517+ struct rt5640_priv * rt5640 = snd_soc_component_get_drvdata (component );
2518+ int ret ;
2519+
2520+ /* Select JD1 for Mic */
2521+ snd_soc_component_update_bits (component , RT5640_JD_CTRL ,
2522+ RT5640_JD_MASK , RT5640_JD_JD1_IN4P );
2523+ snd_soc_component_write (component , RT5640_IRQ_CTRL1 , RT5640_IRQ_JD_NOR );
2524+
2525+ /* Select JD2 for Headphone */
2526+ snd_soc_component_update_bits (component , RT5640_DUMMY2 , 0x1100 , 0x1100 );
2527+
2528+ /* Selecting GPIO01 as an interrupt */
2529+ snd_soc_component_update_bits (component , RT5640_GPIO_CTRL1 ,
2530+ RT5640_GP1_PIN_MASK , RT5640_GP1_PIN_IRQ );
2531+
2532+ /* Set GPIO1 output */
2533+ snd_soc_component_update_bits (component , RT5640_GPIO_CTRL3 ,
2534+ RT5640_GP1_PF_MASK , RT5640_GP1_PF_OUT );
2535+
2536+ snd_soc_component_update_bits (component , RT5640_DUMMY1 , 0x700 , 0x300 );
2537+
2538+ rt5640 -> jack = jack ;
2539+
2540+ ret = request_irq (rt5640 -> irq , rt5640_irq ,
2541+ IRQF_TRIGGER_RISING | IRQF_ONESHOT , "rt5640" , rt5640 );
2542+ if (ret ) {
2543+ dev_warn (component -> dev , "Failed to reguest IRQ %d: %d\n" , rt5640 -> irq , ret );
2544+ rt5640 -> irq = - ENXIO ;
2545+ return ;
2546+ }
2547+
2548+ /* sync initial jack state */
2549+ queue_work (system_long_wq , & rt5640 -> jack_work );
2550+ }
2551+
24812552static int rt5640_set_jack (struct snd_soc_component * component ,
24822553 struct snd_soc_jack * jack , void * data )
24832554{
2484- if (jack )
2485- rt5640_enable_jack_detect (component , jack );
2486- else
2555+ struct rt5640_priv * rt5640 = snd_soc_component_get_drvdata (component );
2556+
2557+ if (jack ) {
2558+ if (rt5640 -> jd_src == RT5640_JD_SRC_HDA_HEADER )
2559+ rt5640_enable_hda_jack_detect (component , jack );
2560+ else
2561+ rt5640_enable_jack_detect (component , jack );
2562+ } else {
24872563 rt5640_disable_jack_detect (component );
2564+ }
24882565
24892566 return 0 ;
24902567}
@@ -2576,6 +2653,8 @@ static int rt5640_probe(struct snd_soc_component *component)
25762653 "realtek,jack-detect-source" , & val ) == 0 ) {
25772654 if (val <= RT5640_JD_SRC_GPIO4 )
25782655 rt5640 -> jd_src = val << RT5640_JD_SFT ;
2656+ else if (val == RT5640_JD_SRC_HDA_HEADER )
2657+ rt5640 -> jd_src = RT5640_JD_SRC_HDA_HEADER ;
25792658 else
25802659 dev_warn (component -> dev , "Warning: Invalid jack-detect-source value: %d, leaving jack-detect disabled\n" ,
25812660 val );
@@ -2632,6 +2711,7 @@ static int rt5640_suspend(struct snd_soc_component *component)
26322711{
26332712 struct rt5640_priv * rt5640 = snd_soc_component_get_drvdata (component );
26342713
2714+ rt5640_cancel_work (rt5640 );
26352715 snd_soc_component_force_bias_level (component , SND_SOC_BIAS_OFF );
26362716 rt5640_reset (component );
26372717 regcache_cache_only (rt5640 -> regmap , true);
@@ -2654,6 +2734,17 @@ static int rt5640_resume(struct snd_soc_component *component)
26542734 regcache_cache_only (rt5640 -> regmap , false);
26552735 regcache_sync (rt5640 -> regmap );
26562736
2737+ if (rt5640 -> jd_src ) {
2738+ if (rt5640 -> jd_src == RT5640_JD_SRC_HDA_HEADER )
2739+ snd_soc_component_update_bits (component ,
2740+ RT5640_DUMMY2 , 0x1100 , 0x1100 );
2741+ else
2742+ snd_soc_component_write (component , RT5640_DUMMY2 ,
2743+ 0x4001 );
2744+
2745+ queue_work (system_long_wq , & rt5640 -> jack_work );
2746+ }
2747+
26572748 return 0 ;
26582749}
26592750#else
0 commit comments