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
);