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
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/pci.h>
42 #include <linux/i2c.h>
43 #include <linux/i2c-algo-bit.h>
46 /* GPIO register locations */
47 #define I810_IOCONTROL_OFFSET 0x5000
48 #define I810_HVSYNC 0x00 /* not used */
49 #define I810_GPIOA 0x10
50 #define I810_GPIOB 0x14
52 /* bit locations in the registers */
53 #define SCL_DIR_MASK 0x0001
54 #define SCL_DIR 0x0002
55 #define SCL_VAL_MASK 0x0004
56 #define SCL_VAL_OUT 0x0008
57 #define SCL_VAL_IN 0x0010
58 #define SDA_DIR_MASK 0x0100
59 #define SDA_DIR 0x0200
60 #define SDA_VAL_MASK 0x0400
61 #define SDA_VAL_OUT 0x0800
62 #define SDA_VAL_IN 0x1000
64 /* initialization states */
70 #define CYCLE_DELAY 10
71 #define TIMEOUT (HZ / 2)
73 static void __iomem *ioaddr;
75 /* The i810 GPIO registers have individual masks for each bit
76 so we never have to read before writing. Nice. */
78 static void bit_i810i2c_setscl(void *data, int val)
80 writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
82 readl(ioaddr + I810_GPIOB); /* flush posted write */
85 static void bit_i810i2c_setsda(void *data, int val)
87 writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
89 readl(ioaddr + I810_GPIOB); /* flush posted write */
92 /* The GPIO pins are open drain, so the pins could always remain outputs.
93 However, some chip versions don't latch the inputs unless they
95 We rely on the i2c-algo-bit routines to set the pins high before
96 reading the input from other chips. Following guidance in the 815
97 prog. ref. guide, we do a "dummy write" of 0 to the register before
98 reading which forces the input value to be latched. We presume this
99 applies to the 810 as well; shouldn't hurt anyway. This is necessary to get
100 i2c_algo_bit bit_test=1 to pass. */
102 static int bit_i810i2c_getscl(void *data)
104 writel(SCL_DIR_MASK, ioaddr + I810_GPIOB);
105 writel(0, ioaddr + I810_GPIOB);
106 return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN));
109 static int bit_i810i2c_getsda(void *data)
111 writel(SDA_DIR_MASK, ioaddr + I810_GPIOB);
112 writel(0, ioaddr + I810_GPIOB);
113 return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN));
116 static void bit_i810ddc_setscl(void *data, int val)
118 writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
119 ioaddr + I810_GPIOA);
120 readl(ioaddr + I810_GPIOA); /* flush posted write */
123 static void bit_i810ddc_setsda(void *data, int val)
125 writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
126 ioaddr + I810_GPIOA);
127 readl(ioaddr + I810_GPIOA); /* flush posted write */
130 static int bit_i810ddc_getscl(void *data)
132 writel(SCL_DIR_MASK, ioaddr + I810_GPIOA);
133 writel(0, ioaddr + I810_GPIOA);
134 return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN));
137 static int bit_i810ddc_getsda(void *data)
139 writel(SDA_DIR_MASK, ioaddr + I810_GPIOA);
140 writel(0, ioaddr + I810_GPIOA);
141 return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN));
144 static int config_i810(struct pci_dev *dev)
148 /* map I810 memory */
149 cadr = dev->resource[1].start;
150 cadr += I810_IOCONTROL_OFFSET;
151 cadr &= PCI_BASE_ADDRESS_MEM_MASK;
152 ioaddr = ioremap_nocache(cadr, 0x1000);
154 bit_i810i2c_setscl(NULL, 1);
155 bit_i810i2c_setsda(NULL, 1);
156 bit_i810ddc_setscl(NULL, 1);
157 bit_i810ddc_setsda(NULL, 1);
163 static struct i2c_algo_bit_data i810_i2c_bit_data = {
164 .setsda = bit_i810i2c_setsda,
165 .setscl = bit_i810i2c_setscl,
166 .getsda = bit_i810i2c_getsda,
167 .getscl = bit_i810i2c_getscl,
168 .udelay = 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,
187 static struct i2c_adapter i810_ddc_adapter = {
188 .owner = THIS_MODULE,
189 .name = "I810/I815 DDC Adapter",
190 .algo_data = &i810_ddc_bit_data,
193 static struct pci_device_id i810_ids[] __devinitdata = {
194 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) },
195 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) },
196 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
197 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
198 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
202 MODULE_DEVICE_TABLE (pci, i810_ids);
204 static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id)
208 retval = config_i810(dev);
211 dev_info(&dev->dev, "i810/i815 i2c device found.\n");
213 /* set up the sysfs linkage to our parent device */
214 i810_i2c_adapter.dev.parent = &dev->dev;
215 i810_ddc_adapter.dev.parent = &dev->dev;
217 retval = i2c_bit_add_bus(&i810_i2c_adapter);
220 retval = i2c_bit_add_bus(&i810_ddc_adapter);
222 i2c_bit_del_bus(&i810_i2c_adapter);
226 static void __devexit i810_remove(struct pci_dev *dev)
228 i2c_bit_del_bus(&i810_ddc_adapter);
229 i2c_bit_del_bus(&i810_i2c_adapter);
233 static struct pci_driver i810_driver = {
234 .name = "i810_smbus",
235 .id_table = i810_ids,
237 .remove = __devexit_p(i810_remove),
240 static int __init i2c_i810_init(void)
242 return pci_register_driver(&i810_driver);
245 static void __exit i2c_i810_exit(void)
247 pci_unregister_driver(&i810_driver);
250 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
251 "Philip Edelbrock <phil@netroedge.com>, "
252 "Ralph Metzler <rjkm@thp.uni-koeln.de>, "
253 "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
254 MODULE_DESCRIPTION("I810/I815 I2C/DDC driver");
255 MODULE_LICENSE("GPL");
257 module_init(i2c_i810_init);
258 module_exit(i2c_i810_exit);