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

Revision 1354, 8.2 KB (checked in by mds, 13 years ago)

give it its own driver ID

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