diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/i2c/busses/i2c-savage4.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/i2c/busses/i2c-savage4.c')
-rw-r--r-- | drivers/i2c/busses/i2c-savage4.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c new file mode 100644 index 000000000000..092d0323c6c6 --- /dev/null +++ b/drivers/i2c/busses/i2c-savage4.c | |||
@@ -0,0 +1,205 @@ | |||
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/config.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/pci.h> | ||
37 | #include <linux/i2c.h> | ||
38 | #include <linux/i2c-algo-bit.h> | ||
39 | #include <asm/io.h> | ||
40 | |||
41 | /* 3DFX defines */ | ||
42 | #define PCI_CHIP_SAVAGE3D 0x8A20 | ||
43 | #define PCI_CHIP_SAVAGE3D_MV 0x8A21 | ||
44 | #define PCI_CHIP_SAVAGE4 0x8A22 | ||
45 | #define PCI_CHIP_SAVAGE2000 0x9102 | ||
46 | #define PCI_CHIP_PROSAVAGE_PM 0x8A25 | ||
47 | #define PCI_CHIP_PROSAVAGE_KM 0x8A26 | ||
48 | #define PCI_CHIP_SAVAGE_MX_MV 0x8c10 | ||
49 | #define PCI_CHIP_SAVAGE_MX 0x8c11 | ||
50 | #define PCI_CHIP_SAVAGE_IX_MV 0x8c12 | ||
51 | #define PCI_CHIP_SAVAGE_IX 0x8c13 | ||
52 | |||
53 | #define REG 0xff20 /* Serial Port 1 Register */ | ||
54 | |||
55 | /* bit locations in the register */ | ||
56 | #define DDC_ENAB 0x00040000 | ||
57 | #define DDC_SCL_OUT 0x00080000 | ||
58 | #define DDC_SDA_OUT 0x00100000 | ||
59 | #define DDC_SCL_IN 0x00200000 | ||
60 | #define DDC_SDA_IN 0x00400000 | ||
61 | #define I2C_ENAB 0x00000020 | ||
62 | #define I2C_SCL_OUT 0x00000001 | ||
63 | #define I2C_SDA_OUT 0x00000002 | ||
64 | #define I2C_SCL_IN 0x00000008 | ||
65 | #define I2C_SDA_IN 0x00000010 | ||
66 | |||
67 | /* initialization states */ | ||
68 | #define INIT2 0x20 | ||
69 | #define INIT3 0x04 | ||
70 | |||
71 | /* delays */ | ||
72 | #define CYCLE_DELAY 10 | ||
73 | #define TIMEOUT (HZ / 2) | ||
74 | |||
75 | |||
76 | static void __iomem *ioaddr; | ||
77 | |||
78 | /* The sav GPIO registers don't have individual masks for each bit | ||
79 | so we always have to read before writing. */ | ||
80 | |||
81 | static void bit_savi2c_setscl(void *data, int val) | ||
82 | { | ||
83 | unsigned int r; | ||
84 | r = readl(ioaddr + REG); | ||
85 | if(val) | ||
86 | r |= I2C_SCL_OUT; | ||
87 | else | ||
88 | r &= ~I2C_SCL_OUT; | ||
89 | writel(r, ioaddr + REG); | ||
90 | readl(ioaddr + REG); /* flush posted write */ | ||
91 | } | ||
92 | |||
93 | static void bit_savi2c_setsda(void *data, int val) | ||
94 | { | ||
95 | unsigned int r; | ||
96 | r = readl(ioaddr + REG); | ||
97 | if(val) | ||
98 | r |= I2C_SDA_OUT; | ||
99 | else | ||
100 | r &= ~I2C_SDA_OUT; | ||
101 | writel(r, ioaddr + REG); | ||
102 | readl(ioaddr + REG); /* flush posted write */ | ||
103 | } | ||
104 | |||
105 | /* The GPIO pins are open drain, so the pins always remain outputs. | ||
106 | We rely on the i2c-algo-bit routines to set the pins high before | ||
107 | reading the input from other chips. */ | ||
108 | |||
109 | static int bit_savi2c_getscl(void *data) | ||
110 | { | ||
111 | return (0 != (readl(ioaddr + REG) & I2C_SCL_IN)); | ||
112 | } | ||
113 | |||
114 | static int bit_savi2c_getsda(void *data) | ||
115 | { | ||
116 | return (0 != (readl(ioaddr + REG) & I2C_SDA_IN)); | ||
117 | } | ||
118 | |||
119 | /* Configures the chip */ | ||
120 | |||
121 | static int config_s4(struct pci_dev *dev) | ||
122 | { | ||
123 | unsigned long cadr; | ||
124 | |||
125 | /* map memory */ | ||
126 | cadr = dev->resource[0].start; | ||
127 | cadr &= PCI_BASE_ADDRESS_MEM_MASK; | ||
128 | ioaddr = ioremap_nocache(cadr, 0x0080000); | ||
129 | if (ioaddr) { | ||
130 | /* writel(0x8160, ioaddr + REG2); */ | ||
131 | writel(0x00000020, ioaddr + REG); | ||
132 | dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr); | ||
133 | return 0; | ||
134 | } | ||
135 | return -ENODEV; | ||
136 | } | ||
137 | |||
138 | static struct i2c_algo_bit_data sav_i2c_bit_data = { | ||
139 | .setsda = bit_savi2c_setsda, | ||
140 | .setscl = bit_savi2c_setscl, | ||
141 | .getsda = bit_savi2c_getsda, | ||
142 | .getscl = bit_savi2c_getscl, | ||
143 | .udelay = CYCLE_DELAY, | ||
144 | .mdelay = CYCLE_DELAY, | ||
145 | .timeout = TIMEOUT | ||
146 | }; | ||
147 | |||
148 | static struct i2c_adapter savage4_i2c_adapter = { | ||
149 | .owner = THIS_MODULE, | ||
150 | .name = "I2C Savage4 adapter", | ||
151 | .algo_data = &sav_i2c_bit_data, | ||
152 | }; | ||
153 | |||
154 | static struct pci_device_id savage4_ids[] __devinitdata = { | ||
155 | { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) }, | ||
156 | { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) }, | ||
157 | { 0, } | ||
158 | }; | ||
159 | |||
160 | MODULE_DEVICE_TABLE (pci, savage4_ids); | ||
161 | |||
162 | static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id) | ||
163 | { | ||
164 | int retval; | ||
165 | |||
166 | retval = config_s4(dev); | ||
167 | if (retval) | ||
168 | return retval; | ||
169 | |||
170 | /* set up the sysfs linkage to our parent device */ | ||
171 | savage4_i2c_adapter.dev.parent = &dev->dev; | ||
172 | |||
173 | return i2c_bit_add_bus(&savage4_i2c_adapter); | ||
174 | } | ||
175 | |||
176 | static void __devexit savage4_remove(struct pci_dev *dev) | ||
177 | { | ||
178 | i2c_bit_del_bus(&savage4_i2c_adapter); | ||
179 | iounmap(ioaddr); | ||
180 | } | ||
181 | |||
182 | static struct pci_driver savage4_driver = { | ||
183 | .name = "savage4_smbus", | ||
184 | .id_table = savage4_ids, | ||
185 | .probe = savage4_probe, | ||
186 | .remove = __devexit_p(savage4_remove), | ||
187 | }; | ||
188 | |||
189 | static int __init i2c_savage4_init(void) | ||
190 | { | ||
191 | return pci_register_driver(&savage4_driver); | ||
192 | } | ||
193 | |||
194 | static void __exit i2c_savage4_exit(void) | ||
195 | { | ||
196 | pci_unregister_driver(&savage4_driver); | ||
197 | } | ||
198 | |||
199 | MODULE_AUTHOR("Alexander Wold <awold@bigfoot.com> " | ||
200 | "and Mark D. Studebaker <mdsxyz123@yahoo.com>"); | ||
201 | MODULE_DESCRIPTION("Savage4 I2C/SMBus driver"); | ||
202 | MODULE_LICENSE("GPL"); | ||
203 | |||
204 | module_init(i2c_savage4_init); | ||
205 | module_exit(i2c_savage4_exit); | ||