Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[linux-2.6] / drivers / i2c / busses / i2c-nforce2.c
1 /*
2     SMBus driver for nVidia nForce2 MCP
3
4     Added nForce3 Pro 150  Thomas Leibold <thomas@plx.com>,
5         Ported to 2.5 Patrick Dreker <patrick@dreker.de>,
6     Copyright (c) 2003  Hans-Frieder Vogt <hfvogt@arcor.de>,
7     Based on
8     SMBus 2.0 driver for AMD-8111 IO-Hub
9     Copyright (c) 2002 Vojtech Pavlik
10
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 /*
27     SUPPORTED DEVICES           PCI ID
28     nForce2 MCP                 0064
29     nForce2 Ultra 400 MCP       0084
30     nForce3 Pro150 MCP          00D4
31     nForce3 250Gb MCP           00E4
32     nForce4 MCP                 0052
33     nForce4 MCP-04              0034
34     nForce4 MCP51               0264
35     nForce4 MCP55               0368
36
37     This driver supports the 2 SMBuses that are included in the MCP of the
38     nForce2/3/4/5xx chipsets.
39 */
40
41 /* Note: we assume there can only be one nForce2, with two SMBus interfaces */
42
43 #include <linux/module.h>
44 #include <linux/pci.h>
45 #include <linux/kernel.h>
46 #include <linux/stddef.h>
47 #include <linux/sched.h>
48 #include <linux/ioport.h>
49 #include <linux/init.h>
50 #include <linux/i2c.h>
51 #include <linux/delay.h>
52 #include <asm/io.h>
53
54 MODULE_LICENSE("GPL");
55 MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
56 MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
57
58
59 struct nforce2_smbus {
60         struct i2c_adapter adapter;
61         int base;
62         int size;
63 };
64
65
66 /*
67  * nVidia nForce2 SMBus control register definitions
68  * (Newer incarnations use standard BARs 4 and 5 instead)
69  */
70 #define NFORCE_PCI_SMB1 0x50
71 #define NFORCE_PCI_SMB2 0x54
72
73
74 /*
75  * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
76  */
77 #define NVIDIA_SMB_PRTCL        (smbus->base + 0x00)    /* protocol, PEC */
78 #define NVIDIA_SMB_STS          (smbus->base + 0x01)    /* status */
79 #define NVIDIA_SMB_ADDR         (smbus->base + 0x02)    /* address */
80 #define NVIDIA_SMB_CMD          (smbus->base + 0x03)    /* command */
81 #define NVIDIA_SMB_DATA         (smbus->base + 0x04)    /* 32 data registers */
82
83 #define NVIDIA_SMB_STS_DONE     0x80
84 #define NVIDIA_SMB_STS_ALRM     0x40
85 #define NVIDIA_SMB_STS_RES      0x20
86 #define NVIDIA_SMB_STS_STATUS   0x1f
87
88 #define NVIDIA_SMB_PRTCL_WRITE                  0x00
89 #define NVIDIA_SMB_PRTCL_READ                   0x01
90 #define NVIDIA_SMB_PRTCL_QUICK                  0x02
91 #define NVIDIA_SMB_PRTCL_BYTE                   0x04
92 #define NVIDIA_SMB_PRTCL_BYTE_DATA              0x06
93 #define NVIDIA_SMB_PRTCL_WORD_DATA              0x08
94 #define NVIDIA_SMB_PRTCL_PEC                    0x80
95
96 static struct pci_driver nforce2_driver;
97
98 /* Return -1 on error */
99 static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
100                 unsigned short flags, char read_write,
101                 u8 command, int size, union i2c_smbus_data * data)
102 {
103         struct nforce2_smbus *smbus = adap->algo_data;
104         unsigned char protocol, pec, temp;
105
106         protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
107                 NVIDIA_SMB_PRTCL_WRITE;
108         pec = (flags & I2C_CLIENT_PEC) ? NVIDIA_SMB_PRTCL_PEC : 0;
109
110         switch (size) {
111
112                 case I2C_SMBUS_QUICK:
113                         protocol |= NVIDIA_SMB_PRTCL_QUICK;
114                         read_write = I2C_SMBUS_WRITE;
115                         break;
116
117                 case I2C_SMBUS_BYTE:
118                         if (read_write == I2C_SMBUS_WRITE)
119                                 outb_p(command, NVIDIA_SMB_CMD);
120                         protocol |= NVIDIA_SMB_PRTCL_BYTE;
121                         break;
122
123                 case I2C_SMBUS_BYTE_DATA:
124                         outb_p(command, NVIDIA_SMB_CMD);
125                         if (read_write == I2C_SMBUS_WRITE)
126                                 outb_p(data->byte, NVIDIA_SMB_DATA);
127                         protocol |= NVIDIA_SMB_PRTCL_BYTE_DATA;
128                         break;
129
130                 case I2C_SMBUS_WORD_DATA:
131                         outb_p(command, NVIDIA_SMB_CMD);
132                         if (read_write == I2C_SMBUS_WRITE) {
133                                  outb_p(data->word, NVIDIA_SMB_DATA);
134                                  outb_p(data->word >> 8, NVIDIA_SMB_DATA+1);
135                         }
136                         protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
137                         break;
138
139                 default:
140                         dev_err(&adap->dev, "Unsupported transaction %d\n", size);
141                         return -1;
142         }
143
144         outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
145         outb_p(protocol, NVIDIA_SMB_PRTCL);
146
147         temp = inb_p(NVIDIA_SMB_STS);
148
149         if (~temp & NVIDIA_SMB_STS_DONE) {
150                 udelay(500);
151                 temp = inb_p(NVIDIA_SMB_STS);
152         }
153         if (~temp & NVIDIA_SMB_STS_DONE) {
154                 msleep(10);
155                 temp = inb_p(NVIDIA_SMB_STS);
156         }
157
158         if ((~temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
159                 dev_dbg(&adap->dev, "SMBus Timeout! (0x%02x)\n", temp);
160                 return -1;
161         }
162
163         if (read_write == I2C_SMBUS_WRITE)
164                 return 0;
165
166         switch (size) {
167
168                 case I2C_SMBUS_BYTE:
169                 case I2C_SMBUS_BYTE_DATA:
170                         data->byte = inb_p(NVIDIA_SMB_DATA);
171                         break;
172
173                 case I2C_SMBUS_WORD_DATA:
174                         data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
175                         break;
176         }
177
178         return 0;
179 }
180
181
182 static u32 nforce2_func(struct i2c_adapter *adapter)
183 {
184         /* other functionality might be possible, but is not tested */
185         return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
186             I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
187 }
188
189 static struct i2c_algorithm smbus_algorithm = {
190         .smbus_xfer     = nforce2_access,
191         .functionality  = nforce2_func,
192 };
193
194
195 static struct pci_device_id nforce2_ids[] = {
196         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
197         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
198         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
199         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
200         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
201         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
202         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
203         { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
204         { 0 }
205 };
206
207 MODULE_DEVICE_TABLE (pci, nforce2_ids);
208
209
210 static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
211         int alt_reg, struct nforce2_smbus *smbus, const char *name)
212 {
213         int error;
214
215         smbus->base = pci_resource_start(dev, bar);
216         if (smbus->base) {
217                 smbus->size = pci_resource_len(dev, bar);
218         } else {
219                 /* Older incarnations of the device used non-standard BARs */
220                 u16 iobase;
221
222                 if (pci_read_config_word(dev, alt_reg, &iobase)
223                     != PCIBIOS_SUCCESSFUL) {
224                         dev_err(&dev->dev, "Error reading PCI config for %s\n",
225                                 name);
226                         return -1;
227                 }
228
229                 smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
230                 smbus->size = 64;
231         }
232
233         if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
234                 dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
235                         smbus->base, smbus->base+smbus->size-1, name);
236                 return -1;
237         }
238         smbus->adapter.owner = THIS_MODULE;
239         smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
240         smbus->adapter.class = I2C_CLASS_HWMON;
241         smbus->adapter.algo = &smbus_algorithm;
242         smbus->adapter.algo_data = smbus;
243         smbus->adapter.dev.parent = &dev->dev;
244         snprintf(smbus->adapter.name, I2C_NAME_SIZE,
245                 "SMBus nForce2 adapter at %04x", smbus->base);
246
247         error = i2c_add_adapter(&smbus->adapter);
248         if (error) {
249                 dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
250                 release_region(smbus->base, smbus->size);
251                 return -1;
252         }
253         dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base);
254         return 0;
255 }
256
257
258 static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id)
259 {
260         struct nforce2_smbus *smbuses;
261         int res1, res2;
262
263         /* we support 2 SMBus adapters */
264         if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
265                 return -ENOMEM;
266         pci_set_drvdata(dev, smbuses);
267
268         /* SMBus adapter 1 */
269         res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
270         if (res1 < 0) {
271                 dev_err(&dev->dev, "Error probing SMB1.\n");
272                 smbuses[0].base = 0;    /* to have a check value */
273         }
274         /* SMBus adapter 2 */
275         res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2");
276         if (res2 < 0) {
277                 dev_err(&dev->dev, "Error probing SMB2.\n");
278                 smbuses[1].base = 0;    /* to have a check value */
279         }
280         if ((res1 < 0) && (res2 < 0)) {
281                 /* we did not find even one of the SMBuses, so we give up */
282                 kfree(smbuses);
283                 return -ENODEV;
284         }
285
286         return 0;
287 }
288
289
290 static void __devexit nforce2_remove(struct pci_dev *dev)
291 {
292         struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev);
293
294         if (smbuses[0].base) {
295                 i2c_del_adapter(&smbuses[0].adapter);
296                 release_region(smbuses[0].base, smbuses[0].size);
297         }
298         if (smbuses[1].base) {
299                 i2c_del_adapter(&smbuses[1].adapter);
300                 release_region(smbuses[1].base, smbuses[1].size);
301         }
302         kfree(smbuses);
303 }
304
305 static struct pci_driver nforce2_driver = {
306         .name           = "nForce2_smbus",
307         .id_table       = nforce2_ids,
308         .probe          = nforce2_probe,
309         .remove         = __devexit_p(nforce2_remove),
310 };
311
312 static int __init nforce2_init(void)
313 {
314         return pci_register_driver(&nforce2_driver);
315 }
316
317 static void __exit nforce2_exit(void)
318 {
319         pci_unregister_driver(&nforce2_driver);
320 }
321
322 module_init(nforce2_init);
323 module_exit(nforce2_exit);
324