@@ -31,6 +31,7 @@ struct tas2764_priv {
3131 struct gpio_desc * sdz_gpio ;
3232 struct regmap * regmap ;
3333 struct device * dev ;
34+ int irq ;
3435
3536 int v_sense_slot ;
3637 int i_sense_slot ;
@@ -39,6 +40,57 @@ struct tas2764_priv {
3940 bool unmuted ;
4041};
4142
43+ static const char * tas2764_int_ltch0_msgs [8 ] = {
44+ "fault: over temperature" , /* INT_LTCH0 & BIT(0) */
45+ "fault: over current" ,
46+ "fault: bad TDM clock" ,
47+ "limiter active" ,
48+ "fault: PVDD below limiter inflection point" ,
49+ "fault: limiter max attenuation" ,
50+ "fault: BOP infinite hold" ,
51+ "fault: BOP mute" , /* INT_LTCH0 & BIT(7) */
52+ };
53+
54+ static const unsigned int tas2764_int_readout_regs [6 ] = {
55+ TAS2764_INT_LTCH0 ,
56+ TAS2764_INT_LTCH1 ,
57+ TAS2764_INT_LTCH1_0 ,
58+ TAS2764_INT_LTCH2 ,
59+ TAS2764_INT_LTCH3 ,
60+ TAS2764_INT_LTCH4 ,
61+ };
62+
63+ static irqreturn_t tas2764_irq (int irq , void * data )
64+ {
65+ struct tas2764_priv * tas2764 = data ;
66+ u8 latched [6 ] = {0 , 0 , 0 , 0 , 0 , 0 };
67+ int ret = IRQ_NONE ;
68+ int i ;
69+
70+ for (i = 0 ; i < ARRAY_SIZE (latched ); i ++ )
71+ latched [i ] = snd_soc_component_read (tas2764 -> component ,
72+ tas2764_int_readout_regs [i ]);
73+
74+ for (i = 0 ; i < 8 ; i ++ ) {
75+ if (latched [0 ] & BIT (i )) {
76+ dev_crit_ratelimited (tas2764 -> dev , "%s\n" ,
77+ tas2764_int_ltch0_msgs [i ]);
78+ ret = IRQ_HANDLED ;
79+ }
80+ }
81+
82+ if (latched [0 ]) {
83+ dev_err_ratelimited (tas2764 -> dev , "other context to the fault: %02x,%02x,%02x,%02x,%02x" ,
84+ latched [1 ], latched [2 ], latched [3 ], latched [4 ], latched [5 ]);
85+ snd_soc_component_update_bits (tas2764 -> component ,
86+ TAS2764_INT_CLK_CFG ,
87+ TAS2764_INT_CLK_CFG_IRQZ_CLR ,
88+ TAS2764_INT_CLK_CFG_IRQZ_CLR );
89+ }
90+
91+ return ret ;
92+ }
93+
4294static void tas2764_reset (struct tas2764_priv * tas2764 )
4395{
4496 if (tas2764 -> reset_gpio ) {
@@ -497,6 +549,34 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
497549
498550 tas2764_reset (tas2764 );
499551
552+ if (tas2764 -> irq ) {
553+ ret = snd_soc_component_write (tas2764 -> component , TAS2764_INT_MASK0 , 0xff );
554+ if (ret < 0 )
555+ return ret ;
556+
557+ ret = snd_soc_component_write (tas2764 -> component , TAS2764_INT_MASK1 , 0xff );
558+ if (ret < 0 )
559+ return ret ;
560+
561+ ret = snd_soc_component_write (tas2764 -> component , TAS2764_INT_MASK2 , 0xff );
562+ if (ret < 0 )
563+ return ret ;
564+
565+ ret = snd_soc_component_write (tas2764 -> component , TAS2764_INT_MASK3 , 0xff );
566+ if (ret < 0 )
567+ return ret ;
568+
569+ ret = snd_soc_component_write (tas2764 -> component , TAS2764_INT_MASK4 , 0xff );
570+ if (ret < 0 )
571+ return ret ;
572+
573+ ret = devm_request_threaded_irq (tas2764 -> dev , tas2764 -> irq , NULL , tas2764_irq ,
574+ IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW ,
575+ "tas2764" , tas2764 );
576+ if (ret )
577+ dev_warn (tas2764 -> dev , "failed to request IRQ: %d\n" , ret );
578+ }
579+
500580 ret = snd_soc_component_update_bits (tas2764 -> component , TAS2764_TDM_CFG5 ,
501581 TAS2764_TDM_CFG5_VSNS_ENABLE , 0 );
502582 if (ret < 0 )
@@ -559,9 +639,21 @@ static const struct regmap_range_cfg tas2764_regmap_ranges[] = {
559639 },
560640};
561641
642+ static bool tas2764_volatile_register (struct device * dev , unsigned int reg )
643+ {
644+ switch (reg ) {
645+ case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4 :
646+ case TAS2764_INT_CLK_CFG :
647+ return true;
648+ default :
649+ return false;
650+ }
651+ }
652+
562653static const struct regmap_config tas2764_i2c_regmap = {
563654 .reg_bits = 8 ,
564655 .val_bits = 8 ,
656+ .volatile_reg = tas2764_volatile_register ,
565657 .reg_defaults = tas2764_reg_defaults ,
566658 .num_reg_defaults = ARRAY_SIZE (tas2764_reg_defaults ),
567659 .cache_type = REGCACHE_RBTREE ,
@@ -615,6 +707,7 @@ static int tas2764_i2c_probe(struct i2c_client *client)
615707 return - ENOMEM ;
616708
617709 tas2764 -> dev = & client -> dev ;
710+ tas2764 -> irq = client -> irq ;
618711 i2c_set_clientdata (client , tas2764 );
619712 dev_set_drvdata (& client -> dev , tas2764 );
620713
0 commit comments