blob: 37793156bd936202a10362e7910d88708c4a9248 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
3 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
4 <mdsxyz123@yahoo.com>
Jean Delvare84c1af42012-03-26 21:47:19 +02005 Copyright (C) 2007 - 2012 Jean Delvare <khali@linux-fr.org>
David Woodhouse0cd96eb2010-10-31 21:06:59 +01006 Copyright (C) 2010 Intel Corporation,
7 David Woodhouse <dwmw2@infradead.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24/*
Jean Delvareae7b0492008-01-27 18:14:49 +010025 Supports the following Intel I/O Controller Hubs (ICH):
26
27 I/O Block I2C
28 region SMBus Block proc. block
29 Chip name PCI ID size PEC buffer call read
30 ----------------------------------------------------------------------
31 82801AA (ICH) 0x2413 16 no no no no
32 82801AB (ICH0) 0x2423 16 no no no no
33 82801BA (ICH2) 0x2443 16 no no no no
34 82801CA (ICH3) 0x2483 32 soft no no no
35 82801DB (ICH4) 0x24c3 32 hard yes no no
36 82801E (ICH5) 0x24d3 32 hard yes yes yes
37 6300ESB 0x25a4 32 hard yes yes yes
38 82801F (ICH6) 0x266a 32 hard yes yes yes
39 6310ESB/6320ESB 0x269b 32 hard yes yes yes
40 82801G (ICH7) 0x27da 32 hard yes yes yes
41 82801H (ICH8) 0x283e 32 hard yes yes yes
42 82801I (ICH9) 0x2930 32 hard yes yes yes
Seth Heasleycb04e952010-10-04 13:27:14 -070043 EP80579 (Tolapai) 0x5032 32 hard yes yes yes
Gaston, Jason Dd28dc712008-02-24 20:03:42 +010044 ICH10 0x3a30 32 hard yes yes yes
45 ICH10 0x3a60 32 hard yes yes yes
Seth Heasleycb04e952010-10-04 13:27:14 -070046 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes
Seth Heasley662cda82011-03-20 14:50:53 +010047 6 Series (PCH) 0x1c22 32 hard yes yes yes
Seth Heasleye30d9852010-10-31 21:06:59 +010048 Patsburg (PCH) 0x1d22 32 hard yes yes yes
David Woodhouse55fee8d2010-10-31 21:07:00 +010049 Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes
50 Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes
51 Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes
Seth Heasley662cda82011-03-20 14:50:53 +010052 DH89xxCC (PCH) 0x2330 32 hard yes yes yes
Seth Heasley6e2a8512011-05-24 20:58:49 +020053 Panther Point (PCH) 0x1e22 32 hard yes yes yes
Seth Heasley062737f2012-03-26 21:47:19 +020054 Lynx Point (PCH) 0x8c22 32 hard yes yes yes
James Ralston4a8f1dd2012-09-10 10:14:02 +020055 Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes
Jean Delvareae7b0492008-01-27 18:14:49 +010056
57 Features supported by this driver:
58 Software PEC no
59 Hardware PEC yes
60 Block buffer yes
61 Block process call transaction no
Jean Delvare63420642008-01-27 18:14:50 +010062 I2C block read transaction yes (doesn't use the block buffer)
David Woodhouse55fee8d2010-10-31 21:07:00 +010063 Slave mode no
Daniel Kurtz636752b2012-07-24 14:13:58 +020064 Interrupt processing yes
Jean Delvareae7b0492008-01-27 18:14:49 +010065
66 See the file Documentation/i2c/busses/i2c-i801 for details.
Linus Torvalds1da177e2005-04-16 15:20:36 -070067*/
68
Daniel Kurtz636752b2012-07-24 14:13:58 +020069#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070070#include <linux/module.h>
71#include <linux/pci.h>
72#include <linux/kernel.h>
73#include <linux/stddef.h>
74#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070075#include <linux/ioport.h>
76#include <linux/init.h>
77#include <linux/i2c.h>
Jean Delvare54fb4a052008-07-14 22:38:33 +020078#include <linux/acpi.h>
Jean Delvare1561bfe2009-01-07 14:29:17 +010079#include <linux/io.h>
Hans de Goedefa5bfab2009-03-30 21:46:44 +020080#include <linux/dmi.h>
Ben Hutchings665a96b2011-01-10 22:11:22 +010081#include <linux/slab.h>
Daniel Kurtz636752b2012-07-24 14:13:58 +020082#include <linux/wait.h>
Jean Delvare3ad7ea12012-10-05 22:23:53 +020083#include <linux/err.h>
84
85#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
86#include <linux/gpio.h>
87#include <linux/i2c-mux-gpio.h>
88#include <linux/platform_device.h>
89#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Linus Torvalds1da177e2005-04-16 15:20:36 -070091/* I801 SMBus address offsets */
David Woodhouse0cd96eb2010-10-31 21:06:59 +010092#define SMBHSTSTS(p) (0 + (p)->smba)
93#define SMBHSTCNT(p) (2 + (p)->smba)
94#define SMBHSTCMD(p) (3 + (p)->smba)
95#define SMBHSTADD(p) (4 + (p)->smba)
96#define SMBHSTDAT0(p) (5 + (p)->smba)
97#define SMBHSTDAT1(p) (6 + (p)->smba)
98#define SMBBLKDAT(p) (7 + (p)->smba)
99#define SMBPEC(p) (8 + (p)->smba) /* ICH3 and later */
100#define SMBAUXSTS(p) (12 + (p)->smba) /* ICH4 and later */
101#define SMBAUXCTL(p) (13 + (p)->smba) /* ICH4 and later */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103/* PCI Address Constants */
Jean Delvare6dcc19d2006-06-12 21:53:02 +0200104#define SMBBAR 4
Daniel Kurtz636752b2012-07-24 14:13:58 +0200105#define SMBPCISTS 0x006
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106#define SMBHSTCFG 0x040
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
Daniel Kurtz636752b2012-07-24 14:13:58 +0200108/* Host status bits for SMBPCISTS */
109#define SMBPCISTS_INTS 0x08
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111/* Host configuration bits for SMBHSTCFG */
112#define SMBHSTCFG_HST_EN 1
113#define SMBHSTCFG_SMB_SMI_EN 2
114#define SMBHSTCFG_I2C_EN 4
115
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300116/* Auxiliary control register bits, ICH4+ only */
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200117#define SMBAUXCTL_CRC 1
118#define SMBAUXCTL_E32B 2
119
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120/* Other settings */
Jean Delvare84c1af42012-03-26 21:47:19 +0200121#define MAX_RETRIES 400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
123/* I801 command constants */
124#define I801_QUICK 0x00
125#define I801_BYTE 0x04
126#define I801_BYTE_DATA 0x08
127#define I801_WORD_DATA 0x0C
Jean Delvareae7b0492008-01-27 18:14:49 +0100128#define I801_PROC_CALL 0x10 /* unimplemented */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129#define I801_BLOCK_DATA 0x14
Jean Delvare63420642008-01-27 18:14:50 +0100130#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200131
132/* I801 Host Control register bits */
133#define SMBHSTCNT_INTREN 0x01
134#define SMBHSTCNT_KILL 0x02
135#define SMBHSTCNT_LAST_BYTE 0x20
136#define SMBHSTCNT_START 0x40
137#define SMBHSTCNT_PEC_EN 0x80 /* ICH3 and later */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200139/* I801 Hosts Status register bits */
140#define SMBHSTSTS_BYTE_DONE 0x80
141#define SMBHSTSTS_INUSE_STS 0x40
142#define SMBHSTSTS_SMBALERT_STS 0x20
143#define SMBHSTSTS_FAILED 0x10
144#define SMBHSTSTS_BUS_ERR 0x08
145#define SMBHSTSTS_DEV_ERR 0x04
146#define SMBHSTSTS_INTR 0x02
147#define SMBHSTSTS_HOST_BUSY 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
Daniel Kurtz70a1cc12012-07-24 14:13:58 +0200149#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \
150 SMBHSTSTS_DEV_ERR)
151
152#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \
153 STATUS_ERROR_FLAGS)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200154
Jean Delvarea6e5e2b2011-05-01 18:18:49 +0200155/* Older devices have their ID defined in <linux/pci_ids.h> */
156#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
157#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
David Woodhouse55fee8d2010-10-31 21:07:00 +0100158/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
159#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70
160#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
161#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72
Seth Heasley6e2a8512011-05-24 20:58:49 +0200162#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
Jean Delvarea6e5e2b2011-05-01 18:18:49 +0200163#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
164#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
Seth Heasley062737f2012-03-26 21:47:19 +0200165#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
James Ralston4a8f1dd2012-09-10 10:14:02 +0200166#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
David Woodhouse55fee8d2010-10-31 21:07:00 +0100167
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200168struct i801_mux_config {
169 char *gpio_chip;
170 unsigned values[3];
171 int n_values;
172 unsigned classes[3];
173 unsigned gpios[2]; /* Relative to gpio_chip->base */
174 int n_gpios;
175};
176
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100177struct i801_priv {
178 struct i2c_adapter adapter;
179 unsigned long smba;
180 unsigned char original_hstcfg;
181 struct pci_dev *pci_dev;
182 unsigned int features;
Daniel Kurtz636752b2012-07-24 14:13:58 +0200183
184 /* isr processing */
185 wait_queue_head_t waitq;
186 u8 status;
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200187
188 /* Command state used by isr for byte-by-byte block transactions */
189 u8 cmd;
190 bool is_read;
191 int count;
192 int len;
193 u8 *data;
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200194
195#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
196 const struct i801_mux_config *mux_drvdata;
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200197 struct platform_device *mux_pdev;
198#endif
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100199};
200
Jean Delvared6072f82005-09-25 16:37:04 +0200201static struct pci_driver i801_driver;
Jean Delvare369f6f42008-01-27 18:14:50 +0100202
203#define FEATURE_SMBUS_PEC (1 << 0)
204#define FEATURE_BLOCK_BUFFER (1 << 1)
205#define FEATURE_BLOCK_PROC (1 << 2)
206#define FEATURE_I2C_BLOCK_READ (1 << 3)
Daniel Kurtz636752b2012-07-24 14:13:58 +0200207#define FEATURE_IRQ (1 << 4)
Jean Delvaree7198fb2011-05-24 20:58:49 +0200208/* Not really a feature, but it's convenient to handle it as such */
209#define FEATURE_IDF (1 << 15)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
Jean Delvareadff6872010-05-21 18:40:54 +0200211static const char *i801_feature_names[] = {
212 "SMBus PEC",
213 "Block buffer",
214 "Block process call",
215 "I2C block read",
Daniel Kurtz636752b2012-07-24 14:13:58 +0200216 "Interrupt",
Jean Delvareadff6872010-05-21 18:40:54 +0200217};
218
219static unsigned int disable_features;
220module_param(disable_features, uint, S_IRUGO | S_IWUSR);
221MODULE_PARM_DESC(disable_features, "Disable selected driver features");
222
Jean Delvarecf898dc2008-07-14 22:38:33 +0200223/* Make sure the SMBus host is ready to start transmitting.
224 Return 0 if it is, -EBUSY if it is not. */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100225static int i801_check_pre(struct i801_priv *priv)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200226{
227 int status;
228
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100229 status = inb_p(SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200230 if (status & SMBHSTSTS_HOST_BUSY) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100231 dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200232 return -EBUSY;
233 }
234
235 status &= STATUS_FLAGS;
236 if (status) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100237 dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n",
Jean Delvarecf898dc2008-07-14 22:38:33 +0200238 status);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100239 outb_p(status, SMBHSTSTS(priv));
240 status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200241 if (status) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100242 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200243 "Failed clearing status flags (%02x)\n",
244 status);
245 return -EBUSY;
246 }
247 }
248
249 return 0;
250}
251
Jean Delvare6cad93c2012-07-24 14:13:58 +0200252/*
253 * Convert the status register to an error code, and clear it.
254 * Note that status only contains the bits we want to clear, not the
255 * actual register value.
256 */
257static int i801_check_post(struct i801_priv *priv, int status)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200258{
259 int result = 0;
260
Daniel Kurtz636752b2012-07-24 14:13:58 +0200261 /*
262 * If the SMBus is still busy, we give up
263 * Note: This timeout condition only happens when using polling
264 * transactions. For interrupt operation, NAK/timeout is indicated by
265 * DEV_ERR.
266 */
Jean Delvare6cad93c2012-07-24 14:13:58 +0200267 if (unlikely(status < 0)) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100268 dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200269 /* try to stop the current command */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100270 dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
271 outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
272 SMBHSTCNT(priv));
Jean Delvare84c1af42012-03-26 21:47:19 +0200273 usleep_range(1000, 2000);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100274 outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
275 SMBHSTCNT(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200276
277 /* Check if it worked */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100278 status = inb_p(SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200279 if ((status & SMBHSTSTS_HOST_BUSY) ||
280 !(status & SMBHSTSTS_FAILED))
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100281 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200282 "Failed terminating the transaction\n");
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100283 outb_p(STATUS_FLAGS, SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200284 return -ETIMEDOUT;
285 }
286
287 if (status & SMBHSTSTS_FAILED) {
288 result = -EIO;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100289 dev_err(&priv->pci_dev->dev, "Transaction failed\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200290 }
291 if (status & SMBHSTSTS_DEV_ERR) {
292 result = -ENXIO;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100293 dev_dbg(&priv->pci_dev->dev, "No response\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200294 }
295 if (status & SMBHSTSTS_BUS_ERR) {
296 result = -EAGAIN;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100297 dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200298 }
299
Jean Delvare6cad93c2012-07-24 14:13:58 +0200300 /* Clear status flags except BYTE_DONE, to be cleared by caller */
301 outb_p(status, SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200302
303 return result;
304}
305
Jean Delvare6cad93c2012-07-24 14:13:58 +0200306/* Wait for BUSY being cleared and either INTR or an error flag being set */
307static int i801_wait_intr(struct i801_priv *priv)
308{
309 int timeout = 0;
310 int status;
311
312 /* We will always wait for a fraction of a second! */
313 do {
314 usleep_range(250, 500);
315 status = inb_p(SMBHSTSTS(priv));
316 } while (((status & SMBHSTSTS_HOST_BUSY) ||
317 !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) &&
318 (timeout++ < MAX_RETRIES));
319
320 if (timeout > MAX_RETRIES) {
321 dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n");
322 return -ETIMEDOUT;
323 }
324 return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR);
325}
326
327/* Wait for either BYTE_DONE or an error flag being set */
328static int i801_wait_byte_done(struct i801_priv *priv)
329{
330 int timeout = 0;
331 int status;
332
333 /* We will always wait for a fraction of a second! */
334 do {
335 usleep_range(250, 500);
336 status = inb_p(SMBHSTSTS(priv));
337 } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) &&
338 (timeout++ < MAX_RETRIES));
339
340 if (timeout > MAX_RETRIES) {
341 dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n");
342 return -ETIMEDOUT;
343 }
344 return status & STATUS_ERROR_FLAGS;
345}
346
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100347static int i801_transaction(struct i801_priv *priv, int xact)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348{
Jean Delvare2b738092008-07-14 22:38:32 +0200349 int status;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200350 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100352 result = i801_check_pre(priv);
Jean Delvarecf898dc2008-07-14 22:38:33 +0200353 if (result < 0)
354 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
Daniel Kurtz636752b2012-07-24 14:13:58 +0200356 if (priv->features & FEATURE_IRQ) {
357 outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
358 SMBHSTCNT(priv));
359 wait_event(priv->waitq, (status = priv->status));
360 priv->status = 0;
361 return i801_check_post(priv, status);
362 }
363
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200364 /* the current contents of SMBHSTCNT can be overwritten, since PEC,
Daniel Kurtz37af8712012-07-24 14:13:58 +0200365 * SMBSCMD are passed in xact */
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200366 outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367
Jean Delvare6cad93c2012-07-24 14:13:58 +0200368 status = i801_wait_intr(priv);
369 return i801_check_post(priv, status);
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200370}
371
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100372static int i801_block_transaction_by_block(struct i801_priv *priv,
373 union i2c_smbus_data *data,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200374 char read_write, int hwpec)
375{
376 int i, len;
David Brownell97140342008-07-14 22:38:25 +0200377 int status;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200378
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100379 inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200380
381 /* Use 32-byte buffer to process this transaction */
382 if (read_write == I2C_SMBUS_WRITE) {
383 len = data->block[0];
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100384 outb_p(len, SMBHSTDAT0(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200385 for (i = 0; i < len; i++)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100386 outb_p(data->block[i+1], SMBBLKDAT(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200387 }
388
Daniel Kurtz37af8712012-07-24 14:13:58 +0200389 status = i801_transaction(priv, I801_BLOCK_DATA |
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200390 (hwpec ? SMBHSTCNT_PEC_EN : 0));
David Brownell97140342008-07-14 22:38:25 +0200391 if (status)
392 return status;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200393
394 if (read_write == I2C_SMBUS_READ) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100395 len = inb_p(SMBHSTDAT0(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200396 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
David Brownell97140342008-07-14 22:38:25 +0200397 return -EPROTO;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200398
399 data->block[0] = len;
400 for (i = 0; i < len; i++)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100401 data->block[i + 1] = inb_p(SMBBLKDAT(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200402 }
403 return 0;
404}
405
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200406static void i801_isr_byte_done(struct i801_priv *priv)
407{
408 if (priv->is_read) {
409 /* For SMBus block reads, length is received with first byte */
410 if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) &&
411 (priv->count == 0)) {
412 priv->len = inb_p(SMBHSTDAT0(priv));
413 if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) {
414 dev_err(&priv->pci_dev->dev,
415 "Illegal SMBus block read size %d\n",
416 priv->len);
417 /* FIXME: Recover */
418 priv->len = I2C_SMBUS_BLOCK_MAX;
419 } else {
420 dev_dbg(&priv->pci_dev->dev,
421 "SMBus block read size is %d\n",
422 priv->len);
423 }
424 priv->data[-1] = priv->len;
425 }
426
427 /* Read next byte */
428 if (priv->count < priv->len)
429 priv->data[priv->count++] = inb(SMBBLKDAT(priv));
430 else
431 dev_dbg(&priv->pci_dev->dev,
432 "Discarding extra byte on block read\n");
433
434 /* Set LAST_BYTE for last byte of read transaction */
435 if (priv->count == priv->len - 1)
436 outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE,
437 SMBHSTCNT(priv));
438 } else if (priv->count < priv->len - 1) {
439 /* Write next byte, except for IRQ after last byte */
440 outb_p(priv->data[++priv->count], SMBBLKDAT(priv));
441 }
442
443 /* Clear BYTE_DONE to continue with next byte */
444 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
445}
446
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200447/*
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200448 * There are two kinds of interrupts:
449 *
450 * 1) i801 signals transaction completion with one of these interrupts:
451 * INTR - Success
452 * DEV_ERR - Invalid command, NAK or communication timeout
453 * BUS_ERR - SMI# transaction collision
454 * FAILED - transaction was canceled due to a KILL request
455 * When any of these occur, update ->status and wake up the waitq.
456 * ->status must be cleared before kicking off the next transaction.
457 *
458 * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt
459 * occurs for each byte of a byte-by-byte to prepare the next byte.
Daniel Kurtz636752b2012-07-24 14:13:58 +0200460 */
461static irqreturn_t i801_isr(int irq, void *dev_id)
462{
463 struct i801_priv *priv = dev_id;
464 u16 pcists;
465 u8 status;
466
467 /* Confirm this is our interrupt */
468 pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
469 if (!(pcists & SMBPCISTS_INTS))
470 return IRQ_NONE;
471
472 status = inb_p(SMBHSTSTS(priv));
473 if (status != 0x42)
474 dev_dbg(&priv->pci_dev->dev, "irq: status = %02x\n", status);
475
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200476 if (status & SMBHSTSTS_BYTE_DONE)
477 i801_isr_byte_done(priv);
478
Daniel Kurtz636752b2012-07-24 14:13:58 +0200479 /*
480 * Clear irq sources and report transaction result.
481 * ->status must be cleared before the next transaction is started.
482 */
483 status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS;
484 if (status) {
485 outb_p(status, SMBHSTSTS(priv));
486 priv->status |= status;
487 wake_up(&priv->waitq);
488 }
489
490 return IRQ_HANDLED;
491}
492
493/*
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200494 * For "byte-by-byte" block transactions:
495 * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1
496 * I2C read uses cmd=I801_I2C_BLOCK_DATA
497 */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100498static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
499 union i2c_smbus_data *data,
Jean Delvare63420642008-01-27 18:14:50 +0100500 char read_write, int command,
501 int hwpec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502{
503 int i, len;
504 int smbcmd;
Jean Delvare2b738092008-07-14 22:38:32 +0200505 int status;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200506 int result;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200507
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100508 result = i801_check_pre(priv);
Jean Delvarecf898dc2008-07-14 22:38:33 +0200509 if (result < 0)
510 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200512 len = data->block[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
514 if (read_write == I2C_SMBUS_WRITE) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100515 outb_p(len, SMBHSTDAT0(priv));
516 outb_p(data->block[1], SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 }
518
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200519 if (command == I2C_SMBUS_I2C_BLOCK_DATA &&
520 read_write == I2C_SMBUS_READ)
521 smbcmd = I801_I2C_BLOCK_DATA;
522 else
523 smbcmd = I801_BLOCK_DATA;
524
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200525 if (priv->features & FEATURE_IRQ) {
526 priv->is_read = (read_write == I2C_SMBUS_READ);
527 if (len == 1 && priv->is_read)
528 smbcmd |= SMBHSTCNT_LAST_BYTE;
529 priv->cmd = smbcmd | SMBHSTCNT_INTREN;
530 priv->len = len;
531 priv->count = 0;
532 priv->data = &data->block[1];
533
534 outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
535 wait_event(priv->waitq, (status = priv->status));
536 priv->status = 0;
537 return i801_check_post(priv, status);
538 }
539
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 for (i = 1; i <= len; i++) {
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200541 if (i == len && read_write == I2C_SMBUS_READ)
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200542 smbcmd |= SMBHSTCNT_LAST_BYTE;
Daniel Kurtz37af8712012-07-24 14:13:58 +0200543 outb_p(smbcmd, SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 if (i == 1)
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200546 outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START,
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100547 SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
Jean Delvare6cad93c2012-07-24 14:13:58 +0200549 status = i801_wait_byte_done(priv);
550 if (status)
551 goto exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
Jean Delvare63420642008-01-27 18:14:50 +0100553 if (i == 1 && read_write == I2C_SMBUS_READ
554 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100555 len = inb_p(SMBHSTDAT0(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200556 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100557 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200558 "Illegal SMBus block read size %d\n",
559 len);
560 /* Recover */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100561 while (inb_p(SMBHSTSTS(priv)) &
562 SMBHSTSTS_HOST_BUSY)
563 outb_p(SMBHSTSTS_BYTE_DONE,
564 SMBHSTSTS(priv));
565 outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
David Brownell97140342008-07-14 22:38:25 +0200566 return -EPROTO;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200567 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 data->block[0] = len;
569 }
570
571 /* Retrieve/store value in SMBBLKDAT */
572 if (read_write == I2C_SMBUS_READ)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100573 data->block[i] = inb_p(SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100575 outb_p(data->block[i+1], SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576
Jean Delvarecf898dc2008-07-14 22:38:33 +0200577 /* signals SMBBLKDAT ready */
Jean Delvare6cad93c2012-07-24 14:13:58 +0200578 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200579 }
Jean Delvarecf898dc2008-07-14 22:38:33 +0200580
Jean Delvare6cad93c2012-07-24 14:13:58 +0200581 status = i801_wait_intr(priv);
582exit:
583 return i801_check_post(priv, status);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200584}
585
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100586static int i801_set_block_buffer_mode(struct i801_priv *priv)
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200587{
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100588 outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
589 if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0)
David Brownell97140342008-07-14 22:38:25 +0200590 return -EIO;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200591 return 0;
592}
593
594/* Block transaction function */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100595static int i801_block_transaction(struct i801_priv *priv,
596 union i2c_smbus_data *data, char read_write,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200597 int command, int hwpec)
598{
599 int result = 0;
600 unsigned char hostc;
601
602 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
603 if (read_write == I2C_SMBUS_WRITE) {
604 /* set I2C_EN bit in configuration register */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100605 pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
606 pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200607 hostc | SMBHSTCFG_I2C_EN);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100608 } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
609 dev_err(&priv->pci_dev->dev,
Jean Delvare63420642008-01-27 18:14:50 +0100610 "I2C block read is unsupported!\n");
David Brownell97140342008-07-14 22:38:25 +0200611 return -EOPNOTSUPP;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 }
614
Jean Delvare63420642008-01-27 18:14:50 +0100615 if (read_write == I2C_SMBUS_WRITE
616 || command == I2C_SMBUS_I2C_BLOCK_DATA) {
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200617 if (data->block[0] < 1)
618 data->block[0] = 1;
619 if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
620 data->block[0] = I2C_SMBUS_BLOCK_MAX;
621 } else {
Jean Delvare63420642008-01-27 18:14:50 +0100622 data->block[0] = 32; /* max for SMBus block reads */
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200623 }
624
Jean Delvarec074c392010-03-13 20:56:53 +0100625 /* Experience has shown that the block buffer can only be used for
626 SMBus (not I2C) block transactions, even though the datasheet
627 doesn't mention this limitation. */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100628 if ((priv->features & FEATURE_BLOCK_BUFFER)
Jean Delvarec074c392010-03-13 20:56:53 +0100629 && command != I2C_SMBUS_I2C_BLOCK_DATA
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100630 && i801_set_block_buffer_mode(priv) == 0)
631 result = i801_block_transaction_by_block(priv, data,
632 read_write, hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200633 else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100634 result = i801_block_transaction_byte_by_byte(priv, data,
635 read_write,
Jean Delvare63420642008-01-27 18:14:50 +0100636 command, hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200637
Jean Delvare63420642008-01-27 18:14:50 +0100638 if (command == I2C_SMBUS_I2C_BLOCK_DATA
639 && read_write == I2C_SMBUS_WRITE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 /* restore saved configuration register value */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100641 pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 }
643 return result;
644}
645
David Brownell97140342008-07-14 22:38:25 +0200646/* Return negative errno on error. */
Ivo Manca3fb21c62010-05-21 18:40:55 +0200647static s32 i801_access(struct i2c_adapter *adap, u16 addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 unsigned short flags, char read_write, u8 command,
Ivo Manca3fb21c62010-05-21 18:40:55 +0200649 int size, union i2c_smbus_data *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650{
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200651 int hwpec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 int block = 0;
653 int ret, xact = 0;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100654 struct i801_priv *priv = i2c_get_adapdata(adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100656 hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200657 && size != I2C_SMBUS_QUICK
658 && size != I2C_SMBUS_I2C_BLOCK_DATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
660 switch (size) {
661 case I2C_SMBUS_QUICK:
662 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100663 SMBHSTADD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 xact = I801_QUICK;
665 break;
666 case I2C_SMBUS_BYTE:
667 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100668 SMBHSTADD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 if (read_write == I2C_SMBUS_WRITE)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100670 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 xact = I801_BYTE;
672 break;
673 case I2C_SMBUS_BYTE_DATA:
674 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100675 SMBHSTADD(priv));
676 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 if (read_write == I2C_SMBUS_WRITE)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100678 outb_p(data->byte, SMBHSTDAT0(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 xact = I801_BYTE_DATA;
680 break;
681 case I2C_SMBUS_WORD_DATA:
682 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100683 SMBHSTADD(priv));
684 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 if (read_write == I2C_SMBUS_WRITE) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100686 outb_p(data->word & 0xff, SMBHSTDAT0(priv));
687 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 }
689 xact = I801_WORD_DATA;
690 break;
691 case I2C_SMBUS_BLOCK_DATA:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100693 SMBHSTADD(priv));
694 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 block = 1;
696 break;
Jean Delvare63420642008-01-27 18:14:50 +0100697 case I2C_SMBUS_I2C_BLOCK_DATA:
698 /* NB: page 240 of ICH5 datasheet shows that the R/#W
699 * bit should be cleared here, even when reading */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100700 outb_p((addr & 0x7f) << 1, SMBHSTADD(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100701 if (read_write == I2C_SMBUS_READ) {
702 /* NB: page 240 of ICH5 datasheet also shows
703 * that DATA1 is the cmd field when reading */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100704 outb_p(command, SMBHSTDAT1(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100705 } else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100706 outb_p(command, SMBHSTCMD(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100707 block = 1;
708 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 default:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100710 dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
711 size);
David Brownell97140342008-07-14 22:38:25 +0200712 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 }
714
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200715 if (hwpec) /* enable/disable hardware PEC */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100716 outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200717 else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100718 outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
719 SMBAUXCTL(priv));
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200720
Ivo Manca3fb21c62010-05-21 18:40:55 +0200721 if (block)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100722 ret = i801_block_transaction(priv, data, read_write, size,
723 hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200724 else
Daniel Kurtz37af8712012-07-24 14:13:58 +0200725 ret = i801_transaction(priv, xact);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
Jean Delvarec79cfba2006-04-20 02:43:18 -0700727 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200728 time, so we forcibly disable it after every transaction. Turn off
729 E32B for the same reason. */
Jean Delvarea0921b62008-01-27 18:14:50 +0100730 if (hwpec || block)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100731 outb_p(inb_p(SMBAUXCTL(priv)) &
732 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
Jean Delvarec79cfba2006-04-20 02:43:18 -0700733
Ivo Manca3fb21c62010-05-21 18:40:55 +0200734 if (block)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 return ret;
Ivo Manca3fb21c62010-05-21 18:40:55 +0200736 if (ret)
David Brownell97140342008-07-14 22:38:25 +0200737 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
739 return 0;
740
741 switch (xact & 0x7f) {
742 case I801_BYTE: /* Result put in SMBHSTDAT0 */
743 case I801_BYTE_DATA:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100744 data->byte = inb_p(SMBHSTDAT0(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 break;
746 case I801_WORD_DATA:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100747 data->word = inb_p(SMBHSTDAT0(priv)) +
748 (inb_p(SMBHSTDAT1(priv)) << 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 break;
750 }
751 return 0;
752}
753
754
755static u32 i801_func(struct i2c_adapter *adapter)
756{
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100757 struct i801_priv *priv = i2c_get_adapdata(adapter);
758
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
Jean Delvare369f6f42008-01-27 18:14:50 +0100760 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
761 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100762 ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
763 ((priv->features & FEATURE_I2C_BLOCK_READ) ?
Jean Delvare63420642008-01-27 18:14:50 +0100764 I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765}
766
Jean Delvare8f9082c2006-09-03 22:39:46 +0200767static const struct i2c_algorithm smbus_algorithm = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 .smbus_xfer = i801_access,
769 .functionality = i801_func,
770};
771
Axel Lin3527bd52012-01-12 20:32:04 +0100772static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
774 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
775 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
776 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
777 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
778 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
779 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
780 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
781 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
Jason Gastonb0a70b52005-04-16 15:24:45 -0700782 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
Jason Gaston8254fc42006-01-09 10:58:08 -0800783 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
Jason Gastonadbc2a12006-11-22 15:19:12 -0800784 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
Seth Heasleycb04e952010-10-04 13:27:14 -0700785 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) },
Gaston, Jason Dd28dc712008-02-24 20:03:42 +0100786 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
787 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
Seth Heasleycb04e952010-10-04 13:27:14 -0700788 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) },
789 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) },
Seth Heasleye30d9852010-10-31 21:06:59 +0100790 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) },
David Woodhouse55fee8d2010-10-31 21:07:00 +0100791 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) },
792 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
793 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
Seth Heasley662cda82011-03-20 14:50:53 +0100794 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },
Seth Heasley6e2a8512011-05-24 20:58:49 +0200795 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
Seth Heasley062737f2012-03-26 21:47:19 +0200796 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) },
James Ralston4a8f1dd2012-09-10 10:14:02 +0200797 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 { 0, }
799};
800
Ivo Manca3fb21c62010-05-21 18:40:55 +0200801MODULE_DEVICE_TABLE(pci, i801_ids);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
Jean Delvare8eacfce2011-05-24 20:58:49 +0200803#if defined CONFIG_X86 && defined CONFIG_DMI
Jean Delvare1561bfe2009-01-07 14:29:17 +0100804static unsigned char apanel_addr;
805
806/* Scan the system ROM for the signature "FJKEYINF" */
807static __init const void __iomem *bios_signature(const void __iomem *bios)
808{
809 ssize_t offset;
810 const unsigned char signature[] = "FJKEYINF";
811
812 for (offset = 0; offset < 0x10000; offset += 0x10) {
813 if (check_signature(bios + offset, signature,
814 sizeof(signature)-1))
815 return bios + offset;
816 }
817 return NULL;
818}
819
820static void __init input_apanel_init(void)
821{
822 void __iomem *bios;
823 const void __iomem *p;
824
825 bios = ioremap(0xF0000, 0x10000); /* Can't fail */
826 p = bios_signature(bios);
827 if (p) {
828 /* just use the first address */
829 apanel_addr = readb(p + 8 + 3) >> 1;
830 }
831 iounmap(bios);
832}
Jean Delvare1561bfe2009-01-07 14:29:17 +0100833
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200834struct dmi_onboard_device_info {
835 const char *name;
836 u8 type;
837 unsigned short i2c_addr;
838 const char *i2c_type;
839};
840
841static struct dmi_onboard_device_info __devinitdata dmi_devices[] = {
842 { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
843 { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
844 { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
845};
846
847static void __devinit dmi_check_onboard_device(u8 type, const char *name,
848 struct i2c_adapter *adap)
849{
850 int i;
851 struct i2c_board_info info;
852
853 for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
854 /* & ~0x80, ignore enabled/disabled bit */
855 if ((type & ~0x80) != dmi_devices[i].type)
856 continue;
Jean Delvarefaabd472010-07-09 16:22:51 +0200857 if (strcasecmp(name, dmi_devices[i].name))
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200858 continue;
859
860 memset(&info, 0, sizeof(struct i2c_board_info));
861 info.addr = dmi_devices[i].i2c_addr;
862 strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
863 i2c_new_device(adap, &info);
864 break;
865 }
866}
867
868/* We use our own function to check for onboard devices instead of
869 dmi_find_device() as some buggy BIOS's have the devices we are interested
870 in marked as disabled */
871static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
872 void *adap)
873{
874 int i, count;
875
876 if (dm->type != 10)
877 return;
878
879 count = (dm->length - sizeof(struct dmi_header)) / 2;
880 for (i = 0; i < count; i++) {
881 const u8 *d = (char *)(dm + 1) + (i * 2);
882 const char *name = ((char *) dm) + dm->length;
883 u8 type = d[0];
884 u8 s = d[1];
885
886 if (!s)
887 continue;
888 s--;
889 while (s > 0 && name[0]) {
890 name += strlen(name) + 1;
891 s--;
892 }
893 if (name[0] == 0) /* Bogus string reference */
894 continue;
895
896 dmi_check_onboard_device(type, name, adap);
897 }
898}
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200899
Jean Delvaree7198fb2011-05-24 20:58:49 +0200900/* Register optional slaves */
901static void __devinit i801_probe_optional_slaves(struct i801_priv *priv)
902{
903 /* Only register slaves on main SMBus channel */
904 if (priv->features & FEATURE_IDF)
905 return;
906
Jean Delvaree7198fb2011-05-24 20:58:49 +0200907 if (apanel_addr) {
908 struct i2c_board_info info;
909
910 memset(&info, 0, sizeof(struct i2c_board_info));
911 info.addr = apanel_addr;
912 strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
913 i2c_new_device(&priv->adapter, &info);
914 }
Jean Delvare8eacfce2011-05-24 20:58:49 +0200915
Jean Delvaree7198fb2011-05-24 20:58:49 +0200916 if (dmi_name_in_vendors("FUJITSU"))
917 dmi_walk(dmi_check_onboard_devices, &priv->adapter);
Jean Delvaree7198fb2011-05-24 20:58:49 +0200918}
Jean Delvare8eacfce2011-05-24 20:58:49 +0200919#else
920static void __init input_apanel_init(void) {}
921static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
922#endif /* CONFIG_X86 && CONFIG_DMI */
Jean Delvaree7198fb2011-05-24 20:58:49 +0200923
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200924#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
925static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
926 .gpio_chip = "gpio_ich",
927 .values = { 0x02, 0x03 },
928 .n_values = 2,
929 .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
930 .gpios = { 52, 53 },
931 .n_gpios = 2,
932};
933
934static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
935 .gpio_chip = "gpio_ich",
936 .values = { 0x02, 0x03, 0x01 },
937 .n_values = 3,
938 .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
939 .gpios = { 52, 53 },
940 .n_gpios = 2,
941};
942
943static struct dmi_system_id __devinitdata mux_dmi_table[] = {
944 {
945 .matches = {
946 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
947 DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"),
948 },
949 .driver_data = &i801_mux_config_asus_z8_d12,
950 },
951 {
952 .matches = {
953 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
954 DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"),
955 },
956 .driver_data = &i801_mux_config_asus_z8_d12,
957 },
958 {
959 .matches = {
960 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
961 DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"),
962 },
963 .driver_data = &i801_mux_config_asus_z8_d12,
964 },
965 {
966 .matches = {
967 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
968 DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"),
969 },
970 .driver_data = &i801_mux_config_asus_z8_d12,
971 },
972 {
973 .matches = {
974 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
975 DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"),
976 },
977 .driver_data = &i801_mux_config_asus_z8_d12,
978 },
979 {
980 .matches = {
981 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
982 DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"),
983 },
984 .driver_data = &i801_mux_config_asus_z8_d12,
985 },
986 {
987 .matches = {
988 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
989 DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"),
990 },
991 .driver_data = &i801_mux_config_asus_z8_d18,
992 },
993 {
994 .matches = {
995 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
996 DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"),
997 },
998 .driver_data = &i801_mux_config_asus_z8_d18,
999 },
1000 {
1001 .matches = {
1002 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1003 DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"),
1004 },
1005 .driver_data = &i801_mux_config_asus_z8_d12,
1006 },
1007 { }
1008};
1009
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001010/* Setup multiplexing if needed */
1011static int __devinit i801_add_mux(struct i801_priv *priv)
1012{
1013 struct device *dev = &priv->adapter.dev;
1014 const struct i801_mux_config *mux_config;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001015 struct i2c_mux_gpio_platform_data gpio_data;
Jean Delvaref82b8622012-10-05 22:23:54 +02001016 int err;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001017
1018 if (!priv->mux_drvdata)
1019 return 0;
1020 mux_config = priv->mux_drvdata;
1021
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001022 /* Prepare the platform data */
1023 memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
1024 gpio_data.parent = priv->adapter.nr;
1025 gpio_data.values = mux_config->values;
1026 gpio_data.n_values = mux_config->n_values;
1027 gpio_data.classes = mux_config->classes;
Jean Delvaref82b8622012-10-05 22:23:54 +02001028 gpio_data.gpio_chip = mux_config->gpio_chip;
1029 gpio_data.gpios = mux_config->gpios;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001030 gpio_data.n_gpios = mux_config->n_gpios;
1031 gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
1032
1033 /* Register the mux device */
1034 priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
Jean Delvaref82b8622012-10-05 22:23:54 +02001035 PLATFORM_DEVID_AUTO, &gpio_data,
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001036 sizeof(struct i2c_mux_gpio_platform_data));
1037 if (IS_ERR(priv->mux_pdev)) {
1038 err = PTR_ERR(priv->mux_pdev);
1039 priv->mux_pdev = NULL;
1040 dev_err(dev, "Failed to register i2c-mux-gpio device\n");
1041 return err;
1042 }
1043
1044 return 0;
1045}
1046
1047static void __devexit i801_del_mux(struct i801_priv *priv)
1048{
1049 if (priv->mux_pdev)
1050 platform_device_unregister(priv->mux_pdev);
1051}
1052
1053static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv)
1054{
1055 const struct dmi_system_id *id;
1056 const struct i801_mux_config *mux_config;
1057 unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
1058 int i;
1059
1060 id = dmi_first_match(mux_dmi_table);
1061 if (id) {
1062 /* Remove from branch classes from trunk */
1063 mux_config = id->driver_data;
1064 for (i = 0; i < mux_config->n_values; i++)
1065 class &= ~mux_config->classes[i];
1066
1067 /* Remember for later */
1068 priv->mux_drvdata = mux_config;
1069 }
1070
1071 return class;
1072}
1073#else
1074static inline int i801_add_mux(struct i801_priv *priv) { return 0; }
1075static inline void i801_del_mux(struct i801_priv *priv) { }
1076
1077static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
1078{
1079 return I2C_CLASS_HWMON | I2C_CLASS_SPD;
1080}
1081#endif
1082
Ivo Manca3fb21c62010-05-21 18:40:55 +02001083static int __devinit i801_probe(struct pci_dev *dev,
1084 const struct pci_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085{
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001086 unsigned char temp;
Jean Delvareadff6872010-05-21 18:40:54 +02001087 int err, i;
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001088 struct i801_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001090 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1091 if (!priv)
1092 return -ENOMEM;
1093
1094 i2c_set_adapdata(&priv->adapter, priv);
1095 priv->adapter.owner = THIS_MODULE;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001096 priv->adapter.class = i801_get_adapter_class(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001097 priv->adapter.algo = &smbus_algorithm;
1098
1099 priv->pci_dev = dev;
Jean Delvare250d1bd2006-12-10 21:21:33 +01001100 switch (dev->device) {
Jean Delvaree7198fb2011-05-24 20:58:49 +02001101 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0:
1102 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1:
1103 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2:
1104 priv->features |= FEATURE_IDF;
1105 /* fall through */
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001106 default:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001107 priv->features |= FEATURE_I2C_BLOCK_READ;
Jean Delvare63420642008-01-27 18:14:50 +01001108 /* fall through */
1109 case PCI_DEVICE_ID_INTEL_82801DB_3:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001110 priv->features |= FEATURE_SMBUS_PEC;
1111 priv->features |= FEATURE_BLOCK_BUFFER;
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001112 /* fall through */
1113 case PCI_DEVICE_ID_INTEL_82801CA_3:
1114 case PCI_DEVICE_ID_INTEL_82801BA_2:
1115 case PCI_DEVICE_ID_INTEL_82801AB_3:
1116 case PCI_DEVICE_ID_INTEL_82801AA_3:
Jean Delvare250d1bd2006-12-10 21:21:33 +01001117 break;
Jean Delvare250d1bd2006-12-10 21:21:33 +01001118 }
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001119
Jean Delvare29b60852012-07-24 14:13:59 +02001120 /* IRQ processing tested on CougarPoint PCH, ICH5, ICH7-M and ICH10 */
1121 if (dev->device == PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS ||
1122 dev->device == PCI_DEVICE_ID_INTEL_82801EB_3 ||
1123 dev->device == PCI_DEVICE_ID_INTEL_ICH7_17 ||
1124 dev->device == PCI_DEVICE_ID_INTEL_ICH8_5 ||
1125 dev->device == PCI_DEVICE_ID_INTEL_ICH9_6 ||
1126 dev->device == PCI_DEVICE_ID_INTEL_ICH10_4 ||
1127 dev->device == PCI_DEVICE_ID_INTEL_ICH10_5)
Daniel Kurtz636752b2012-07-24 14:13:58 +02001128 priv->features |= FEATURE_IRQ;
1129
Jean Delvareadff6872010-05-21 18:40:54 +02001130 /* Disable features on user request */
1131 for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001132 if (priv->features & disable_features & (1 << i))
Jean Delvareadff6872010-05-21 18:40:54 +02001133 dev_notice(&dev->dev, "%s disabled by user\n",
1134 i801_feature_names[i]);
1135 }
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001136 priv->features &= ~disable_features;
Jean Delvareadff6872010-05-21 18:40:54 +02001137
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001138 err = pci_enable_device(dev);
1139 if (err) {
1140 dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
1141 err);
1142 goto exit;
1143 }
1144
1145 /* Determine the address of the SMBus area */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001146 priv->smba = pci_resource_start(dev, SMBBAR);
1147 if (!priv->smba) {
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001148 dev_err(&dev->dev, "SMBus base address uninitialized, "
1149 "upgrade BIOS\n");
1150 err = -ENODEV;
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001151 goto exit;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001152 }
1153
Jean Delvare54fb4a052008-07-14 22:38:33 +02001154 err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
Jean Delvare18669ea2009-10-04 22:53:45 +02001155 if (err) {
1156 err = -ENODEV;
Jean Delvare54fb4a052008-07-14 22:38:33 +02001157 goto exit;
Jean Delvare18669ea2009-10-04 22:53:45 +02001158 }
Jean Delvare54fb4a052008-07-14 22:38:33 +02001159
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001160 err = pci_request_region(dev, SMBBAR, i801_driver.name);
1161 if (err) {
1162 dev_err(&dev->dev, "Failed to request SMBus region "
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001163 "0x%lx-0x%Lx\n", priv->smba,
Andrew Morton598736c2006-06-30 01:56:20 -07001164 (unsigned long long)pci_resource_end(dev, SMBBAR));
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001165 goto exit;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001166 }
1167
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001168 pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
1169 priv->original_hstcfg = temp;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001170 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
1171 if (!(temp & SMBHSTCFG_HST_EN)) {
1172 dev_info(&dev->dev, "Enabling SMBus device\n");
1173 temp |= SMBHSTCFG_HST_EN;
1174 }
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001175 pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001176
Daniel Kurtz636752b2012-07-24 14:13:58 +02001177 if (temp & SMBHSTCFG_SMB_SMI_EN) {
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001178 dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001179 /* Disable SMBus interrupt feature if SMBus using SMI# */
1180 priv->features &= ~FEATURE_IRQ;
Daniel Kurtz636752b2012-07-24 14:13:58 +02001181 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
Jean Delvarea0921b62008-01-27 18:14:50 +01001183 /* Clear special mode bits */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001184 if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
1185 outb_p(inb_p(SMBAUXCTL(priv)) &
1186 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
Jean Delvarea0921b62008-01-27 18:14:50 +01001187
Daniel Kurtz636752b2012-07-24 14:13:58 +02001188 if (priv->features & FEATURE_IRQ) {
1189 init_waitqueue_head(&priv->waitq);
1190
1191 err = request_irq(dev->irq, i801_isr, IRQF_SHARED,
1192 i801_driver.name, priv);
1193 if (err) {
1194 dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
1195 dev->irq, err);
1196 goto exit_release;
1197 }
Jean Delvare29b60852012-07-24 14:13:59 +02001198 dev_info(&dev->dev, "SMBus using PCI Interrupt\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001199 }
1200
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01001201 /* set up the sysfs linkage to our parent device */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001202 priv->adapter.dev.parent = &dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
Jean Delvare7e2193a8f2009-12-06 17:06:27 +01001204 /* Retry up to 3 times on lost arbitration */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001205 priv->adapter.retries = 3;
Jean Delvare7e2193a8f2009-12-06 17:06:27 +01001206
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001207 snprintf(priv->adapter.name, sizeof(priv->adapter.name),
1208 "SMBus I801 adapter at %04lx", priv->smba);
1209 err = i2c_add_adapter(&priv->adapter);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001210 if (err) {
1211 dev_err(&dev->dev, "Failed to add SMBus adapter\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001212 goto exit_free_irq;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001213 }
Jean Delvare1561bfe2009-01-07 14:29:17 +01001214
Jean Delvaree7198fb2011-05-24 20:58:49 +02001215 i801_probe_optional_slaves(priv);
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001216 /* We ignore errors - multiplexing is optional */
1217 i801_add_mux(priv);
Jean Delvare1561bfe2009-01-07 14:29:17 +01001218
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001219 pci_set_drvdata(dev, priv);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001220
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001221 return 0;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001222
Daniel Kurtz636752b2012-07-24 14:13:58 +02001223exit_free_irq:
1224 if (priv->features & FEATURE_IRQ)
1225 free_irq(dev->irq, priv);
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001226exit_release:
1227 pci_release_region(dev, SMBBAR);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001228exit:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001229 kfree(priv);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001230 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231}
1232
1233static void __devexit i801_remove(struct pci_dev *dev)
1234{
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001235 struct i801_priv *priv = pci_get_drvdata(dev);
1236
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001237 i801_del_mux(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001238 i2c_del_adapter(&priv->adapter);
1239 pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001240
1241 if (priv->features & FEATURE_IRQ)
1242 free_irq(dev->irq, priv);
Jean Delvare6dcc19d2006-06-12 21:53:02 +02001243 pci_release_region(dev, SMBBAR);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001244
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001245 pci_set_drvdata(dev, NULL);
1246 kfree(priv);
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001247 /*
1248 * do not call pci_disable_device(dev) since it can cause hard hangs on
1249 * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
1250 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251}
1252
Jean Delvarea5aaea32007-03-22 19:49:01 +01001253#ifdef CONFIG_PM
1254static int i801_suspend(struct pci_dev *dev, pm_message_t mesg)
1255{
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001256 struct i801_priv *priv = pci_get_drvdata(dev);
1257
Jean Delvarea5aaea32007-03-22 19:49:01 +01001258 pci_save_state(dev);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001259 pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
Jean Delvarea5aaea32007-03-22 19:49:01 +01001260 pci_set_power_state(dev, pci_choose_state(dev, mesg));
1261 return 0;
1262}
1263
1264static int i801_resume(struct pci_dev *dev)
1265{
1266 pci_set_power_state(dev, PCI_D0);
1267 pci_restore_state(dev);
1268 return pci_enable_device(dev);
1269}
1270#else
1271#define i801_suspend NULL
1272#define i801_resume NULL
1273#endif
1274
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275static struct pci_driver i801_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 .name = "i801_smbus",
1277 .id_table = i801_ids,
1278 .probe = i801_probe,
1279 .remove = __devexit_p(i801_remove),
Jean Delvarea5aaea32007-03-22 19:49:01 +01001280 .suspend = i801_suspend,
1281 .resume = i801_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282};
1283
1284static int __init i2c_i801_init(void)
1285{
Jean Delvare6aa14642011-05-24 20:58:49 +02001286 if (dmi_name_in_vendors("FUJITSU"))
1287 input_apanel_init();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 return pci_register_driver(&i801_driver);
1289}
1290
1291static void __exit i2c_i801_exit(void)
1292{
1293 pci_unregister_driver(&i801_driver);
1294}
1295
Jean Delvare63420642008-01-27 18:14:50 +01001296MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, "
1297 "Jean Delvare <khali@linux-fr.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298MODULE_DESCRIPTION("I801 SMBus driver");
1299MODULE_LICENSE("GPL");
1300
1301module_init(i2c_i801_init);
1302module_exit(i2c_i801_exit);