blob: b00c29d8a5f12ed0072f07ce8c4a44b60261aafe [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
Seth Heasleyc2db409c2013-01-30 15:25:32 +000056 Avoton (SOC) 0x1f3c 32 hard yes yes yes
Jean Delvareae7b0492008-01-27 18:14:49 +010057
58 Features supported by this driver:
59 Software PEC no
60 Hardware PEC yes
61 Block buffer yes
62 Block process call transaction no
Jean Delvare63420642008-01-27 18:14:50 +010063 I2C block read transaction yes (doesn't use the block buffer)
David Woodhouse55fee8d2010-10-31 21:07:00 +010064 Slave mode no
Daniel Kurtz636752b2012-07-24 14:13:58 +020065 Interrupt processing yes
Jean Delvareae7b0492008-01-27 18:14:49 +010066
67 See the file Documentation/i2c/busses/i2c-i801 for details.
Linus Torvalds1da177e2005-04-16 15:20:36 -070068*/
69
Daniel Kurtz636752b2012-07-24 14:13:58 +020070#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070071#include <linux/module.h>
72#include <linux/pci.h>
73#include <linux/kernel.h>
74#include <linux/stddef.h>
75#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070076#include <linux/ioport.h>
77#include <linux/init.h>
78#include <linux/i2c.h>
Jean Delvare54fb4a052008-07-14 22:38:33 +020079#include <linux/acpi.h>
Jean Delvare1561bfe2009-01-07 14:29:17 +010080#include <linux/io.h>
Hans de Goedefa5bfab2009-03-30 21:46:44 +020081#include <linux/dmi.h>
Ben Hutchings665a96b2011-01-10 22:11:22 +010082#include <linux/slab.h>
Daniel Kurtz636752b2012-07-24 14:13:58 +020083#include <linux/wait.h>
Jean Delvare3ad7ea12012-10-05 22:23:53 +020084#include <linux/err.h>
Thierry Redingf6afc8b2012-12-16 21:11:54 +010085#include <linux/of_i2c.h>
Jean Delvare3ad7ea12012-10-05 22:23:53 +020086
Jean Delvare79e3e5b2012-10-28 21:37:01 +010087#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
88 defined CONFIG_DMI
Jean Delvare3ad7ea12012-10-05 22:23:53 +020089#include <linux/gpio.h>
90#include <linux/i2c-mux-gpio.h>
91#include <linux/platform_device.h>
92#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/* I801 SMBus address offsets */
David Woodhouse0cd96eb2010-10-31 21:06:59 +010095#define SMBHSTSTS(p) (0 + (p)->smba)
96#define SMBHSTCNT(p) (2 + (p)->smba)
97#define SMBHSTCMD(p) (3 + (p)->smba)
98#define SMBHSTADD(p) (4 + (p)->smba)
99#define SMBHSTDAT0(p) (5 + (p)->smba)
100#define SMBHSTDAT1(p) (6 + (p)->smba)
101#define SMBBLKDAT(p) (7 + (p)->smba)
102#define SMBPEC(p) (8 + (p)->smba) /* ICH3 and later */
103#define SMBAUXSTS(p) (12 + (p)->smba) /* ICH4 and later */
104#define SMBAUXCTL(p) (13 + (p)->smba) /* ICH4 and later */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106/* PCI Address Constants */
Jean Delvare6dcc19d2006-06-12 21:53:02 +0200107#define SMBBAR 4
Daniel Kurtz636752b2012-07-24 14:13:58 +0200108#define SMBPCISTS 0x006
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109#define SMBHSTCFG 0x040
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
Daniel Kurtz636752b2012-07-24 14:13:58 +0200111/* Host status bits for SMBPCISTS */
112#define SMBPCISTS_INTS 0x08
113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114/* Host configuration bits for SMBHSTCFG */
115#define SMBHSTCFG_HST_EN 1
116#define SMBHSTCFG_SMB_SMI_EN 2
117#define SMBHSTCFG_I2C_EN 4
118
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300119/* Auxiliary control register bits, ICH4+ only */
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200120#define SMBAUXCTL_CRC 1
121#define SMBAUXCTL_E32B 2
122
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123/* Other settings */
Jean Delvare84c1af42012-03-26 21:47:19 +0200124#define MAX_RETRIES 400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
126/* I801 command constants */
127#define I801_QUICK 0x00
128#define I801_BYTE 0x04
129#define I801_BYTE_DATA 0x08
130#define I801_WORD_DATA 0x0C
Jean Delvareae7b0492008-01-27 18:14:49 +0100131#define I801_PROC_CALL 0x10 /* unimplemented */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132#define I801_BLOCK_DATA 0x14
Jean Delvare63420642008-01-27 18:14:50 +0100133#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200134
135/* I801 Host Control register bits */
136#define SMBHSTCNT_INTREN 0x01
137#define SMBHSTCNT_KILL 0x02
138#define SMBHSTCNT_LAST_BYTE 0x20
139#define SMBHSTCNT_START 0x40
140#define SMBHSTCNT_PEC_EN 0x80 /* ICH3 and later */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200142/* I801 Hosts Status register bits */
143#define SMBHSTSTS_BYTE_DONE 0x80
144#define SMBHSTSTS_INUSE_STS 0x40
145#define SMBHSTSTS_SMBALERT_STS 0x20
146#define SMBHSTSTS_FAILED 0x10
147#define SMBHSTSTS_BUS_ERR 0x08
148#define SMBHSTSTS_DEV_ERR 0x04
149#define SMBHSTSTS_INTR 0x02
150#define SMBHSTSTS_HOST_BUSY 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
Daniel Kurtz70a1cc12012-07-24 14:13:58 +0200152#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \
153 SMBHSTSTS_DEV_ERR)
154
155#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \
156 STATUS_ERROR_FLAGS)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200157
Jean Delvarea6e5e2b2011-05-01 18:18:49 +0200158/* Older devices have their ID defined in <linux/pci_ids.h> */
159#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
160#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
David Woodhouse55fee8d2010-10-31 21:07:00 +0100161/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
162#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70
163#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
164#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72
Seth Heasley6e2a8512011-05-24 20:58:49 +0200165#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
Seth Heasleyc2db409c2013-01-30 15:25:32 +0000166#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c
Jean Delvarea6e5e2b2011-05-01 18:18:49 +0200167#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
168#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
Seth Heasley062737f2012-03-26 21:47:19 +0200169#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
James Ralston4a8f1dd2012-09-10 10:14:02 +0200170#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
David Woodhouse55fee8d2010-10-31 21:07:00 +0100171
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200172struct i801_mux_config {
173 char *gpio_chip;
174 unsigned values[3];
175 int n_values;
176 unsigned classes[3];
177 unsigned gpios[2]; /* Relative to gpio_chip->base */
178 int n_gpios;
179};
180
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100181struct i801_priv {
182 struct i2c_adapter adapter;
183 unsigned long smba;
184 unsigned char original_hstcfg;
185 struct pci_dev *pci_dev;
186 unsigned int features;
Daniel Kurtz636752b2012-07-24 14:13:58 +0200187
188 /* isr processing */
189 wait_queue_head_t waitq;
190 u8 status;
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200191
192 /* Command state used by isr for byte-by-byte block transactions */
193 u8 cmd;
194 bool is_read;
195 int count;
196 int len;
197 u8 *data;
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200198
Jean Delvare79e3e5b2012-10-28 21:37:01 +0100199#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
200 defined CONFIG_DMI
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200201 const struct i801_mux_config *mux_drvdata;
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200202 struct platform_device *mux_pdev;
203#endif
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100204};
205
Jean Delvared6072f82005-09-25 16:37:04 +0200206static struct pci_driver i801_driver;
Jean Delvare369f6f42008-01-27 18:14:50 +0100207
208#define FEATURE_SMBUS_PEC (1 << 0)
209#define FEATURE_BLOCK_BUFFER (1 << 1)
210#define FEATURE_BLOCK_PROC (1 << 2)
211#define FEATURE_I2C_BLOCK_READ (1 << 3)
Daniel Kurtz636752b2012-07-24 14:13:58 +0200212#define FEATURE_IRQ (1 << 4)
Jean Delvaree7198fb2011-05-24 20:58:49 +0200213/* Not really a feature, but it's convenient to handle it as such */
214#define FEATURE_IDF (1 << 15)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
Jean Delvareadff6872010-05-21 18:40:54 +0200216static const char *i801_feature_names[] = {
217 "SMBus PEC",
218 "Block buffer",
219 "Block process call",
220 "I2C block read",
Daniel Kurtz636752b2012-07-24 14:13:58 +0200221 "Interrupt",
Jean Delvareadff6872010-05-21 18:40:54 +0200222};
223
224static unsigned int disable_features;
225module_param(disable_features, uint, S_IRUGO | S_IWUSR);
226MODULE_PARM_DESC(disable_features, "Disable selected driver features");
227
Jean Delvarecf898dc2008-07-14 22:38:33 +0200228/* Make sure the SMBus host is ready to start transmitting.
229 Return 0 if it is, -EBUSY if it is not. */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100230static int i801_check_pre(struct i801_priv *priv)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200231{
232 int status;
233
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100234 status = inb_p(SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200235 if (status & SMBHSTSTS_HOST_BUSY) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100236 dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200237 return -EBUSY;
238 }
239
240 status &= STATUS_FLAGS;
241 if (status) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100242 dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n",
Jean Delvarecf898dc2008-07-14 22:38:33 +0200243 status);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100244 outb_p(status, SMBHSTSTS(priv));
245 status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200246 if (status) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100247 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200248 "Failed clearing status flags (%02x)\n",
249 status);
250 return -EBUSY;
251 }
252 }
253
254 return 0;
255}
256
Jean Delvare6cad93c2012-07-24 14:13:58 +0200257/*
258 * Convert the status register to an error code, and clear it.
259 * Note that status only contains the bits we want to clear, not the
260 * actual register value.
261 */
262static int i801_check_post(struct i801_priv *priv, int status)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200263{
264 int result = 0;
265
Daniel Kurtz636752b2012-07-24 14:13:58 +0200266 /*
267 * If the SMBus is still busy, we give up
268 * Note: This timeout condition only happens when using polling
269 * transactions. For interrupt operation, NAK/timeout is indicated by
270 * DEV_ERR.
271 */
Jean Delvare6cad93c2012-07-24 14:13:58 +0200272 if (unlikely(status < 0)) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100273 dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200274 /* try to stop the current command */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100275 dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
276 outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
277 SMBHSTCNT(priv));
Jean Delvare84c1af42012-03-26 21:47:19 +0200278 usleep_range(1000, 2000);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100279 outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
280 SMBHSTCNT(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200281
282 /* Check if it worked */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100283 status = inb_p(SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200284 if ((status & SMBHSTSTS_HOST_BUSY) ||
285 !(status & SMBHSTSTS_FAILED))
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100286 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200287 "Failed terminating the transaction\n");
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100288 outb_p(STATUS_FLAGS, SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200289 return -ETIMEDOUT;
290 }
291
292 if (status & SMBHSTSTS_FAILED) {
293 result = -EIO;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100294 dev_err(&priv->pci_dev->dev, "Transaction failed\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200295 }
296 if (status & SMBHSTSTS_DEV_ERR) {
297 result = -ENXIO;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100298 dev_dbg(&priv->pci_dev->dev, "No response\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200299 }
300 if (status & SMBHSTSTS_BUS_ERR) {
301 result = -EAGAIN;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100302 dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200303 }
304
Jean Delvare6cad93c2012-07-24 14:13:58 +0200305 /* Clear status flags except BYTE_DONE, to be cleared by caller */
306 outb_p(status, SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200307
308 return result;
309}
310
Jean Delvare6cad93c2012-07-24 14:13:58 +0200311/* Wait for BUSY being cleared and either INTR or an error flag being set */
312static int i801_wait_intr(struct i801_priv *priv)
313{
314 int timeout = 0;
315 int status;
316
317 /* We will always wait for a fraction of a second! */
318 do {
319 usleep_range(250, 500);
320 status = inb_p(SMBHSTSTS(priv));
321 } while (((status & SMBHSTSTS_HOST_BUSY) ||
322 !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) &&
323 (timeout++ < MAX_RETRIES));
324
325 if (timeout > MAX_RETRIES) {
326 dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n");
327 return -ETIMEDOUT;
328 }
329 return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR);
330}
331
332/* Wait for either BYTE_DONE or an error flag being set */
333static int i801_wait_byte_done(struct i801_priv *priv)
334{
335 int timeout = 0;
336 int status;
337
338 /* We will always wait for a fraction of a second! */
339 do {
340 usleep_range(250, 500);
341 status = inb_p(SMBHSTSTS(priv));
342 } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) &&
343 (timeout++ < MAX_RETRIES));
344
345 if (timeout > MAX_RETRIES) {
346 dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n");
347 return -ETIMEDOUT;
348 }
349 return status & STATUS_ERROR_FLAGS;
350}
351
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100352static int i801_transaction(struct i801_priv *priv, int xact)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353{
Jean Delvare2b738092008-07-14 22:38:32 +0200354 int status;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200355 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100357 result = i801_check_pre(priv);
Jean Delvarecf898dc2008-07-14 22:38:33 +0200358 if (result < 0)
359 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
Daniel Kurtz636752b2012-07-24 14:13:58 +0200361 if (priv->features & FEATURE_IRQ) {
362 outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
363 SMBHSTCNT(priv));
364 wait_event(priv->waitq, (status = priv->status));
365 priv->status = 0;
366 return i801_check_post(priv, status);
367 }
368
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200369 /* the current contents of SMBHSTCNT can be overwritten, since PEC,
Daniel Kurtz37af8712012-07-24 14:13:58 +0200370 * SMBSCMD are passed in xact */
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200371 outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Jean Delvare6cad93c2012-07-24 14:13:58 +0200373 status = i801_wait_intr(priv);
374 return i801_check_post(priv, status);
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200375}
376
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100377static int i801_block_transaction_by_block(struct i801_priv *priv,
378 union i2c_smbus_data *data,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200379 char read_write, int hwpec)
380{
381 int i, len;
David Brownell97140342008-07-14 22:38:25 +0200382 int status;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200383
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100384 inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200385
386 /* Use 32-byte buffer to process this transaction */
387 if (read_write == I2C_SMBUS_WRITE) {
388 len = data->block[0];
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100389 outb_p(len, SMBHSTDAT0(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200390 for (i = 0; i < len; i++)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100391 outb_p(data->block[i+1], SMBBLKDAT(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200392 }
393
Daniel Kurtz37af8712012-07-24 14:13:58 +0200394 status = i801_transaction(priv, I801_BLOCK_DATA |
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200395 (hwpec ? SMBHSTCNT_PEC_EN : 0));
David Brownell97140342008-07-14 22:38:25 +0200396 if (status)
397 return status;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200398
399 if (read_write == I2C_SMBUS_READ) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100400 len = inb_p(SMBHSTDAT0(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200401 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
David Brownell97140342008-07-14 22:38:25 +0200402 return -EPROTO;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200403
404 data->block[0] = len;
405 for (i = 0; i < len; i++)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100406 data->block[i + 1] = inb_p(SMBBLKDAT(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200407 }
408 return 0;
409}
410
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200411static void i801_isr_byte_done(struct i801_priv *priv)
412{
413 if (priv->is_read) {
414 /* For SMBus block reads, length is received with first byte */
415 if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) &&
416 (priv->count == 0)) {
417 priv->len = inb_p(SMBHSTDAT0(priv));
418 if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) {
419 dev_err(&priv->pci_dev->dev,
420 "Illegal SMBus block read size %d\n",
421 priv->len);
422 /* FIXME: Recover */
423 priv->len = I2C_SMBUS_BLOCK_MAX;
424 } else {
425 dev_dbg(&priv->pci_dev->dev,
426 "SMBus block read size is %d\n",
427 priv->len);
428 }
429 priv->data[-1] = priv->len;
430 }
431
432 /* Read next byte */
433 if (priv->count < priv->len)
434 priv->data[priv->count++] = inb(SMBBLKDAT(priv));
435 else
436 dev_dbg(&priv->pci_dev->dev,
437 "Discarding extra byte on block read\n");
438
439 /* Set LAST_BYTE for last byte of read transaction */
440 if (priv->count == priv->len - 1)
441 outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE,
442 SMBHSTCNT(priv));
443 } else if (priv->count < priv->len - 1) {
444 /* Write next byte, except for IRQ after last byte */
445 outb_p(priv->data[++priv->count], SMBBLKDAT(priv));
446 }
447
448 /* Clear BYTE_DONE to continue with next byte */
449 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
450}
451
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200452/*
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200453 * There are two kinds of interrupts:
454 *
455 * 1) i801 signals transaction completion with one of these interrupts:
456 * INTR - Success
457 * DEV_ERR - Invalid command, NAK or communication timeout
458 * BUS_ERR - SMI# transaction collision
459 * FAILED - transaction was canceled due to a KILL request
460 * When any of these occur, update ->status and wake up the waitq.
461 * ->status must be cleared before kicking off the next transaction.
462 *
463 * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt
464 * occurs for each byte of a byte-by-byte to prepare the next byte.
Daniel Kurtz636752b2012-07-24 14:13:58 +0200465 */
466static irqreturn_t i801_isr(int irq, void *dev_id)
467{
468 struct i801_priv *priv = dev_id;
469 u16 pcists;
470 u8 status;
471
472 /* Confirm this is our interrupt */
473 pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
474 if (!(pcists & SMBPCISTS_INTS))
475 return IRQ_NONE;
476
477 status = inb_p(SMBHSTSTS(priv));
478 if (status != 0x42)
479 dev_dbg(&priv->pci_dev->dev, "irq: status = %02x\n", status);
480
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200481 if (status & SMBHSTSTS_BYTE_DONE)
482 i801_isr_byte_done(priv);
483
Daniel Kurtz636752b2012-07-24 14:13:58 +0200484 /*
485 * Clear irq sources and report transaction result.
486 * ->status must be cleared before the next transaction is started.
487 */
488 status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS;
489 if (status) {
490 outb_p(status, SMBHSTSTS(priv));
491 priv->status |= status;
492 wake_up(&priv->waitq);
493 }
494
495 return IRQ_HANDLED;
496}
497
498/*
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200499 * For "byte-by-byte" block transactions:
500 * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1
501 * I2C read uses cmd=I801_I2C_BLOCK_DATA
502 */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100503static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
504 union i2c_smbus_data *data,
Jean Delvare63420642008-01-27 18:14:50 +0100505 char read_write, int command,
506 int hwpec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507{
508 int i, len;
509 int smbcmd;
Jean Delvare2b738092008-07-14 22:38:32 +0200510 int status;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200511 int result;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200512
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100513 result = i801_check_pre(priv);
Jean Delvarecf898dc2008-07-14 22:38:33 +0200514 if (result < 0)
515 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200517 len = data->block[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
519 if (read_write == I2C_SMBUS_WRITE) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100520 outb_p(len, SMBHSTDAT0(priv));
521 outb_p(data->block[1], SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 }
523
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200524 if (command == I2C_SMBUS_I2C_BLOCK_DATA &&
525 read_write == I2C_SMBUS_READ)
526 smbcmd = I801_I2C_BLOCK_DATA;
527 else
528 smbcmd = I801_BLOCK_DATA;
529
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200530 if (priv->features & FEATURE_IRQ) {
531 priv->is_read = (read_write == I2C_SMBUS_READ);
532 if (len == 1 && priv->is_read)
533 smbcmd |= SMBHSTCNT_LAST_BYTE;
534 priv->cmd = smbcmd | SMBHSTCNT_INTREN;
535 priv->len = len;
536 priv->count = 0;
537 priv->data = &data->block[1];
538
539 outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
540 wait_event(priv->waitq, (status = priv->status));
541 priv->status = 0;
542 return i801_check_post(priv, status);
543 }
544
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 for (i = 1; i <= len; i++) {
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200546 if (i == len && read_write == I2C_SMBUS_READ)
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200547 smbcmd |= SMBHSTCNT_LAST_BYTE;
Daniel Kurtz37af8712012-07-24 14:13:58 +0200548 outb_p(smbcmd, SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 if (i == 1)
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200551 outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START,
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100552 SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553
Jean Delvare6cad93c2012-07-24 14:13:58 +0200554 status = i801_wait_byte_done(priv);
555 if (status)
556 goto exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
Jean Delvare63420642008-01-27 18:14:50 +0100558 if (i == 1 && read_write == I2C_SMBUS_READ
559 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100560 len = inb_p(SMBHSTDAT0(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200561 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100562 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200563 "Illegal SMBus block read size %d\n",
564 len);
565 /* Recover */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100566 while (inb_p(SMBHSTSTS(priv)) &
567 SMBHSTSTS_HOST_BUSY)
568 outb_p(SMBHSTSTS_BYTE_DONE,
569 SMBHSTSTS(priv));
570 outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
David Brownell97140342008-07-14 22:38:25 +0200571 return -EPROTO;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200572 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 data->block[0] = len;
574 }
575
576 /* Retrieve/store value in SMBBLKDAT */
577 if (read_write == I2C_SMBUS_READ)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100578 data->block[i] = inb_p(SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100580 outb_p(data->block[i+1], SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
Jean Delvarecf898dc2008-07-14 22:38:33 +0200582 /* signals SMBBLKDAT ready */
Jean Delvare6cad93c2012-07-24 14:13:58 +0200583 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200584 }
Jean Delvarecf898dc2008-07-14 22:38:33 +0200585
Jean Delvare6cad93c2012-07-24 14:13:58 +0200586 status = i801_wait_intr(priv);
587exit:
588 return i801_check_post(priv, status);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200589}
590
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100591static int i801_set_block_buffer_mode(struct i801_priv *priv)
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200592{
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100593 outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
594 if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0)
David Brownell97140342008-07-14 22:38:25 +0200595 return -EIO;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200596 return 0;
597}
598
599/* Block transaction function */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100600static int i801_block_transaction(struct i801_priv *priv,
601 union i2c_smbus_data *data, char read_write,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200602 int command, int hwpec)
603{
604 int result = 0;
605 unsigned char hostc;
606
607 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
608 if (read_write == I2C_SMBUS_WRITE) {
609 /* set I2C_EN bit in configuration register */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100610 pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
611 pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200612 hostc | SMBHSTCFG_I2C_EN);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100613 } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
614 dev_err(&priv->pci_dev->dev,
Jean Delvare63420642008-01-27 18:14:50 +0100615 "I2C block read is unsupported!\n");
David Brownell97140342008-07-14 22:38:25 +0200616 return -EOPNOTSUPP;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200617 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 }
619
Jean Delvare63420642008-01-27 18:14:50 +0100620 if (read_write == I2C_SMBUS_WRITE
621 || command == I2C_SMBUS_I2C_BLOCK_DATA) {
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200622 if (data->block[0] < 1)
623 data->block[0] = 1;
624 if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
625 data->block[0] = I2C_SMBUS_BLOCK_MAX;
626 } else {
Jean Delvare63420642008-01-27 18:14:50 +0100627 data->block[0] = 32; /* max for SMBus block reads */
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200628 }
629
Jean Delvarec074c392010-03-13 20:56:53 +0100630 /* Experience has shown that the block buffer can only be used for
631 SMBus (not I2C) block transactions, even though the datasheet
632 doesn't mention this limitation. */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100633 if ((priv->features & FEATURE_BLOCK_BUFFER)
Jean Delvarec074c392010-03-13 20:56:53 +0100634 && command != I2C_SMBUS_I2C_BLOCK_DATA
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100635 && i801_set_block_buffer_mode(priv) == 0)
636 result = i801_block_transaction_by_block(priv, data,
637 read_write, hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200638 else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100639 result = i801_block_transaction_byte_by_byte(priv, data,
640 read_write,
Jean Delvare63420642008-01-27 18:14:50 +0100641 command, hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200642
Jean Delvare63420642008-01-27 18:14:50 +0100643 if (command == I2C_SMBUS_I2C_BLOCK_DATA
644 && read_write == I2C_SMBUS_WRITE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 /* restore saved configuration register value */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100646 pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 }
648 return result;
649}
650
David Brownell97140342008-07-14 22:38:25 +0200651/* Return negative errno on error. */
Ivo Manca3fb21c62010-05-21 18:40:55 +0200652static s32 i801_access(struct i2c_adapter *adap, u16 addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 unsigned short flags, char read_write, u8 command,
Ivo Manca3fb21c62010-05-21 18:40:55 +0200654 int size, union i2c_smbus_data *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655{
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200656 int hwpec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 int block = 0;
658 int ret, xact = 0;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100659 struct i801_priv *priv = i2c_get_adapdata(adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100661 hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200662 && size != I2C_SMBUS_QUICK
663 && size != I2C_SMBUS_I2C_BLOCK_DATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
665 switch (size) {
666 case I2C_SMBUS_QUICK:
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 xact = I801_QUICK;
670 break;
671 case I2C_SMBUS_BYTE:
672 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100673 SMBHSTADD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 if (read_write == I2C_SMBUS_WRITE)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100675 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 xact = I801_BYTE;
677 break;
678 case I2C_SMBUS_BYTE_DATA:
679 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100680 SMBHSTADD(priv));
681 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 if (read_write == I2C_SMBUS_WRITE)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100683 outb_p(data->byte, SMBHSTDAT0(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 xact = I801_BYTE_DATA;
685 break;
686 case I2C_SMBUS_WORD_DATA:
687 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100688 SMBHSTADD(priv));
689 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 if (read_write == I2C_SMBUS_WRITE) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100691 outb_p(data->word & 0xff, SMBHSTDAT0(priv));
692 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 }
694 xact = I801_WORD_DATA;
695 break;
696 case I2C_SMBUS_BLOCK_DATA:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100698 SMBHSTADD(priv));
699 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 block = 1;
701 break;
Jean Delvare63420642008-01-27 18:14:50 +0100702 case I2C_SMBUS_I2C_BLOCK_DATA:
703 /* NB: page 240 of ICH5 datasheet shows that the R/#W
704 * bit should be cleared here, even when reading */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100705 outb_p((addr & 0x7f) << 1, SMBHSTADD(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100706 if (read_write == I2C_SMBUS_READ) {
707 /* NB: page 240 of ICH5 datasheet also shows
708 * that DATA1 is the cmd field when reading */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100709 outb_p(command, SMBHSTDAT1(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100710 } else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100711 outb_p(command, SMBHSTCMD(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100712 block = 1;
713 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 default:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100715 dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
716 size);
David Brownell97140342008-07-14 22:38:25 +0200717 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 }
719
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200720 if (hwpec) /* enable/disable hardware PEC */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100721 outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200722 else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100723 outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
724 SMBAUXCTL(priv));
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200725
Ivo Manca3fb21c62010-05-21 18:40:55 +0200726 if (block)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100727 ret = i801_block_transaction(priv, data, read_write, size,
728 hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200729 else
Daniel Kurtz37af8712012-07-24 14:13:58 +0200730 ret = i801_transaction(priv, xact);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731
Jean Delvarec79cfba2006-04-20 02:43:18 -0700732 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200733 time, so we forcibly disable it after every transaction. Turn off
734 E32B for the same reason. */
Jean Delvarea0921b62008-01-27 18:14:50 +0100735 if (hwpec || block)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100736 outb_p(inb_p(SMBAUXCTL(priv)) &
737 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
Jean Delvarec79cfba2006-04-20 02:43:18 -0700738
Ivo Manca3fb21c62010-05-21 18:40:55 +0200739 if (block)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 return ret;
Ivo Manca3fb21c62010-05-21 18:40:55 +0200741 if (ret)
David Brownell97140342008-07-14 22:38:25 +0200742 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
744 return 0;
745
746 switch (xact & 0x7f) {
747 case I801_BYTE: /* Result put in SMBHSTDAT0 */
748 case I801_BYTE_DATA:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100749 data->byte = inb_p(SMBHSTDAT0(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 break;
751 case I801_WORD_DATA:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100752 data->word = inb_p(SMBHSTDAT0(priv)) +
753 (inb_p(SMBHSTDAT1(priv)) << 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 break;
755 }
756 return 0;
757}
758
759
760static u32 i801_func(struct i2c_adapter *adapter)
761{
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100762 struct i801_priv *priv = i2c_get_adapdata(adapter);
763
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
Jean Delvare369f6f42008-01-27 18:14:50 +0100765 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
766 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100767 ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
768 ((priv->features & FEATURE_I2C_BLOCK_READ) ?
Jean Delvare63420642008-01-27 18:14:50 +0100769 I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770}
771
Jean Delvare8f9082c2006-09-03 22:39:46 +0200772static const struct i2c_algorithm smbus_algorithm = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 .smbus_xfer = i801_access,
774 .functionality = i801_func,
775};
776
Axel Lin3527bd52012-01-12 20:32:04 +0100777static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
779 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
780 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
781 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
782 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
783 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
784 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
785 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
786 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
Jason Gastonb0a70b52005-04-16 15:24:45 -0700787 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
Jason Gaston8254fc42006-01-09 10:58:08 -0800788 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
Jason Gastonadbc2a12006-11-22 15:19:12 -0800789 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
Seth Heasleycb04e952010-10-04 13:27:14 -0700790 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) },
Gaston, Jason Dd28dc712008-02-24 20:03:42 +0100791 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
792 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
Seth Heasleycb04e952010-10-04 13:27:14 -0700793 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) },
794 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) },
Seth Heasleye30d9852010-10-31 21:06:59 +0100795 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) },
David Woodhouse55fee8d2010-10-31 21:07:00 +0100796 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) },
797 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
798 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
Seth Heasley662cda82011-03-20 14:50:53 +0100799 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },
Seth Heasley6e2a8512011-05-24 20:58:49 +0200800 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
Seth Heasley062737f2012-03-26 21:47:19 +0200801 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) },
James Ralston4a8f1dd2012-09-10 10:14:02 +0200802 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) },
Seth Heasleyc2db409c2013-01-30 15:25:32 +0000803 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 { 0, }
805};
806
Ivo Manca3fb21c62010-05-21 18:40:55 +0200807MODULE_DEVICE_TABLE(pci, i801_ids);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
Jean Delvare8eacfce2011-05-24 20:58:49 +0200809#if defined CONFIG_X86 && defined CONFIG_DMI
Jean Delvare1561bfe2009-01-07 14:29:17 +0100810static unsigned char apanel_addr;
811
812/* Scan the system ROM for the signature "FJKEYINF" */
813static __init const void __iomem *bios_signature(const void __iomem *bios)
814{
815 ssize_t offset;
816 const unsigned char signature[] = "FJKEYINF";
817
818 for (offset = 0; offset < 0x10000; offset += 0x10) {
819 if (check_signature(bios + offset, signature,
820 sizeof(signature)-1))
821 return bios + offset;
822 }
823 return NULL;
824}
825
826static void __init input_apanel_init(void)
827{
828 void __iomem *bios;
829 const void __iomem *p;
830
831 bios = ioremap(0xF0000, 0x10000); /* Can't fail */
832 p = bios_signature(bios);
833 if (p) {
834 /* just use the first address */
835 apanel_addr = readb(p + 8 + 3) >> 1;
836 }
837 iounmap(bios);
838}
Jean Delvare1561bfe2009-01-07 14:29:17 +0100839
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200840struct dmi_onboard_device_info {
841 const char *name;
842 u8 type;
843 unsigned short i2c_addr;
844 const char *i2c_type;
845};
846
Bill Pemberton0b255e92012-11-27 15:59:38 -0500847static const struct dmi_onboard_device_info dmi_devices[] = {
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200848 { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
849 { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
850 { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
851};
852
Bill Pemberton0b255e92012-11-27 15:59:38 -0500853static void dmi_check_onboard_device(u8 type, const char *name,
854 struct i2c_adapter *adap)
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200855{
856 int i;
857 struct i2c_board_info info;
858
859 for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
860 /* & ~0x80, ignore enabled/disabled bit */
861 if ((type & ~0x80) != dmi_devices[i].type)
862 continue;
Jean Delvarefaabd472010-07-09 16:22:51 +0200863 if (strcasecmp(name, dmi_devices[i].name))
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200864 continue;
865
866 memset(&info, 0, sizeof(struct i2c_board_info));
867 info.addr = dmi_devices[i].i2c_addr;
868 strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
869 i2c_new_device(adap, &info);
870 break;
871 }
872}
873
874/* We use our own function to check for onboard devices instead of
875 dmi_find_device() as some buggy BIOS's have the devices we are interested
876 in marked as disabled */
Bill Pemberton0b255e92012-11-27 15:59:38 -0500877static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap)
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200878{
879 int i, count;
880
881 if (dm->type != 10)
882 return;
883
884 count = (dm->length - sizeof(struct dmi_header)) / 2;
885 for (i = 0; i < count; i++) {
886 const u8 *d = (char *)(dm + 1) + (i * 2);
887 const char *name = ((char *) dm) + dm->length;
888 u8 type = d[0];
889 u8 s = d[1];
890
891 if (!s)
892 continue;
893 s--;
894 while (s > 0 && name[0]) {
895 name += strlen(name) + 1;
896 s--;
897 }
898 if (name[0] == 0) /* Bogus string reference */
899 continue;
900
901 dmi_check_onboard_device(type, name, adap);
902 }
903}
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200904
Jean Delvaree7198fb2011-05-24 20:58:49 +0200905/* Register optional slaves */
Bill Pemberton0b255e92012-11-27 15:59:38 -0500906static void i801_probe_optional_slaves(struct i801_priv *priv)
Jean Delvaree7198fb2011-05-24 20:58:49 +0200907{
908 /* Only register slaves on main SMBus channel */
909 if (priv->features & FEATURE_IDF)
910 return;
911
Jean Delvaree7198fb2011-05-24 20:58:49 +0200912 if (apanel_addr) {
913 struct i2c_board_info info;
914
915 memset(&info, 0, sizeof(struct i2c_board_info));
916 info.addr = apanel_addr;
917 strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
918 i2c_new_device(&priv->adapter, &info);
919 }
Jean Delvare8eacfce2011-05-24 20:58:49 +0200920
Jean Delvaree7198fb2011-05-24 20:58:49 +0200921 if (dmi_name_in_vendors("FUJITSU"))
922 dmi_walk(dmi_check_onboard_devices, &priv->adapter);
Jean Delvaree7198fb2011-05-24 20:58:49 +0200923}
Jean Delvare8eacfce2011-05-24 20:58:49 +0200924#else
925static void __init input_apanel_init(void) {}
Bill Pemberton0b255e92012-11-27 15:59:38 -0500926static void i801_probe_optional_slaves(struct i801_priv *priv) {}
Jean Delvare8eacfce2011-05-24 20:58:49 +0200927#endif /* CONFIG_X86 && CONFIG_DMI */
Jean Delvaree7198fb2011-05-24 20:58:49 +0200928
Jean Delvare79e3e5b2012-10-28 21:37:01 +0100929#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
930 defined CONFIG_DMI
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200931static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
932 .gpio_chip = "gpio_ich",
933 .values = { 0x02, 0x03 },
934 .n_values = 2,
935 .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
936 .gpios = { 52, 53 },
937 .n_gpios = 2,
938};
939
940static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
941 .gpio_chip = "gpio_ich",
942 .values = { 0x02, 0x03, 0x01 },
943 .n_values = 3,
944 .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
945 .gpios = { 52, 53 },
946 .n_gpios = 2,
947};
948
Bill Pemberton0b255e92012-11-27 15:59:38 -0500949static const struct dmi_system_id mux_dmi_table[] = {
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200950 {
951 .matches = {
952 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
953 DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"),
954 },
955 .driver_data = &i801_mux_config_asus_z8_d12,
956 },
957 {
958 .matches = {
959 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
960 DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"),
961 },
962 .driver_data = &i801_mux_config_asus_z8_d12,
963 },
964 {
965 .matches = {
966 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
967 DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"),
968 },
969 .driver_data = &i801_mux_config_asus_z8_d12,
970 },
971 {
972 .matches = {
973 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
974 DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"),
975 },
976 .driver_data = &i801_mux_config_asus_z8_d12,
977 },
978 {
979 .matches = {
980 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
981 DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"),
982 },
983 .driver_data = &i801_mux_config_asus_z8_d12,
984 },
985 {
986 .matches = {
987 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
988 DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"),
989 },
990 .driver_data = &i801_mux_config_asus_z8_d12,
991 },
992 {
993 .matches = {
994 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
995 DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"),
996 },
997 .driver_data = &i801_mux_config_asus_z8_d18,
998 },
999 {
1000 .matches = {
1001 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1002 DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"),
1003 },
1004 .driver_data = &i801_mux_config_asus_z8_d18,
1005 },
1006 {
1007 .matches = {
1008 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1009 DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"),
1010 },
1011 .driver_data = &i801_mux_config_asus_z8_d12,
1012 },
1013 { }
1014};
1015
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001016/* Setup multiplexing if needed */
Bill Pemberton0b255e92012-11-27 15:59:38 -05001017static int i801_add_mux(struct i801_priv *priv)
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001018{
1019 struct device *dev = &priv->adapter.dev;
1020 const struct i801_mux_config *mux_config;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001021 struct i2c_mux_gpio_platform_data gpio_data;
Jean Delvaref82b8622012-10-05 22:23:54 +02001022 int err;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001023
1024 if (!priv->mux_drvdata)
1025 return 0;
1026 mux_config = priv->mux_drvdata;
1027
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001028 /* Prepare the platform data */
1029 memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
1030 gpio_data.parent = priv->adapter.nr;
1031 gpio_data.values = mux_config->values;
1032 gpio_data.n_values = mux_config->n_values;
1033 gpio_data.classes = mux_config->classes;
Jean Delvaref82b8622012-10-05 22:23:54 +02001034 gpio_data.gpio_chip = mux_config->gpio_chip;
1035 gpio_data.gpios = mux_config->gpios;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001036 gpio_data.n_gpios = mux_config->n_gpios;
1037 gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
1038
1039 /* Register the mux device */
1040 priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
Jean Delvaref82b8622012-10-05 22:23:54 +02001041 PLATFORM_DEVID_AUTO, &gpio_data,
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001042 sizeof(struct i2c_mux_gpio_platform_data));
1043 if (IS_ERR(priv->mux_pdev)) {
1044 err = PTR_ERR(priv->mux_pdev);
1045 priv->mux_pdev = NULL;
1046 dev_err(dev, "Failed to register i2c-mux-gpio device\n");
1047 return err;
1048 }
1049
1050 return 0;
1051}
1052
Bill Pemberton0b255e92012-11-27 15:59:38 -05001053static void i801_del_mux(struct i801_priv *priv)
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001054{
1055 if (priv->mux_pdev)
1056 platform_device_unregister(priv->mux_pdev);
1057}
1058
Bill Pemberton0b255e92012-11-27 15:59:38 -05001059static unsigned int i801_get_adapter_class(struct i801_priv *priv)
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001060{
1061 const struct dmi_system_id *id;
1062 const struct i801_mux_config *mux_config;
1063 unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
1064 int i;
1065
1066 id = dmi_first_match(mux_dmi_table);
1067 if (id) {
Jean Delvare28901f52012-10-28 21:37:01 +01001068 /* Remove branch classes from trunk */
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001069 mux_config = id->driver_data;
1070 for (i = 0; i < mux_config->n_values; i++)
1071 class &= ~mux_config->classes[i];
1072
1073 /* Remember for later */
1074 priv->mux_drvdata = mux_config;
1075 }
1076
1077 return class;
1078}
1079#else
1080static inline int i801_add_mux(struct i801_priv *priv) { return 0; }
1081static inline void i801_del_mux(struct i801_priv *priv) { }
1082
1083static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
1084{
1085 return I2C_CLASS_HWMON | I2C_CLASS_SPD;
1086}
1087#endif
1088
Bill Pemberton0b255e92012-11-27 15:59:38 -05001089static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090{
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001091 unsigned char temp;
Jean Delvareadff6872010-05-21 18:40:54 +02001092 int err, i;
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001093 struct i801_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001095 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1096 if (!priv)
1097 return -ENOMEM;
1098
1099 i2c_set_adapdata(&priv->adapter, priv);
1100 priv->adapter.owner = THIS_MODULE;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001101 priv->adapter.class = i801_get_adapter_class(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001102 priv->adapter.algo = &smbus_algorithm;
1103
1104 priv->pci_dev = dev;
Jean Delvare250d1bd2006-12-10 21:21:33 +01001105 switch (dev->device) {
Jean Delvaree7198fb2011-05-24 20:58:49 +02001106 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0:
1107 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1:
1108 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2:
1109 priv->features |= FEATURE_IDF;
1110 /* fall through */
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001111 default:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001112 priv->features |= FEATURE_I2C_BLOCK_READ;
Jean Delvare6676a842012-12-16 21:11:55 +01001113 priv->features |= FEATURE_IRQ;
Jean Delvare63420642008-01-27 18:14:50 +01001114 /* fall through */
1115 case PCI_DEVICE_ID_INTEL_82801DB_3:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001116 priv->features |= FEATURE_SMBUS_PEC;
1117 priv->features |= FEATURE_BLOCK_BUFFER;
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001118 /* fall through */
1119 case PCI_DEVICE_ID_INTEL_82801CA_3:
1120 case PCI_DEVICE_ID_INTEL_82801BA_2:
1121 case PCI_DEVICE_ID_INTEL_82801AB_3:
1122 case PCI_DEVICE_ID_INTEL_82801AA_3:
Jean Delvare250d1bd2006-12-10 21:21:33 +01001123 break;
Jean Delvare250d1bd2006-12-10 21:21:33 +01001124 }
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001125
Jean Delvareadff6872010-05-21 18:40:54 +02001126 /* Disable features on user request */
1127 for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001128 if (priv->features & disable_features & (1 << i))
Jean Delvareadff6872010-05-21 18:40:54 +02001129 dev_notice(&dev->dev, "%s disabled by user\n",
1130 i801_feature_names[i]);
1131 }
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001132 priv->features &= ~disable_features;
Jean Delvareadff6872010-05-21 18:40:54 +02001133
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001134 err = pci_enable_device(dev);
1135 if (err) {
1136 dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
1137 err);
1138 goto exit;
1139 }
1140
1141 /* Determine the address of the SMBus area */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001142 priv->smba = pci_resource_start(dev, SMBBAR);
1143 if (!priv->smba) {
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001144 dev_err(&dev->dev, "SMBus base address uninitialized, "
1145 "upgrade BIOS\n");
1146 err = -ENODEV;
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001147 goto exit;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001148 }
1149
Jean Delvare54fb4a052008-07-14 22:38:33 +02001150 err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
Jean Delvare18669ea2009-10-04 22:53:45 +02001151 if (err) {
1152 err = -ENODEV;
Jean Delvare54fb4a052008-07-14 22:38:33 +02001153 goto exit;
Jean Delvare18669ea2009-10-04 22:53:45 +02001154 }
Jean Delvare54fb4a052008-07-14 22:38:33 +02001155
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001156 err = pci_request_region(dev, SMBBAR, i801_driver.name);
1157 if (err) {
1158 dev_err(&dev->dev, "Failed to request SMBus region "
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001159 "0x%lx-0x%Lx\n", priv->smba,
Andrew Morton598736c2006-06-30 01:56:20 -07001160 (unsigned long long)pci_resource_end(dev, SMBBAR));
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001161 goto exit;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001162 }
1163
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001164 pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
1165 priv->original_hstcfg = temp;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001166 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
1167 if (!(temp & SMBHSTCFG_HST_EN)) {
1168 dev_info(&dev->dev, "Enabling SMBus device\n");
1169 temp |= SMBHSTCFG_HST_EN;
1170 }
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001171 pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001172
Daniel Kurtz636752b2012-07-24 14:13:58 +02001173 if (temp & SMBHSTCFG_SMB_SMI_EN) {
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001174 dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001175 /* Disable SMBus interrupt feature if SMBus using SMI# */
1176 priv->features &= ~FEATURE_IRQ;
Daniel Kurtz636752b2012-07-24 14:13:58 +02001177 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Jean Delvarea0921b62008-01-27 18:14:50 +01001179 /* Clear special mode bits */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001180 if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
1181 outb_p(inb_p(SMBAUXCTL(priv)) &
1182 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
Jean Delvarea0921b62008-01-27 18:14:50 +01001183
Daniel Kurtz636752b2012-07-24 14:13:58 +02001184 if (priv->features & FEATURE_IRQ) {
1185 init_waitqueue_head(&priv->waitq);
1186
1187 err = request_irq(dev->irq, i801_isr, IRQF_SHARED,
1188 i801_driver.name, priv);
1189 if (err) {
1190 dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
1191 dev->irq, err);
1192 goto exit_release;
1193 }
Jean Delvare29b60852012-07-24 14:13:59 +02001194 dev_info(&dev->dev, "SMBus using PCI Interrupt\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001195 }
1196
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01001197 /* set up the sysfs linkage to our parent device */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001198 priv->adapter.dev.parent = &dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
Jean Delvare7e2193a8f2009-12-06 17:06:27 +01001200 /* Retry up to 3 times on lost arbitration */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001201 priv->adapter.retries = 3;
Jean Delvare7e2193a8f2009-12-06 17:06:27 +01001202
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001203 snprintf(priv->adapter.name, sizeof(priv->adapter.name),
1204 "SMBus I801 adapter at %04lx", priv->smba);
1205 err = i2c_add_adapter(&priv->adapter);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001206 if (err) {
1207 dev_err(&dev->dev, "Failed to add SMBus adapter\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001208 goto exit_free_irq;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001209 }
Jean Delvare1561bfe2009-01-07 14:29:17 +01001210
Thierry Redingf6afc8b2012-12-16 21:11:54 +01001211 of_i2c_register_devices(&priv->adapter);
Jean Delvaree7198fb2011-05-24 20:58:49 +02001212 i801_probe_optional_slaves(priv);
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001213 /* We ignore errors - multiplexing is optional */
1214 i801_add_mux(priv);
Jean Delvare1561bfe2009-01-07 14:29:17 +01001215
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001216 pci_set_drvdata(dev, priv);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001217
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001218 return 0;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001219
Daniel Kurtz636752b2012-07-24 14:13:58 +02001220exit_free_irq:
1221 if (priv->features & FEATURE_IRQ)
1222 free_irq(dev->irq, priv);
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001223exit_release:
1224 pci_release_region(dev, SMBBAR);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001225exit:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001226 kfree(priv);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001227 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228}
1229
Bill Pemberton0b255e92012-11-27 15:59:38 -05001230static void i801_remove(struct pci_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231{
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001232 struct i801_priv *priv = pci_get_drvdata(dev);
1233
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001234 i801_del_mux(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001235 i2c_del_adapter(&priv->adapter);
1236 pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001237
1238 if (priv->features & FEATURE_IRQ)
1239 free_irq(dev->irq, priv);
Jean Delvare6dcc19d2006-06-12 21:53:02 +02001240 pci_release_region(dev, SMBBAR);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001241
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001242 pci_set_drvdata(dev, NULL);
1243 kfree(priv);
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001244 /*
1245 * do not call pci_disable_device(dev) since it can cause hard hangs on
1246 * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
1247 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248}
1249
Jean Delvarea5aaea32007-03-22 19:49:01 +01001250#ifdef CONFIG_PM
1251static int i801_suspend(struct pci_dev *dev, pm_message_t mesg)
1252{
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001253 struct i801_priv *priv = pci_get_drvdata(dev);
1254
Jean Delvarea5aaea32007-03-22 19:49:01 +01001255 pci_save_state(dev);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001256 pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
Jean Delvarea5aaea32007-03-22 19:49:01 +01001257 pci_set_power_state(dev, pci_choose_state(dev, mesg));
1258 return 0;
1259}
1260
1261static int i801_resume(struct pci_dev *dev)
1262{
1263 pci_set_power_state(dev, PCI_D0);
1264 pci_restore_state(dev);
1265 return pci_enable_device(dev);
1266}
1267#else
1268#define i801_suspend NULL
1269#define i801_resume NULL
1270#endif
1271
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272static struct pci_driver i801_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 .name = "i801_smbus",
1274 .id_table = i801_ids,
1275 .probe = i801_probe,
Bill Pemberton0b255e92012-11-27 15:59:38 -05001276 .remove = i801_remove,
Jean Delvarea5aaea32007-03-22 19:49:01 +01001277 .suspend = i801_suspend,
1278 .resume = i801_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279};
1280
1281static int __init i2c_i801_init(void)
1282{
Jean Delvare6aa14642011-05-24 20:58:49 +02001283 if (dmi_name_in_vendors("FUJITSU"))
1284 input_apanel_init();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 return pci_register_driver(&i801_driver);
1286}
1287
1288static void __exit i2c_i801_exit(void)
1289{
1290 pci_unregister_driver(&i801_driver);
1291}
1292
Jean Delvare63420642008-01-27 18:14:50 +01001293MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, "
1294 "Jean Delvare <khali@linux-fr.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295MODULE_DESCRIPTION("I801 SMBus driver");
1296MODULE_LICENSE("GPL");
1297
1298module_init(i2c_i801_init);
1299module_exit(i2c_i801_exit);