Merge with /home/shaggy/git/linus-clean/
[linux-2.6] / drivers / i2c / busses / i2c-i810.c
1 /*
2     i2c-i810.c - Part of lm_sensors, Linux kernel modules for hardware
3               monitoring
4     Copyright (c) 1998, 1999, 2000  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 I810/I815 to provide access to
28    the DDC Bus and the I2C Bus.
29
30    SUPPORTED DEVICES    PCI ID
31    i810AA               7121           
32    i810AB               7123           
33    i810E                7125           
34    i815                 1132           
35 */
36
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/init.h>
40 #include <linux/pci.h>
41 #include <linux/i2c.h>
42 #include <linux/i2c-algo-bit.h>
43 #include <asm/io.h>
44
45 /* GPIO register locations */
46 #define I810_IOCONTROL_OFFSET   0x5000
47 #define I810_HVSYNC             0x00    /* not used */
48 #define I810_GPIOA              0x10
49 #define I810_GPIOB              0x14
50
51 /* bit locations in the registers */
52 #define SCL_DIR_MASK            0x0001
53 #define SCL_DIR                 0x0002
54 #define SCL_VAL_MASK            0x0004
55 #define SCL_VAL_OUT             0x0008
56 #define SCL_VAL_IN              0x0010
57 #define SDA_DIR_MASK            0x0100
58 #define SDA_DIR                 0x0200
59 #define SDA_VAL_MASK            0x0400
60 #define SDA_VAL_OUT             0x0800
61 #define SDA_VAL_IN              0x1000
62
63 /* initialization states */
64 #define INIT1                   0x1
65 #define INIT2                   0x2
66 #define INIT3                   0x4
67
68 /* delays */
69 #define CYCLE_DELAY             10
70 #define TIMEOUT                 (HZ / 2)
71
72 static void __iomem *ioaddr;
73
74 /* The i810 GPIO registers have individual masks for each bit
75    so we never have to read before writing. Nice. */
76
77 static void bit_i810i2c_setscl(void *data, int val)
78 {
79         writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
80              ioaddr + I810_GPIOB);
81         readl(ioaddr + I810_GPIOB);     /* flush posted write */
82 }
83
84 static void bit_i810i2c_setsda(void *data, int val)
85 {
86         writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
87              ioaddr + I810_GPIOB);
88         readl(ioaddr + I810_GPIOB);     /* flush posted write */
89 }
90
91 /* The GPIO pins are open drain, so the pins could always remain outputs.
92    However, some chip versions don't latch the inputs unless they
93    are set as inputs.
94    We rely on the i2c-algo-bit routines to set the pins high before
95    reading the input from other chips. Following guidance in the 815
96    prog. ref. guide, we do a "dummy write" of 0 to the register before
97    reading which forces the input value to be latched. We presume this
98    applies to the 810 as well; shouldn't hurt anyway. This is necessary to get
99    i2c_algo_bit bit_test=1 to pass. */
100
101 static int bit_i810i2c_getscl(void *data)
102 {
103         writel(SCL_DIR_MASK, ioaddr + I810_GPIOB);
104         writel(0, ioaddr + I810_GPIOB);
105         return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN));
106 }
107
108 static int bit_i810i2c_getsda(void *data)
109 {
110         writel(SDA_DIR_MASK, ioaddr + I810_GPIOB);
111         writel(0, ioaddr + I810_GPIOB);
112         return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN));
113 }
114
115 static void bit_i810ddc_setscl(void *data, int val)
116 {
117         writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
118              ioaddr + I810_GPIOA);
119         readl(ioaddr + I810_GPIOA);     /* flush posted write */
120 }
121
122 static void bit_i810ddc_setsda(void *data, int val)
123 {
124         writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
125              ioaddr + I810_GPIOA);
126         readl(ioaddr + I810_GPIOA);     /* flush posted write */
127 }
128
129 static int bit_i810ddc_getscl(void *data)
130 {
131         writel(SCL_DIR_MASK, ioaddr + I810_GPIOA);
132         writel(0, ioaddr + I810_GPIOA);
133         return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN));
134 }
135
136 static int bit_i810ddc_getsda(void *data)
137 {
138         writel(SDA_DIR_MASK, ioaddr + I810_GPIOA);
139         writel(0, ioaddr + I810_GPIOA);
140         return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN));
141 }
142
143 static int config_i810(struct pci_dev *dev)
144 {
145         unsigned long cadr;
146
147         /* map I810 memory */
148         cadr = dev->resource[1].start;
149         cadr += I810_IOCONTROL_OFFSET;
150         cadr &= PCI_BASE_ADDRESS_MEM_MASK;
151         ioaddr = ioremap_nocache(cadr, 0x1000);
152         if (ioaddr) {
153                 bit_i810i2c_setscl(NULL, 1);
154                 bit_i810i2c_setsda(NULL, 1);
155                 bit_i810ddc_setscl(NULL, 1);
156                 bit_i810ddc_setsda(NULL, 1);
157                 return 0;
158         }
159         return -ENODEV;
160 }
161
162 static struct i2c_algo_bit_data i810_i2c_bit_data = {
163         .setsda         = bit_i810i2c_setsda,
164         .setscl         = bit_i810i2c_setscl,
165         .getsda         = bit_i810i2c_getsda,
166         .getscl         = bit_i810i2c_getscl,
167         .udelay         = CYCLE_DELAY,
168         .mdelay         = CYCLE_DELAY,
169         .timeout        = TIMEOUT,
170 };
171
172 static struct i2c_adapter i810_i2c_adapter = {
173         .owner          = THIS_MODULE,
174         .name           = "I810/I815 I2C Adapter",
175         .algo_data      = &i810_i2c_bit_data,
176 };
177
178 static struct i2c_algo_bit_data i810_ddc_bit_data = {
179         .setsda         = bit_i810ddc_setsda,
180         .setscl         = bit_i810ddc_setscl,
181         .getsda         = bit_i810ddc_getsda,
182         .getscl         = bit_i810ddc_getscl,
183         .udelay         = CYCLE_DELAY,
184         .mdelay         = CYCLE_DELAY,
185         .timeout        = TIMEOUT,
186 };
187
188 static struct i2c_adapter i810_ddc_adapter = {
189         .owner          = THIS_MODULE,
190         .name           = "I810/I815 DDC Adapter",
191         .algo_data      = &i810_ddc_bit_data,
192 };
193
194 static struct pci_device_id i810_ids[] __devinitdata = {
195         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) },
196         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) },
197         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
198         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
199         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
200         { 0, },
201 };
202
203 MODULE_DEVICE_TABLE (pci, i810_ids);
204
205 static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id)
206 {
207         int retval;
208
209         retval = config_i810(dev);
210         if (retval)
211                 return retval;
212         dev_info(&dev->dev, "i810/i815 i2c device found.\n");
213
214         /* set up the sysfs linkage to our parent device */
215         i810_i2c_adapter.dev.parent = &dev->dev;
216         i810_ddc_adapter.dev.parent = &dev->dev;
217
218         retval = i2c_bit_add_bus(&i810_i2c_adapter);
219         if (retval)
220                 return retval;
221         retval = i2c_bit_add_bus(&i810_ddc_adapter);
222         if (retval)
223                 i2c_bit_del_bus(&i810_i2c_adapter);
224         return retval;
225 }
226
227 static void __devexit i810_remove(struct pci_dev *dev)
228 {
229         i2c_bit_del_bus(&i810_ddc_adapter);
230         i2c_bit_del_bus(&i810_i2c_adapter);
231         iounmap(ioaddr);
232 }
233
234 static struct pci_driver i810_driver = {
235         .name           = "i810_smbus",
236         .id_table       = i810_ids,
237         .probe          = i810_probe,
238         .remove         = __devexit_p(i810_remove),
239 };
240
241 static int __init i2c_i810_init(void)
242 {
243         return pci_register_driver(&i810_driver);
244 }
245
246 static void __exit i2c_i810_exit(void)
247 {
248         pci_unregister_driver(&i810_driver);
249 }
250
251 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
252                 "Philip Edelbrock <phil@netroedge.com>, "
253                 "Ralph Metzler <rjkm@thp.uni-koeln.de>, "
254                 "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
255 MODULE_DESCRIPTION("I810/I815 I2C/DDC driver");
256 MODULE_LICENSE("GPL");
257
258 module_init(i2c_i810_init);
259 module_exit(i2c_i810_exit);