From: "Fang, Yang A" yang.a.fang@intel.com
After suspend -> resume the ts3a227e_interrupt sometimes comes before i2c controller resume is called .regmap_read will return incorrect status and report a wrong jack status.We should return if there is read err,the interrupt will come again since it is level triggered and we are not yet clear the interrupt. In addtion,cht_bsw_max98090_ti machine driver registered additional notifier base on jack event which will program the audio codec.there will be codec timeout err if such event occurs prior to i2c controller is resumed.
Signed-off-by: Fang, Yang A yang.a.fang@intel.com --- sound/soc/codecs/ts3a227e.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index 12232d7..12d0f2a 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c @@ -23,6 +23,7 @@ #include "ts3a227e.h"
struct ts3a227e { + struct device *dev; struct regmap *regmap; struct snd_soc_jack *jack; bool plugged; @@ -189,16 +190,28 @@ static irqreturn_t ts3a227e_interrupt(int irq, void *data) struct ts3a227e *ts3a227e = (struct ts3a227e *)data; struct regmap *regmap = ts3a227e->regmap; unsigned int int_reg, kp_int_reg, acc_reg, i; + struct device *dev = ts3a227e->dev; + int ret;
/* Check for plug/unplug. */ - regmap_read(regmap, TS3A227E_REG_INTERRUPT, &int_reg); + ret = regmap_read(regmap, TS3A227E_REG_INTERRUPT, &int_reg); + if (ret) { + dev_err(dev, "failed to clear interrupt ret=%d\n", ret); + return IRQ_HANDLED; + } + if (int_reg & (DETECTION_COMPLETE_EVENT | INS_REM_EVENT)) { regmap_read(regmap, TS3A227E_REG_ACCESSORY_STATUS, &acc_reg); ts3a227e_new_jack_state(ts3a227e, acc_reg); }
/* Report any key events. */ - regmap_read(regmap, TS3A227E_REG_KP_INTERRUPT, &kp_int_reg); + ret = regmap_read(regmap, TS3A227E_REG_KP_INTERRUPT, &kp_int_reg); + if (ret) { + dev_err(dev, "failed to clear key interrupt ret=%d\n", ret); + return IRQ_HANDLED; + } + for (i = 0; i < TS3A227E_NUM_BUTTONS; i++) { if (kp_int_reg & PRESS_MASK(i)) ts3a227e->buttons_held |= (1 << i); @@ -283,6 +296,7 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c, return -ENOMEM;
i2c_set_clientdata(i2c, ts3a227e); + ts3a227e->dev = dev;
ts3a227e->regmap = devm_regmap_init_i2c(i2c, &ts3a227e_regmap_config); if (IS_ERR(ts3a227e->regmap))