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

i2c: i801: Add i801_simple_transaction(), complementing i801_block_transaction()

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: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: default avatarJean Delvare <jdelvare@suse.de>
Signed-off-by: default avatarWolfram Sang <wsa@kernel.org>
parent 38bd4136
...@@ -732,6 +732,59 @@ static void i801_set_hstadd(struct i801_priv *priv, u8 addr, char read_write) ...@@ -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)); 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 */ /* 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) char read_write, int command)
...@@ -783,9 +836,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, ...@@ -783,9 +836,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; int hwpec, ret, block = 0;
int block = 0;
int ret, xact;
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);
...@@ -803,36 +854,23 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, ...@@ -803,36 +854,23 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
switch (size) { switch (size) {
case I2C_SMBUS_QUICK: case I2C_SMBUS_QUICK:
i801_set_hstadd(priv, addr, read_write); i801_set_hstadd(priv, addr, read_write);
xact = I801_QUICK;
break; break;
case I2C_SMBUS_BYTE: case I2C_SMBUS_BYTE:
i801_set_hstadd(priv, addr, read_write); i801_set_hstadd(priv, addr, read_write);
if (read_write == I2C_SMBUS_WRITE) if (read_write == I2C_SMBUS_WRITE)
outb_p(command, SMBHSTCMD(priv)); outb_p(command, SMBHSTCMD(priv));
xact = I801_BYTE;
break; break;
case I2C_SMBUS_BYTE_DATA: case I2C_SMBUS_BYTE_DATA:
i801_set_hstadd(priv, addr, read_write); i801_set_hstadd(priv, addr, read_write);
outb_p(command, SMBHSTCMD(priv)); outb_p(command, SMBHSTCMD(priv));
if (read_write == I2C_SMBUS_WRITE)
outb_p(data->byte, SMBHSTDAT0(priv));
xact = I801_BYTE_DATA;
break; break;
case I2C_SMBUS_WORD_DATA: case I2C_SMBUS_WORD_DATA:
i801_set_hstadd(priv, addr, read_write); i801_set_hstadd(priv, addr, read_write);
outb_p(command, SMBHSTCMD(priv)); 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; break;
case I2C_SMBUS_PROC_CALL: case I2C_SMBUS_PROC_CALL:
i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE); i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
outb_p(command, SMBHSTCMD(priv)); 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; read_write = I2C_SMBUS_READ;
break; break;
case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_BLOCK_DATA:
...@@ -880,7 +918,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, ...@@ -880,7 +918,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
if (block) if (block)
ret = i801_block_transaction(priv, data, read_write, size); ret = i801_block_transaction(priv, data, read_write, size);
else 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 /* 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 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, ...@@ -888,26 +926,6 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
if (hwpec || block) if (hwpec || block)
outb_p(inb_p(SMBAUXCTL(priv)) & outb_p(inb_p(SMBAUXCTL(priv)) &
~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), 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: out:
/* /*
* Unlock the SMBus device for use by BIOS/ACPI, * Unlock the SMBus device for use by BIOS/ACPI,
......
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