i2c: i801: Add i801_simple_transaction(), complementing i801_block_transaction()
authorHeiner Kallweit <hkallweit1@gmail.com>
Thu, 16 Feb 2023 16:10:30 +0000 (17:10 +0100)
committerWolfram Sang <wsa@kernel.org>
Fri, 17 Feb 2023 21:11:22 +0000 (22:11 +0100)
Factor out non-block pre/post processing to a new function
i801_simple_transaction(), complementing existing function
i801_block_transaction(). This makes i801_access() better readable.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
drivers/i2c/busses/i2c-i801.c

index 882cf51..d934d41 100644 (file)
@@ -732,6 +732,59 @@ static void i801_set_hstadd(struct i801_priv *priv, u8 addr, char read_write)
        outb_p((addr << 1) | (read_write & 0x01), SMBHSTADD(priv));
 }
 
+/* Single value transaction function */
+static int i801_simple_transaction(struct i801_priv *priv, union i2c_smbus_data *data,
+                                  char read_write, int command)
+{
+       int xact, ret;
+
+       switch (command) {
+       case I2C_SMBUS_QUICK:
+               xact = I801_QUICK;
+               break;
+       case I2C_SMBUS_BYTE:
+               xact = I801_BYTE;
+               break;
+       case I2C_SMBUS_BYTE_DATA:
+               if (read_write == I2C_SMBUS_WRITE)
+                       outb_p(data->byte, SMBHSTDAT0(priv));
+               xact = I801_BYTE_DATA;
+               break;
+       case I2C_SMBUS_WORD_DATA:
+               if (read_write == I2C_SMBUS_WRITE) {
+                       outb_p(data->word & 0xff, SMBHSTDAT0(priv));
+                       outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
+               }
+               xact = I801_WORD_DATA;
+               break;
+       case I2C_SMBUS_PROC_CALL:
+               outb_p(data->word & 0xff, SMBHSTDAT0(priv));
+               outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
+               xact = I801_PROC_CALL;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       ret = i801_transaction(priv, xact);
+       if (ret || read_write == I2C_SMBUS_WRITE)
+               return ret;
+
+       switch (command) {
+       case I2C_SMBUS_BYTE:
+       case I2C_SMBUS_BYTE_DATA:
+               data->byte = inb_p(SMBHSTDAT0(priv));
+               break;
+       case I2C_SMBUS_WORD_DATA:
+       case I2C_SMBUS_PROC_CALL:
+               data->word = inb_p(SMBHSTDAT0(priv)) +
+                            (inb_p(SMBHSTDAT1(priv)) << 8);
+               break;
+       }
+
+       return 0;
+}
+
 /* Block transaction function */
 static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data,
                                  char read_write, int command)
@@ -783,9 +836,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
                       unsigned short flags, char read_write, u8 command,
                       int size, union i2c_smbus_data *data)
 {
-       int hwpec;
-       int block = 0;
-       int ret, xact;
+       int hwpec, ret, block = 0;
        struct i801_priv *priv = i2c_get_adapdata(adap);
 
        mutex_lock(&priv->acpi_lock);
@@ -803,36 +854,23 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        switch (size) {
        case I2C_SMBUS_QUICK:
                i801_set_hstadd(priv, addr, read_write);
-               xact = I801_QUICK;
                break;
        case I2C_SMBUS_BYTE:
                i801_set_hstadd(priv, addr, read_write);
                if (read_write == I2C_SMBUS_WRITE)
                        outb_p(command, SMBHSTCMD(priv));
-               xact = I801_BYTE;
                break;
        case I2C_SMBUS_BYTE_DATA:
                i801_set_hstadd(priv, addr, read_write);
                outb_p(command, SMBHSTCMD(priv));
-               if (read_write == I2C_SMBUS_WRITE)
-                       outb_p(data->byte, SMBHSTDAT0(priv));
-               xact = I801_BYTE_DATA;
                break;
        case I2C_SMBUS_WORD_DATA:
                i801_set_hstadd(priv, addr, read_write);
                outb_p(command, SMBHSTCMD(priv));
-               if (read_write == I2C_SMBUS_WRITE) {
-                       outb_p(data->word & 0xff, SMBHSTDAT0(priv));
-                       outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
-               }
-               xact = I801_WORD_DATA;
                break;
        case I2C_SMBUS_PROC_CALL:
                i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
                outb_p(command, SMBHSTCMD(priv));
-               outb_p(data->word & 0xff, SMBHSTDAT0(priv));
-               outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
-               xact = I801_PROC_CALL;
                read_write = I2C_SMBUS_READ;
                break;
        case I2C_SMBUS_BLOCK_DATA:
@@ -880,7 +918,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        if (block)
                ret = i801_block_transaction(priv, data, read_write, size);
        else
-               ret = i801_transaction(priv, xact);
+               ret = i801_simple_transaction(priv, data, read_write, size);
 
        /* Some BIOSes don't like it when PEC is enabled at reboot or resume
           time, so we forcibly disable it after every transaction. Turn off
@@ -888,26 +926,6 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        if (hwpec || block)
                outb_p(inb_p(SMBAUXCTL(priv)) &
                       ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
-
-       if (block)
-               goto out;
-       if (ret)
-               goto out;
-       if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
-               goto out;
-
-       switch (xact) {
-       case I801_BYTE: /* Result put in SMBHSTDAT0 */
-       case I801_BYTE_DATA:
-               data->byte = inb_p(SMBHSTDAT0(priv));
-               break;
-       case I801_WORD_DATA:
-       case I801_PROC_CALL:
-               data->word = inb_p(SMBHSTDAT0(priv)) +
-                            (inb_p(SMBHSTDAT1(priv)) << 8);
-               break;
-       }
-
 out:
        /*
         * Unlock the SMBus device for use by BIOS/ACPI,