Automatic merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/gregkh/i2c-2.6
This commit is contained in:
commit
a340ba1071
|
@ -239,6 +239,12 @@ L: linux-usb-devel@lists.sourceforge.net
|
||||||
W: http://www.linux-usb.org/SpeedTouch/
|
W: http://www.linux-usb.org/SpeedTouch/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ALI1563 I2C DRIVER
|
||||||
|
P: Rudolf Marek
|
||||||
|
M: r.marek@sh.cvut.cz
|
||||||
|
L: sensors@stimpy.netroedge.com
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ALPHA PORT
|
ALPHA PORT
|
||||||
P: Richard Henderson
|
P: Richard Henderson
|
||||||
M: rth@twiddle.net
|
M: rth@twiddle.net
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
|
* i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Patrick Mochel
|
* Copyright (C) 2004 Patrick Mochel
|
||||||
|
* 2005 Rudolf Marek <r.marek@sh.cvut.cz>
|
||||||
*
|
*
|
||||||
* The 1563 southbridge is deceptively similar to the 1533, with a
|
* The 1563 southbridge is deceptively similar to the 1533, with a
|
||||||
* few notable exceptions. One of those happens to be the fact they
|
* few notable exceptions. One of those happens to be the fact they
|
||||||
|
@ -57,10 +58,11 @@
|
||||||
#define HST_CNTL2_BLOCK 0x05
|
#define HST_CNTL2_BLOCK 0x05
|
||||||
|
|
||||||
|
|
||||||
|
#define HST_CNTL2_SIZEMASK 0x38
|
||||||
|
|
||||||
static unsigned short ali1563_smba;
|
static unsigned short ali1563_smba;
|
||||||
|
|
||||||
static int ali1563_transaction(struct i2c_adapter * a)
|
static int ali1563_transaction(struct i2c_adapter * a, int size)
|
||||||
{
|
{
|
||||||
u32 data;
|
u32 data;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a)
|
||||||
|
|
||||||
data = inb_p(SMB_HST_STS);
|
data = inb_p(SMB_HST_STS);
|
||||||
if (data & HST_STS_BAD) {
|
if (data & HST_STS_BAD) {
|
||||||
dev_warn(&a->dev,"ali1563: Trying to reset busy device\n");
|
dev_err(&a->dev, "ali1563: Trying to reset busy device\n");
|
||||||
outb_p(data | HST_STS_BAD,SMB_HST_STS);
|
outb_p(data | HST_STS_BAD,SMB_HST_STS);
|
||||||
data = inb_p(SMB_HST_STS);
|
data = inb_p(SMB_HST_STS);
|
||||||
if (data & HST_STS_BAD)
|
if (data & HST_STS_BAD)
|
||||||
|
@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a)
|
||||||
|
|
||||||
if (timeout && !(data & HST_STS_BAD))
|
if (timeout && !(data & HST_STS_BAD))
|
||||||
return 0;
|
return 0;
|
||||||
dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n",
|
|
||||||
timeout ? "Timeout " : "",
|
|
||||||
data & HST_STS_FAIL ? "Transaction Failed " : "",
|
|
||||||
data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
|
|
||||||
data & HST_STS_DEVERR ? "Device Error " : "",
|
|
||||||
!(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
|
|
||||||
|
|
||||||
if (!(data & HST_STS_DONE))
|
if (!timeout) {
|
||||||
|
dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n");
|
||||||
/* Issue 'kill' to host controller */
|
/* Issue 'kill' to host controller */
|
||||||
outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
|
outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
|
||||||
else
|
data = inb_p(SMB_HST_STS);
|
||||||
/* Issue timeout to reset all devices on bus */
|
}
|
||||||
|
|
||||||
|
/* device error - no response, ignore the autodetection case */
|
||||||
|
if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) {
|
||||||
|
dev_err(&a->dev, "Device error!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bus collision */
|
||||||
|
if (data & HST_STS_BUSERR) {
|
||||||
|
dev_err(&a->dev, "Bus collision!\n");
|
||||||
|
/* Issue timeout, hoping it helps */
|
||||||
outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1);
|
outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data & HST_STS_FAIL) {
|
||||||
|
dev_err(&a->dev, "Cleaning fail after KILL!\n");
|
||||||
|
outb_p(0x0,SMB_HST_CNTL2);
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a)
|
||||||
|
|
||||||
if (timeout && !(data & HST_STS_BAD))
|
if (timeout && !(data & HST_STS_BAD))
|
||||||
return 0;
|
return 0;
|
||||||
dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n",
|
dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n",
|
||||||
timeout ? "Timeout " : "",
|
timeout ? "Timeout " : "",
|
||||||
data & HST_STS_FAIL ? "Transaction Failed " : "",
|
data & HST_STS_FAIL ? "Transaction Failed " : "",
|
||||||
data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
|
data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
|
||||||
|
@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD);
|
outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD);
|
||||||
outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2);
|
outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2);
|
||||||
|
|
||||||
/* Write the command register */
|
/* Write the command register */
|
||||||
|
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case HST_CNTL2_BYTE:
|
case HST_CNTL2_BYTE:
|
||||||
if (rw== I2C_SMBUS_WRITE)
|
if (rw== I2C_SMBUS_WRITE)
|
||||||
outb_p(cmd, SMB_HST_CMD);
|
/* Beware it uses DAT0 register and not CMD! */
|
||||||
|
outb_p(cmd, SMB_HST_DAT0);
|
||||||
break;
|
break;
|
||||||
case HST_CNTL2_BYTE_DATA:
|
case HST_CNTL2_BYTE_DATA:
|
||||||
outb_p(cmd, SMB_HST_CMD);
|
outb_p(cmd, SMB_HST_CMD);
|
||||||
|
@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = ali1563_transaction(a)))
|
if ((error = ali1563_transaction(a, size)))
|
||||||
goto Done;
|
goto Done;
|
||||||
|
|
||||||
if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))
|
if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))
|
||||||
|
|
Loading…
Reference in New Issue