32 #include <linux/module.h>
33 #include <linux/pci.h>
34 #include <linux/kernel.h>
36 #include <linux/stddef.h>
38 #include <linux/i2c.h>
44 #define SIS96x_BAR 0x04
50 #define SMB_HOST_CNT 0x03
53 #define SMB_PCOUNT 0x06
54 #define SMB_COUNT 0x07
56 #define SMB_DEV_ADDR 0x10
62 #define SMB_IOSIZE 0x20
65 #define MAX_TIMEOUT 500
68 #define SIS96x_QUICK 0x00
69 #define SIS96x_BYTE 0x01
70 #define SIS96x_BYTE_DATA 0x02
71 #define SIS96x_WORD_DATA 0x03
72 #define SIS96x_PROC_CALL 0x04
73 #define SIS96x_BLOCK_DATA 0x05
77 static u16 sis96x_smbus_base;
79 static inline u8 sis96x_read(
u8 reg)
81 return inb(sis96x_smbus_base + reg) ;
86 outb(data, sis96x_smbus_base + reg) ;
92 static int sis96x_transaction(
int size)
98 dev_dbg(&sis96x_adapter.dev,
"SMBus transaction %d\n", size);
101 if (((temp = sis96x_read(
SMB_CNT)) & 0x03) != 0x00) {
103 dev_dbg(&sis96x_adapter.dev,
"SMBus busy (0x%02x). "
104 "Resetting...\n", temp);
110 if (((temp = sis96x_read(
SMB_CNT)) & 0x03) != 0x00) {
111 dev_dbg(&sis96x_adapter.dev,
"Failed (0x%02x)\n", temp);
114 dev_dbg(&sis96x_adapter.dev,
"Successful\n");
123 sis96x_write(
SMB_STS, temp & 0x1e);
132 }
while (!(temp & 0x0e) && (timeout++ <
MAX_TIMEOUT));
136 dev_dbg(&sis96x_adapter.dev,
"SMBus Timeout! (0x%02x)\n", temp);
142 dev_dbg(&sis96x_adapter.dev,
"Failed bus transaction!\n");
148 dev_dbg(&sis96x_adapter.dev,
"Bus collision!\n");
154 if ((temp = sis96x_read(
SMB_STS))) {
155 dev_dbg(&sis96x_adapter.dev,
"Failed reset at "
156 "end of transaction! (0x%02x)\n", temp);
164 unsigned short flags,
char read_write,
171 sis96x_write(
SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
176 sis96x_write(
SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
178 sis96x_write(
SMB_CMD, command);
183 sis96x_write(
SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
184 sis96x_write(
SMB_CMD, command);
192 sis96x_write(
SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
193 sis96x_write(
SMB_CMD, command);
203 dev_warn(&adap->
dev,
"Unsupported transaction %d\n", size);
207 status = sis96x_transaction(size);
238 .smbus_xfer = sis96x_access,
239 .functionality = sis96x_func,
245 .algo = &smbus_algorithm,
261 if (sis96x_smbus_base) {
262 dev_err(&dev->
dev,
"Only one device supported.\n");
268 dev_err(&dev->
dev,
"Unsupported device class 0x%04x!\n", ww);
273 if (!sis96x_smbus_base) {
274 dev_err(&dev->
dev,
"SiS96x SMBus base address "
275 "not initialized!\n");
278 dev_info(&dev->
dev,
"SiS96x SMBus base address: 0x%04x\n",
287 sis96x_driver.name)) {
288 dev_err(&dev->
dev,
"SMBus registers 0x%04x-0x%04x "
289 "already in use!\n", sis96x_smbus_base,
292 sis96x_smbus_base = 0;
297 sis96x_adapter.
dev.parent = &dev->
dev;
300 "SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
303 dev_err(&dev->
dev,
"Couldn't register adapter!\n");
305 sis96x_smbus_base = 0;
313 if (sis96x_smbus_base) {
316 sis96x_smbus_base = 0;
321 .name =
"sis96x_smbus",
322 .id_table = sis96x_ids,
323 .probe = sis96x_probe,