net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel
authorKory Maincent <kory.maincent@bootlin.com>
Fri, 10 Jan 2025 09:40:24 +0000 (10:40 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 14 Jan 2025 12:56:32 +0000 (13:56 +0100)
This driver frequently follows a pattern where two registers are read or
written in a single operation, followed by calculating the bit offset for
a specific channel.

Introduce helpers to streamline this process and reduce code redundancy,
making the codebase cleaner and more maintainable.

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 a3507520ff872219e547a0ab88b5969da524f420..4a75206b2de673c7262e5591b63a22128d4f3d08 100644 (file)
@@ -53,6 +53,55 @@ static struct tps23881_priv *to_tps23881_priv(struct pse_controller_dev *pcdev)
        return container_of(pcdev, struct tps23881_priv, pcdev);
 }
 
+/*
+ * Helper to extract a value from a u16 register value, which is made of two
+ * u8 registers. The function calculates the bit offset based on the channel
+ * and extracts the relevant bits using a provided field mask.
+ *
+ * @param reg_val: The u16 register value (composed of two u8 registers).
+ * @param chan: The channel number (0-7).
+ * @param field_offset: The base bit offset to apply (e.g., 0 or 4).
+ * @param field_mask: The mask to apply to extract the required bits.
+ * @return: The extracted value for the specific channel.
+ */
+static u16 tps23881_calc_val(u16 reg_val, u8 chan, u8 field_offset,
+                            u16 field_mask)
+{
+       if (chan >= 4)
+               reg_val >>= 8;
+
+       return (reg_val >> field_offset) & field_mask;
+}
+
+/*
+ * Helper to combine individual channel values into a u16 register value.
+ * The function sets the value for a specific channel in the appropriate
+ * position.
+ *
+ * @param reg_val: The current u16 register value.
+ * @param chan: The channel number (0-7).
+ * @param field_offset: The base bit offset to apply (e.g., 0 or 4).
+ * @param field_mask: The mask to apply for the field (e.g., 0x0F).
+ * @param field_val: The value to set for the specific channel (masked by
+ *                   field_mask).
+ * @return: The updated u16 register value with the channel value set.
+ */
+static u16 tps23881_set_val(u16 reg_val, u8 chan, u8 field_offset,
+                           u16 field_mask, u16 field_val)
+{
+       field_val &= field_mask;
+
+       if (chan < 4) {
+               reg_val &= ~(field_mask << field_offset);
+               reg_val |= (field_val << field_offset);
+       } else {
+               reg_val &= ~(field_mask << (field_offset + 8));
+               reg_val |= (field_val << (field_offset + 8));
+       }
+
+       return reg_val;
+}
+
 static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id)
 {
        struct tps23881_priv *priv = to_tps23881_priv(pcdev);
@@ -64,17 +113,12 @@ static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id)
                return -ERANGE;
 
        chan = priv->port[id].chan[0];
-       if (chan < 4)
-               val = BIT(chan);
-       else
-               val = BIT(chan + 4);
+       val = tps23881_set_val(0, chan, 0, BIT(chan % 4), BIT(chan % 4));
 
        if (priv->port[id].is_4p) {
                chan = priv->port[id].chan[1];
-               if (chan < 4)
-                       val |= BIT(chan);
-               else
-                       val |= BIT(chan + 4);
+               val = tps23881_set_val(val, chan, 0, BIT(chan % 4),
+                                      BIT(chan % 4));
        }
 
        return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
@@ -91,17 +135,12 @@ static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id)
                return -ERANGE;
 
        chan = priv->port[id].chan[0];
-       if (chan < 4)
-               val = BIT(chan + 4);
-       else
-               val = BIT(chan + 8);
+       val = tps23881_set_val(0, chan, 4, BIT(chan % 4), BIT(chan % 4));
 
        if (priv->port[id].is_4p) {
                chan = priv->port[id].chan[1];
-               if (chan < 4)
-                       val |= BIT(chan + 4);
-               else
-                       val |= BIT(chan + 8);
+               val = tps23881_set_val(val, chan, 4, BIT(chan % 4),
+                                      BIT(chan % 4));
        }
 
        return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
@@ -113,6 +152,7 @@ static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
        struct i2c_client *client = priv->client;
        bool enabled;
        u8 chan;
+       u16 val;
        int ret;
 
        ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
@@ -120,17 +160,13 @@ static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
                return ret;
 
        chan = priv->port[id].chan[0];
-       if (chan < 4)
-               enabled = ret & BIT(chan);
-       else
-               enabled = ret & BIT(chan + 4);
+       val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+       enabled = !!(val);
 
        if (priv->port[id].is_4p) {
                chan = priv->port[id].chan[1];
-               if (chan < 4)
-                       enabled &= !!(ret & BIT(chan));
-               else
-                       enabled &= !!(ret & BIT(chan + 4));
+               val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+               enabled &= !!(val);
        }
 
        /* Return enabled status only if both channel are on this state */
@@ -146,6 +182,7 @@ static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
        struct i2c_client *client = priv->client;
        bool enabled, delivering;
        u8 chan;
+       u16 val;
        int ret;
 
        ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
@@ -153,23 +190,17 @@ static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
                return ret;
 
        chan = priv->port[id].chan[0];
-       if (chan < 4) {
-               enabled = ret & BIT(chan);
-               delivering = ret & BIT(chan + 4);
-       } else {
-               enabled = ret & BIT(chan + 4);
-               delivering = ret & BIT(chan + 8);
-       }
+       val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+       enabled = !!(val);
+       val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
+       delivering = !!(val);
 
        if (priv->port[id].is_4p) {
                chan = priv->port[id].chan[1];
-               if (chan < 4) {
-                       enabled &= !!(ret & BIT(chan));
-                       delivering &= !!(ret & BIT(chan + 4));
-               } else {
-                       enabled &= !!(ret & BIT(chan + 4));
-                       delivering &= !!(ret & BIT(chan + 8));
-               }
+               val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+               enabled &= !!(val);
+               val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
+               delivering &= !!(val);
        }
 
        /* Return delivering status only if both channel are on this state */