Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/i2c/busses/i2c-sis5595.c

  1 /*
  2     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
  3     Philip Edelbrock <phil@netroedge.com>
  4 
  5     This program is free software; you can redistribute it and/or modify
  6     it under the terms of the GNU General Public License as published by
  7     the Free Software Foundation; either version 2 of the License, or
  8     (at your option) any later version.
  9 
 10     This program is distributed in the hope that it will be useful,
 11     but WITHOUT ANY WARRANTY; without even the implied warranty of
 12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13     GNU General Public License for more details.
 14 
 15     You should have received a copy of the GNU General Public License
 16     along with this program; if not, write to the Free Software
 17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 18 */
 19 
 20 /* Note: we assume there can only be one SIS5595 with one SMBus interface */
 21 
 22 /*
 23    Note: all have mfr. ID 0x1039.
 24    SUPPORTED            PCI ID          
 25         5595            0008
 26 
 27    Note: these chips contain a 0008 device which is incompatible with the
 28          5595. We recognize these by the presence of the listed
 29          "blacklist" PCI ID and refuse to load.
 30 
 31    NOT SUPPORTED        PCI ID          BLACKLIST PCI ID        
 32          540            0008            0540
 33          550            0008            0550
 34         5513            0008            5511
 35         5581            0008            5597
 36         5582            0008            5597
 37         5597            0008            5597
 38         5598            0008            5597/5598
 39          630            0008            0630
 40          645            0008            0645
 41          646            0008            0646
 42          648            0008            0648
 43          650            0008            0650
 44          651            0008            0651
 45          730            0008            0730
 46          735            0008            0735
 47          745            0008            0745
 48          746            0008            0746
 49 */
 50 
 51 /* TO DO: 
 52  * Add Block Transfers (ugly, but supported by the adapter)
 53  * Add adapter resets
 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 
 66 static 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,  /* 5513 chip has the 0008 device but that ID
 80                                    shows up in other chips so we use the 5511
 81                                    ID for recognition */
 82         PCI_DEVICE_ID_SI_5597,
 83         PCI_DEVICE_ID_SI_5598,
 84         0,                      /* terminates the list */
 85 };
 86 
 87 /* Length of ISA address segment */
 88 #define SIS5595_EXTENT          8
 89 /* SIS5595 SMBus registers */
 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 /* PCI Address Constants */
105 #define SMB_INDEX               0x38
106 #define SMB_DAT                 0x39
107 #define SIS5595_ENABLE_REG      0x40
108 #define ACPI_BASE               0x90
109 
110 /* Other settings */
111 #define MAX_TIMEOUT             500
112 
113 /* SIS5595 constants */
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 /* insmod parameters */
122 
123 /* If force_addr is set to anything different from 0, we forcibly enable
124    the device at the given address. */
125 static u16 force_addr;
126 module_param(force_addr, ushort, 0);
127 MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
128 
129 static struct pci_driver sis5595_driver;
130 static unsigned short sis5595_base;
131 static struct pci_dev *sis5595_pdev;
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;
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         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                         /* doesn't work for some chips! */
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                         /* doesn't work for some chips? */
216                         dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
217                         goto error;
218                 }
219         }
220 
221         /* Everything is happy */
222         return 0;
223 
224 error:
225         release_region(sis5595_base + SMB_INDEX, 2);
226         return -ENODEV;
227 }
228 
229 static int sis5595_transaction(struct i2c_adapter *adap)
230 {
231         int temp;
232         int result = 0;
233         int timeout = 0;
234 
235         /* Make sure the SMBus host is ready to start transmitting */
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         /* start the transaction by setting bit 4 */
250         sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
251 
252         /* We will always wait for a fraction of a second! */
253         do {
254                 msleep(1);
255                 temp = sis5595_read(SMB_STS_LO);
256         } while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
257 
258         /* If the SMBus is still busy, we give up */
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                 /* Clock stops and slave is stuck in mid-transmission */
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 /* Return negative errno on error. */
290 static 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 
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 | I2C_CLASS_SPD,
369         .algo           = &smbus_algorithm,
370 };
371 
372 static const struct pci_device_id sis5595_ids[] = {
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 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         /* set up the sysfs linkage to our parent device */
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         /* Always return failure here.  This is to allow other drivers to bind
400          * to this pci device.  We don't really want to have control over the
401          * pci device, we only wanted to read as few register values from it.
402          */
403         sis5595_pdev =  pci_dev_get(dev);
404         return -ENODEV;
405 }
406 
407 static struct pci_driver sis5595_driver = {
408         .name           = "sis5595_smbus",
409         .id_table       = sis5595_ids,
410         .probe          = sis5595_probe,
411 };
412 
413 static int __init i2c_sis5595_init(void)
414 {
415         return pci_register_driver(&sis5595_driver);
416 }
417 
418 static 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 
429 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
430 MODULE_DESCRIPTION("SIS5595 SMBus driver");
431 MODULE_LICENSE("GPL");
432 
433 module_init(i2c_sis5595_init);
434 module_exit(i2c_sis5595_exit);
435 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us