aboutsummaryrefslogtreecommitdiffstats
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.c249
1 files changed, 166 insertions, 83 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 611b57192c96..8f5c686123b8 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -22,12 +22,12 @@
22 22
23/* 23/*
24 SUPPORTED DEVICES PCI ID 24 SUPPORTED DEVICES PCI ID
25 82801AA 2413 25 82801AA 2413
26 82801AB 2423 26 82801AB 2423
27 82801BA 2443 27 82801BA 2443
28 82801CA/CAM 2483 28 82801CA/CAM 2483
29 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported) 29 82801DB 24C3 (HW PEC supported)
30 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported) 30 82801EB 24D3 (HW PEC supported)
31 6300ESB 25A4 31 6300ESB 25A4
32 ICH6 266A 32 ICH6 266A
33 ICH7 27DA 33 ICH7 27DA
@@ -74,6 +74,13 @@
74#define SMBHSTCFG_SMB_SMI_EN 2 74#define SMBHSTCFG_SMB_SMI_EN 2
75#define SMBHSTCFG_I2C_EN 4 75#define SMBHSTCFG_I2C_EN 4
76 76
77/* Auxillary control register bits, ICH4+ only */
78#define SMBAUXCTL_CRC 1
79#define SMBAUXCTL_E32B 2
80
81/* kill bit for SMBHSTCNT */
82#define SMBHSTCNT_KILL 2
83
77/* Other settings */ 84/* Other settings */
78#define MAX_TIMEOUT 100 85#define MAX_TIMEOUT 100
79#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ 86#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */
@@ -91,10 +98,15 @@
91#define I801_START 0x40 98#define I801_START 0x40
92#define I801_PEC_EN 0x80 /* ICH4 only */ 99#define I801_PEC_EN 0x80 /* ICH4 only */
93 100
94 101/* I801 Hosts Status register bits */
95static int i801_transaction(void); 102#define SMBHSTSTS_BYTE_DONE 0x80
96static int i801_block_transaction(union i2c_smbus_data *data, char read_write, 103#define SMBHSTSTS_INUSE_STS 0x40
97 int command, int hwpec); 104#define SMBHSTSTS_SMBALERT_STS 0x20
105#define SMBHSTSTS_FAILED 0x10
106#define SMBHSTSTS_BUS_ERR 0x08
107#define SMBHSTSTS_DEV_ERR 0x04
108#define SMBHSTSTS_INTR 0x02
109#define SMBHSTSTS_HOST_BUSY 0x01
98 110
99static unsigned long i801_smba; 111static unsigned long i801_smba;
100static unsigned char i801_original_hstcfg; 112static unsigned char i801_original_hstcfg;
@@ -102,7 +114,7 @@ static struct pci_driver i801_driver;
102static struct pci_dev *I801_dev; 114static struct pci_dev *I801_dev;
103static int isich4; 115static int isich4;
104 116
105static int i801_transaction(void) 117static int i801_transaction(int xact)
106{ 118{
107 int temp; 119 int temp;
108 int result = 0; 120 int result = 0;
@@ -127,33 +139,40 @@ static int i801_transaction(void)
127 } 139 }
128 } 140 }
129 141
130 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); 142 /* the current contents of SMBHSTCNT can be overwritten, since PEC,
143 * INTREN, SMBSCMD are passed in xact */
144 outb_p(xact | I801_START, SMBHSTCNT);
131 145
132 /* We will always wait for a fraction of a second! */ 146 /* We will always wait for a fraction of a second! */
133 do { 147 do {
134 msleep(1); 148 msleep(1);
135 temp = inb_p(SMBHSTSTS); 149 temp = inb_p(SMBHSTSTS);
136 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); 150 } while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
137 151
138 /* If the SMBus is still busy, we give up */ 152 /* If the SMBus is still busy, we give up */
139 if (timeout >= MAX_TIMEOUT) { 153 if (timeout >= MAX_TIMEOUT) {
140 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); 154 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
141 result = -1; 155 result = -1;
156 /* try to stop the current command */
157 dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
158 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
159 msleep(1);
160 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
142 } 161 }
143 162
144 if (temp & 0x10) { 163 if (temp & SMBHSTSTS_FAILED) {
145 result = -1; 164 result = -1;
146 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); 165 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
147 } 166 }
148 167
149 if (temp & 0x08) { 168 if (temp & SMBHSTSTS_BUS_ERR) {
150 result = -1; 169 result = -1;
151 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " 170 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
152 "until next hard reset. (sorry!)\n"); 171 "until next hard reset. (sorry!)\n");
153 /* Clock stops and slave is stuck in mid-transmission */ 172 /* Clock stops and slave is stuck in mid-transmission */
154 } 173 }
155 174
156 if (temp & 0x04) { 175 if (temp & SMBHSTSTS_DEV_ERR) {
157 result = -1; 176 result = -1;
158 dev_dbg(&I801_dev->dev, "Error: no response!\n"); 177 dev_dbg(&I801_dev->dev, "Error: no response!\n");
159 } 178 }
@@ -172,44 +191,70 @@ static int i801_transaction(void)
172 return result; 191 return result;
173} 192}
174 193
175/* All-inclusive block transaction function */ 194/* wait for INTR bit as advised by Intel */
176static int i801_block_transaction(union i2c_smbus_data *data, char read_write, 195static void i801_wait_hwpec(void)
177 int command, int hwpec) 196{
197 int timeout = 0;
198 int temp;
199
200 do {
201 msleep(1);
202 temp = inb_p(SMBHSTSTS);
203 } while ((!(temp & SMBHSTSTS_INTR))
204 && (timeout++ < MAX_TIMEOUT));
205
206 if (timeout >= MAX_TIMEOUT) {
207 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
208 }
209 outb_p(temp, SMBHSTSTS);
210}
211
212static int i801_block_transaction_by_block(union i2c_smbus_data *data,
213 char read_write, int hwpec)
214{
215 int i, len;
216
217 inb_p(SMBHSTCNT); /* reset the data buffer index */
218
219 /* Use 32-byte buffer to process this transaction */
220 if (read_write == I2C_SMBUS_WRITE) {
221 len = data->block[0];
222 outb_p(len, SMBHSTDAT0);
223 for (i = 0; i < len; i++)
224 outb_p(data->block[i+1], SMBBLKDAT);
225 }
226
227 if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
228 I801_PEC_EN * hwpec))
229 return -1;
230
231 if (read_write == I2C_SMBUS_READ) {
232 len = inb_p(SMBHSTDAT0);
233 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
234 return -1;
235
236 data->block[0] = len;
237 for (i = 0; i < len; i++)
238 data->block[i + 1] = inb_p(SMBBLKDAT);
239 }
240 return 0;
241}
242
243static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
244 char read_write, int hwpec)
178{ 245{
179 int i, len; 246 int i, len;
180 int smbcmd; 247 int smbcmd;
181 int temp; 248 int temp;
182 int result = 0; 249 int result = 0;
183 int timeout; 250 int timeout;
184 unsigned char hostc, errmask; 251 unsigned char errmask;
185 252
186 if (command == I2C_SMBUS_I2C_BLOCK_DATA) { 253 len = data->block[0];
187 if (read_write == I2C_SMBUS_WRITE) {
188 /* set I2C_EN bit in configuration register */
189 pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
190 pci_write_config_byte(I801_dev, SMBHSTCFG,
191 hostc | SMBHSTCFG_I2C_EN);
192 } else {
193 dev_err(&I801_dev->dev,
194 "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
195 return -1;
196 }
197 }
198 254
199 if (read_write == I2C_SMBUS_WRITE) { 255 if (read_write == I2C_SMBUS_WRITE) {
200 len = data->block[0];
201 if (len < 1)
202 len = 1;
203 if (len > 32)
204 len = 32;
205 outb_p(len, SMBHSTDAT0); 256 outb_p(len, SMBHSTDAT0);
206 outb_p(data->block[1], SMBBLKDAT); 257 outb_p(data->block[1], SMBBLKDAT);
207 } else {
208 len = 32; /* max for reads */
209 }
210
211 if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
212 /* set 32 byte buffer */
213 } 258 }
214 259
215 for (i = 1; i <= len; i++) { 260 for (i = 1; i <= len; i++) {
@@ -227,13 +272,13 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
227 /* Make sure the SMBus host is ready to start transmitting */ 272 /* Make sure the SMBus host is ready to start transmitting */
228 temp = inb_p(SMBHSTSTS); 273 temp = inb_p(SMBHSTSTS);
229 if (i == 1) { 274 if (i == 1) {
230 /* Erronenous conditions before transaction: 275 /* Erronenous conditions before transaction:
231 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ 276 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
232 errmask=0x9f; 277 errmask = 0x9f;
233 } else { 278 } else {
234 /* Erronenous conditions during transaction: 279 /* Erronenous conditions during transaction:
235 * Failed, Bus_Err, Dev_Err, Intr */ 280 * Failed, Bus_Err, Dev_Err, Intr */
236 errmask=0x1e; 281 errmask = 0x1e;
237 } 282 }
238 if (temp & errmask) { 283 if (temp & errmask) {
239 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " 284 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
@@ -242,14 +287,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
242 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { 287 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
243 dev_err(&I801_dev->dev, 288 dev_err(&I801_dev->dev,
244 "Reset failed! (%02x)\n", temp); 289 "Reset failed! (%02x)\n", temp);
245 result = -1; 290 return -1;
246 goto END;
247 } 291 }
248 if (i != 1) { 292 if (i != 1)
249 /* if die in middle of block transaction, fail */ 293 /* if die in middle of block transaction, fail */
250 result = -1; 294 return -1;
251 goto END;
252 }
253 } 295 }
254 296
255 if (i == 1) 297 if (i == 1)
@@ -261,33 +303,38 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
261 msleep(1); 303 msleep(1);
262 temp = inb_p(SMBHSTSTS); 304 temp = inb_p(SMBHSTSTS);
263 } 305 }
264 while ((!(temp & 0x80)) 306 while ((!(temp & SMBHSTSTS_BYTE_DONE))
265 && (timeout++ < MAX_TIMEOUT)); 307 && (timeout++ < MAX_TIMEOUT));
266 308
267 /* If the SMBus is still busy, we give up */ 309 /* If the SMBus is still busy, we give up */
268 if (timeout >= MAX_TIMEOUT) { 310 if (timeout >= MAX_TIMEOUT) {
311 /* try to stop the current command */
312 dev_dbg(&I801_dev->dev, "Terminating the current "
313 "operation\n");
314 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
315 msleep(1);
316 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
317 SMBHSTCNT);
269 result = -1; 318 result = -1;
270 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); 319 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
271 } 320 }
272 321
273 if (temp & 0x10) { 322 if (temp & SMBHSTSTS_FAILED) {
274 result = -1; 323 result = -1;
275 dev_dbg(&I801_dev->dev, 324 dev_dbg(&I801_dev->dev,
276 "Error: Failed bus transaction\n"); 325 "Error: Failed bus transaction\n");
277 } else if (temp & 0x08) { 326 } else if (temp & SMBHSTSTS_BUS_ERR) {
278 result = -1; 327 result = -1;
279 dev_err(&I801_dev->dev, "Bus collision!\n"); 328 dev_err(&I801_dev->dev, "Bus collision!\n");
280 } else if (temp & 0x04) { 329 } else if (temp & SMBHSTSTS_DEV_ERR) {
281 result = -1; 330 result = -1;
282 dev_dbg(&I801_dev->dev, "Error: no response!\n"); 331 dev_dbg(&I801_dev->dev, "Error: no response!\n");
283 } 332 }
284 333
285 if (i == 1 && read_write == I2C_SMBUS_READ) { 334 if (i == 1 && read_write == I2C_SMBUS_READ) {
286 len = inb_p(SMBHSTDAT0); 335 len = inb_p(SMBHSTDAT0);
287 if (len < 1) 336 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
288 len = 1; 337 return -1;
289 if (len > 32)
290 len = 32;
291 data->block[0] = len; 338 data->block[0] = len;
292 } 339 }
293 340
@@ -310,25 +357,58 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
310 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); 357 inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
311 358
312 if (result < 0) 359 if (result < 0)
313 goto END; 360 return result;
314 } 361 }
362 return result;
363}
315 364
316 if (hwpec) { 365static int i801_set_block_buffer_mode(void)
317 /* wait for INTR bit as advised by Intel */ 366{
318 timeout = 0; 367 outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
319 do { 368 if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
320 msleep(1); 369 return -1;
321 temp = inb_p(SMBHSTSTS); 370 return 0;
322 } while ((!(temp & 0x02)) 371}
323 && (timeout++ < MAX_TIMEOUT));
324 372
325 if (timeout >= MAX_TIMEOUT) { 373/* Block transaction function */
326 dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); 374static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
375 int command, int hwpec)
376{
377 int result = 0;
378 unsigned char hostc;
379
380 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
381 if (read_write == I2C_SMBUS_WRITE) {
382 /* set I2C_EN bit in configuration register */
383 pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
384 pci_write_config_byte(I801_dev, SMBHSTCFG,
385 hostc | SMBHSTCFG_I2C_EN);
386 } else {
387 dev_err(&I801_dev->dev,
388 "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
389 return -1;
327 } 390 }
328 outb_p(temp, SMBHSTSTS);
329 } 391 }
330 result = 0; 392
331END: 393 if (read_write == I2C_SMBUS_WRITE) {
394 if (data->block[0] < 1)
395 data->block[0] = 1;
396 if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
397 data->block[0] = I2C_SMBUS_BLOCK_MAX;
398 } else {
399 data->block[0] = 32; /* max for reads */
400 }
401
402 if (isich4 && i801_set_block_buffer_mode() == 0 )
403 result = i801_block_transaction_by_block(data, read_write,
404 hwpec);
405 else
406 result = i801_block_transaction_byte_by_byte(data, read_write,
407 hwpec);
408
409 if (result == 0 && hwpec)
410 i801_wait_hwpec();
411
332 if (command == I2C_SMBUS_I2C_BLOCK_DATA) { 412 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
333 /* restore saved configuration register value */ 413 /* restore saved configuration register value */
334 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); 414 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
@@ -393,19 +473,22 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
393 return -1; 473 return -1;
394 } 474 }
395 475
396 outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */ 476 if (hwpec) /* enable/disable hardware PEC */
477 outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_CRC, SMBAUXCTL);
478 else
479 outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
397 480
398 if(block) 481 if(block)
399 ret = i801_block_transaction(data, read_write, size, hwpec); 482 ret = i801_block_transaction(data, read_write, size, hwpec);
400 else { 483 else
401 outb_p(xact | ENABLE_INT9, SMBHSTCNT); 484 ret = i801_transaction(xact | ENABLE_INT9);
402 ret = i801_transaction();
403 }
404 485
405 /* Some BIOSes don't like it when PEC is enabled at reboot or resume 486 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
406 time, so we forcibly disable it after every transaction. */ 487 time, so we forcibly disable it after every transaction. Turn off
488 E32B for the same reason. */
407 if (hwpec) 489 if (hwpec)
408 outb_p(0, SMBAUXCTL); 490 outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
491 SMBAUXCTL);
409 492
410 if(block) 493 if(block)
411 return ret; 494 return ret;