root/lm-sensors/trunk/kernel/busses/i2c-via.c @ 2772

Revision 2772, 5.0 KB (checked in by khali, 9 years ago)

Remove owner from i2c_adapter, restore inc_use and dec_use
instead.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    i2c-via.c - Part of lm_sensors,  Linux kernel modules
3                for hardware monitoring
4
5    i2c Support for Via Technologies 82C586B South Bridge
6
7    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
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#include <linux/kernel.h>
25#include <linux/ioport.h>
26#include <linux/module.h>
27#include <linux/pci.h>
28#include <linux/types.h>
29#include <linux/i2c.h>
30#include <linux/i2c-algo-bit.h>
31#include <linux/init.h>
32#include <asm/io.h>
33#include <asm/param.h>  /* for HZ */
34#include "version.h"
35
36/* Power management registers */
37
38#define PM_CFG_REVID    0x08    /* silicon revision code */
39#define PM_CFG_IOBASE0  0x20
40#define PM_CFG_IOBASE1  0x48
41
42#define I2C_DIR         (pm_io_base+0x40)
43#define I2C_OUT         (pm_io_base+0x42)
44#define I2C_IN          (pm_io_base+0x44)
45#define I2C_SCL         0x02    /* clock bit in DIR/OUT/IN register */
46#define I2C_SDA         0x04
47
48/* io-region reservation */
49#define IOSPACE         0x06
50#define IOTEXT          "via-i2c"
51
52static u16 pm_io_base = 0;
53
54/*
55   It does not appear from the datasheet that the GPIO pins are
56   open drain. So a we set a low value by setting the direction to
57   output and a high value by setting the direction to input and
58   relying on the required I2C pullup. The data value is initialized
59   to 0 in via_init() and never changed.
60*/
61
62static void bit_via_setscl(void *data, int state)
63{
64        outb(state ? inb(I2C_DIR) & ~I2C_SCL : inb(I2C_DIR) | I2C_SCL,
65             I2C_DIR);
66}
67
68static void bit_via_setsda(void *data, int state)
69{
70        outb(state ? inb(I2C_DIR) & ~I2C_SDA : inb(I2C_DIR) | I2C_SDA,
71             I2C_DIR);
72}
73
74static int bit_via_getscl(void *data)
75{
76        return (0 != (inb(I2C_IN) & I2C_SCL));
77}
78
79static int bit_via_getsda(void *data)
80{
81        return (0 != (inb(I2C_IN) & I2C_SDA));
82}
83
84static void bit_via_inc(struct i2c_adapter *adapter)
85{
86#ifdef MODULE
87        MOD_INC_USE_COUNT;
88#endif
89}
90
91static void bit_via_dec(struct i2c_adapter *adapter)
92{
93#ifdef MODULE
94        MOD_DEC_USE_COUNT;
95#endif
96}
97
98static struct i2c_algo_bit_data bit_data = {
99        .setsda         = bit_via_setsda,
100        .setscl         = bit_via_setscl,
101        .getsda         = bit_via_getsda,
102        .getscl         = bit_via_getscl,
103        .udelay         = 5,
104        .mdelay         = 5,
105        .timeout        = HZ
106};
107
108static struct i2c_adapter vt586b_adapter = {
109        .name           = "VIA i2c",
110        .id             = I2C_HW_B_VIA,
111        .algo_data      = &bit_data,
112        .inc_use        = bit_via_inc,
113        .dec_use        = bit_via_dec,
114};
115
116
117static struct pci_device_id vt586b_ids[] __devinitdata = {
118        { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
119        { 0, }
120};
121
122static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_id *id)
123{
124        u16 base;
125        u8 rev;
126        int res;
127
128        if (pm_io_base) {
129                printk(KERN_ERR "i2c-via.o: Will only support one host\n");
130                return -EBUSY;
131        }
132
133        pci_read_config_byte(dev, PM_CFG_REVID, &rev);
134
135        switch (rev) {
136        case 0x00:
137                base = PM_CFG_IOBASE0;
138                break;
139        case 0x01:
140        case 0x10:
141                base = PM_CFG_IOBASE1;
142                break;
143
144        default:
145                base = PM_CFG_IOBASE1;
146                /* later revision */
147        }
148
149        pci_read_config_word(dev, base, &pm_io_base);
150        pm_io_base &= (0xff << 8);
151
152        if (! request_region(I2C_DIR, IOSPACE, IOTEXT)) {
153            printk("i2c-via.o: IO 0x%x-0x%x already in use\n",
154                   I2C_DIR, I2C_DIR + IOSPACE);
155            return -EBUSY;
156        }
157        outb(inb(I2C_DIR) & ~(I2C_SDA | I2C_SCL), I2C_DIR);
158        outb(inb(I2C_OUT) & ~(I2C_SDA | I2C_SCL), I2C_OUT);
159       
160        res = i2c_bit_add_bus(&vt586b_adapter);
161        if ( res < 0 ) {
162                release_region(I2C_DIR, IOSPACE);
163                pm_io_base = 0;
164                return res;
165        }
166        return 0;
167}
168
169static void __devexit vt586b_remove(struct pci_dev *dev)
170{
171        i2c_bit_del_bus(&vt586b_adapter);
172        release_region(I2C_DIR, IOSPACE);
173        pm_io_base = 0;
174}
175
176
177/* Don't register driver to avoid driver conflicts */
178/*
179static struct pci_driver vt586b_driver = {
180        .name           = "vt586b smbus",
181        .id_table       = vt586b_ids,
182        .probe          = vt586b_probe,
183        .remove         = __devexit_p(vt586b_remove),
184};
185*/
186
187static int __init i2c_vt586b_init(void)
188{
189        struct pci_dev *dev;
190        const struct pci_device_id *id;
191
192        printk("i2c-via.o version %s (%s)\n", LM_VERSION, LM_DATE);
193/*
194        return pci_module_init(&vt586b_driver);
195*/
196        pci_for_each_dev(dev) {
197                id = pci_match_device(vt586b_ids, dev);
198                if(id)
199                        if(vt586b_probe(dev, id) >= 0)
200                                return 0;
201        }
202        return -ENODEV;
203}
204
205
206static void __exit i2c_vt586b_exit(void)
207{
208/*
209        pci_unregister_driver(&vt586b_driver);
210*/
211        vt586b_remove(NULL);
212}
213
214
215MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
216MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge");
217MODULE_LICENSE("GPL");
218
219module_init(i2c_vt586b_init);
220module_exit(i2c_vt586b_exit);
Note: See TracBrowser for help on using the browser.