@@ -46,7 +46,8 @@ struct cs42l84_private {
4646 struct gpio_desc * reset_gpio ;
4747 struct snd_soc_jack * jack ;
4848 struct mutex irq_lock ;
49- u8 plug_state ;
49+ u8 tip_state ;
50+ u8 ring_state ;
5051 int pll_config ;
5152 int bclk ;
5253 u8 pll_mclk_f ;
@@ -808,13 +809,23 @@ static void cs42l84_revert_hs(struct cs42l84_private *cs42l84)
808809 FIELD_PREP (CS42L84_HS_DET_CTL2_SET , 2 ));
809810}
810811
812+ static void cs42l84_set_interrupt_masks (struct cs42l84_private * cs42l84 ,
813+ unsigned int val )
814+ {
815+ regmap_update_bits (cs42l84 -> regmap , CS42L84_TSRS_PLUG_INT_MASK ,
816+ CS42L84_RS_PLUG | CS42L84_RS_UNPLUG |
817+ CS42L84_TS_PLUG | CS42L84_TS_UNPLUG ,
818+ val );
819+ }
820+
811821static irqreturn_t cs42l84_irq_thread (int irq , void * data )
812822{
813823 struct cs42l84_private * cs42l84 = (struct cs42l84_private * )data ;
814824 unsigned int stickies [1 ];
815825 unsigned int masks [1 ];
816826 unsigned int reg ;
817- u8 current_plug_status ;
827+ u8 current_tip_state ;
828+ u8 current_ring_state ;
818829 int i ;
819830
820831 mutex_lock (& cs42l84 -> irq_lock );
@@ -828,15 +839,22 @@ static irqreturn_t cs42l84_irq_thread(int irq, void *data)
828839 irq_params_table [i ].mask ;
829840 }
830841
842+ /* When handling plug sene IRQs, we only care about EITHER tip OR ring.
843+ * Ring is useless on remove, and is only useful on insert for
844+ * detecting if the plug state has changed AFTER we have handled the
845+ * tip sense IRQ, e.g. if the plug was not fully seated within the tip
846+ * sense debounce time. */
847+
831848 if ((~masks [0 ]) & irq_params_table [0 ].mask ) {
832849 regmap_read (cs42l84 -> regmap , CS42L84_TSRS_PLUG_STATUS , & reg );
833- current_plug_status = (((char ) reg ) &
850+
851+ current_tip_state = (((char ) reg ) &
834852 (CS42L84_TS_PLUG | CS42L84_TS_UNPLUG )) >>
835853 CS42L84_TS_PLUG_SHIFT ;
836854
837- if (current_plug_status != cs42l84 -> plug_state ) {
838- cs42l84 -> plug_state = current_plug_status ;
839- switch (current_plug_status ) {
855+ if (current_tip_state != cs42l84 -> tip_state ) {
856+ cs42l84 -> tip_state = current_tip_state ;
857+ switch (current_tip_state ) {
840858 case CS42L84_PLUG :
841859 dev_dbg (cs42l84 -> dev , "Plug event\n" );
842860
@@ -850,41 +868,55 @@ static irqreturn_t cs42l84_irq_thread(int irq, void *data)
850868 * was disconnected at any point during the detection procedure.
851869 */
852870 regmap_read (cs42l84 -> regmap , CS42L84_TSRS_PLUG_STATUS , & reg );
853- current_plug_status = (((char ) reg ) &
871+ current_tip_state = (((char ) reg ) &
854872 (CS42L84_TS_PLUG | CS42L84_TS_UNPLUG )) >>
855873 CS42L84_TS_PLUG_SHIFT ;
856- if (current_plug_status != CS42L84_PLUG ) {
874+ if (current_tip_state != CS42L84_PLUG ) {
857875 dev_dbg (cs42l84 -> dev , "Wobbly connection, detection invalidated\n" );
858- cs42l84 -> plug_state = CS42L84_UNPLUG ;
876+ cs42l84 -> tip_state = CS42L84_UNPLUG ;
859877 cs42l84_revert_hs (cs42l84 );
860878 }
879+
880+ /* Unmask ring sense interrupts */
881+ cs42l84_set_interrupt_masks (cs42l84 , 0 );
861882 break ;
862883 case CS42L84_UNPLUG :
884+ cs42l84 -> ring_state = CS42L84_UNPLUG ;
863885 dev_dbg (cs42l84 -> dev , "Unplug event\n" );
864886
865887 cs42l84_revert_hs (cs42l84 );
866888 cs42l84 -> hs_type = 0 ;
867889 snd_soc_jack_report (cs42l84 -> jack , 0 ,
868890 SND_JACK_HEADSET );
891+
892+ /* Mask ring sense interrupts */
893+ cs42l84_set_interrupt_masks (cs42l84 , CS42L84_RS_PLUG | CS42L84_RS_UNPLUG );
869894 break ;
870895 default :
871- break ;
896+ cs42l84 -> ring_state = CS42L84_TRANS ;
872897 }
898+
899+ mutex_unlock (& cs42l84 -> irq_lock );
900+ return IRQ_HANDLED ;
873901 }
902+
903+ /* Tip state didn't change, we must've got a ring sense IRQ */
904+ current_ring_state = (((char ) reg ) &
905+ (CS42L84_RS_PLUG | CS42L84_RS_UNPLUG )) >>
906+ CS42L84_RS_PLUG_SHIFT ;
907+
908+ if (current_ring_state != cs42l84 -> ring_state ) {
909+ cs42l84 -> ring_state = current_ring_state ;
910+ if (current_ring_state == CS42L84_PLUG )
911+ cs42l84_detect_hs (cs42l84 );
912+ }
913+ }
914+
874915 mutex_unlock (& cs42l84 -> irq_lock );
875916
876917 return IRQ_HANDLED ;
877918}
878919
879- static void cs42l84_set_interrupt_masks (struct cs42l84_private * cs42l84 ,
880- unsigned int val )
881- {
882- regmap_update_bits (cs42l84 -> regmap , CS42L84_TSRS_PLUG_INT_MASK ,
883- CS42L84_RS_PLUG | CS42L84_RS_UNPLUG |
884- CS42L84_TS_PLUG | CS42L84_TS_UNPLUG ,
885- val );
886- }
887-
888920static void cs42l84_setup_plug_detect (struct cs42l84_private * cs42l84 )
889921{
890922 unsigned int reg ;
@@ -914,7 +946,7 @@ static void cs42l84_setup_plug_detect(struct cs42l84_private *cs42l84)
914946
915947 /* Save the initial status of the tip sense */
916948 regmap_read (cs42l84 -> regmap , CS42L84_TSRS_PLUG_STATUS , & reg );
917- cs42l84 -> plug_state = (((char ) reg ) &
949+ cs42l84 -> tip_state = (((char ) reg ) &
918950 (CS42L84_TS_PLUG | CS42L84_TS_UNPLUG )) >>
919951 CS42L84_TS_PLUG_SHIFT ;
920952
0 commit comments