summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-i801.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-i801.c')
-rw-r--r--drivers/i2c/busses/i2c-i801.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 7428cc6af5cc..ff706349bdfb 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -75,6 +75,7 @@
* Alder Lake-S (PCH) 0x7aa3 32 hard yes yes yes
* Alder Lake-P (PCH) 0x51a3 32 hard yes yes yes
* Alder Lake-M (PCH) 0x54a3 32 hard yes yes yes
+ * Raptor Lake-S (PCH) 0x7a23 32 hard yes yes yes
*
* Features supported by this driver:
* Software PEC no
@@ -165,7 +166,7 @@
#define I801_BYTE 0x04
#define I801_BYTE_DATA 0x08
#define I801_WORD_DATA 0x0C
-#define I801_PROC_CALL 0x10 /* unimplemented */
+#define I801_PROC_CALL 0x10
#define I801_BLOCK_DATA 0x14
#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
#define I801_BLOCK_PROC_CALL 0x1C
@@ -228,6 +229,7 @@
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3
#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
+#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2
@@ -362,9 +364,6 @@ static int i801_check_post(struct i801_priv *priv, int status)
/*
* If the SMBus is still busy, we give up
- * Note: This timeout condition only happens when using polling
- * transactions. For interrupt operation, NAK/timeout is indicated by
- * DEV_ERR.
*/
if (unlikely(status < 0)) {
dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
@@ -473,8 +472,6 @@ static int i801_transaction(struct i801_priv *priv, int xact)
return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
}
- /* the current contents of SMBHSTCNT can be overwritten, since PEC,
- * SMBSCMD are passed in xact */
outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
status = i801_wait_intr(priv);
@@ -790,7 +787,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
{
int hwpec;
int block = 0;
- int ret = 0, xact = 0;
+ int ret, xact;
struct i801_priv *priv = i2c_get_adapdata(adap);
mutex_lock(&priv->acpi_lock);
@@ -836,6 +833,14 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
}
xact = I801_WORD_DATA;
break;
+ case I2C_SMBUS_PROC_CALL:
+ outb_p((addr & 0x7f) << 1, SMBHSTADD(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;
+ break;
case I2C_SMBUS_BLOCK_DATA:
outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
SMBHSTADD(priv));
@@ -902,12 +907,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
goto out;
- switch (xact & 0x7f) {
+ 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;
@@ -933,6 +939,7 @@ static u32 i801_func(struct i2c_adapter *adapter)
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_PROC_CALL |
I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
((priv->features & FEATURE_BLOCK_PROC) ?
@@ -1041,6 +1048,7 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE_DATA(INTEL, ALDER_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
+ { PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ 0, }
};