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