]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: pse-pd: tps23881: Add missing configuration register after disable
authorKory Maincent <kory.maincent@bootlin.com>
Fri, 10 Jan 2025 09:40:25 +0000 (10:40 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 14 Jan 2025 12:56:32 +0000 (13:56 +0100)
When setting the PWOFF register, the controller resets multiple
configuration registers. This patch ensures these registers are
reconfigured as needed following a disable operation.

Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/pse-pd/tps23881.c

index 4a75206b2de673c7262e5591b63a22128d4f3d08..b87c391ae0f57ba5710e3b2f709f832d31dc447e 100644 (file)
@@ -130,6 +130,7 @@ static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id)
        struct i2c_client *client = priv->client;
        u8 chan;
        u16 val;
+       int ret;
 
        if (id >= TPS23881_MAX_CHANS)
                return -ERANGE;
@@ -143,7 +144,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)