root/lm-sensors/trunk/kernel/busses/i2c-savage4.c @ 1344

Revision 1344, 8.2 KB (checked in by mds, 11 years ago)

voodoo3 -> savage4 global replace

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware
3              monitoring
4    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
5    Philip Edelbrock <phil@netroedge.com>,
6    Ralph Metzler <rjkm@thp.uni-koeln.de>, and
7    Mark D. Studebaker <mdsxyz123@yahoo.com>
8   
9    Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
10    Simon Vogl
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 2 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25*/
26
27/* This interfaces to the I2C bus of the Savage4 to gain access to
28   the BT869 and possibly other I2C devices. The DDC bus is not
29   yet supported because its register is not memory-mapped.
30   However we leave the DDC code here, commented out, to make
31   it easier to add later. */
32
33#include <linux/version.h>
34#include <linux/module.h>
35#include <linux/pci.h>
36#include <asm/io.h>
37#include <linux/i2c.h>
38#include <linux/i2c-algo-bit.h>
39#include "version.h"
40#include <linux/init.h>
41
42#ifdef MODULE_LICENSE
43MODULE_LICENSE("GPL");
44#endif
45
46/* 3DFX defines */
47/* #define PCI_VENDOR_ID_S3             0x5333 */
48#define PCI_CHIP_SAVAGE3D       0x8A20
49#define PCI_CHIP_SAVAGE3D_MV    0x8A21
50#define PCI_CHIP_SAVAGE4        0x8A22
51#define PCI_CHIP_SAVAGE2000     0x9102
52#define PCI_CHIP_PROSAVAGE_PM   0x8A25
53#define PCI_CHIP_PROSAVAGE_KM   0x8A26
54#define PCI_CHIP_SAVAGE_MX_MV   0x8c10
55#define PCI_CHIP_SAVAGE_MX      0x8c11
56#define PCI_CHIP_SAVAGE_IX_MV   0x8c12
57#define PCI_CHIP_SAVAGE_IX      0x8c13
58
59/* the only registers we use */
60//#define REG   0x78
61//#define REG2  0x70
62#define REG 0xff20      /* Serial Port 1 Register */
63
64/* bit locations in the register */
65//#define DDC_ENAB      0x00040000
66//#define DDC_SCL_OUT   0x00080000
67//#define DDC_SDA_OUT   0x00100000
68//#define DDC_SCL_IN    0x00200000
69//#define DDC_SDA_IN    0x00400000
70#define I2C_ENAB        0x00000020
71#define I2C_SCL_OUT     0x00000001
72#define I2C_SDA_OUT     0x00000002
73#define I2C_SCL_IN      0x00000008
74#define I2C_SDA_IN      0x00000010
75
76/* initialization states */
77#define INIT2   0x20
78/* #define INIT3        0x4 */
79
80/* delays */
81#define CYCLE_DELAY     10
82#define TIMEOUT         50
83
84#ifdef MODULE
85static
86#else
87extern
88#endif
89int __init i2c_savage4_init(void);
90static int __init savage4_cleanup(void);
91static int savage4_setup(void);
92static void config_s4(struct pci_dev *dev);
93static void savage4_inc(struct i2c_adapter *adapter);
94static void savage4_dec(struct i2c_adapter *adapter);
95
96#ifdef MODULE
97extern int init_module(void);
98extern int cleanup_module(void);
99#endif                          /* MODULE */
100
101
102static int __initdata savage4_initialized;
103static unsigned char *mem;
104
105extern inline void outlong(unsigned int dat)
106{
107        *((unsigned int *) (mem + REG)) = dat;
108}
109
110extern inline unsigned int readlong(void)
111{
112        return *((unsigned int *) (mem + REG));
113}
114
115/* The sav GPIO registers don't have individual masks for each bit
116   so we always have to read before writing. */
117
118static void bit_savi2c_setscl(void *data, int val)
119{
120        unsigned int r;
121        r = readlong();
122        if(val)
123                r |= I2C_SCL_OUT;
124        else
125                r &= ~I2C_SCL_OUT;
126        outlong(r);
127}
128
129static void bit_savi2c_setsda(void *data, int val)
130{
131        unsigned int r;
132        r = readlong();
133        if(val)
134                r |= I2C_SDA_OUT;
135        else
136                r &= ~I2C_SDA_OUT;
137        outlong(r);
138}
139
140/* The GPIO pins are open drain, so the pins always remain outputs.
141   We rely on the i2c-algo-bit routines to set the pins high before
142   reading the input from other chips. */
143
144static int bit_savi2c_getscl(void *data)
145{
146        return (0 != (readlong() & I2C_SCL_IN));
147}
148
149static int bit_savi2c_getsda(void *data)
150{
151        return (0 != (readlong() & I2C_SDA_IN));
152}
153
154/*static void bit_savddc_setscl(void *data, int val)
155{
156        unsigned int r;
157        r = readlong();
158        if(val)
159                r |= DDC_SCL_OUT;
160        else
161                r &= ~DDC_SCL_OUT;
162        outlong(r);
163}
164
165static void bit_savddc_setsda(void *data, int val)
166{
167        unsigned int r;
168        r = readlong();
169        if(val)
170                r |= DDC_SDA_OUT;
171        else
172                r &= ~DDC_SDA_OUT;
173        outlong(r);
174}
175
176static int bit_savddc_getscl(void *data)
177{
178        return (0 != (readlong() & DDC_SCL_IN));
179}
180
181static int bit_savddc_getsda(void *data)
182{
183        return (0 != (readlong() & DDC_SDA_IN));
184}
185*/
186static struct i2c_algo_bit_data sav_i2c_bit_data = {
187        NULL,
188        bit_savi2c_setsda,
189        bit_savi2c_setscl,
190        bit_savi2c_getsda,
191        bit_savi2c_getscl,
192        CYCLE_DELAY, CYCLE_DELAY, TIMEOUT
193};
194
195static struct i2c_adapter savage4_i2c_adapter = {
196        "I2C Savage4 adapter",
197        I2C_HW_B_VOO,
198        NULL,
199        &sav_i2c_bit_data,
200        savage4_inc,
201        savage4_dec,
202        NULL,
203        NULL,
204};
205/*
206static struct i2c_algo_bit_data sav_ddc_bit_data = {
207        NULL,
208        bit_savddc_setsda,
209        bit_savddc_setscl,
210        bit_savddc_getsda,
211        bit_savddc_getscl,
212        CYCLE_DELAY, CYCLE_DELAY, TIMEOUT
213};
214
215static struct i2c_adapter savage4_ddc_adapter = {
216        "DDC Voodoo3/Banshee adapter",
217        I2C_HW_B_VOO,
218        NULL,
219        &sav_ddc_bit_data,
220        savage4_inc,
221        savage4_dec,
222        NULL,
223        NULL,
224};
225*/
226/* Configures the chip */
227
228void config_s4(struct pci_dev *dev)
229{
230        unsigned int cadr;
231
232        /* map memory */
233#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)
234        cadr = dev->resource[0].start;
235#else
236        cadr = dev->base_address[0];
237#endif
238        cadr &= PCI_BASE_ADDRESS_MEM_MASK;
239        mem = ioremap_nocache(cadr, 0x0080000);
240
241//      *((unsigned int *) (mem + REG2)) = 0x8160;
242        *((unsigned int *) (mem + REG)) = 0x00000020;
243        printk("i2c-savage4: Using Savage4 at 0x%p\n", mem);
244}
245
246/* Detect chip and initialize it. */
247static int savage4_setup(void)
248{
249        struct pci_dev *dev;
250        int s4_num;
251
252        s4_num = 0;
253
254        dev = NULL;
255        do {
256                if ((dev = pci_find_device(PCI_VENDOR_ID_S3,
257                                           PCI_CHIP_SAVAGE4,
258                                           dev))) {
259                        if (!s4_num)
260                                config_s4(dev);
261                        s4_num++;
262                }
263        } while (dev);
264
265        dev = NULL;
266        do {
267                if ((dev = pci_find_device(PCI_VENDOR_ID_S3,
268                                           PCI_CHIP_SAVAGE2000,
269                                           dev))) {
270                        if (!s4_num)
271                                config_s4(dev);
272                        s4_num++;
273                }
274        } while (dev);
275
276        if (s4_num > 0) {
277                printk("i2c-savage4: %d Savage4 found.\n", s4_num);
278                if (s4_num > 1)
279                        printk("i2c-savage4: warning: only 1 supported.\n");
280                return 0;
281        } else {
282                printk("i2c-savage4: No Savage4 found.\n");
283                return -ENODEV;
284        }
285}
286
287void savage4_inc(struct i2c_adapter *adapter)
288{
289        MOD_INC_USE_COUNT;
290}
291
292void savage4_dec(struct i2c_adapter *adapter)
293{
294        MOD_DEC_USE_COUNT;
295}
296
297int __init i2c_savage4_init(void)
298{
299        int res;
300        printk("i2c-savage4.o version %s (%s)\n", LM_VERSION, LM_DATE);
301        savage4_initialized = 0;
302        if ((res = savage4_setup())) {
303                printk
304                    ("i2c-savage4.o: Savage4 not detected, module not inserted.\n");
305                savage4_cleanup();
306                return res;
307        }
308        if ((res = i2c_bit_add_bus(&savage4_i2c_adapter))) {
309                printk("i2c-savage4.o: I2C adapter registration failed\n");
310        } else {
311                printk("i2c-savage4.o: I2C bus initialized\n");
312                savage4_initialized |= INIT2;
313        }
314/*
315        if ((res = i2c_bit_add_bus(&savage4_ddc_adapter))) {
316                printk("i2c-savage4.o: DDC adapter registration failed\n");
317        } else {
318                printk("i2c-savage4.o: DDC bus initialized\n");
319                savage4_initialized |= INIT3;
320        }
321*/
322        if(!(savage4_initialized & (INIT2 /* | INIT3 */ ))) {
323                printk("i2c-savage4.o: Both registrations failed, module not inserted\n");
324                savage4_cleanup();
325                return res;
326        }
327        return 0;
328}
329
330int __init savage4_cleanup(void)
331{
332        int res;
333
334        iounmap(mem);
335/*
336        if (savage4_initialized & INIT3) {
337                if ((res = i2c_bit_del_bus(&savage4_ddc_adapter))) {
338                        printk
339                            ("i2c-savage4.o: i2c_bit_del_bus failed, module not removed\n");
340                        return res;
341                }
342        }
343*/
344        if (savage4_initialized & INIT2) {
345                if ((res = i2c_bit_del_bus(&savage4_i2c_adapter))) {
346                        printk
347                            ("i2c-savage4.o: i2c_bit_del_bus failed, module not removed\n");
348                        return res;
349                }
350        }
351        return 0;
352}
353
354EXPORT_NO_SYMBOLS;
355
356#ifdef MODULE
357
358MODULE_AUTHOR
359    ("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, Ralph Metzler <rjkm@thp.uni-koeln.de>, and Mark D. Studebaker <mdsxyz123@yahoo.com>");
360MODULE_DESCRIPTION("Savage4 I2C/SMBus driver");
361
362
363int init_module(void)
364{
365        return i2c_savage4_init();
366}
367
368int cleanup_module(void)
369{
370        return savage4_cleanup();
371}
372
373#endif                          /* MODULE */
Note: See TracBrowser for help on using the browser.