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