root/lm-sensors/trunk/kernel/busses/i2c-viapro.c @ 3142

Revision 3142, 13.2 KB (checked in by khali, 8 years ago)

Refactor a control outb. This allows for some other
simplifications. Backported from Linux 2.6.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
3              monitoring
4    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
5    Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
6    Mark D. Studebaker <mdsxyz123@yahoo.com>
7    Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24/*
25   Supports the following VIA south bridges:
26
27   Chip name          PCI ID  REV     I2C block
28   VT82C596A          0x3050             no
29   VT82C596B          0x3051             no
30   VT82C686A          0x3057  0x30       no
31   VT82C686B          0x3057  0x40       yes
32   VT8231             0x8235             no?
33   VT8233             0x3074             yes
34   VT8233A            0x3147             yes?
35   VT8235             0x3177             yes
36   VT8237R            0x3227             yes
37
38   Note: we assume there can only be one device, with one SMBus interface.
39*/
40
41#include <linux/module.h>
42#include <linux/pci.h>
43#include <linux/kernel.h>
44#include <linux/stddef.h>
45#include <linux/ioport.h>
46#include <linux/i2c.h>
47#include <linux/init.h>
48#include <asm/io.h>
49#include "version.h"
50#include "sensors_compat.h"
51
52#define SMBBA1          0x90
53#define SMBBA2          0x80
54#define SMBBA3          0xD0
55
56/* SMBus address offsets */
57static unsigned short vt596_smba;
58#define SMBHSTSTS       (vt596_smba + 0)
59#define SMBHSTCNT       (vt596_smba + 2)
60#define SMBHSTCMD       (vt596_smba + 3)
61#define SMBHSTADD       (vt596_smba + 4)
62#define SMBHSTDAT0      (vt596_smba + 5)
63#define SMBHSTDAT1      (vt596_smba + 6)
64#define SMBBLKDAT       (vt596_smba + 7)
65
66/* PCI Address Constants */
67
68/* SMBus data in configuration space can be found in two places,
69   We try to select the better one */
70
71static unsigned short SMBHSTCFG = 0xD2;
72
73/* Other settings */
74#define MAX_TIMEOUT     500
75
76/* VT82C596 constants */
77#define VT596_QUICK             0x00
78#define VT596_BYTE              0x04
79#define VT596_BYTE_DATA         0x08
80#define VT596_WORD_DATA         0x0C
81#define VT596_BLOCK_DATA        0x14
82#define VT596_I2C_BLOCK_DATA    0x34
83
84
85/* If force is set to anything different from 0, we forcibly enable the
86   VT596. DANGEROUS! */
87static int force;
88MODULE_PARM(force, "i");
89MODULE_PARM_DESC(force, "Forcibly enable the SMBus. DANGEROUS!");
90
91/* If force_addr is set to anything different from 0, we forcibly enable
92   the VT596 at the given address. VERY DANGEROUS! */
93static int force_addr;
94MODULE_PARM(force_addr, "i");
95MODULE_PARM_DESC(force_addr,
96                 "Forcibly enable the SMBus at the given address. "
97                 "EXTREMELY DANGEROUS!");
98
99
100static struct pci_driver vt596_driver;
101static struct i2c_adapter vt596_adapter;
102
103#define FEATURE_I2CBLOCK        (1<<0)
104static unsigned int vt596_features;
105
106/* Return -1 on error, 0 on success */
107static int vt596_transaction(u8 size)
108{
109        int temp;
110        int result = 0;
111        int timeout = 0;
112
113        dev_dbg(&vt596_adapter, "Transaction (pre): CNT=%02x, CMD=%02x, "
114                "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
115                inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
116                inb_p(SMBHSTDAT1));
117
118        /* Make sure the SMBus host is ready to start transmitting */
119        if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
120                dev_dbg(&vt596_adapter, "SMBus busy (0x%02x). "
121                        "Resetting...\n", temp);
122
123                outb_p(temp, SMBHSTSTS);
124                if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
125                        dev_dbg(&vt596_adapter, "Failed! (0x%02x)\n", temp);
126                        return -1;
127                } else {
128                        dev_dbg(&vt596_adapter, "Successful!\n");
129                }
130        }
131
132        /* Start the transaction by setting bit 6 */
133        outb_p(0x40 | size, SMBHSTCNT);
134
135        /* We will always wait for a fraction of a second */
136        do {
137                i2c_delay(1);
138                temp = inb_p(SMBHSTSTS);
139        } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
140
141        /* If the SMBus is still busy, we give up */
142        if (timeout >= MAX_TIMEOUT) {
143                result = -1;
144                dev_err(&vt596_adapter, "SMBus Timeout!\n");
145        }
146
147        if (temp & 0x10) {
148                result = -1;
149                dev_err(&vt596_adapter, "Transaction failed (0x%02x)\n", size);
150        }
151
152        if (temp & 0x08) {
153                result = -1;
154                dev_err(&vt596_adapter, "SMBus collision!\n");
155        }
156
157        if (temp & 0x04) {
158                int read = inb_p(SMBHSTADD) & 0x01;
159                result = -1;
160                /* The quick and receive byte commands are used to probe
161                   for chips, so errors are expected, and we don't
162                   want to frighten the user. */
163                if (!((size == VT596_QUICK && !read) ||
164                      (size == VT596_BYTE && read)))
165                        dev_err(&vt596_adapter, "Transaction error!\n");
166        }
167
168        /* Resetting status register */
169        if (temp & 0x1F)
170                outb_p(temp, SMBHSTSTS);
171
172        dev_dbg(&vt596_adapter, "Transaction (post): CNT=%02x, CMD=%02x, "
173                "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
174                inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
175                inb_p(SMBHSTDAT1));
176
177        return result;
178}
179
180/* Return -1 on error, 0 on success */
181static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
182                unsigned short flags, char read_write, u8 command,
183                int size, union i2c_smbus_data *data)
184{
185        int i;
186
187        switch (size) {
188        case I2C_SMBUS_QUICK:
189                size = VT596_QUICK;
190                break;
191        case I2C_SMBUS_BYTE:
192                if (read_write == I2C_SMBUS_WRITE)
193                        outb_p(command, SMBHSTCMD);
194                size = VT596_BYTE;
195                break;
196        case I2C_SMBUS_BYTE_DATA:
197                outb_p(command, SMBHSTCMD);
198                if (read_write == I2C_SMBUS_WRITE)
199                        outb_p(data->byte, SMBHSTDAT0);
200                size = VT596_BYTE_DATA;
201                break;
202        case I2C_SMBUS_WORD_DATA:
203                outb_p(command, SMBHSTCMD);
204                if (read_write == I2C_SMBUS_WRITE) {
205                        outb_p(data->word & 0xff, SMBHSTDAT0);
206                        outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
207                }
208                size = VT596_WORD_DATA;
209                break;
210        case I2C_SMBUS_I2C_BLOCK_DATA:
211                if (!(vt596_features & FEATURE_I2CBLOCK))
212                        goto exit_unsupported;
213                if (read_write == I2C_SMBUS_READ)
214                        outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0);
215                /* Fall through */
216        case I2C_SMBUS_BLOCK_DATA:
217                outb_p(command, SMBHSTCMD);
218                if (read_write == I2C_SMBUS_WRITE) {
219                        u8 len = data->block[0];
220                        if (len > I2C_SMBUS_BLOCK_MAX)
221                                len = I2C_SMBUS_BLOCK_MAX;
222                        outb_p(len, SMBHSTDAT0);
223                        inb_p(SMBHSTCNT);       /* Reset SMBBLKDAT */
224                        for (i = 1; i <= len; i++)
225                                outb_p(data->block[i], SMBBLKDAT);
226                }
227                size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ?
228                       VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA;
229                break;
230        default:
231                goto exit_unsupported;
232        }
233
234        outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
235
236        if (vt596_transaction(size)) /* Error in transaction */
237                return -1;
238
239        if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
240                return 0;
241
242        switch (size) {
243        case VT596_BYTE:
244        case VT596_BYTE_DATA:
245                data->byte = inb_p(SMBHSTDAT0);
246                break;
247        case VT596_WORD_DATA:
248                data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
249                break;
250        case VT596_I2C_BLOCK_DATA:
251        case VT596_BLOCK_DATA:
252                data->block[0] = inb_p(SMBHSTDAT0);
253                if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
254                        data->block[0] = I2C_SMBUS_BLOCK_MAX;
255                inb_p(SMBHSTCNT);       /* Reset SMBBLKDAT */
256                for (i = 1; i <= data->block[0]; i++)
257                        data->block[i] = inb_p(SMBBLKDAT);
258                break;
259        }
260        return 0;
261
262exit_unsupported:
263        dev_warn(&vt596_adapter, "Unsupported command invoked! (0x%02x)\n",
264                 size);
265        return -1;
266}
267
268static void vt596_inc(struct i2c_adapter *adapter)
269{
270#ifdef MODULE
271        MOD_INC_USE_COUNT;
272#endif
273}
274
275static void vt596_dec(struct i2c_adapter *adapter)
276{
277#ifdef MODULE
278        MOD_DEC_USE_COUNT;
279#endif
280}
281
282static u32 vt596_func(struct i2c_adapter *adapter)
283{
284        u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
285            I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
286            I2C_FUNC_SMBUS_BLOCK_DATA;
287
288        if (vt596_features & FEATURE_I2CBLOCK)
289                func |= I2C_FUNC_SMBUS_I2C_BLOCK;
290        return func;
291}
292
293static struct i2c_algorithm smbus_algorithm = {
294        .name           = "Non-I2C SMBus adapter",
295        .id             = I2C_ALGO_SMBUS,
296        .smbus_xfer     = vt596_access,
297        .functionality  = vt596_func,
298};
299
300static struct i2c_adapter vt596_adapter = {
301        .id             = I2C_ALGO_SMBUS | I2C_HW_SMBUS_VIA2,
302        .algo           = &smbus_algorithm,
303        .inc_use        = vt596_inc,
304        .dec_use        = vt596_dec,
305};
306
307static int __init vt596_probe(struct pci_dev *pdev,
308                              const struct pci_device_id *id)
309{
310        unsigned char temp;
311        int error = -ENODEV;
312
313        /* Determine the address of the SMBus areas */
314        if (force_addr) {
315                vt596_smba = force_addr & 0xfff0;
316                force = 0;
317                goto found;
318        }
319
320        if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) ||
321            !(vt596_smba & 0x0001)) {
322                /* try 2nd address and config reg. for 596 */
323                if (id->device == PCI_DEVICE_ID_VIA_82C596_3 &&
324                    !pci_read_config_word(pdev, SMBBA2, &vt596_smba) &&
325                    (vt596_smba & 0x0001)) {
326                        SMBHSTCFG = 0x84;
327                } else {
328                        /* no matches at all */
329                        dev_err(pdev, "Cannot configure "
330                                "SMBus I/O Base address\n");
331                        return -ENODEV;
332                }
333        }
334
335        vt596_smba &= 0xfff0;
336        if (vt596_smba == 0) {
337                dev_err(pdev, "SMBus base address "
338                        "uninitialized - upgrade BIOS or use "
339                        "force_addr=0xaddr\n");
340                return -ENODEV;
341        }
342
343found:
344        if (!request_region(vt596_smba, 8, vt596_driver.name)) {
345                dev_err(pdev, "SMBus region 0x%x already in use!\n",
346                        vt596_smba);
347                return -ENODEV;
348        }
349
350        pci_read_config_byte(pdev, SMBHSTCFG, &temp);
351        /* If force_addr is set, we program the new address here. Just to make
352           sure, we disable the VT596 first. */
353        if (force_addr) {
354                pci_write_config_byte(pdev, SMBHSTCFG, temp & 0xfe);
355                pci_write_config_word(pdev, id->driver_data, vt596_smba);
356                pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
357                dev_warn(pdev, "WARNING: SMBus interface set to new "
358                         "address 0x%04x!\n", vt596_smba);
359        } else if (!(temp & 0x01)) {
360                if (force) {
361                        /* NOTE: This assumes I/O space and other allocations
362                         * WERE done by the Bios!  Don't complain if your
363                         * hardware does weird things after enabling this.
364                         * :') Check for Bios updates before resorting to
365                         * this.
366                         */
367                        pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
368                        dev_info(pdev, "Enabling SMBus device\n");
369                } else {
370                        dev_err(pdev, "SMBUS: Error: Host SMBus "
371                                "controller not enabled! - upgrade BIOS or "
372                                "use force=1\n");
373                        goto release_region;
374                }
375        }
376
377        dev_dbg(pdev, "VT596_smba = 0x%X\n", vt596_smba);
378
379        switch (id->device) {
380        case PCI_DEVICE_ID_VIA_8237:
381        case PCI_DEVICE_ID_VIA_8235:
382        case PCI_DEVICE_ID_VIA_8233A:
383        case PCI_DEVICE_ID_VIA_8233_0:
384                vt596_features |= FEATURE_I2CBLOCK;
385                break;
386        case PCI_DEVICE_ID_VIA_82C686_4:
387                /* The VT82C686B (rev 0x40) does support I2C block
388                   transactions, but the VT82C686A (rev 0x30) doesn't */
389                if (!pci_read_config_byte(pdev, PCI_REVISION_ID, &temp)
390                 && temp >= 0x40)
391                        vt596_features |= FEATURE_I2CBLOCK;
392                break;
393        }
394
395        snprintf(vt596_adapter.name, 32,
396                 "SMBus Via Pro adapter at %04x", vt596_smba);
397
398        return i2c_add_adapter(&vt596_adapter);
399
400release_region:
401        release_region(vt596_smba, 8);
402        return error;
403}
404
405/* 8233A is undefined before kernel 2.4.19 */
406#ifndef PCI_DEVICE_ID_VIA_8233A
407#define PCI_DEVICE_ID_VIA_8233A 0x3147
408#endif
409/* 8235 is undefined before kernel 2.4.20 */
410#ifndef PCI_DEVICE_ID_VIA_8235
411#define PCI_DEVICE_ID_VIA_8235  0x3177
412#endif
413/* 8237 is undefined before kernel 2.4.21 */
414#ifndef PCI_DEVICE_ID_VIA_8237
415#define PCI_DEVICE_ID_VIA_8237  0x3227
416#endif
417static struct pci_device_id vt596_ids[] __initdata = {
418        {
419                .vendor         = PCI_VENDOR_ID_VIA,
420                .device         = PCI_DEVICE_ID_VIA_82C596_3,
421                .subvendor      = PCI_ANY_ID,
422                .subdevice      = PCI_ANY_ID,
423                .driver_data    = SMBBA1,
424        },
425        {
426                .vendor         = PCI_VENDOR_ID_VIA,
427                .device         = PCI_DEVICE_ID_VIA_82C596B_3,
428                .subvendor      = PCI_ANY_ID,
429                .subdevice      = PCI_ANY_ID,
430                .driver_data    = SMBBA1,
431        },
432        {
433                .vendor         = PCI_VENDOR_ID_VIA,
434                .device         = PCI_DEVICE_ID_VIA_82C686_4,
435                .subvendor      = PCI_ANY_ID,
436                .subdevice      = PCI_ANY_ID,
437                .driver_data    = SMBBA1,
438        },
439        {
440                .vendor         = PCI_VENDOR_ID_VIA,
441                .device         = PCI_DEVICE_ID_VIA_8233_0,
442                .subvendor      = PCI_ANY_ID,
443                .subdevice      = PCI_ANY_ID,
444                .driver_data    = SMBBA3
445        },
446        {
447                .vendor         = PCI_VENDOR_ID_VIA,
448                .device         = PCI_DEVICE_ID_VIA_8233A,
449                .subvendor      = PCI_ANY_ID,
450                .subdevice      = PCI_ANY_ID,
451                .driver_data    = SMBBA3,
452        },
453        {
454                .vendor         = PCI_VENDOR_ID_VIA,
455                .device         = PCI_DEVICE_ID_VIA_8235,
456                .subvendor      = PCI_ANY_ID,
457                .subdevice      = PCI_ANY_ID,
458                .driver_data    = SMBBA3
459        },
460        {
461                .vendor         = PCI_VENDOR_ID_VIA,
462                .device         = PCI_DEVICE_ID_VIA_8237,
463                .subvendor      = PCI_ANY_ID,
464                .subdevice      = PCI_ANY_ID,
465                .driver_data    = SMBBA3
466        },
467        {
468                .vendor         = PCI_VENDOR_ID_VIA,
469                .device         = PCI_DEVICE_ID_VIA_8231_4,
470                .subvendor      = PCI_ANY_ID,
471                .subdevice      = PCI_ANY_ID,
472                .driver_data    = SMBBA1,
473        },
474        { 0, }
475};
476
477static int __init i2c_vt596_init(void)
478{
479        struct pci_dev *dev;
480        const struct pci_device_id *id;
481
482        printk("i2c-viapro.o version %s (%s)\n", LM_VERSION, LM_DATE);
483        pci_for_each_dev(dev) {
484                id = pci_match_device(vt596_ids, dev);
485                if(id)
486                        if(vt596_probe(dev, id) >= 0)
487                                return 0;
488        }
489        return -ENODEV;
490}
491
492
493static void __exit i2c_vt596_exit(void)
494{
495        i2c_del_adapter(&vt596_adapter);
496        release_region(vt596_smba, 8);
497}
498
499MODULE_AUTHOR(
500    "Frodo Looijaard <frodol@dds.nl> and "
501    "Philip Edelbrock <phil@netroedge.com>");
502MODULE_DESCRIPTION("vt82c596 SMBus driver");
503MODULE_LICENSE("GPL");
504
505module_init(i2c_vt596_init);
506module_exit(i2c_vt596_exit);
Note: See TracBrowser for help on using the browser.