xref: /openbmc/linux/drivers/i2c/busses/i2c-sis5595.c (revision 8f9082c5)
1 /*
2     sis5595.c - Part of lm_sensors, Linux kernel modules for hardware
3               monitoring
4     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
5     Philip Edelbrock <phil@netroedge.com>
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 
22 /* Note: we assume there can only be one SIS5595 with one SMBus interface */
23 
24 /*
25    Note: all have mfr. ID 0x1039.
26    SUPPORTED		PCI ID
27 	5595		0008
28 
29    Note: these chips contain a 0008 device which is incompatible with the
30          5595. We recognize these by the presence of the listed
31          "blacklist" PCI ID and refuse to load.
32 
33    NOT SUPPORTED	PCI ID		BLACKLIST PCI ID
34 	 540		0008		0540
35 	 550		0008		0550
36 	5513		0008		5511
37 	5581		0008		5597
38 	5582		0008		5597
39 	5597		0008		5597
40 	5598		0008		5597/5598
41 	 630		0008		0630
42 	 645		0008		0645
43 	 646		0008		0646
44 	 648		0008		0648
45 	 650		0008		0650
46 	 651		0008		0651
47 	 730		0008		0730
48 	 735		0008		0735
49 	 745		0008		0745
50 	 746		0008		0746
51 */
52 
53 /* TO DO:
54  * Add Block Transfers (ugly, but supported by the adapter)
55  * Add adapter resets
56  */
57 
58 #include <linux/kernel.h>
59 #include <linux/module.h>
60 #include <linux/delay.h>
61 #include <linux/pci.h>
62 #include <linux/ioport.h>
63 #include <linux/init.h>
64 #include <linux/i2c.h>
65 #include <asm/io.h>
66 
67 static int blacklist[] = {
68 	PCI_DEVICE_ID_SI_540,
69 	PCI_DEVICE_ID_SI_550,
70 	PCI_DEVICE_ID_SI_630,
71 	PCI_DEVICE_ID_SI_645,
72 	PCI_DEVICE_ID_SI_646,
73 	PCI_DEVICE_ID_SI_648,
74 	PCI_DEVICE_ID_SI_650,
75 	PCI_DEVICE_ID_SI_651,
76 	PCI_DEVICE_ID_SI_730,
77 	PCI_DEVICE_ID_SI_735,
78 	PCI_DEVICE_ID_SI_745,
79 	PCI_DEVICE_ID_SI_746,
80 	PCI_DEVICE_ID_SI_5511,	/* 5513 chip has the 0008 device but that ID
81 				   shows up in other chips so we use the 5511
82 				   ID for recognition */
83 	PCI_DEVICE_ID_SI_5597,
84 	PCI_DEVICE_ID_SI_5598,
85 	0,			/* terminates the list */
86 };
87 
88 /* Length of ISA address segment */
89 #define SIS5595_EXTENT		8
90 /* SIS5595 SMBus registers */
91 #define SMB_STS_LO		0x00
92 #define SMB_STS_HI		0x01
93 #define SMB_CTL_LO		0x02
94 #define SMB_CTL_HI		0x03
95 #define SMB_ADDR		0x04
96 #define SMB_CMD			0x05
97 #define SMB_PCNT		0x06
98 #define SMB_CNT			0x07
99 #define SMB_BYTE		0x08
100 #define SMB_DEV			0x10
101 #define SMB_DB0			0x11
102 #define SMB_DB1			0x12
103 #define SMB_HAA			0x13
104 
105 /* PCI Address Constants */
106 #define SMB_INDEX		0x38
107 #define SMB_DAT			0x39
108 #define SIS5595_ENABLE_REG	0x40
109 #define ACPI_BASE		0x90
110 
111 /* Other settings */
112 #define MAX_TIMEOUT		500
113 
114 /* SIS5595 constants */
115 #define SIS5595_QUICK		0x00
116 #define SIS5595_BYTE		0x02
117 #define SIS5595_BYTE_DATA	0x04
118 #define SIS5595_WORD_DATA	0x06
119 #define SIS5595_PROC_CALL	0x08
120 #define SIS5595_BLOCK_DATA	0x0A
121 
122 /* insmod parameters */
123 
124 /* If force_addr is set to anything different from 0, we forcibly enable
125    the device at the given address. */
126 static u16 force_addr;
127 module_param(force_addr, ushort, 0);
128 MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
129 
130 static struct pci_driver sis5595_driver;
131 static unsigned short sis5595_base;
132 
133 static u8 sis5595_read(u8 reg)
134 {
135 	outb(reg, sis5595_base + SMB_INDEX);
136 	return inb(sis5595_base + SMB_DAT);
137 }
138 
139 static void sis5595_write(u8 reg, u8 data)
140 {
141 	outb(reg, sis5595_base + SMB_INDEX);
142 	outb(data, sis5595_base + SMB_DAT);
143 }
144 
145 static int sis5595_setup(struct pci_dev *SIS5595_dev)
146 {
147 	u16 a;
148 	u8 val;
149 	int *i;
150 	int retval = -ENODEV;
151 
152 	/* Look for imposters */
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 	/* Determine the address of the SMBus areas */
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 	/* NB: We grab just the two SMBus registers here, but this may still
175 	 * interfere with ACPI :-(  */
176 	if (!request_region(sis5595_base + SMB_INDEX, 2,
177 			    sis5595_driver.name)) {
178 		dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
179 			sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
180 		return -ENODEV;
181 	}
182 
183 	if (force_addr) {
184 		dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
185 		if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)
186 		    != PCIBIOS_SUCCESSFUL)
187 			goto error;
188 		if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)
189 		    != PCIBIOS_SUCCESSFUL)
190 			goto error;
191 		if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
192 			/* doesn't work for some chips! */
193 			dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
194 			goto error;
195 		}
196 	}
197 
198 	if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
199 	    != PCIBIOS_SUCCESSFUL)
200 		goto error;
201 	if ((val & 0x80) == 0) {
202 		dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
203 		if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)
204 		    != PCIBIOS_SUCCESSFUL)
205 			goto error;
206 		if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
207 		    != PCIBIOS_SUCCESSFUL)
208 			goto error;
209 		if ((val & 0x80) == 0) {
210 			/* doesn't work for some chips? */
211 			dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
212 			goto error;
213 		}
214 	}
215 
216 	/* Everything is happy */
217 	return 0;
218 
219 error:
220 	release_region(sis5595_base + SMB_INDEX, 2);
221 	return retval;
222 }
223 
224 static int sis5595_transaction(struct i2c_adapter *adap)
225 {
226 	int temp;
227 	int result = 0;
228 	int timeout = 0;
229 
230 	/* Make sure the SMBus host is ready to start transmitting */
231 	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
232 	if (temp != 0x00) {
233 		dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
234 		sis5595_write(SMB_STS_LO, temp & 0xff);
235 		sis5595_write(SMB_STS_HI, temp >> 8);
236 		if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
237 			dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
238 			return -1;
239 		} else {
240 			dev_dbg(&adap->dev, "Successfull!\n");
241 		}
242 	}
243 
244 	/* start the transaction by setting bit 4 */
245 	sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
246 
247 	/* We will always wait for a fraction of a second! */
248 	do {
249 		msleep(1);
250 		temp = sis5595_read(SMB_STS_LO);
251 	} while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
252 
253 	/* If the SMBus is still busy, we give up */
254 	if (timeout >= MAX_TIMEOUT) {
255 		dev_dbg(&adap->dev, "SMBus Timeout!\n");
256 		result = -1;
257 	}
258 
259 	if (temp & 0x10) {
260 		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
261 		result = -1;
262 	}
263 
264 	if (temp & 0x20) {
265 		dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
266 			"next hard reset (or not...)\n");
267 		/* Clock stops and slave is stuck in mid-transmission */
268 		result = -1;
269 	}
270 
271 	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
272 	if (temp != 0x00) {
273 		sis5595_write(SMB_STS_LO, temp & 0xff);
274 		sis5595_write(SMB_STS_HI, temp >> 8);
275 	}
276 
277 	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
278 	if (temp != 0x00)
279 		dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
280 
281 	return result;
282 }
283 
284 /* Return -1 on error. */
285 static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
286 			  unsigned short flags, char read_write,
287 			  u8 command, int size, union i2c_smbus_data *data)
288 {
289 	switch (size) {
290 	case I2C_SMBUS_QUICK:
291 		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
292 		size = SIS5595_QUICK;
293 		break;
294 	case I2C_SMBUS_BYTE:
295 		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
296 		if (read_write == I2C_SMBUS_WRITE)
297 			sis5595_write(SMB_CMD, command);
298 		size = SIS5595_BYTE;
299 		break;
300 	case I2C_SMBUS_BYTE_DATA:
301 		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
302 		sis5595_write(SMB_CMD, command);
303 		if (read_write == I2C_SMBUS_WRITE)
304 			sis5595_write(SMB_BYTE, data->byte);
305 		size = SIS5595_BYTE_DATA;
306 		break;
307 	case I2C_SMBUS_PROC_CALL:
308 	case I2C_SMBUS_WORD_DATA:
309 		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
310 		sis5595_write(SMB_CMD, command);
311 		if (read_write == I2C_SMBUS_WRITE) {
312 			sis5595_write(SMB_BYTE, data->word & 0xff);
313 			sis5595_write(SMB_BYTE + 1,
314 				      (data->word & 0xff00) >> 8);
315 		}
316 		size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
317 		break;
318 /*
319 	case I2C_SMBUS_BLOCK_DATA:
320 		printk(KERN_WARNING "sis5595.o: Block data not yet implemented!\n");
321 		return -1;
322 		break;
323 */
324 	default:
325 		printk(KERN_WARNING "sis5595.o: Unsupported transaction %d\n", size);
326 		return -1;
327 	}
328 
329 	sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
330 
331 	if (sis5595_transaction(adap))
332 		return -1;
333 
334 	if ((size != SIS5595_PROC_CALL) &&
335 	    ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
336 		return 0;
337 
338 
339 	switch (size) {
340 	case SIS5595_BYTE:	/* Where is the result put? I assume here it is in
341 				   SMB_DATA but it might just as well be in the
342 				   SMB_CMD. No clue in the docs */
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 
354 static 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 
361 static const struct i2c_algorithm smbus_algorithm = {
362 	.smbus_xfer	= sis5595_access,
363 	.functionality	= sis5595_func,
364 };
365 
366 static struct i2c_adapter sis5595_adapter = {
367 	.owner		= THIS_MODULE,
368 	.class          = I2C_CLASS_HWMON,
369 	.algo		= &smbus_algorithm,
370 };
371 
372 static struct pci_device_id sis5595_ids[] __devinitdata = {
373 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
374 	{ 0, }
375 };
376 
377 MODULE_DEVICE_TABLE (pci, sis5595_ids);
378 
379 static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
380 {
381 	if (sis5595_setup(dev)) {
382 		dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
383 		return -ENODEV;
384 	}
385 
386 	/* set up the driverfs linkage to our parent device */
387 	sis5595_adapter.dev.parent = &dev->dev;
388 
389 	sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
390 		sis5595_base + SMB_INDEX);
391 	return i2c_add_adapter(&sis5595_adapter);
392 }
393 
394 static void __devexit sis5595_remove(struct pci_dev *dev)
395 {
396 	i2c_del_adapter(&sis5595_adapter);
397 	release_region(sis5595_base + SMB_INDEX, 2);
398 }
399 
400 static struct pci_driver sis5595_driver = {
401 	.name		= "sis5595_smbus",
402 	.id_table	= sis5595_ids,
403 	.probe		= sis5595_probe,
404 	.remove		= __devexit_p(sis5595_remove),
405 };
406 
407 static int __init i2c_sis5595_init(void)
408 {
409 	return pci_register_driver(&sis5595_driver);
410 }
411 
412 static void __exit i2c_sis5595_exit(void)
413 {
414 	pci_unregister_driver(&sis5595_driver);
415 }
416 
417 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
418 MODULE_DESCRIPTION("SIS5595 SMBus driver");
419 MODULE_LICENSE("GPL");
420 
421 module_init(i2c_sis5595_init);
422 module_exit(i2c_sis5595_exit);
423