]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - drivers/i2c/busses/i2c-amd8111.c
Merge branch 'drm-nouveau-fixes-3.8' of git://anongit.freedesktop.org/git/nouveau...
[android-sdk/kernel-video.git] / drivers / i2c / busses / i2c-amd8111.c
1 /*
2  * SMBus 2.0 driver for AMD-8111 IO-Hub.
3  *
4  * Copyright (c) 2002 Vojtech Pavlik
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation version 2.
9  */
11 #include <linux/module.h>
12 #include <linux/pci.h>
13 #include <linux/kernel.h>
14 #include <linux/stddef.h>
15 #include <linux/ioport.h>
16 #include <linux/init.h>
17 #include <linux/i2c.h>
18 #include <linux/delay.h>
19 #include <linux/acpi.h>
20 #include <linux/slab.h>
21 #include <linux/io.h>
23 MODULE_LICENSE("GPL");
24 MODULE_AUTHOR ("Vojtech Pavlik <vojtech@suse.cz>");
25 MODULE_DESCRIPTION("AMD8111 SMBus 2.0 driver");
27 struct amd_smbus {
28         struct pci_dev *dev;
29         struct i2c_adapter adapter;
30         int base;
31         int size;
32 };
34 static struct pci_driver amd8111_driver;
36 /*
37  * AMD PCI control registers definitions.
38  */
40 #define AMD_PCI_MISC    0x48
42 #define AMD_PCI_MISC_SCI        0x04    /* deliver SCI */
43 #define AMD_PCI_MISC_INT        0x02    /* deliver PCI IRQ */
44 #define AMD_PCI_MISC_SPEEDUP    0x01    /* 16x clock speedup */
46 /*
47  * ACPI 2.0 chapter 13 PCI interface definitions.
48  */
50 #define AMD_EC_DATA     0x00    /* data register */
51 #define AMD_EC_SC       0x04    /* status of controller */
52 #define AMD_EC_CMD      0x04    /* command register */
53 #define AMD_EC_ICR      0x08    /* interrupt control register */
55 #define AMD_EC_SC_SMI   0x04    /* smi event pending */
56 #define AMD_EC_SC_SCI   0x02    /* sci event pending */
57 #define AMD_EC_SC_BURST 0x01    /* burst mode enabled */
58 #define AMD_EC_SC_CMD   0x08    /* byte in data reg is command */
59 #define AMD_EC_SC_IBF   0x02    /* data ready for embedded controller */
60 #define AMD_EC_SC_OBF   0x01    /* data ready for host */
62 #define AMD_EC_CMD_RD   0x80    /* read EC */
63 #define AMD_EC_CMD_WR   0x81    /* write EC */
64 #define AMD_EC_CMD_BE   0x82    /* enable burst mode */
65 #define AMD_EC_CMD_BD   0x83    /* disable burst mode */
66 #define AMD_EC_CMD_QR   0x84    /* query EC */
68 /*
69  * ACPI 2.0 chapter 13 access of registers of the EC
70  */
72 static int amd_ec_wait_write(struct amd_smbus *smbus)
73 {
74         int timeout = 500;
76         while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
77                 udelay(1);
79         if (!timeout) {
80                 dev_warn(&smbus->dev->dev,
81                          "Timeout while waiting for IBF to clear\n");
82                 return -ETIMEDOUT;
83         }
85         return 0;
86 }
88 static int amd_ec_wait_read(struct amd_smbus *smbus)
89 {
90         int timeout = 500;
92         while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
93                 udelay(1);
95         if (!timeout) {
96                 dev_warn(&smbus->dev->dev,
97                          "Timeout while waiting for OBF to set\n");
98                 return -ETIMEDOUT;
99         }
101         return 0;
104 static int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
105                 unsigned char *data)
107         int status;
109         status = amd_ec_wait_write(smbus);
110         if (status)
111                 return status;
112         outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
114         status = amd_ec_wait_write(smbus);
115         if (status)
116                 return status;
117         outb(address, smbus->base + AMD_EC_DATA);
119         status = amd_ec_wait_read(smbus);
120         if (status)
121                 return status;
122         *data = inb(smbus->base + AMD_EC_DATA);
124         return 0;
127 static int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
128                 unsigned char data)
130         int status;
132         status = amd_ec_wait_write(smbus);
133         if (status)
134                 return status;
135         outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
137         status = amd_ec_wait_write(smbus);
138         if (status)
139                 return status;
140         outb(address, smbus->base + AMD_EC_DATA);
142         status = amd_ec_wait_write(smbus);
143         if (status)
144                 return status;
145         outb(data, smbus->base + AMD_EC_DATA);
147         return 0;
150 /*
151  * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
152  */
154 #define AMD_SMB_PRTCL   0x00    /* protocol, PEC */
155 #define AMD_SMB_STS     0x01    /* status */
156 #define AMD_SMB_ADDR    0x02    /* address */
157 #define AMD_SMB_CMD     0x03    /* command */
158 #define AMD_SMB_DATA    0x04    /* 32 data registers */
159 #define AMD_SMB_BCNT    0x24    /* number of data bytes */
160 #define AMD_SMB_ALRM_A  0x25    /* alarm address */
161 #define AMD_SMB_ALRM_D  0x26    /* 2 bytes alarm data */
163 #define AMD_SMB_STS_DONE        0x80
164 #define AMD_SMB_STS_ALRM        0x40
165 #define AMD_SMB_STS_RES         0x20
166 #define AMD_SMB_STS_STATUS      0x1f
168 #define AMD_SMB_STATUS_OK       0x00
169 #define AMD_SMB_STATUS_FAIL     0x07
170 #define AMD_SMB_STATUS_DNAK     0x10
171 #define AMD_SMB_STATUS_DERR     0x11
172 #define AMD_SMB_STATUS_CMD_DENY 0x12
173 #define AMD_SMB_STATUS_UNKNOWN  0x13
174 #define AMD_SMB_STATUS_ACC_DENY 0x17
175 #define AMD_SMB_STATUS_TIMEOUT  0x18
176 #define AMD_SMB_STATUS_NOTSUP   0x19
177 #define AMD_SMB_STATUS_BUSY     0x1A
178 #define AMD_SMB_STATUS_PEC      0x1F
180 #define AMD_SMB_PRTCL_WRITE             0x00
181 #define AMD_SMB_PRTCL_READ              0x01
182 #define AMD_SMB_PRTCL_QUICK             0x02
183 #define AMD_SMB_PRTCL_BYTE              0x04
184 #define AMD_SMB_PRTCL_BYTE_DATA         0x06
185 #define AMD_SMB_PRTCL_WORD_DATA         0x08
186 #define AMD_SMB_PRTCL_BLOCK_DATA        0x0a
187 #define AMD_SMB_PRTCL_PROC_CALL         0x0c
188 #define AMD_SMB_PRTCL_BLOCK_PROC_CALL   0x0d
189 #define AMD_SMB_PRTCL_I2C_BLOCK_DATA    0x4a
190 #define AMD_SMB_PRTCL_PEC               0x80
193 static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
194                 unsigned short flags, char read_write, u8 command, int size,
195                 union i2c_smbus_data * data)
197         struct amd_smbus *smbus = adap->algo_data;
198         unsigned char protocol, len, pec, temp[2];
199         int i, status;
201         protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
202                                                   : AMD_SMB_PRTCL_WRITE;
203         pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0;
205         switch (size) {
206                 case I2C_SMBUS_QUICK:
207                         protocol |= AMD_SMB_PRTCL_QUICK;
208                         read_write = I2C_SMBUS_WRITE;
209                         break;
211                 case I2C_SMBUS_BYTE:
212                         if (read_write == I2C_SMBUS_WRITE) {
213                                 status = amd_ec_write(smbus, AMD_SMB_CMD,
214                                                       command);
215                                 if (status)
216                                         return status;
217                         }
218                         protocol |= AMD_SMB_PRTCL_BYTE;
219                         break;
221                 case I2C_SMBUS_BYTE_DATA:
222                         status = amd_ec_write(smbus, AMD_SMB_CMD, command);
223                         if (status)
224                                 return status;
225                         if (read_write == I2C_SMBUS_WRITE) {
226                                 status = amd_ec_write(smbus, AMD_SMB_DATA,
227                                                       data->byte);
228                                 if (status)
229                                         return status;
230                         }
231                         protocol |= AMD_SMB_PRTCL_BYTE_DATA;
232                         break;
234                 case I2C_SMBUS_WORD_DATA:
235                         status = amd_ec_write(smbus, AMD_SMB_CMD, command);
236                         if (status)
237                                 return status;
238                         if (read_write == I2C_SMBUS_WRITE) {
239                                 status = amd_ec_write(smbus, AMD_SMB_DATA,
240                                                       data->word & 0xff);
241                                 if (status)
242                                         return status;
243                                 status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
244                                                       data->word >> 8);
245                                 if (status)
246                                         return status;
247                         }
248                         protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
249                         break;
251                 case I2C_SMBUS_BLOCK_DATA:
252                         status = amd_ec_write(smbus, AMD_SMB_CMD, command);
253                         if (status)
254                                 return status;
255                         if (read_write == I2C_SMBUS_WRITE) {
256                                 len = min_t(u8, data->block[0],
257                                             I2C_SMBUS_BLOCK_MAX);
258                                 status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
259                                 if (status)
260                                         return status;
261                                 for (i = 0; i < len; i++) {
262                                         status =
263                                           amd_ec_write(smbus, AMD_SMB_DATA + i,
264                                                        data->block[i + 1]);
265                                         if (status)
266                                                 return status;
267                                 }
268                         }
269                         protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
270                         break;
272                 case I2C_SMBUS_I2C_BLOCK_DATA:
273                         len = min_t(u8, data->block[0],
274                                     I2C_SMBUS_BLOCK_MAX);
275                         status = amd_ec_write(smbus, AMD_SMB_CMD, command);
276                         if (status)
277                                 return status;
278                         status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
279                         if (status)
280                                 return status;
281                         if (read_write == I2C_SMBUS_WRITE)
282                                 for (i = 0; i < len; i++) {
283                                         status =
284                                           amd_ec_write(smbus, AMD_SMB_DATA + i,
285                                                        data->block[i + 1]);
286                                         if (status)
287                                                 return status;
288                                 }
289                         protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
290                         break;
292                 case I2C_SMBUS_PROC_CALL:
293                         status = amd_ec_write(smbus, AMD_SMB_CMD, command);
294                         if (status)
295                                 return status;
296                         status = amd_ec_write(smbus, AMD_SMB_DATA,
297                                               data->word & 0xff);
298                         if (status)
299                                 return status;
300                         status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
301                                               data->word >> 8);
302                         if (status)
303                                 return status;
304                         protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
305                         read_write = I2C_SMBUS_READ;
306                         break;
308                 case I2C_SMBUS_BLOCK_PROC_CALL:
309                         len = min_t(u8, data->block[0],
310                                     I2C_SMBUS_BLOCK_MAX - 1);
311                         status = amd_ec_write(smbus, AMD_SMB_CMD, command);
312                         if (status)
313                                 return status;
314                         status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
315                         if (status)
316                                 return status;
317                         for (i = 0; i < len; i++) {
318                                 status = amd_ec_write(smbus, AMD_SMB_DATA + i,
319                                                       data->block[i + 1]);
320                                 if (status)
321                                         return status;
322                         }
323                         protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
324                         read_write = I2C_SMBUS_READ;
325                         break;
327                 default:
328                         dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
329                         return -EOPNOTSUPP;
330         }
332         status = amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
333         if (status)
334                 return status;
335         status = amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
336         if (status)
337                 return status;
339         status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
340         if (status)
341                 return status;
343         if (~temp[0] & AMD_SMB_STS_DONE) {
344                 udelay(500);
345                 status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
346                 if (status)
347                         return status;
348         }
350         if (~temp[0] & AMD_SMB_STS_DONE) {
351                 msleep(1);
352                 status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
353                 if (status)
354                         return status;
355         }
357         if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
358                 return -EIO;
360         if (read_write == I2C_SMBUS_WRITE)
361                 return 0;
363         switch (size) {
364                 case I2C_SMBUS_BYTE:
365                 case I2C_SMBUS_BYTE_DATA:
366                         status = amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
367                         if (status)
368                                 return status;
369                         break;
371                 case I2C_SMBUS_WORD_DATA:
372                 case I2C_SMBUS_PROC_CALL:
373                         status = amd_ec_read(smbus, AMD_SMB_DATA, temp + 0);
374                         if (status)
375                                 return status;
376                         status = amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1);
377                         if (status)
378                                 return status;
379                         data->word = (temp[1] << 8) | temp[0];
380                         break;
382                 case I2C_SMBUS_BLOCK_DATA:
383                 case I2C_SMBUS_BLOCK_PROC_CALL:
384                         status = amd_ec_read(smbus, AMD_SMB_BCNT, &len);
385                         if (status)
386                                 return status;
387                         len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
388                 case I2C_SMBUS_I2C_BLOCK_DATA:
389                         for (i = 0; i < len; i++) {
390                                 status = amd_ec_read(smbus, AMD_SMB_DATA + i,
391                                                      data->block + i + 1);
392                                 if (status)
393                                         return status;
394                         }
395                         data->block[0] = len;
396                         break;
397         }
399         return 0;
403 static u32 amd8111_func(struct i2c_adapter *adapter)
405         return  I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
406                 I2C_FUNC_SMBUS_BYTE_DATA |
407                 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
408                 I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
409                 I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_PEC;
412 static const struct i2c_algorithm smbus_algorithm = {
413         .smbus_xfer = amd8111_access,
414         .functionality = amd8111_func,
415 };
418 static DEFINE_PCI_DEVICE_TABLE(amd8111_ids) = {
419         { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
420         { 0, }
421 };
423 MODULE_DEVICE_TABLE (pci, amd8111_ids);
425 static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
427         struct amd_smbus *smbus;
428         int error;
430         if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
431                 return -ENODEV;
433         smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
434         if (!smbus)
435                 return -ENOMEM;
437         smbus->dev = dev;
438         smbus->base = pci_resource_start(dev, 0);
439         smbus->size = pci_resource_len(dev, 0);
441         error = acpi_check_resource_conflict(&dev->resource[0]);
442         if (error) {
443                 error = -ENODEV;
444                 goto out_kfree;
445         }
447         if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
448                 error = -EBUSY;
449                 goto out_kfree;
450         }
452         smbus->adapter.owner = THIS_MODULE;
453         snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
454                 "SMBus2 AMD8111 adapter at %04x", smbus->base);
455         smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
456         smbus->adapter.algo = &smbus_algorithm;
457         smbus->adapter.algo_data = smbus;
459         /* set up the sysfs linkage to our parent device */
460         smbus->adapter.dev.parent = &dev->dev;
462         pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
463         error = i2c_add_adapter(&smbus->adapter);
464         if (error)
465                 goto out_release_region;
467         pci_set_drvdata(dev, smbus);
468         return 0;
470  out_release_region:
471         release_region(smbus->base, smbus->size);
472  out_kfree:
473         kfree(smbus);
474         return error;
477 static void amd8111_remove(struct pci_dev *dev)
479         struct amd_smbus *smbus = pci_get_drvdata(dev);
481         i2c_del_adapter(&smbus->adapter);
482         release_region(smbus->base, smbus->size);
483         kfree(smbus);
486 static struct pci_driver amd8111_driver = {
487         .name           = "amd8111_smbus2",
488         .id_table       = amd8111_ids,
489         .probe          = amd8111_probe,
490         .remove         = amd8111_remove,
491 };
493 module_pci_driver(amd8111_driver);