// SPDX-License-Identifier: GPL-2.0-only /* * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge * * Copyright (C) 2004 Patrick Mochel * 2005 Rudolf Marek <r.marek@assembler.cz> * * The 1563 southbridge is deceptively similar to the 1533, with a * few notable exceptions. One of those happens to be the fact they * upgraded the i2c core to be 2.0 compliant, and happens to be almost * identical to the i2c controller found in the Intel 801 south * bridges. * * This driver is based on a mix of the 15x3, 1535, and i801 drivers, * with a little help from the ALi 1563 spec.
*/
for (i = 0; i < len; i++) { if (rw == I2C_SMBUS_WRITE) {
outb_p(data->block[i + 1], SMB_BLK_DAT);
error = ali1563_block_start(a); if (error) break;
} else {
error = ali1563_block_start(a); if (error) break; if (i == 0) {
len = inb_p(SMB_HST_DAT0); if (len < 1)
len = 1; elseif (len > 32)
len = 32;
}
data->block[i+1] = inb_p(SMB_BLK_DAT);
}
} /* Do we need this? */
outb_p(HST_CNTL1_LAST, SMB_HST_CNTL1); return error;
}
static s32 ali1563_access(struct i2c_adapter *a, u16 addr, unsignedshort flags, char rw, u8 cmd, int size, union i2c_smbus_data *data)
{ int error = 0; int timeout;
u32 reg;
for (timeout = ALI1563_MAX_TIMEOUT; timeout; timeout--) {
reg = inb_p(SMB_HST_STS); if (!(reg & HST_STS_BUSY)) break;
} if (!timeout)
dev_warn(&a->dev, "SMBus not idle. HST_STS = %02x\n", reg);
outb_p(0xff, SMB_HST_STS);
/* Map the size to what the chip understands */ switch (size) { case I2C_SMBUS_QUICK:
size = HST_CNTL2_QUICK; break; case I2C_SMBUS_BYTE:
size = HST_CNTL2_BYTE; break; case I2C_SMBUS_BYTE_DATA:
size = HST_CNTL2_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA:
size = HST_CNTL2_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA:
size = HST_CNTL2_BLOCK; break; default:
dev_warn(&a->dev, "Unsupported transaction %d\n", size);
error = -EOPNOTSUPP; goto Done;
}
/* SMB I/O Base in high 12 bits and must be aligned with the
* size of the I/O space. */
ali1563_smba = ctrl & ~(ALI1563_SMB_IOSIZE - 1); if (!ali1563_smba) {
dev_warn(&dev->dev, "ali1563_smba Uninitialized\n"); goto Err;
}
/* Check if device is enabled */ if (!(ctrl & ALI1563_SMB_HOSTEN)) {
dev_warn(&dev->dev, "Host Controller not enabled\n"); goto Err;
} if (!(ctrl & ALI1563_SMB_IOEN)) {
dev_warn(&dev->dev, "I/O space not enabled, trying manually\n");
pci_write_config_word(dev, ALI1563_SMBBA,
ctrl | ALI1563_SMB_IOEN);
pci_read_config_word(dev, ALI1563_SMBBA, &ctrl); if (!(ctrl & ALI1563_SMB_IOEN)) {
dev_err(&dev->dev, "I/O space still not enabled, giving up\n"); goto Err;
}
}
if (acpi_check_region(ali1563_smba, ALI1563_SMB_IOSIZE,
ali1563_pci_driver.name)) goto Err;
if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
ali1563_pci_driver.name)) {
dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n",
ali1563_smba); goto Err;
}
dev_info(&dev->dev, "Found ALi1563 SMBus at 0x%04x\n", ali1563_smba);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.