Commit a3989dc0 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Wolfram Sang

i2c: i801: Centralize configuring block commands in i801_block_transaction

Similar to what was done for non-block commands, centralize block
command register settings in i801_block_transaction().
Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: default avatarJean Delvare <jdelvare@suse.de>
Signed-off-by: default avatarWolfram Sang <wsa@kernel.org>
parent 24592482
...@@ -803,7 +803,7 @@ static int i801_simple_transaction(struct i801_priv *priv, union i2c_smbus_data ...@@ -803,7 +803,7 @@ static int i801_simple_transaction(struct i801_priv *priv, union i2c_smbus_data
/* Block transaction function */ /* Block transaction function */
static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data, static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data,
char read_write, int command) u8 addr, u8 hstcmd, char read_write, int command)
{ {
int result = 0; int result = 0;
unsigned char hostc; unsigned char hostc;
...@@ -813,7 +813,29 @@ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data * ...@@ -813,7 +813,29 @@ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *
else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
return -EPROTO; return -EPROTO;
if (command == I2C_SMBUS_I2C_BLOCK_DATA) { switch (command) {
case I2C_SMBUS_BLOCK_DATA:
i801_set_hstadd(priv, addr, read_write);
outb_p(hstcmd, SMBHSTCMD(priv));
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
/*
* NB: page 240 of ICH5 datasheet shows that the R/#W
* bit should be cleared here, even when reading.
* However if SPD Write Disable is set (Lynx Point and later),
* the read will fail if we don't set the R/#W bit.
*/
i801_set_hstadd(priv, addr,
priv->original_hstcfg & SMBHSTCFG_SPD_WD ?
read_write : I2C_SMBUS_WRITE);
if (read_write == I2C_SMBUS_READ) {
/* NB: page 240 of ICH5 datasheet also shows
* that DATA1 is the cmd field when reading
*/
outb_p(hstcmd, SMBHSTDAT1(priv));
} else
outb_p(hstcmd, SMBHSTCMD(priv));
if (read_write == I2C_SMBUS_WRITE) { if (read_write == I2C_SMBUS_WRITE) {
/* set I2C_EN bit in configuration register */ /* set I2C_EN bit in configuration register */
pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc); pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
...@@ -824,6 +846,12 @@ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data * ...@@ -824,6 +846,12 @@ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *
"I2C block read is unsupported!\n"); "I2C block read is unsupported!\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
/* Needs to be flagged as write transaction */
i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
outb_p(hstcmd, SMBHSTCMD(priv));
break;
} }
/* Experience has shown that the block buffer can only be used for /* Experience has shown that the block buffer can only be used for
...@@ -852,7 +880,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, ...@@ -852,7 +880,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write, u8 command, unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data) int size, union i2c_smbus_data *data)
{ {
int hwpec, ret, block = 0; int hwpec, ret;
struct i801_priv *priv = i2c_get_adapdata(adap); struct i801_priv *priv = i2c_get_adapdata(adap);
mutex_lock(&priv->acpi_lock); mutex_lock(&priv->acpi_lock);
...@@ -867,57 +895,16 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, ...@@ -867,57 +895,16 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
&& size != I2C_SMBUS_QUICK && size != I2C_SMBUS_QUICK
&& size != I2C_SMBUS_I2C_BLOCK_DATA; && size != I2C_SMBUS_I2C_BLOCK_DATA;
switch (size) {
case I2C_SMBUS_QUICK:
case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
case I2C_SMBUS_WORD_DATA:
case I2C_SMBUS_PROC_CALL:
break;
case I2C_SMBUS_BLOCK_DATA:
i801_set_hstadd(priv, addr, read_write);
outb_p(command, SMBHSTCMD(priv));
block = 1;
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
/*
* NB: page 240 of ICH5 datasheet shows that the R/#W
* bit should be cleared here, even when reading.
* However if SPD Write Disable is set (Lynx Point and later),
* the read will fail if we don't set the R/#W bit.
*/
i801_set_hstadd(priv, addr,
priv->original_hstcfg & SMBHSTCFG_SPD_WD ?
read_write : I2C_SMBUS_WRITE);
if (read_write == I2C_SMBUS_READ) {
/* NB: page 240 of ICH5 datasheet also shows
* that DATA1 is the cmd field when reading */
outb_p(command, SMBHSTDAT1(priv));
} else
outb_p(command, SMBHSTCMD(priv));
block = 1;
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
/* Needs to be flagged as write transaction */
i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
outb_p(command, SMBHSTCMD(priv));
block = 1;
break;
default:
dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
size);
ret = -EOPNOTSUPP;
goto out;
}
if (hwpec) /* enable/disable hardware PEC */ if (hwpec) /* enable/disable hardware PEC */
outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv)); outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
else else
outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC), outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
SMBAUXCTL(priv)); SMBAUXCTL(priv));
if (block) if (size == I2C_SMBUS_BLOCK_DATA ||
ret = i801_block_transaction(priv, data, read_write, size); size == I2C_SMBUS_I2C_BLOCK_DATA ||
size == I2C_SMBUS_BLOCK_PROC_CALL)
ret = i801_block_transaction(priv, data, addr, command, read_write, size);
else else
ret = i801_simple_transaction(priv, data, addr, command, read_write, size); ret = i801_simple_transaction(priv, data, addr, command, read_write, size);
...@@ -926,7 +913,6 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, ...@@ -926,7 +913,6 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
*/ */
if (hwpec) if (hwpec)
outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv)); outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
out:
/* /*
* Unlock the SMBus device for use by BIOS/ACPI, * Unlock the SMBus device for use by BIOS/ACPI,
* and clear status flags if not done already. * and clear status flags if not done already.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment