2 i2c-i810.c - Part of lm_sensors, Linux kernel modules for hardware
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>
9 Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
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.
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.
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.
27 This interfaces to the I810/I815 to provide access to
28 the DDC Bus and the I2C Bus.
30 SUPPORTED DEVICES PCI ID
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>
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
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
63 /* initialization states */
69 #define CYCLE_DELAY 10
70 #define TIMEOUT (HZ / 2)
72 static void __iomem *ioaddr;
74 /* The i810 GPIO registers have individual masks for each bit
75 so we never have to read before writing. Nice. */
77 static void bit_i810i2c_setscl(void *data, int val)
79 writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
81 readl(ioaddr + I810_GPIOB); /* flush posted write */
84 static void bit_i810i2c_setsda(void *data, int val)
86 writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
88 readl(ioaddr + I810_GPIOB); /* flush posted write */
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
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. */
101 static int bit_i810i2c_getscl(void *data)
103 writel(SCL_DIR_MASK, ioaddr + I810_GPIOB);
104 writel(0, ioaddr + I810_GPIOB);
105 return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN));
108 static int bit_i810i2c_getsda(void *data)
110 writel(SDA_DIR_MASK, ioaddr + I810_GPIOB);
111 writel(0, ioaddr + I810_GPIOB);
112 return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN));
115 static void bit_i810ddc_setscl(void *data, int val)
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 */
122 static void bit_i810ddc_setsda(void *data, int val)
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 */
129 static int bit_i810ddc_getscl(void *data)
131 writel(SCL_DIR_MASK, ioaddr + I810_GPIOA);
132 writel(0, ioaddr + I810_GPIOA);
133 return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN));
136 static int bit_i810ddc_getsda(void *data)
138 writel(SDA_DIR_MASK, ioaddr + I810_GPIOA);
139 writel(0, ioaddr + I810_GPIOA);
140 return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN));
143 static int config_i810(struct pci_dev *dev)
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);
153 bit_i810i2c_setscl(NULL, 1);
154 bit_i810i2c_setsda(NULL, 1);
155 bit_i810ddc_setscl(NULL, 1);
156 bit_i810ddc_setsda(NULL, 1);
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,
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,
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,
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,
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) },
203 MODULE_DEVICE_TABLE (pci, i810_ids);
205 static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id)
209 retval = config_i810(dev);
212 dev_info(&dev->dev, "i810/i815 i2c device found.\n");
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;
218 retval = i2c_bit_add_bus(&i810_i2c_adapter);
221 retval = i2c_bit_add_bus(&i810_ddc_adapter);
223 i2c_bit_del_bus(&i810_i2c_adapter);
227 static void __devexit i810_remove(struct pci_dev *dev)
229 i2c_bit_del_bus(&i810_ddc_adapter);
230 i2c_bit_del_bus(&i810_i2c_adapter);
234 static struct pci_driver i810_driver = {
235 .name = "i810_smbus",
236 .id_table = i810_ids,
238 .remove = __devexit_p(i810_remove),
241 static int __init i2c_i810_init(void)
243 return pci_register_driver(&i810_driver);
246 static void __exit i2c_i810_exit(void)
248 pci_unregister_driver(&i810_driver);
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");
258 module_init(i2c_i810_init);
259 module_exit(i2c_i810_exit);