b7fb65c301124eb54e786bc5ef33153737028f06
[linux-2.6.git] / drivers / i2c / busses / i2c-savage4.c
1 /*
2     i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware
3               monitoring
4     Copyright (C) 1998-2003  The LM Sensors Team
5     Alexander Wold <awold@bigfoot.com>
6     Mark D. Studebaker <mdsxyz123@yahoo.com>
7     
8     Based on i2c-voodoo3.c.
9
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 /* This interfaces to the I2C bus of the Savage4 to gain access to
26    the BT869 and possibly other I2C devices. The DDC bus is not
27    yet supported because its register is not memory-mapped.
28    However we leave the DDC code here, commented out, to make
29    it easier to add later.
30 */
31
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/init.h>
35 #include <linux/pci.h>
36 #include <linux/i2c.h>
37 #include <linux/i2c-algo-bit.h>
38 #include <asm/io.h>
39
40 /* 3DFX defines */
41 #define PCI_CHIP_SAVAGE3D       0x8A20
42 #define PCI_CHIP_SAVAGE3D_MV    0x8A21
43 #define PCI_CHIP_SAVAGE4        0x8A22
44 #define PCI_CHIP_SAVAGE2000     0x9102
45 #define PCI_CHIP_PROSAVAGE_PM   0x8A25
46 #define PCI_CHIP_PROSAVAGE_KM   0x8A26
47 #define PCI_CHIP_SAVAGE_MX_MV   0x8c10
48 #define PCI_CHIP_SAVAGE_MX      0x8c11
49 #define PCI_CHIP_SAVAGE_IX_MV   0x8c12
50 #define PCI_CHIP_SAVAGE_IX      0x8c13
51
52 #define REG                     0xff20  /* Serial Port 1 Register */
53
54 /* bit locations in the register */
55 #define DDC_ENAB                0x00040000
56 #define DDC_SCL_OUT             0x00080000
57 #define DDC_SDA_OUT             0x00100000
58 #define DDC_SCL_IN              0x00200000
59 #define DDC_SDA_IN              0x00400000
60 #define I2C_ENAB                0x00000020
61 #define I2C_SCL_OUT             0x00000001
62 #define I2C_SDA_OUT             0x00000002
63 #define I2C_SCL_IN              0x00000008
64 #define I2C_SDA_IN              0x00000010
65
66 /* initialization states */
67 #define INIT2                   0x20
68 #define INIT3                   0x04
69
70 /* delays */
71 #define CYCLE_DELAY             10
72 #define TIMEOUT                 (HZ / 2)
73
74
75 static void __iomem *ioaddr;
76
77 /* The sav GPIO registers don't have individual masks for each bit
78    so we always have to read before writing. */
79
80 static void bit_savi2c_setscl(void *data, int val)
81 {
82         unsigned int r;
83         r = readl(ioaddr + REG);
84         if(val)
85                 r |= I2C_SCL_OUT;
86         else
87                 r &= ~I2C_SCL_OUT;
88         writel(r, ioaddr + REG);
89         readl(ioaddr + REG);    /* flush posted write */
90 }
91
92 static void bit_savi2c_setsda(void *data, int val)
93 {
94         unsigned int r;
95         r = readl(ioaddr + REG);
96         if(val)
97                 r |= I2C_SDA_OUT;
98         else
99                 r &= ~I2C_SDA_OUT;
100         writel(r, ioaddr + REG);
101         readl(ioaddr + REG);    /* flush posted write */
102 }
103
104 /* The GPIO pins are open drain, so the pins always remain outputs.
105    We rely on the i2c-algo-bit routines to set the pins high before
106    reading the input from other chips. */
107
108 static int bit_savi2c_getscl(void *data)
109 {
110         return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
111 }
112
113 static int bit_savi2c_getsda(void *data)
114 {
115         return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
116 }
117
118 /* Configures the chip */
119
120 static int config_s4(struct pci_dev *dev)
121 {
122         unsigned long cadr;
123
124         /* map memory */
125         cadr = dev->resource[0].start;
126         cadr &= PCI_BASE_ADDRESS_MEM_MASK;
127         ioaddr = ioremap_nocache(cadr, 0x0080000);
128         if (ioaddr) {
129                 /* writel(0x8160, ioaddr + REG2); */
130                 writel(0x00000020, ioaddr + REG);
131                 dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr);
132                 return 0;
133         }
134         return -ENODEV;
135 }
136
137 static struct i2c_algo_bit_data sav_i2c_bit_data = {
138         .setsda         = bit_savi2c_setsda,
139         .setscl         = bit_savi2c_setscl,
140         .getsda         = bit_savi2c_getsda,
141         .getscl         = bit_savi2c_getscl,
142         .udelay         = CYCLE_DELAY,
143         .timeout        = TIMEOUT
144 };
145
146 static struct i2c_adapter savage4_i2c_adapter = {
147         .owner          = THIS_MODULE,
148         .id             = I2C_HW_B_SAVAGE,
149         .name           = "I2C Savage4 adapter",
150         .algo_data      = &sav_i2c_bit_data,
151 };
152
153 static struct pci_device_id savage4_ids[] __devinitdata = {
154         { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) },
155         { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) },
156         { 0, }
157 };
158
159 MODULE_DEVICE_TABLE (pci, savage4_ids);
160
161 static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id)
162 {
163         int retval;
164
165         retval = config_s4(dev);
166         if (retval)
167                 return retval;
168
169         /* set up the sysfs linkage to our parent device */
170         savage4_i2c_adapter.dev.parent = &dev->dev;
171
172         return i2c_bit_add_bus(&savage4_i2c_adapter);
173 }
174
175 static void __devexit savage4_remove(struct pci_dev *dev)
176 {
177         i2c_del_adapter(&savage4_i2c_adapter);
178         iounmap(ioaddr);
179 }
180
181 static struct pci_driver savage4_driver = {
182         .name           = "savage4_smbus",
183         .id_table       = savage4_ids,
184         .probe          = savage4_probe,
185         .remove         = __devexit_p(savage4_remove),
186 };
187
188 static int __init i2c_savage4_init(void)
189 {
190         return pci_register_driver(&savage4_driver);
191 }
192
193 static void __exit i2c_savage4_exit(void)
194 {
195         pci_unregister_driver(&savage4_driver);
196 }
197
198 MODULE_AUTHOR("Alexander Wold <awold@bigfoot.com> "
199                 "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
200 MODULE_DESCRIPTION("Savage4 I2C/SMBus driver");
201 MODULE_LICENSE("GPL");
202
203 module_init(i2c_savage4_init);
204 module_exit(i2c_savage4_exit);