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
55
56#include <linux/kernel.h>
57#include <linux/module.h>
58#include <linux/delay.h>
59#include <linux/pci.h>
60#include <linux/ioport.h>
61#include <linux/init.h>
62#include <linux/i2c.h>
63#include <linux/acpi.h>
64#include <linux/io.h>
65
66static int blacklist[] = {
67 PCI_DEVICE_ID_SI_540,
68 PCI_DEVICE_ID_SI_550,
69 PCI_DEVICE_ID_SI_630,
70 PCI_DEVICE_ID_SI_645,
71 PCI_DEVICE_ID_SI_646,
72 PCI_DEVICE_ID_SI_648,
73 PCI_DEVICE_ID_SI_650,
74 PCI_DEVICE_ID_SI_651,
75 PCI_DEVICE_ID_SI_730,
76 PCI_DEVICE_ID_SI_735,
77 PCI_DEVICE_ID_SI_745,
78 PCI_DEVICE_ID_SI_746,
79 PCI_DEVICE_ID_SI_5511,
80
81
82 PCI_DEVICE_ID_SI_5597,
83 PCI_DEVICE_ID_SI_5598,
84 0,
85};
86
87
88#define SIS5595_EXTENT 8
89
90#define SMB_STS_LO 0x00
91#define SMB_STS_HI 0x01
92#define SMB_CTL_LO 0x02
93#define SMB_CTL_HI 0x03
94#define SMB_ADDR 0x04
95#define SMB_CMD 0x05
96#define SMB_PCNT 0x06
97#define SMB_CNT 0x07
98#define SMB_BYTE 0x08
99#define SMB_DEV 0x10
100#define SMB_DB0 0x11
101#define SMB_DB1 0x12
102#define SMB_HAA 0x13
103
104
105#define SMB_INDEX 0x38
106#define SMB_DAT 0x39
107#define SIS5595_ENABLE_REG 0x40
108#define ACPI_BASE 0x90
109
110
111#define MAX_TIMEOUT 500
112
113
114#define SIS5595_QUICK 0x00
115#define SIS5595_BYTE 0x02
116#define SIS5595_BYTE_DATA 0x04
117#define SIS5595_WORD_DATA 0x06
118#define SIS5595_PROC_CALL 0x08
119#define SIS5595_BLOCK_DATA 0x0A
120
121
122
123
124
125static u16 force_addr;
126module_param(force_addr, ushort, 0);
127MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
128
129static struct pci_driver sis5595_driver;
130static unsigned short sis5595_base;
131static struct pci_dev *sis5595_pdev;
132
133static u8 sis5595_read(u8 reg)
134{
135 outb(reg, sis5595_base + SMB_INDEX);
136 return inb(sis5595_base + SMB_DAT);
137}
138
139static void sis5595_write(u8 reg, u8 data)
140{
141 outb(reg, sis5595_base + SMB_INDEX);
142 outb(data, sis5595_base + SMB_DAT);
143}
144
145static int sis5595_setup(struct pci_dev *SIS5595_dev)
146{
147 u16 a;
148 u8 val;
149 int *i;
150 int retval;
151
152
153 for (i = blacklist; *i != 0; i++) {
154 struct pci_dev *dev;
155 dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
156 if (dev) {
157 dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
158 pci_dev_put(dev);
159 return -ENODEV;
160 }
161 }
162
163
164 pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
165 if (sis5595_base == 0 && force_addr == 0) {
166 dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
167 return -ENODEV;
168 }
169
170 if (force_addr)
171 sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
172 dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
173
174
175
176 retval = acpi_check_region(sis5595_base + SMB_INDEX, 2,
177 sis5595_driver.name);
178 if (retval)
179 return retval;
180
181 if (!request_region(sis5595_base + SMB_INDEX, 2,
182 sis5595_driver.name)) {
183 dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
184 sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
185 return -ENODEV;
186 }
187
188 if (force_addr) {
189 dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
190 if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)
191 != PCIBIOS_SUCCESSFUL)
192 goto error;
193 if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)
194 != PCIBIOS_SUCCESSFUL)
195 goto error;
196 if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
197
198 dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
199 goto error;
200 }
201 }
202
203 if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
204 != PCIBIOS_SUCCESSFUL)
205 goto error;
206 if ((val & 0x80) == 0) {
207 dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
208 if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)
209 != PCIBIOS_SUCCESSFUL)
210 goto error;
211 if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
212 != PCIBIOS_SUCCESSFUL)
213 goto error;
214 if ((val & 0x80) == 0) {
215
216 dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
217 goto error;
218 }
219 }
220
221
222 return 0;
223
224error:
225 release_region(sis5595_base + SMB_INDEX, 2);
226 return -ENODEV;
227}
228
229static int sis5595_transaction(struct i2c_adapter *adap)
230{
231 int temp;
232 int result = 0;
233 int timeout = 0;
234
235
236 temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
237 if (temp != 0x00) {
238 dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
239 sis5595_write(SMB_STS_LO, temp & 0xff);
240 sis5595_write(SMB_STS_HI, temp >> 8);
241 if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
242 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
243 return -EBUSY;
244 } else {
245 dev_dbg(&adap->dev, "Successful!\n");
246 }
247 }
248
249
250 sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
251
252
253 do {
254 msleep(1);
255 temp = sis5595_read(SMB_STS_LO);
256 } while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
257
258
259 if (timeout > MAX_TIMEOUT) {
260 dev_dbg(&adap->dev, "SMBus Timeout!\n");
261 result = -ETIMEDOUT;
262 }
263
264 if (temp & 0x10) {
265 dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
266 result = -ENXIO;
267 }
268
269 if (temp & 0x20) {
270 dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
271 "next hard reset (or not...)\n");
272
273 result = -EIO;
274 }
275
276 temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
277 if (temp != 0x00) {
278 sis5595_write(SMB_STS_LO, temp & 0xff);
279 sis5595_write(SMB_STS_HI, temp >> 8);
280 }
281
282 temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
283 if (temp != 0x00)
284 dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
285
286 return result;
287}
288
289
290static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
291 unsigned short flags, char read_write,
292 u8 command, int size, union i2c_smbus_data *data)
293{
294 int status;
295
296 switch (size) {
297 case I2C_SMBUS_QUICK:
298 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
299 size = SIS5595_QUICK;
300 break;
301 case I2C_SMBUS_BYTE:
302 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
303 if (read_write == I2C_SMBUS_WRITE)
304 sis5595_write(SMB_CMD, command);
305 size = SIS5595_BYTE;
306 break;
307 case I2C_SMBUS_BYTE_DATA:
308 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
309 sis5595_write(SMB_CMD, command);
310 if (read_write == I2C_SMBUS_WRITE)
311 sis5595_write(SMB_BYTE, data->byte);
312 size = SIS5595_BYTE_DATA;
313 break;
314 case I2C_SMBUS_PROC_CALL:
315 case I2C_SMBUS_WORD_DATA:
316 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
317 sis5595_write(SMB_CMD, command);
318 if (read_write == I2C_SMBUS_WRITE) {
319 sis5595_write(SMB_BYTE, data->word & 0xff);
320 sis5595_write(SMB_BYTE + 1,
321 (data->word & 0xff00) >> 8);
322 }
323 size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
324 break;
325 default:
326 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
327 return -EOPNOTSUPP;
328 }
329
330 sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
331
332 status = sis5595_transaction(adap);
333 if (status)
334 return status;
335
336 if ((size != SIS5595_PROC_CALL) &&
337 ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
338 return 0;
339
340
341 switch (size) {
342 case SIS5595_BYTE:
343 case SIS5595_BYTE_DATA:
344 data->byte = sis5595_read(SMB_BYTE);
345 break;
346 case SIS5595_WORD_DATA:
347 case SIS5595_PROC_CALL:
348 data->word = sis5595_read(SMB_BYTE) + (sis5595_read(SMB_BYTE + 1) << 8);
349 break;
350 }
351 return 0;
352}
353
354static u32 sis5595_func(struct i2c_adapter *adapter)
355{
356 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
357 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
358 I2C_FUNC_SMBUS_PROC_CALL;
359}
360
361static const struct i2c_algorithm smbus_algorithm = {
362 .smbus_xfer = sis5595_access,
363 .functionality = sis5595_func,
364};
365
366static struct i2c_adapter sis5595_adapter = {
367 .owner = THIS_MODULE,
368 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
369 .algo = &smbus_algorithm,
370};
371
372static DEFINE_PCI_DEVICE_TABLE(sis5595_ids) = {
373 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
374 { 0, }
375};
376
377MODULE_DEVICE_TABLE (pci, sis5595_ids);
378
379static int sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
380{
381 int err;
382
383 if (sis5595_setup(dev)) {
384 dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
385 return -ENODEV;
386 }
387
388
389 sis5595_adapter.dev.parent = &dev->dev;
390
391 snprintf(sis5595_adapter.name, sizeof(sis5595_adapter.name),
392 "SMBus SIS5595 adapter at %04x", sis5595_base + SMB_INDEX);
393 err = i2c_add_adapter(&sis5595_adapter);
394 if (err) {
395 release_region(sis5595_base + SMB_INDEX, 2);
396 return err;
397 }
398
399
400
401
402
403 sis5595_pdev = pci_dev_get(dev);
404 return -ENODEV;
405}
406
407static struct pci_driver sis5595_driver = {
408 .name = "sis5595_smbus",
409 .id_table = sis5595_ids,
410 .probe = sis5595_probe,
411};
412
413static int __init i2c_sis5595_init(void)
414{
415 return pci_register_driver(&sis5595_driver);
416}
417
418static void __exit i2c_sis5595_exit(void)
419{
420 pci_unregister_driver(&sis5595_driver);
421 if (sis5595_pdev) {
422 i2c_del_adapter(&sis5595_adapter);
423 release_region(sis5595_base + SMB_INDEX, 2);
424 pci_dev_put(sis5595_pdev);
425 sis5595_pdev = NULL;
426 }
427}
428
429MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
430MODULE_DESCRIPTION("SIS5595 SMBus driver");
431MODULE_LICENSE("GPL");
432
433module_init(i2c_sis5595_init);
434module_exit(i2c_sis5595_exit);
435