1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54#include <linux/module.h>
55#include <linux/pci.h>
56#include <linux/kernel.h>
57#include <linux/stddef.h>
58#include <linux/delay.h>
59#include <linux/ioport.h>
60#include <linux/i2c.h>
61#include <linux/init.h>
62#include <linux/acpi.h>
63#include <linux/io.h>
64
65
66
67#define SMBHSTSTS (0 + ali1535_smba)
68#define SMBHSTTYP (1 + ali1535_smba)
69#define SMBHSTPORT (2 + ali1535_smba)
70#define SMBHSTCMD (7 + ali1535_smba)
71#define SMBHSTADD (3 + ali1535_smba)
72#define SMBHSTDAT0 (4 + ali1535_smba)
73#define SMBHSTDAT1 (5 + ali1535_smba)
74#define SMBBLKDAT (6 + ali1535_smba)
75
76
77#define SMBCOM 0x004
78#define SMBREV 0x008
79#define SMBCFG 0x0D1
80#define SMBBA 0x0E2
81#define SMBHSTCFG 0x0F0
82#define SMBCLK 0x0F2
83
84
85#define MAX_TIMEOUT 500
86#define ALI1535_SMB_IOSIZE 32
87
88#define ALI1535_SMB_DEFAULTBASE 0x8040
89
90
91#define ALI1535_LOCK 0x06
92
93
94#define ALI1535_QUICK 0x00
95#define ALI1535_BYTE 0x10
96#define ALI1535_BYTE_DATA 0x20
97#define ALI1535_WORD_DATA 0x30
98#define ALI1535_BLOCK_DATA 0x40
99#define ALI1535_I2C_READ 0x60
100
101#define ALI1535_DEV10B_EN 0x80
102
103#define ALI1535_T_OUT 0x08
104#define ALI1535_A_HIGH_BIT9 0x08
105
106
107#define ALI1535_KILL 0x04
108#define ALI1535_A_HIGH_BIT8 0x04
109
110
111
112#define ALI1535_D_HI_MASK 0x03
113
114
115
116
117#define ALI1535_STS_IDLE 0x04
118#define ALI1535_STS_BUSY 0x08
119#define ALI1535_STS_DONE 0x10
120#define ALI1535_STS_DEV 0x20
121#define ALI1535_STS_BUSERR 0x40
122#define ALI1535_STS_FAIL 0x80
123#define ALI1535_STS_ERR 0xE0
124
125#define ALI1535_BLOCK_CLR 0x04
126
127
128#define ALI1535_RD_ADDR 0x01
129
130
131
132#define ALI1535_SMBIO_EN 0x04
133
134static struct pci_driver ali1535_driver;
135static unsigned short ali1535_smba;
136
137
138
139
140
141static int __devinit ali1535_setup(struct pci_dev *dev)
142{
143 int retval = -ENODEV;
144 unsigned char temp;
145
146
147
148
149
150
151
152
153 pci_read_config_word(dev, SMBBA, &ali1535_smba);
154 ali1535_smba &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
155 if (ali1535_smba == 0) {
156 dev_warn(&dev->dev,
157 "ALI1535_smb region uninitialized - upgrade BIOS?\n");
158 goto exit;
159 }
160
161 retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
162 ali1535_driver.name);
163 if (retval)
164 goto exit;
165
166 if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
167 ali1535_driver.name)) {
168 dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
169 ali1535_smba);
170 goto exit;
171 }
172
173
174 pci_read_config_byte(dev, SMBCFG, &temp);
175 if ((temp & ALI1535_SMBIO_EN) == 0) {
176 dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
177 goto exit_free;
178 }
179
180
181 pci_read_config_byte(dev, SMBHSTCFG, &temp);
182 if ((temp & 1) == 0) {
183 dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
184 goto exit_free;
185 }
186
187
188 pci_write_config_byte(dev, SMBCLK, 0x20);
189
190
191
192
193
194
195
196
197 pci_read_config_byte(dev, SMBREV, &temp);
198 dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
199 dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba);
200
201 retval = 0;
202exit:
203 return retval;
204
205exit_free:
206 release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
207 return retval;
208}
209
210static int ali1535_transaction(struct i2c_adapter *adap)
211{
212 int temp;
213 int result = 0;
214 int timeout = 0;
215
216 dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
217 "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
218 inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
219 inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
220
221
222 temp = inb_p(SMBHSTSTS);
223
224
225
226 if (temp & ALI1535_STS_BUSY) {
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 dev_info(&adap->dev,
247 "Resetting entire SMB Bus to clear busy condition (%02x)\n",
248 temp);
249 outb_p(ALI1535_T_OUT, SMBHSTTYP);
250 temp = inb_p(SMBHSTSTS);
251 }
252
253
254 if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
255
256 outb_p(0xFF, SMBHSTSTS);
257 if ((temp = inb_p(SMBHSTSTS)) &
258 (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
259
260
261
262
263 dev_err(&adap->dev,
264 "SMBus reset failed! (0x%02x) - controller or "
265 "device on bus is probably hung\n", temp);
266 return -EBUSY;
267 }
268 } else {
269
270 if (temp & ALI1535_STS_DONE) {
271 outb_p(temp, SMBHSTSTS);
272 }
273 }
274
275
276 outb_p(0xFF, SMBHSTPORT);
277
278
279 timeout = 0;
280 do {
281 msleep(1);
282 temp = inb_p(SMBHSTSTS);
283 } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
284 && (timeout++ < MAX_TIMEOUT));
285
286
287 if (timeout > MAX_TIMEOUT) {
288 result = -ETIMEDOUT;
289 dev_err(&adap->dev, "SMBus Timeout!\n");
290 }
291
292 if (temp & ALI1535_STS_FAIL) {
293 result = -EIO;
294 dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
295 }
296
297
298
299
300
301 if (temp & ALI1535_STS_BUSERR) {
302 result = -ENXIO;
303 dev_dbg(&adap->dev,
304 "Error: no response or bus collision ADD=%02x\n",
305 inb_p(SMBHSTADD));
306 }
307
308
309 if (temp & ALI1535_STS_DEV) {
310 result = -EIO;
311 dev_err(&adap->dev, "Error: device error\n");
312 }
313
314
315 if (!(temp & ALI1535_STS_DONE)) {
316 result = -ETIMEDOUT;
317 dev_err(&adap->dev, "Error: command never completed\n");
318 }
319
320 dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
321 "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
322 inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
323 inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
324
325
326 if (!(temp & ALI1535_STS_DONE)) {
327
328 outb_p(ALI1535_KILL,SMBHSTTYP);
329 outb_p(0xFF,SMBHSTSTS);
330 } else if (temp & ALI1535_STS_ERR) {
331
332 outb_p(ALI1535_T_OUT,SMBHSTTYP);
333 outb_p(0xFF,SMBHSTSTS);
334 }
335
336 return result;
337}
338
339
340static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
341 unsigned short flags, char read_write, u8 command,
342 int size, union i2c_smbus_data *data)
343{
344 int i, len;
345 int temp;
346 int timeout;
347 s32 result = 0;
348
349
350 temp = inb_p(SMBHSTSTS);
351 for (timeout = 0;
352 (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
353 timeout++) {
354 msleep(1);
355 temp = inb_p(SMBHSTSTS);
356 }
357 if (timeout >= MAX_TIMEOUT)
358 dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
359
360
361 outb_p(0xFF, SMBHSTSTS);
362
363 switch (size) {
364 case I2C_SMBUS_QUICK:
365 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
366 SMBHSTADD);
367 size = ALI1535_QUICK;
368 outb_p(size, SMBHSTTYP);
369 break;
370 case I2C_SMBUS_BYTE:
371 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
372 SMBHSTADD);
373 size = ALI1535_BYTE;
374 outb_p(size, SMBHSTTYP);
375 if (read_write == I2C_SMBUS_WRITE)
376 outb_p(command, SMBHSTCMD);
377 break;
378 case I2C_SMBUS_BYTE_DATA:
379 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
380 SMBHSTADD);
381 size = ALI1535_BYTE_DATA;
382 outb_p(size, SMBHSTTYP);
383 outb_p(command, SMBHSTCMD);
384 if (read_write == I2C_SMBUS_WRITE)
385 outb_p(data->byte, SMBHSTDAT0);
386 break;
387 case I2C_SMBUS_WORD_DATA:
388 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
389 SMBHSTADD);
390 size = ALI1535_WORD_DATA;
391 outb_p(size, SMBHSTTYP);
392 outb_p(command, SMBHSTCMD);
393 if (read_write == I2C_SMBUS_WRITE) {
394 outb_p(data->word & 0xff, SMBHSTDAT0);
395 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
396 }
397 break;
398 case I2C_SMBUS_BLOCK_DATA:
399 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
400 SMBHSTADD);
401 size = ALI1535_BLOCK_DATA;
402 outb_p(size, SMBHSTTYP);
403 outb_p(command, SMBHSTCMD);
404 if (read_write == I2C_SMBUS_WRITE) {
405 len = data->block[0];
406 if (len < 0) {
407 len = 0;
408 data->block[0] = len;
409 }
410 if (len > 32) {
411 len = 32;
412 data->block[0] = len;
413 }
414 outb_p(len, SMBHSTDAT0);
415
416 outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
417 for (i = 1; i <= len; i++)
418 outb_p(data->block[i], SMBBLKDAT);
419 }
420 break;
421 default:
422 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
423 result = -EOPNOTSUPP;
424 goto EXIT;
425 }
426
427 result = ali1535_transaction(adap);
428 if (result)
429 goto EXIT;
430
431 if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
432 result = 0;
433 goto EXIT;
434 }
435
436 switch (size) {
437 case ALI1535_BYTE:
438 data->byte = inb_p(SMBHSTDAT0);
439 break;
440 case ALI1535_BYTE_DATA:
441 data->byte = inb_p(SMBHSTDAT0);
442 break;
443 case ALI1535_WORD_DATA:
444 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
445 break;
446 case ALI1535_BLOCK_DATA:
447 len = inb_p(SMBHSTDAT0);
448 if (len > 32)
449 len = 32;
450 data->block[0] = len;
451
452 outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
453 for (i = 1; i <= data->block[0]; i++) {
454 data->block[i] = inb_p(SMBBLKDAT);
455 dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
456 len, i, data->block[i]);
457 }
458 break;
459 }
460EXIT:
461 return result;
462}
463
464
465static u32 ali1535_func(struct i2c_adapter *adapter)
466{
467 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
468 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
469 I2C_FUNC_SMBUS_BLOCK_DATA;
470}
471
472static const struct i2c_algorithm smbus_algorithm = {
473 .smbus_xfer = ali1535_access,
474 .functionality = ali1535_func,
475};
476
477static struct i2c_adapter ali1535_adapter = {
478 .owner = THIS_MODULE,
479 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
480 .algo = &smbus_algorithm,
481};
482
483static const struct pci_device_id ali1535_ids[] = {
484 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
485 { },
486};
487
488MODULE_DEVICE_TABLE (pci, ali1535_ids);
489
490static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
491{
492 if (ali1535_setup(dev)) {
493 dev_warn(&dev->dev,
494 "ALI1535 not detected, module not inserted.\n");
495 return -ENODEV;
496 }
497
498
499 ali1535_adapter.dev.parent = &dev->dev;
500
501 snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
502 "SMBus ALI1535 adapter at %04x", ali1535_smba);
503 return i2c_add_adapter(&ali1535_adapter);
504}
505
506static void __devexit ali1535_remove(struct pci_dev *dev)
507{
508 i2c_del_adapter(&ali1535_adapter);
509 release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
510}
511
512static struct pci_driver ali1535_driver = {
513 .name = "ali1535_smbus",
514 .id_table = ali1535_ids,
515 .probe = ali1535_probe,
516 .remove = __devexit_p(ali1535_remove),
517};
518
519static int __init i2c_ali1535_init(void)
520{
521 return pci_register_driver(&ali1535_driver);
522}
523
524static void __exit i2c_ali1535_exit(void)
525{
526 pci_unregister_driver(&ali1535_driver);
527}
528
529MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
530 "Philip Edelbrock <phil@netroedge.com>, "
531 "Mark D. Studebaker <mdsxyz123@yahoo.com> "
532 "and Dan Eaton <dan.eaton@rocketlogix.com>");
533MODULE_DESCRIPTION("ALI1535 SMBus driver");
534MODULE_LICENSE("GPL");
535
536module_init(i2c_ali1535_init);
537module_exit(i2c_ali1535_exit);
538