From: Kory Maincent (Dent Project) <kory.maincent@xxxxxxxxxxx> When setting the PWOFF register, the controller resets multiple configuration registers. This patch ensures these registers are reconfigured as needed following a disable operation. Signed-off-by: Kory Maincent <kory.maincent@xxxxxxxxxxx> --- Change in v3: - New patch --- drivers/net/pse-pd/tps23881.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c index 6fd76ecb2961..58864b7d28d2 100644 --- a/drivers/net/pse-pd/tps23881.c +++ b/drivers/net/pse-pd/tps23881.c @@ -157,7 +157,34 @@ static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id) BIT(chan % 4)); } - return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val); + ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val); + if (ret) + return ret; + + /* PWOFF command resets lots of register which need to be + * configured again. According to the datasheet "It may take upwards + * of 5ms after PWOFFn command for all register values to be updated" + */ + mdelay(5); + + /* Enable detection and classification */ + ret = i2c_smbus_read_word_data(client, TPS23881_REG_DET_CLA_EN); + if (ret < 0) + return ret; + + chan = priv->port[id].chan[0]; + val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4)); + val = tps23881_set_val(val, chan, 4, BIT(chan % 4), BIT(chan % 4)); + + if (priv->port[id].is_4p) { + chan = priv->port[id].chan[1]; + val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), + BIT(chan % 4)); + val = tps23881_set_val(val, chan, 4, BIT(chan % 4), + BIT(chan % 4)); + } + + return i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val); } static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id) -- 2.34.1