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

Revision 3140, 12.9 KB (checked in by khali, 8 years ago)

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