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