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

Revision 3139, 14.0 KB (checked in by khali, 8 years ago)

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