[PATCH] I2C: ALI1563 SMBus driver fix

This patch fixes "grave" bugs in i2c-ali1563 driver. It seems on recent
chipset revisions the HSTS_DONE is set only for block transfers, so we
must detect the end of ordinary transaction other way. Also due to missing
and mask, setting other transfer modes was not possible. Moreover the
continous byte mode transfer uses DAT0 for command rather than CMD command.
All those changes were tested with help of Chunhao Huang from Winbond.

I'm willing to maintain the driver. Second patch adds me as maintainer
if this is neccessary.

Signed-Off-By: Rudolf Marek <r.marek@sh.cvut.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

R.Marek@sh.cvut.cz and committed by
Greg KH
4a4e5787 2e3e80c2

+37 -15
+6
MAINTAINERS
··· 239 W: http://www.linux-usb.org/SpeedTouch/ 240 S: Maintained 241 242 ALPHA PORT 243 P: Richard Henderson 244 M: rth@twiddle.net
··· 239 W: http://www.linux-usb.org/SpeedTouch/ 240 S: Maintained 241 242 + ALI1563 I2C DRIVER 243 + P: Rudolf Marek 244 + M: r.marek@sh.cvut.cz 245 + L: sensors@stimpy.netroedge.com 246 + S: Maintained 247 + 248 ALPHA PORT 249 P: Richard Henderson 250 M: rth@twiddle.net
+31 -15
drivers/i2c/busses/i2c-ali1563.c
··· 2 * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge 3 * 4 * Copyright (C) 2004 Patrick Mochel 5 * 6 * The 1563 southbridge is deceptively similar to the 1533, with a 7 * few notable exceptions. One of those happens to be the fact they ··· 58 #define HST_CNTL2_BLOCK 0x05 59 60 61 62 static unsigned short ali1563_smba; 63 64 - static int ali1563_transaction(struct i2c_adapter * a) 65 { 66 u32 data; 67 int timeout; ··· 75 76 data = inb_p(SMB_HST_STS); 77 if (data & HST_STS_BAD) { 78 - dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); 79 outb_p(data | HST_STS_BAD,SMB_HST_STS); 80 data = inb_p(SMB_HST_STS); 81 if (data & HST_STS_BAD) ··· 96 97 if (timeout && !(data & HST_STS_BAD)) 98 return 0; 99 - dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", 100 - timeout ? "Timeout " : "", 101 - data & HST_STS_FAIL ? "Transaction Failed " : "", 102 - data & HST_STS_BUSERR ? "No response or Bus Collision " : "", 103 - data & HST_STS_DEVERR ? "Device Error " : "", 104 - !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); 105 106 - if (!(data & HST_STS_DONE)) 107 /* Issue 'kill' to host controller */ 108 outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); 109 - else 110 - /* Issue timeout to reset all devices on bus */ 111 outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); 112 return -1; 113 } 114 ··· 163 164 if (timeout && !(data & HST_STS_BAD)) 165 return 0; 166 - dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", 167 timeout ? "Timeout " : "", 168 data & HST_STS_FAIL ? "Transaction Failed " : "", 169 data & HST_STS_BUSERR ? "No response or Bus Collision " : "", ··· 256 } 257 258 outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); 259 - outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2); 260 261 /* Write the command register */ 262 switch(size) { 263 case HST_CNTL2_BYTE: 264 if (rw== I2C_SMBUS_WRITE) 265 - outb_p(cmd, SMB_HST_CMD); 266 break; 267 case HST_CNTL2_BYTE_DATA: 268 outb_p(cmd, SMB_HST_CMD); ··· 284 goto Done; 285 } 286 287 - if ((error = ali1563_transaction(a))) 288 goto Done; 289 290 if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))
··· 2 * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge 3 * 4 * Copyright (C) 2004 Patrick Mochel 5 + * 2005 Rudolf Marek <r.marek@sh.cvut.cz> 6 * 7 * The 1563 southbridge is deceptively similar to the 1533, with a 8 * few notable exceptions. One of those happens to be the fact they ··· 57 #define HST_CNTL2_BLOCK 0x05 58 59 60 + #define HST_CNTL2_SIZEMASK 0x38 61 62 static unsigned short ali1563_smba; 63 64 + static int ali1563_transaction(struct i2c_adapter * a, int size) 65 { 66 u32 data; 67 int timeout; ··· 73 74 data = inb_p(SMB_HST_STS); 75 if (data & HST_STS_BAD) { 76 + dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); 77 outb_p(data | HST_STS_BAD,SMB_HST_STS); 78 data = inb_p(SMB_HST_STS); 79 if (data & HST_STS_BAD) ··· 94 95 if (timeout && !(data & HST_STS_BAD)) 96 return 0; 97 98 + if (!timeout) { 99 + dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n"); 100 /* Issue 'kill' to host controller */ 101 outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); 102 + data = inb_p(SMB_HST_STS); 103 + } 104 + 105 + /* device error - no response, ignore the autodetection case */ 106 + if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { 107 + dev_err(&a->dev, "Device error!\n"); 108 + } 109 + 110 + /* bus collision */ 111 + if (data & HST_STS_BUSERR) { 112 + dev_err(&a->dev, "Bus collision!\n"); 113 + /* Issue timeout, hoping it helps */ 114 outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); 115 + } 116 + 117 + if (data & HST_STS_FAIL) { 118 + dev_err(&a->dev, "Cleaning fail after KILL!\n"); 119 + outb_p(0x0,SMB_HST_CNTL2); 120 + } 121 + 122 return -1; 123 } 124 ··· 149 150 if (timeout && !(data & HST_STS_BAD)) 151 return 0; 152 + dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", 153 timeout ? "Timeout " : "", 154 data & HST_STS_FAIL ? "Transaction Failed " : "", 155 data & HST_STS_BUSERR ? "No response or Bus Collision " : "", ··· 242 } 243 244 outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); 245 + outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); 246 247 /* Write the command register */ 248 + 249 switch(size) { 250 case HST_CNTL2_BYTE: 251 if (rw== I2C_SMBUS_WRITE) 252 + /* Beware it uses DAT0 register and not CMD! */ 253 + outb_p(cmd, SMB_HST_DAT0); 254 break; 255 case HST_CNTL2_BYTE_DATA: 256 outb_p(cmd, SMB_HST_CMD); ··· 268 goto Done; 269 } 270 271 + if ((error = ali1563_transaction(a, size))) 272 goto Done; 273 274 if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))