Skip to content

Commit 6ff9d46

Browse files
hkallweitAndi Shyti
authored andcommitted
i2c: i801: Split i801_block_transaction
i2c and smbus block transaction handling have little in common, therefore split this function to improve code readability. Signed-off-by: Heiner Kallweit <[email protected]> Reviewed-by: Andi Shyti <[email protected]> Signed-off-by: Andi Shyti <[email protected]>
1 parent 03f9863 commit 6ff9d46

File tree

1 file changed

+50
-62
lines changed

1 file changed

+50
-62
lines changed

drivers/i2c/busses/i2c-i801.c

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -802,77 +802,65 @@ static int i801_simple_transaction(struct i801_priv *priv, union i2c_smbus_data
802802
return 0;
803803
}
804804

805-
/* Block transaction function */
806-
static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data,
807-
u8 addr, u8 hstcmd, char read_write, int command)
805+
static int i801_smbus_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data,
806+
u8 addr, u8 hstcmd, char read_write, int command)
808807
{
809-
int result = 0;
810-
unsigned char hostc;
811-
812808
if (read_write == I2C_SMBUS_READ && command == I2C_SMBUS_BLOCK_DATA)
813809
data->block[0] = I2C_SMBUS_BLOCK_MAX;
814810
else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
815811
return -EPROTO;
816812

817-
switch (command) {
818-
case I2C_SMBUS_BLOCK_DATA:
819-
i801_set_hstadd(priv, addr, read_write);
820-
outb_p(hstcmd, SMBHSTCMD(priv));
821-
break;
822-
case I2C_SMBUS_I2C_BLOCK_DATA:
823-
/*
824-
* NB: page 240 of ICH5 datasheet shows that the R/#W
825-
* bit should be cleared here, even when reading.
826-
* However if SPD Write Disable is set (Lynx Point and later),
827-
* the read will fail if we don't set the R/#W bit.
828-
*/
829-
i801_set_hstadd(priv, addr,
830-
priv->original_hstcfg & SMBHSTCFG_SPD_WD ?
831-
read_write : I2C_SMBUS_WRITE);
832-
if (read_write == I2C_SMBUS_READ) {
833-
/* NB: page 240 of ICH5 datasheet also shows
834-
* that DATA1 is the cmd field when reading
835-
*/
836-
outb_p(hstcmd, SMBHSTDAT1(priv));
837-
} else
838-
outb_p(hstcmd, SMBHSTCMD(priv));
839-
840-
if (read_write == I2C_SMBUS_WRITE) {
841-
/* set I2C_EN bit in configuration register */
842-
pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
843-
pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
844-
hostc | SMBHSTCFG_I2C_EN);
845-
} else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
846-
dev_err(&priv->pci_dev->dev,
847-
"I2C block read is unsupported!\n");
848-
return -EOPNOTSUPP;
849-
}
850-
break;
851-
case I2C_SMBUS_BLOCK_PROC_CALL:
813+
if (command == I2C_SMBUS_BLOCK_PROC_CALL)
852814
/* Needs to be flagged as write transaction */
853815
i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
816+
else
817+
i801_set_hstadd(priv, addr, read_write);
818+
outb_p(hstcmd, SMBHSTCMD(priv));
819+
820+
if (priv->features & FEATURE_BLOCK_BUFFER)
821+
return i801_block_transaction_by_block(priv, data, read_write, command);
822+
else
823+
return i801_block_transaction_byte_by_byte(priv, data, read_write, command);
824+
}
825+
826+
static int i801_i2c_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data,
827+
u8 addr, u8 hstcmd, char read_write, int command)
828+
{
829+
int result;
830+
u8 hostc;
831+
832+
if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
833+
return -EPROTO;
834+
/*
835+
* NB: page 240 of ICH5 datasheet shows that the R/#W bit should be cleared here,
836+
* even when reading. However if SPD Write Disable is set (Lynx Point and later),
837+
* the read will fail if we don't set the R/#W bit.
838+
*/
839+
i801_set_hstadd(priv, addr,
840+
priv->original_hstcfg & SMBHSTCFG_SPD_WD ? read_write : I2C_SMBUS_WRITE);
841+
842+
/* NB: page 240 of ICH5 datasheet shows that DATA1 is the cmd field when reading */
843+
if (read_write == I2C_SMBUS_READ)
844+
outb_p(hstcmd, SMBHSTDAT1(priv));
845+
else
854846
outb_p(hstcmd, SMBHSTCMD(priv));
855-
break;
847+
848+
if (read_write == I2C_SMBUS_WRITE) {
849+
/* set I2C_EN bit in configuration register */
850+
pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
851+
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc | SMBHSTCFG_I2C_EN);
852+
} else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
853+
pci_err(priv->pci_dev, "I2C block read is unsupported!\n");
854+
return -EOPNOTSUPP;
856855
}
857856

858-
/* Experience has shown that the block buffer can only be used for
859-
SMBus (not I2C) block transactions, even though the datasheet
860-
doesn't mention this limitation. */
861-
if ((priv->features & FEATURE_BLOCK_BUFFER) &&
862-
command != I2C_SMBUS_I2C_BLOCK_DATA)
863-
result = i801_block_transaction_by_block(priv, data,
864-
read_write,
865-
command);
866-
else
867-
result = i801_block_transaction_byte_by_byte(priv, data,
868-
read_write,
869-
command);
857+
/* Block buffer isn't supported for I2C block transactions */
858+
result = i801_block_transaction_byte_by_byte(priv, data, read_write, command);
870859

871-
if (command == I2C_SMBUS_I2C_BLOCK_DATA
872-
&& read_write == I2C_SMBUS_WRITE) {
873-
/* restore saved configuration register value */
860+
/* restore saved configuration register value */
861+
if (read_write == I2C_SMBUS_WRITE)
874862
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
875-
}
863+
876864
return result;
877865
}
878866

@@ -903,10 +891,10 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
903891
outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
904892
SMBAUXCTL(priv));
905893

906-
if (size == I2C_SMBUS_BLOCK_DATA ||
907-
size == I2C_SMBUS_I2C_BLOCK_DATA ||
908-
size == I2C_SMBUS_BLOCK_PROC_CALL)
909-
ret = i801_block_transaction(priv, data, addr, command, read_write, size);
894+
if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_BLOCK_PROC_CALL)
895+
ret = i801_smbus_block_transaction(priv, data, addr, command, read_write, size);
896+
else if (size == I2C_SMBUS_I2C_BLOCK_DATA)
897+
ret = i801_i2c_block_transaction(priv, data, addr, command, read_write, size);
910898
else
911899
ret = i801_simple_transaction(priv, data, addr, command, read_write, size);
912900

0 commit comments

Comments
 (0)