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