blob: 941c223f64914450fc2e2d76a293cd6202441b0b [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 Delvareb3b8df92014-11-12 10:20:40 +01005 Copyright (C) 2007 - 2014 Jean Delvare <jdelvare@suse.de>
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.
Linus Torvalds1da177e2005-04-16 15:20:36 -070018*/
19
20/*
Jean Delvarece316112014-07-17 15:03:24 +020021 * Supports the following Intel I/O Controller Hubs (ICH):
22 *
23 * I/O Block I2C
24 * region SMBus Block proc. block
25 * Chip name PCI ID size PEC buffer call read
26 * ---------------------------------------------------------------------------
27 * 82801AA (ICH) 0x2413 16 no no no no
28 * 82801AB (ICH0) 0x2423 16 no no no no
29 * 82801BA (ICH2) 0x2443 16 no no no no
30 * 82801CA (ICH3) 0x2483 32 soft no no no
31 * 82801DB (ICH4) 0x24c3 32 hard yes no no
32 * 82801E (ICH5) 0x24d3 32 hard yes yes yes
33 * 6300ESB 0x25a4 32 hard yes yes yes
34 * 82801F (ICH6) 0x266a 32 hard yes yes yes
35 * 6310ESB/6320ESB 0x269b 32 hard yes yes yes
36 * 82801G (ICH7) 0x27da 32 hard yes yes yes
37 * 82801H (ICH8) 0x283e 32 hard yes yes yes
38 * 82801I (ICH9) 0x2930 32 hard yes yes yes
39 * EP80579 (Tolapai) 0x5032 32 hard yes yes yes
40 * ICH10 0x3a30 32 hard yes yes yes
41 * ICH10 0x3a60 32 hard yes yes yes
42 * 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes
43 * 6 Series (PCH) 0x1c22 32 hard yes yes yes
44 * Patsburg (PCH) 0x1d22 32 hard yes yes yes
45 * Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes
46 * Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes
47 * Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes
48 * DH89xxCC (PCH) 0x2330 32 hard yes yes yes
49 * Panther Point (PCH) 0x1e22 32 hard yes yes yes
50 * Lynx Point (PCH) 0x8c22 32 hard yes yes yes
51 * Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes
52 * Avoton (SOC) 0x1f3c 32 hard yes yes yes
53 * Wellsburg (PCH) 0x8d22 32 hard yes yes yes
54 * Wellsburg (PCH) MS 0x8d7d 32 hard yes yes yes
55 * Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes
56 * Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes
57 * Coleto Creek (PCH) 0x23b0 32 hard yes yes yes
Jean Delvareb299de82014-07-17 15:04:41 +020058 * Wildcat Point (PCH) 0x8ca2 32 hard yes yes yes
Jean Delvarece316112014-07-17 15:03:24 +020059 * Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes
60 * BayTrail (SOC) 0x0f12 32 hard yes yes yes
Jarkko Nikula15407792018-02-16 11:24:29 +020061 * Braswell (SOC) 0x2292 32 hard yes yes yes
james.d.ralston@intel.com3e27a842014-10-13 15:20:24 -070062 * Sunrise Point-H (PCH) 0xa123 32 hard yes yes yes
Devin Ryles3eee17992014-11-05 16:30:03 -050063 * Sunrise Point-LP (PCH) 0x9d23 32 hard yes yes yes
Mika Westerberg84d7f2e2015-10-13 15:41:39 +030064 * DNV (SOC) 0x19df 32 hard yes yes yes
Jarkko Nikuladd77f422015-10-22 17:16:58 +030065 * Broxton (SOC) 0x5ad4 32 hard yes yes yes
Alexandra Yatescdc5a312015-11-05 11:40:25 -080066 * Lewisburg (PCH) 0xa1a3 32 hard yes yes yes
67 * Lewisburg Supersku (PCH) 0xa223 32 hard yes yes yes
Andy Shevchenko31158762016-09-23 11:56:01 +030068 * Kaby Lake PCH-H (PCH) 0xa2a3 32 hard yes yes yes
Mika Westerberg9827f9e2017-02-01 19:20:59 +030069 * Gemini Lake (SOC) 0x31d4 32 hard yes yes yes
Srinivas Pandruvada09a1de02017-05-18 11:23:06 +030070 * Cannon Lake-H (PCH) 0xa323 32 hard yes yes yes
71 * Cannon Lake-LP (PCH) 0x9da3 32 hard yes yes yes
Jarkko Nikulacb09d942017-09-21 16:23:16 +030072 * Cedar Fork (PCH) 0x18df 32 hard yes yes yes
Mika Westerberg0bff2a82018-06-28 16:08:24 +030073 * Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes
Jean Delvarece316112014-07-17 15:03:24 +020074 *
75 * Features supported by this driver:
76 * Software PEC no
77 * Hardware PEC yes
78 * Block buffer yes
79 * Block process call transaction no
80 * I2C block read transaction yes (doesn't use the block buffer)
81 * Slave mode no
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +020082 * SMBus Host Notify yes
Jean Delvarece316112014-07-17 15:03:24 +020083 * Interrupt processing yes
84 *
85 * See the file Documentation/i2c/busses/i2c-i801 for details.
86 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
Daniel Kurtz636752b2012-07-24 14:13:58 +020088#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070089#include <linux/module.h>
90#include <linux/pci.h>
91#include <linux/kernel.h>
92#include <linux/stddef.h>
93#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070094#include <linux/ioport.h>
95#include <linux/init.h>
96#include <linux/i2c.h>
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +020097#include <linux/i2c-smbus.h>
Jean Delvare54fb4a052008-07-14 22:38:33 +020098#include <linux/acpi.h>
Jean Delvare1561bfe2009-01-07 14:29:17 +010099#include <linux/io.h>
Hans de Goedefa5bfab2009-03-30 21:46:44 +0200100#include <linux/dmi.h>
Ben Hutchings665a96b2011-01-10 22:11:22 +0100101#include <linux/slab.h>
Daniel Kurtz636752b2012-07-24 14:13:58 +0200102#include <linux/wait.h>
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200103#include <linux/err.h>
Mika Westerberg94246932015-08-06 13:46:25 +0100104#include <linux/platform_device.h>
105#include <linux/platform_data/itco_wdt.h>
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200106#include <linux/pm_runtime.h>
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200107
Javier Martinez Canillas175c7082016-07-21 12:11:01 -0400108#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200109#include <linux/gpio.h>
Wolfram Sang62ea22c2018-04-19 22:00:08 +0200110#include <linux/platform_data/i2c-mux-gpio.h>
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200111#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113/* I801 SMBus address offsets */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100114#define SMBHSTSTS(p) (0 + (p)->smba)
115#define SMBHSTCNT(p) (2 + (p)->smba)
116#define SMBHSTCMD(p) (3 + (p)->smba)
117#define SMBHSTADD(p) (4 + (p)->smba)
118#define SMBHSTDAT0(p) (5 + (p)->smba)
119#define SMBHSTDAT1(p) (6 + (p)->smba)
120#define SMBBLKDAT(p) (7 + (p)->smba)
121#define SMBPEC(p) (8 + (p)->smba) /* ICH3 and later */
122#define SMBAUXSTS(p) (12 + (p)->smba) /* ICH4 and later */
123#define SMBAUXCTL(p) (13 + (p)->smba) /* ICH4 and later */
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200124#define SMBSLVSTS(p) (16 + (p)->smba) /* ICH3 and later */
125#define SMBSLVCMD(p) (17 + (p)->smba) /* ICH3 and later */
126#define SMBNTFDADD(p) (20 + (p)->smba) /* ICH3 and later */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128/* PCI Address Constants */
Jean Delvare6dcc19d2006-06-12 21:53:02 +0200129#define SMBBAR 4
Jean Delvareaeb8a3d2014-11-12 10:25:37 +0100130#define SMBPCICTL 0x004
Daniel Kurtz636752b2012-07-24 14:13:58 +0200131#define SMBPCISTS 0x006
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132#define SMBHSTCFG 0x040
Mika Westerberg94246932015-08-06 13:46:25 +0100133#define TCOBASE 0x050
134#define TCOCTL 0x054
135
136#define ACPIBASE 0x040
137#define ACPIBASE_SMI_OFF 0x030
138#define ACPICTRL 0x044
139#define ACPICTRL_EN 0x080
140
141#define SBREG_BAR 0x10
142#define SBREG_SMBCTRL 0xc6000c
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Daniel Kurtz636752b2012-07-24 14:13:58 +0200144/* Host status bits for SMBPCISTS */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200145#define SMBPCISTS_INTS BIT(3)
Daniel Kurtz636752b2012-07-24 14:13:58 +0200146
Jean Delvareaeb8a3d2014-11-12 10:25:37 +0100147/* Control bits for SMBPCICTL */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200148#define SMBPCICTL_INTDIS BIT(10)
Jean Delvareaeb8a3d2014-11-12 10:25:37 +0100149
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150/* Host configuration bits for SMBHSTCFG */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200151#define SMBHSTCFG_HST_EN BIT(0)
152#define SMBHSTCFG_SMB_SMI_EN BIT(1)
153#define SMBHSTCFG_I2C_EN BIT(2)
154#define SMBHSTCFG_SPD_WD BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
Mika Westerberg94246932015-08-06 13:46:25 +0100156/* TCO configuration bits for TCOCTL */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200157#define TCOCTL_EN BIT(8)
Mika Westerberg94246932015-08-06 13:46:25 +0100158
Ellen Wang97d34ec2016-07-01 22:42:15 +0200159/* Auxiliary status register bits, ICH4+ only */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200160#define SMBAUXSTS_CRCE BIT(0)
161#define SMBAUXSTS_STCO BIT(1)
Ellen Wang97d34ec2016-07-01 22:42:15 +0200162
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300163/* Auxiliary control register bits, ICH4+ only */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200164#define SMBAUXCTL_CRC BIT(0)
165#define SMBAUXCTL_E32B BIT(1)
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200166
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167/* Other settings */
Jean Delvare84c1af42012-03-26 21:47:19 +0200168#define MAX_RETRIES 400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
170/* I801 command constants */
171#define I801_QUICK 0x00
172#define I801_BYTE 0x04
173#define I801_BYTE_DATA 0x08
174#define I801_WORD_DATA 0x0C
Jean Delvareae7b0492008-01-27 18:14:49 +0100175#define I801_PROC_CALL 0x10 /* unimplemented */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176#define I801_BLOCK_DATA 0x14
Jean Delvare63420642008-01-27 18:14:50 +0100177#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200178
179/* I801 Host Control register bits */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200180#define SMBHSTCNT_INTREN BIT(0)
181#define SMBHSTCNT_KILL BIT(1)
182#define SMBHSTCNT_LAST_BYTE BIT(5)
183#define SMBHSTCNT_START BIT(6)
184#define SMBHSTCNT_PEC_EN BIT(7) /* ICH3 and later */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200186/* I801 Hosts Status register bits */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200187#define SMBHSTSTS_BYTE_DONE BIT(7)
188#define SMBHSTSTS_INUSE_STS BIT(6)
189#define SMBHSTSTS_SMBALERT_STS BIT(5)
190#define SMBHSTSTS_FAILED BIT(4)
191#define SMBHSTSTS_BUS_ERR BIT(3)
192#define SMBHSTSTS_DEV_ERR BIT(2)
193#define SMBHSTSTS_INTR BIT(1)
194#define SMBHSTSTS_HOST_BUSY BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
Benjamin Tissoires9786b1f2016-10-13 14:10:36 +0200196/* Host Notify Status register bits */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200197#define SMBSLVSTS_HST_NTFY_STS BIT(0)
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200198
Benjamin Tissoires9786b1f2016-10-13 14:10:36 +0200199/* Host Notify Command register bits */
Benjamin Tissoiresfe9ba3e2016-10-13 14:10:37 +0200200#define SMBSLVCMD_HST_NTFY_INTREN BIT(0)
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200201
Daniel Kurtz70a1cc12012-07-24 14:13:58 +0200202#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \
203 SMBHSTSTS_DEV_ERR)
204
205#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \
206 STATUS_ERROR_FLAGS)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200207
Jean Delvarea6e5e2b2011-05-01 18:18:49 +0200208/* Older devices have their ID defined in <linux/pci_ids.h> */
Jean Delvarece316112014-07-17 15:03:24 +0200209#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12
Jarkko Nikulacb09d942017-09-21 16:23:16 +0300210#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df
Andy Shevchenko34b57f42016-03-09 14:14:17 +0200211#define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df
Jean Delvarece316112014-07-17 15:03:24 +0200212#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
213#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
David Woodhouse55fee8d2010-10-31 21:07:00 +0100214/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
Jean Delvarece316112014-07-17 15:03:24 +0200215#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70
216#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
217#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72
218#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
219#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c
Andy Shevchenko34b57f42016-03-09 14:14:17 +0200220#define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292
Jean Delvarece316112014-07-17 15:03:24 +0200221#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
222#define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS 0x23b0
Mika Westerberg9827f9e2017-02-01 19:20:59 +0300223#define PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS 0x31d4
Mika Westerberg0bff2a82018-06-28 16:08:24 +0300224#define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3
Jean Delvarece316112014-07-17 15:03:24 +0200225#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
Andy Shevchenko34b57f42016-03-09 14:14:17 +0200226#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
Jean Delvarece316112014-07-17 15:03:24 +0200227#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
Jean Delvareb299de82014-07-17 15:04:41 +0200228#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2
Jean Delvarece316112014-07-17 15:03:24 +0200229#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22
230#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0 0x8d7d
231#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e
232#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f
233#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
James Ralstonafc65922013-11-04 09:29:48 -0800234#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2
Devin Ryles3eee17992014-11-05 16:30:03 -0500235#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS 0x9d23
Srinivas Pandruvada09a1de02017-05-18 11:23:06 +0300236#define PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS 0x9da3
Andy Shevchenko34b57f42016-03-09 14:14:17 +0200237#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS 0xa123
Alexandra Yatescdc5a312015-11-05 11:40:25 -0800238#define PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS 0xa1a3
239#define PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS 0xa223
Andy Shevchenko31158762016-09-23 11:56:01 +0300240#define PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS 0xa2a3
Srinivas Pandruvada09a1de02017-05-18 11:23:06 +0300241#define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS 0xa323
David Woodhouse55fee8d2010-10-31 21:07:00 +0100242
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200243struct i801_mux_config {
244 char *gpio_chip;
245 unsigned values[3];
246 int n_values;
247 unsigned classes[3];
248 unsigned gpios[2]; /* Relative to gpio_chip->base */
249 int n_gpios;
250};
251
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100252struct i801_priv {
253 struct i2c_adapter adapter;
254 unsigned long smba;
255 unsigned char original_hstcfg;
Benjamin Tissoires22e94bd2016-10-13 14:10:35 +0200256 unsigned char original_slvcmd;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100257 struct pci_dev *pci_dev;
258 unsigned int features;
Daniel Kurtz636752b2012-07-24 14:13:58 +0200259
260 /* isr processing */
261 wait_queue_head_t waitq;
262 u8 status;
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200263
264 /* Command state used by isr for byte-by-byte block transactions */
265 u8 cmd;
266 bool is_read;
267 int count;
268 int len;
269 u8 *data;
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200270
Javier Martinez Canillas175c7082016-07-21 12:11:01 -0400271#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200272 const struct i801_mux_config *mux_drvdata;
Jean Delvare3ad7ea12012-10-05 22:23:53 +0200273 struct platform_device *mux_pdev;
274#endif
Mika Westerberg94246932015-08-06 13:46:25 +0100275 struct platform_device *tco_pdev;
Mika Westerberga7ae8192016-06-09 16:56:28 +0300276
277 /*
278 * If set to true the host controller registers are reserved for
279 * ACPI AML use. Protected by acpi_lock.
280 */
281 bool acpi_reserved;
282 struct mutex acpi_lock;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100283};
284
Benjamin Tissoiresf91fba62016-10-13 14:10:38 +0200285#define FEATURE_SMBUS_PEC BIT(0)
286#define FEATURE_BLOCK_BUFFER BIT(1)
287#define FEATURE_BLOCK_PROC BIT(2)
288#define FEATURE_I2C_BLOCK_READ BIT(3)
289#define FEATURE_IRQ BIT(4)
290#define FEATURE_HOST_NOTIFY BIT(5)
Jean Delvaree7198fb2011-05-24 20:58:49 +0200291/* Not really a feature, but it's convenient to handle it as such */
Benjamin Tissoiresf91fba62016-10-13 14:10:38 +0200292#define FEATURE_IDF BIT(15)
293#define FEATURE_TCO BIT(16)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294
Jean Delvareadff6872010-05-21 18:40:54 +0200295static const char *i801_feature_names[] = {
296 "SMBus PEC",
297 "Block buffer",
298 "Block process call",
299 "I2C block read",
Daniel Kurtz636752b2012-07-24 14:13:58 +0200300 "Interrupt",
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200301 "SMBus Host Notify",
Jean Delvareadff6872010-05-21 18:40:54 +0200302};
303
304static unsigned int disable_features;
305module_param(disable_features, uint, S_IRUGO | S_IWUSR);
Jean Delvare53229342013-05-15 02:44:10 +0000306MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n"
307 "\t\t 0x01 disable SMBus PEC\n"
308 "\t\t 0x02 disable the block buffer\n"
309 "\t\t 0x08 disable the I2C block read functionality\n"
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200310 "\t\t 0x10 don't use interrupts\n"
311 "\t\t 0x20 disable SMBus Host Notify ");
Jean Delvareadff6872010-05-21 18:40:54 +0200312
Jean Delvarecf898dc2008-07-14 22:38:33 +0200313/* Make sure the SMBus host is ready to start transmitting.
314 Return 0 if it is, -EBUSY if it is not. */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100315static int i801_check_pre(struct i801_priv *priv)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200316{
317 int status;
318
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100319 status = inb_p(SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200320 if (status & SMBHSTSTS_HOST_BUSY) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100321 dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200322 return -EBUSY;
323 }
324
325 status &= STATUS_FLAGS;
326 if (status) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100327 dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n",
Jean Delvarecf898dc2008-07-14 22:38:33 +0200328 status);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100329 outb_p(status, SMBHSTSTS(priv));
330 status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200331 if (status) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100332 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200333 "Failed clearing status flags (%02x)\n",
334 status);
335 return -EBUSY;
336 }
337 }
338
Ellen Wang97d34ec2016-07-01 22:42:15 +0200339 /*
340 * Clear CRC status if needed.
341 * During normal operation, i801_check_post() takes care
342 * of it after every operation. We do it here only in case
343 * the hardware was already in this state when the driver
344 * started.
345 */
346 if (priv->features & FEATURE_SMBUS_PEC) {
347 status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE;
348 if (status) {
349 dev_dbg(&priv->pci_dev->dev,
350 "Clearing aux status flags (%02x)\n", status);
351 outb_p(status, SMBAUXSTS(priv));
352 status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE;
353 if (status) {
354 dev_err(&priv->pci_dev->dev,
355 "Failed clearing aux status flags (%02x)\n",
356 status);
357 return -EBUSY;
358 }
359 }
360 }
361
Jean Delvarecf898dc2008-07-14 22:38:33 +0200362 return 0;
363}
364
Jean Delvare6cad93c2012-07-24 14:13:58 +0200365/*
366 * Convert the status register to an error code, and clear it.
367 * Note that status only contains the bits we want to clear, not the
368 * actual register value.
369 */
370static int i801_check_post(struct i801_priv *priv, int status)
Jean Delvarecf898dc2008-07-14 22:38:33 +0200371{
372 int result = 0;
373
Daniel Kurtz636752b2012-07-24 14:13:58 +0200374 /*
375 * If the SMBus is still busy, we give up
376 * Note: This timeout condition only happens when using polling
377 * transactions. For interrupt operation, NAK/timeout is indicated by
378 * DEV_ERR.
379 */
Jean Delvare6cad93c2012-07-24 14:13:58 +0200380 if (unlikely(status < 0)) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100381 dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200382 /* try to stop the current command */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100383 dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
384 outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
385 SMBHSTCNT(priv));
Jean Delvare84c1af42012-03-26 21:47:19 +0200386 usleep_range(1000, 2000);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100387 outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
388 SMBHSTCNT(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200389
390 /* Check if it worked */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100391 status = inb_p(SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200392 if ((status & SMBHSTSTS_HOST_BUSY) ||
393 !(status & SMBHSTSTS_FAILED))
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100394 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200395 "Failed terminating the transaction\n");
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100396 outb_p(STATUS_FLAGS, SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200397 return -ETIMEDOUT;
398 }
399
400 if (status & SMBHSTSTS_FAILED) {
401 result = -EIO;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100402 dev_err(&priv->pci_dev->dev, "Transaction failed\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200403 }
404 if (status & SMBHSTSTS_DEV_ERR) {
Ellen Wang97d34ec2016-07-01 22:42:15 +0200405 /*
406 * This may be a PEC error, check and clear it.
407 *
408 * AUXSTS is handled differently from HSTSTS.
409 * For HSTSTS, i801_isr() or i801_wait_intr()
410 * has already cleared the error bits in hardware,
411 * and we are passed a copy of the original value
412 * in "status".
413 * For AUXSTS, the hardware register is left
414 * for us to handle here.
415 * This is asymmetric, slightly iffy, but safe,
416 * since all this code is serialized and the CRCE
417 * bit is harmless as long as it's cleared before
418 * the next operation.
419 */
420 if ((priv->features & FEATURE_SMBUS_PEC) &&
421 (inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE)) {
422 outb_p(SMBAUXSTS_CRCE, SMBAUXSTS(priv));
423 result = -EBADMSG;
424 dev_dbg(&priv->pci_dev->dev, "PEC error\n");
425 } else {
426 result = -ENXIO;
427 dev_dbg(&priv->pci_dev->dev, "No response\n");
428 }
Jean Delvarecf898dc2008-07-14 22:38:33 +0200429 }
430 if (status & SMBHSTSTS_BUS_ERR) {
431 result = -EAGAIN;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100432 dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
Jean Delvarecf898dc2008-07-14 22:38:33 +0200433 }
434
Jean Delvare6cad93c2012-07-24 14:13:58 +0200435 /* Clear status flags except BYTE_DONE, to be cleared by caller */
436 outb_p(status, SMBHSTSTS(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200437
438 return result;
439}
440
Jean Delvare6cad93c2012-07-24 14:13:58 +0200441/* Wait for BUSY being cleared and either INTR or an error flag being set */
442static int i801_wait_intr(struct i801_priv *priv)
443{
444 int timeout = 0;
445 int status;
446
447 /* We will always wait for a fraction of a second! */
448 do {
449 usleep_range(250, 500);
450 status = inb_p(SMBHSTSTS(priv));
451 } while (((status & SMBHSTSTS_HOST_BUSY) ||
452 !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) &&
453 (timeout++ < MAX_RETRIES));
454
455 if (timeout > MAX_RETRIES) {
456 dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n");
457 return -ETIMEDOUT;
458 }
459 return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR);
460}
461
462/* Wait for either BYTE_DONE or an error flag being set */
463static int i801_wait_byte_done(struct i801_priv *priv)
464{
465 int timeout = 0;
466 int status;
467
468 /* We will always wait for a fraction of a second! */
469 do {
470 usleep_range(250, 500);
471 status = inb_p(SMBHSTSTS(priv));
472 } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) &&
473 (timeout++ < MAX_RETRIES));
474
475 if (timeout > MAX_RETRIES) {
476 dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n");
477 return -ETIMEDOUT;
478 }
479 return status & STATUS_ERROR_FLAGS;
480}
481
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100482static int i801_transaction(struct i801_priv *priv, int xact)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483{
Jean Delvare2b738092008-07-14 22:38:32 +0200484 int status;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200485 int result;
Jean Delvareb3b8df92014-11-12 10:20:40 +0100486 const struct i2c_adapter *adap = &priv->adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100488 result = i801_check_pre(priv);
Jean Delvarecf898dc2008-07-14 22:38:33 +0200489 if (result < 0)
490 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
Daniel Kurtz636752b2012-07-24 14:13:58 +0200492 if (priv->features & FEATURE_IRQ) {
493 outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
494 SMBHSTCNT(priv));
Jean Delvareb3b8df92014-11-12 10:20:40 +0100495 result = wait_event_timeout(priv->waitq,
496 (status = priv->status),
497 adap->timeout);
498 if (!result) {
499 status = -ETIMEDOUT;
500 dev_warn(&priv->pci_dev->dev,
501 "Timeout waiting for interrupt!\n");
502 }
Daniel Kurtz636752b2012-07-24 14:13:58 +0200503 priv->status = 0;
504 return i801_check_post(priv, status);
505 }
506
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200507 /* the current contents of SMBHSTCNT can be overwritten, since PEC,
Daniel Kurtz37af8712012-07-24 14:13:58 +0200508 * SMBSCMD are passed in xact */
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200509 outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
Jean Delvare6cad93c2012-07-24 14:13:58 +0200511 status = i801_wait_intr(priv);
512 return i801_check_post(priv, status);
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200513}
514
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100515static int i801_block_transaction_by_block(struct i801_priv *priv,
516 union i2c_smbus_data *data,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200517 char read_write, int hwpec)
518{
519 int i, len;
David Brownell97140342008-07-14 22:38:25 +0200520 int status;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200521
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100522 inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200523
524 /* Use 32-byte buffer to process this transaction */
525 if (read_write == I2C_SMBUS_WRITE) {
526 len = data->block[0];
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100527 outb_p(len, SMBHSTDAT0(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200528 for (i = 0; i < len; i++)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100529 outb_p(data->block[i+1], SMBBLKDAT(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200530 }
531
Daniel Kurtz37af8712012-07-24 14:13:58 +0200532 status = i801_transaction(priv, I801_BLOCK_DATA |
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200533 (hwpec ? SMBHSTCNT_PEC_EN : 0));
David Brownell97140342008-07-14 22:38:25 +0200534 if (status)
535 return status;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200536
537 if (read_write == I2C_SMBUS_READ) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100538 len = inb_p(SMBHSTDAT0(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200539 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
David Brownell97140342008-07-14 22:38:25 +0200540 return -EPROTO;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200541
542 data->block[0] = len;
543 for (i = 0; i < len; i++)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100544 data->block[i + 1] = inb_p(SMBBLKDAT(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200545 }
546 return 0;
547}
548
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200549static void i801_isr_byte_done(struct i801_priv *priv)
550{
551 if (priv->is_read) {
552 /* For SMBus block reads, length is received with first byte */
553 if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) &&
554 (priv->count == 0)) {
555 priv->len = inb_p(SMBHSTDAT0(priv));
556 if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) {
557 dev_err(&priv->pci_dev->dev,
558 "Illegal SMBus block read size %d\n",
559 priv->len);
560 /* FIXME: Recover */
561 priv->len = I2C_SMBUS_BLOCK_MAX;
562 } else {
563 dev_dbg(&priv->pci_dev->dev,
564 "SMBus block read size is %d\n",
565 priv->len);
566 }
567 priv->data[-1] = priv->len;
568 }
569
570 /* Read next byte */
571 if (priv->count < priv->len)
572 priv->data[priv->count++] = inb(SMBBLKDAT(priv));
573 else
574 dev_dbg(&priv->pci_dev->dev,
575 "Discarding extra byte on block read\n");
576
577 /* Set LAST_BYTE for last byte of read transaction */
578 if (priv->count == priv->len - 1)
579 outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE,
580 SMBHSTCNT(priv));
581 } else if (priv->count < priv->len - 1) {
582 /* Write next byte, except for IRQ after last byte */
583 outb_p(priv->data[++priv->count], SMBBLKDAT(priv));
584 }
585
586 /* Clear BYTE_DONE to continue with next byte */
587 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
588}
589
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200590static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
591{
592 unsigned short addr;
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200593
594 addr = inb_p(SMBNTFDADD(priv)) >> 1;
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200595
Benjamin Tissoiresc912a252016-10-13 14:10:39 +0200596 /*
597 * With the tested platforms, reading SMBNTFDDAT (22 + (p)->smba)
Benjamin Tissoires4d5538f2016-10-13 14:10:40 +0200598 * always returns 0. Our current implementation doesn't provide
599 * data, so we just ignore it.
Benjamin Tissoiresc912a252016-10-13 14:10:39 +0200600 */
Benjamin Tissoires4d5538f2016-10-13 14:10:40 +0200601 i2c_handle_smbus_host_notify(&priv->adapter, addr);
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200602
603 /* clear Host Notify bit and return */
604 outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
605 return IRQ_HANDLED;
606}
607
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200608/*
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200609 * There are three kinds of interrupts:
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200610 *
611 * 1) i801 signals transaction completion with one of these interrupts:
612 * INTR - Success
613 * DEV_ERR - Invalid command, NAK or communication timeout
614 * BUS_ERR - SMI# transaction collision
615 * FAILED - transaction was canceled due to a KILL request
616 * When any of these occur, update ->status and wake up the waitq.
617 * ->status must be cleared before kicking off the next transaction.
618 *
619 * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt
620 * occurs for each byte of a byte-by-byte to prepare the next byte.
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200621 *
622 * 3) Host Notify interrupts
Daniel Kurtz636752b2012-07-24 14:13:58 +0200623 */
624static irqreturn_t i801_isr(int irq, void *dev_id)
625{
626 struct i801_priv *priv = dev_id;
627 u16 pcists;
628 u8 status;
629
630 /* Confirm this is our interrupt */
631 pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
632 if (!(pcists & SMBPCISTS_INTS))
633 return IRQ_NONE;
634
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200635 if (priv->features & FEATURE_HOST_NOTIFY) {
636 status = inb_p(SMBSLVSTS(priv));
637 if (status & SMBSLVSTS_HST_NTFY_STS)
638 return i801_host_notify_isr(priv);
639 }
640
Daniel Kurtz636752b2012-07-24 14:13:58 +0200641 status = inb_p(SMBHSTSTS(priv));
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200642 if (status & SMBHSTSTS_BYTE_DONE)
643 i801_isr_byte_done(priv);
644
Daniel Kurtz636752b2012-07-24 14:13:58 +0200645 /*
646 * Clear irq sources and report transaction result.
647 * ->status must be cleared before the next transaction is started.
648 */
649 status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS;
650 if (status) {
651 outb_p(status, SMBHSTSTS(priv));
Jean Delvarea90bc5d2016-05-25 09:37:02 +0200652 priv->status = status;
Daniel Kurtz636752b2012-07-24 14:13:58 +0200653 wake_up(&priv->waitq);
654 }
655
656 return IRQ_HANDLED;
657}
658
659/*
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200660 * For "byte-by-byte" block transactions:
661 * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1
662 * I2C read uses cmd=I801_I2C_BLOCK_DATA
663 */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100664static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
665 union i2c_smbus_data *data,
Jean Delvare63420642008-01-27 18:14:50 +0100666 char read_write, int command,
667 int hwpec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668{
669 int i, len;
670 int smbcmd;
Jean Delvare2b738092008-07-14 22:38:32 +0200671 int status;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200672 int result;
Jean Delvareb3b8df92014-11-12 10:20:40 +0100673 const struct i2c_adapter *adap = &priv->adapter;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200674
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100675 result = i801_check_pre(priv);
Jean Delvarecf898dc2008-07-14 22:38:33 +0200676 if (result < 0)
677 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200679 len = data->block[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
681 if (read_write == I2C_SMBUS_WRITE) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100682 outb_p(len, SMBHSTDAT0(priv));
683 outb_p(data->block[1], SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 }
685
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200686 if (command == I2C_SMBUS_I2C_BLOCK_DATA &&
687 read_write == I2C_SMBUS_READ)
688 smbcmd = I801_I2C_BLOCK_DATA;
689 else
690 smbcmd = I801_BLOCK_DATA;
691
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200692 if (priv->features & FEATURE_IRQ) {
693 priv->is_read = (read_write == I2C_SMBUS_READ);
694 if (len == 1 && priv->is_read)
695 smbcmd |= SMBHSTCNT_LAST_BYTE;
696 priv->cmd = smbcmd | SMBHSTCNT_INTREN;
697 priv->len = len;
698 priv->count = 0;
699 priv->data = &data->block[1];
700
701 outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
Jean Delvareb3b8df92014-11-12 10:20:40 +0100702 result = wait_event_timeout(priv->waitq,
703 (status = priv->status),
704 adap->timeout);
705 if (!result) {
706 status = -ETIMEDOUT;
707 dev_warn(&priv->pci_dev->dev,
708 "Timeout waiting for interrupt!\n");
709 }
Daniel Kurtzd3ff6ce2012-07-24 14:13:59 +0200710 priv->status = 0;
711 return i801_check_post(priv, status);
712 }
713
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 for (i = 1; i <= len; i++) {
Daniel Kurtzefa3cb12012-07-24 14:13:57 +0200715 if (i == len && read_write == I2C_SMBUS_READ)
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200716 smbcmd |= SMBHSTCNT_LAST_BYTE;
Daniel Kurtz37af8712012-07-24 14:13:58 +0200717 outb_p(smbcmd, SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 if (i == 1)
Daniel Kurtzedbeea62012-07-24 14:13:58 +0200720 outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START,
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100721 SMBHSTCNT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
Jean Delvare6cad93c2012-07-24 14:13:58 +0200723 status = i801_wait_byte_done(priv);
724 if (status)
725 goto exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
Jean Delvare63420642008-01-27 18:14:50 +0100727 if (i == 1 && read_write == I2C_SMBUS_READ
728 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100729 len = inb_p(SMBHSTDAT0(priv));
Jean Delvarecf898dc2008-07-14 22:38:33 +0200730 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100731 dev_err(&priv->pci_dev->dev,
Jean Delvarecf898dc2008-07-14 22:38:33 +0200732 "Illegal SMBus block read size %d\n",
733 len);
734 /* Recover */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100735 while (inb_p(SMBHSTSTS(priv)) &
736 SMBHSTSTS_HOST_BUSY)
737 outb_p(SMBHSTSTS_BYTE_DONE,
738 SMBHSTSTS(priv));
739 outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
David Brownell97140342008-07-14 22:38:25 +0200740 return -EPROTO;
Jean Delvarecf898dc2008-07-14 22:38:33 +0200741 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 data->block[0] = len;
743 }
744
745 /* Retrieve/store value in SMBBLKDAT */
746 if (read_write == I2C_SMBUS_READ)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100747 data->block[i] = inb_p(SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100749 outb_p(data->block[i+1], SMBBLKDAT(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
Jean Delvarecf898dc2008-07-14 22:38:33 +0200751 /* signals SMBBLKDAT ready */
Jean Delvare6cad93c2012-07-24 14:13:58 +0200752 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200753 }
Jean Delvarecf898dc2008-07-14 22:38:33 +0200754
Jean Delvare6cad93c2012-07-24 14:13:58 +0200755 status = i801_wait_intr(priv);
756exit:
757 return i801_check_post(priv, status);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200758}
759
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100760static int i801_set_block_buffer_mode(struct i801_priv *priv)
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200761{
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100762 outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
763 if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0)
David Brownell97140342008-07-14 22:38:25 +0200764 return -EIO;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200765 return 0;
766}
767
768/* Block transaction function */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100769static int i801_block_transaction(struct i801_priv *priv,
770 union i2c_smbus_data *data, char read_write,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200771 int command, int hwpec)
772{
773 int result = 0;
774 unsigned char hostc;
775
776 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
777 if (read_write == I2C_SMBUS_WRITE) {
778 /* set I2C_EN bit in configuration register */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100779 pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
780 pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200781 hostc | SMBHSTCFG_I2C_EN);
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100782 } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
783 dev_err(&priv->pci_dev->dev,
Jean Delvare63420642008-01-27 18:14:50 +0100784 "I2C block read is unsupported!\n");
David Brownell97140342008-07-14 22:38:25 +0200785 return -EOPNOTSUPP;
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200786 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 }
788
Jean Delvare63420642008-01-27 18:14:50 +0100789 if (read_write == I2C_SMBUS_WRITE
790 || command == I2C_SMBUS_I2C_BLOCK_DATA) {
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200791 if (data->block[0] < 1)
792 data->block[0] = 1;
793 if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
794 data->block[0] = I2C_SMBUS_BLOCK_MAX;
795 } else {
Jean Delvare63420642008-01-27 18:14:50 +0100796 data->block[0] = 32; /* max for SMBus block reads */
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200797 }
798
Jean Delvarec074c392010-03-13 20:56:53 +0100799 /* Experience has shown that the block buffer can only be used for
800 SMBus (not I2C) block transactions, even though the datasheet
801 doesn't mention this limitation. */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100802 if ((priv->features & FEATURE_BLOCK_BUFFER)
Jean Delvarec074c392010-03-13 20:56:53 +0100803 && command != I2C_SMBUS_I2C_BLOCK_DATA
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100804 && i801_set_block_buffer_mode(priv) == 0)
805 result = i801_block_transaction_by_block(priv, data,
806 read_write, hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200807 else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100808 result = i801_block_transaction_byte_by_byte(priv, data,
809 read_write,
Jean Delvare63420642008-01-27 18:14:50 +0100810 command, hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200811
Jean Delvare63420642008-01-27 18:14:50 +0100812 if (command == I2C_SMBUS_I2C_BLOCK_DATA
813 && read_write == I2C_SMBUS_WRITE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 /* restore saved configuration register value */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100815 pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 }
817 return result;
818}
819
David Brownell97140342008-07-14 22:38:25 +0200820/* Return negative errno on error. */
Ivo Manca3fb21c62010-05-21 18:40:55 +0200821static s32 i801_access(struct i2c_adapter *adap, u16 addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 unsigned short flags, char read_write, u8 command,
Ivo Manca3fb21c62010-05-21 18:40:55 +0200823 int size, union i2c_smbus_data *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824{
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200825 int hwpec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 int block = 0;
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200827 int ret = 0, xact = 0;
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100828 struct i801_priv *priv = i2c_get_adapdata(adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
Mika Westerberga7ae8192016-06-09 16:56:28 +0300830 mutex_lock(&priv->acpi_lock);
831 if (priv->acpi_reserved) {
832 mutex_unlock(&priv->acpi_lock);
833 return -EBUSY;
834 }
835
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200836 pm_runtime_get_sync(&priv->pci_dev->dev);
837
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100838 hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200839 && size != I2C_SMBUS_QUICK
840 && size != I2C_SMBUS_I2C_BLOCK_DATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842 switch (size) {
843 case I2C_SMBUS_QUICK:
844 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100845 SMBHSTADD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 xact = I801_QUICK;
847 break;
848 case I2C_SMBUS_BYTE:
849 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100850 SMBHSTADD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 if (read_write == I2C_SMBUS_WRITE)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100852 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 xact = I801_BYTE;
854 break;
855 case I2C_SMBUS_BYTE_DATA:
856 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100857 SMBHSTADD(priv));
858 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 if (read_write == I2C_SMBUS_WRITE)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100860 outb_p(data->byte, SMBHSTDAT0(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 xact = I801_BYTE_DATA;
862 break;
863 case I2C_SMBUS_WORD_DATA:
864 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100865 SMBHSTADD(priv));
866 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 if (read_write == I2C_SMBUS_WRITE) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100868 outb_p(data->word & 0xff, SMBHSTDAT0(priv));
869 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 }
871 xact = I801_WORD_DATA;
872 break;
873 case I2C_SMBUS_BLOCK_DATA:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100875 SMBHSTADD(priv));
876 outb_p(command, SMBHSTCMD(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 block = 1;
878 break;
Jean Delvare63420642008-01-27 18:14:50 +0100879 case I2C_SMBUS_I2C_BLOCK_DATA:
Jean Delvareba9ad2a2016-10-11 13:13:27 +0200880 /*
881 * NB: page 240 of ICH5 datasheet shows that the R/#W
882 * bit should be cleared here, even when reading.
883 * However if SPD Write Disable is set (Lynx Point and later),
884 * the read will fail if we don't set the R/#W bit.
885 */
886 outb_p(((addr & 0x7f) << 1) |
887 ((priv->original_hstcfg & SMBHSTCFG_SPD_WD) ?
888 (read_write & 0x01) : 0),
889 SMBHSTADD(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100890 if (read_write == I2C_SMBUS_READ) {
891 /* NB: page 240 of ICH5 datasheet also shows
892 * that DATA1 is the cmd field when reading */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100893 outb_p(command, SMBHSTDAT1(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100894 } else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100895 outb_p(command, SMBHSTCMD(priv));
Jean Delvare63420642008-01-27 18:14:50 +0100896 block = 1;
897 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 default:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100899 dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
900 size);
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200901 ret = -EOPNOTSUPP;
902 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 }
904
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200905 if (hwpec) /* enable/disable hardware PEC */
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100906 outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
Oleg Ryjkovca8b9e32007-07-12 14:12:31 +0200907 else
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100908 outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
909 SMBAUXCTL(priv));
Jean Delvaree8aac4a2005-10-26 21:34:42 +0200910
Ivo Manca3fb21c62010-05-21 18:40:55 +0200911 if (block)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100912 ret = i801_block_transaction(priv, data, read_write, size,
913 hwpec);
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200914 else
Daniel Kurtz37af8712012-07-24 14:13:58 +0200915 ret = i801_transaction(priv, xact);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
Jean Delvarec79cfba2006-04-20 02:43:18 -0700917 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
Oleg Ryjkov7edcb9a2007-07-12 14:12:31 +0200918 time, so we forcibly disable it after every transaction. Turn off
919 E32B for the same reason. */
Jean Delvarea0921b62008-01-27 18:14:50 +0100920 if (hwpec || block)
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100921 outb_p(inb_p(SMBAUXCTL(priv)) &
922 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
Jean Delvarec79cfba2006-04-20 02:43:18 -0700923
Ivo Manca3fb21c62010-05-21 18:40:55 +0200924 if (block)
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200925 goto out;
Ivo Manca3fb21c62010-05-21 18:40:55 +0200926 if (ret)
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200927 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200929 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931 switch (xact & 0x7f) {
932 case I801_BYTE: /* Result put in SMBHSTDAT0 */
933 case I801_BYTE_DATA:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100934 data->byte = inb_p(SMBHSTDAT0(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 break;
936 case I801_WORD_DATA:
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100937 data->word = inb_p(SMBHSTDAT0(priv)) +
938 (inb_p(SMBHSTDAT1(priv)) << 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 break;
940 }
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200941
942out:
943 pm_runtime_mark_last_busy(&priv->pci_dev->dev);
944 pm_runtime_put_autosuspend(&priv->pci_dev->dev);
Mika Westerberga7ae8192016-06-09 16:56:28 +0300945 mutex_unlock(&priv->acpi_lock);
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +0200946 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947}
948
949
950static u32 i801_func(struct i2c_adapter *adapter)
951{
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100952 struct i801_priv *priv = i2c_get_adapdata(adapter);
953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
Jean Delvare369f6f42008-01-27 18:14:50 +0100955 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
956 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
David Woodhouse0cd96eb2010-10-31 21:06:59 +0100957 ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
958 ((priv->features & FEATURE_I2C_BLOCK_READ) ?
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200959 I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0) |
960 ((priv->features & FEATURE_HOST_NOTIFY) ?
961 I2C_FUNC_SMBUS_HOST_NOTIFY : 0);
962}
963
Benjamin Tissoires4d5538f2016-10-13 14:10:40 +0200964static void i801_enable_host_notify(struct i2c_adapter *adapter)
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200965{
966 struct i801_priv *priv = i2c_get_adapdata(adapter);
967
968 if (!(priv->features & FEATURE_HOST_NOTIFY))
Benjamin Tissoires4d5538f2016-10-13 14:10:40 +0200969 return;
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200970
Benjamin Tissoires22e94bd2016-10-13 14:10:35 +0200971 if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd))
972 outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd,
973 SMBSLVCMD(priv));
974
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +0200975 /* clear Host Notify bit to allow a new notification */
976 outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977}
978
Benjamin Tissoires22e94bd2016-10-13 14:10:35 +0200979static void i801_disable_host_notify(struct i801_priv *priv)
980{
981 if (!(priv->features & FEATURE_HOST_NOTIFY))
982 return;
983
984 outb_p(priv->original_slvcmd, SMBSLVCMD(priv));
985}
986
Jean Delvare8f9082c2006-09-03 22:39:46 +0200987static const struct i2c_algorithm smbus_algorithm = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 .smbus_xfer = i801_access,
989 .functionality = i801_func,
990};
991
Jingoo Han392debf2013-12-03 08:11:20 +0900992static const struct pci_device_id i801_ids[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
994 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
995 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
996 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
997 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
998 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
999 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
1000 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
1001 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
Jason Gastonb0a70b52005-04-16 15:24:45 -07001002 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
Jason Gaston8254fc42006-01-09 10:58:08 -08001003 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
Jason Gastonadbc2a12006-11-22 15:19:12 -08001004 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
Seth Heasleycb04e952010-10-04 13:27:14 -07001005 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) },
Gaston, Jason Dd28dc712008-02-24 20:03:42 +01001006 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
1007 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
Seth Heasleycb04e952010-10-04 13:27:14 -07001008 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) },
1009 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) },
Seth Heasleye30d9852010-10-31 21:06:59 +01001010 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) },
David Woodhouse55fee8d2010-10-31 21:07:00 +01001011 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) },
1012 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
1013 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
Seth Heasley662cda82011-03-20 14:50:53 +01001014 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },
Seth Heasley6e2a8512011-05-24 20:58:49 +02001015 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
Seth Heasley062737f2012-03-26 21:47:19 +02001016 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) },
James Ralston4a8f1dd2012-09-10 10:14:02 +02001017 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) },
Seth Heasleyc2db409c2013-01-30 15:25:32 +00001018 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) },
James Ralstona3fc0ff2013-02-14 09:15:33 +00001019 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS) },
1020 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) },
1021 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },
1022 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
Seth Heasleyf39901c2013-06-19 16:59:57 -07001023 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) },
Mika Westerberg9827f9e2017-02-01 19:20:59 +03001024 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS) },
Jean Delvareb299de82014-07-17 15:04:41 +02001025 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) },
James Ralstonafc65922013-11-04 09:29:48 -08001026 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) },
Chew, Kean ho1b31e9b2014-03-01 00:03:56 +08001027 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) },
Alan Cox39e8e302014-08-19 17:37:28 +03001028 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) },
james.d.ralston@intel.com3e27a842014-10-13 15:20:24 -07001029 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) },
Devin Ryles3eee17992014-11-05 16:30:03 -05001030 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) },
Jarkko Nikulacb09d942017-09-21 16:23:16 +03001031 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) },
Mika Westerberg84d7f2e2015-10-13 15:41:39 +03001032 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) },
Jarkko Nikuladd77f422015-10-22 17:16:58 +03001033 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) },
Alexandra Yatescdc5a312015-11-05 11:40:25 -08001034 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) },
1035 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) },
Andy Shevchenko31158762016-09-23 11:56:01 +03001036 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS) },
Srinivas Pandruvada09a1de02017-05-18 11:23:06 +03001037 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS) },
1038 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) },
Mika Westerberg0bff2a82018-06-28 16:08:24 +03001039 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 { 0, }
1041};
1042
Ivo Manca3fb21c62010-05-21 18:40:55 +02001043MODULE_DEVICE_TABLE(pci, i801_ids);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044
Jean Delvare8eacfce2011-05-24 20:58:49 +02001045#if defined CONFIG_X86 && defined CONFIG_DMI
Jean Delvare1561bfe2009-01-07 14:29:17 +01001046static unsigned char apanel_addr;
1047
1048/* Scan the system ROM for the signature "FJKEYINF" */
1049static __init const void __iomem *bios_signature(const void __iomem *bios)
1050{
1051 ssize_t offset;
1052 const unsigned char signature[] = "FJKEYINF";
1053
1054 for (offset = 0; offset < 0x10000; offset += 0x10) {
1055 if (check_signature(bios + offset, signature,
1056 sizeof(signature)-1))
1057 return bios + offset;
1058 }
1059 return NULL;
1060}
1061
1062static void __init input_apanel_init(void)
1063{
1064 void __iomem *bios;
1065 const void __iomem *p;
1066
1067 bios = ioremap(0xF0000, 0x10000); /* Can't fail */
1068 p = bios_signature(bios);
1069 if (p) {
1070 /* just use the first address */
1071 apanel_addr = readb(p + 8 + 3) >> 1;
1072 }
1073 iounmap(bios);
1074}
Jean Delvare1561bfe2009-01-07 14:29:17 +01001075
Hans de Goedefa5bfab2009-03-30 21:46:44 +02001076struct dmi_onboard_device_info {
1077 const char *name;
1078 u8 type;
1079 unsigned short i2c_addr;
1080 const char *i2c_type;
1081};
1082
Bill Pemberton0b255e92012-11-27 15:59:38 -05001083static const struct dmi_onboard_device_info dmi_devices[] = {
Hans de Goedefa5bfab2009-03-30 21:46:44 +02001084 { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
1085 { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
1086 { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
1087};
1088
Bill Pemberton0b255e92012-11-27 15:59:38 -05001089static void dmi_check_onboard_device(u8 type, const char *name,
1090 struct i2c_adapter *adap)
Hans de Goedefa5bfab2009-03-30 21:46:44 +02001091{
1092 int i;
1093 struct i2c_board_info info;
1094
1095 for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
1096 /* & ~0x80, ignore enabled/disabled bit */
1097 if ((type & ~0x80) != dmi_devices[i].type)
1098 continue;
Jean Delvarefaabd472010-07-09 16:22:51 +02001099 if (strcasecmp(name, dmi_devices[i].name))
Hans de Goedefa5bfab2009-03-30 21:46:44 +02001100 continue;
1101
1102 memset(&info, 0, sizeof(struct i2c_board_info));
1103 info.addr = dmi_devices[i].i2c_addr;
1104 strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
1105 i2c_new_device(adap, &info);
1106 break;
1107 }
1108}
1109
1110/* We use our own function to check for onboard devices instead of
1111 dmi_find_device() as some buggy BIOS's have the devices we are interested
1112 in marked as disabled */
Bill Pemberton0b255e92012-11-27 15:59:38 -05001113static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap)
Hans de Goedefa5bfab2009-03-30 21:46:44 +02001114{
1115 int i, count;
1116
1117 if (dm->type != 10)
1118 return;
1119
1120 count = (dm->length - sizeof(struct dmi_header)) / 2;
1121 for (i = 0; i < count; i++) {
1122 const u8 *d = (char *)(dm + 1) + (i * 2);
1123 const char *name = ((char *) dm) + dm->length;
1124 u8 type = d[0];
1125 u8 s = d[1];
1126
1127 if (!s)
1128 continue;
1129 s--;
1130 while (s > 0 && name[0]) {
1131 name += strlen(name) + 1;
1132 s--;
1133 }
1134 if (name[0] == 0) /* Bogus string reference */
1135 continue;
1136
1137 dmi_check_onboard_device(type, name, adap);
1138 }
1139}
Hans de Goedefa5bfab2009-03-30 21:46:44 +02001140
Jean Delvaree7198fb2011-05-24 20:58:49 +02001141/* Register optional slaves */
Bill Pemberton0b255e92012-11-27 15:59:38 -05001142static void i801_probe_optional_slaves(struct i801_priv *priv)
Jean Delvaree7198fb2011-05-24 20:58:49 +02001143{
1144 /* Only register slaves on main SMBus channel */
1145 if (priv->features & FEATURE_IDF)
1146 return;
1147
Jean Delvaree7198fb2011-05-24 20:58:49 +02001148 if (apanel_addr) {
1149 struct i2c_board_info info;
1150
1151 memset(&info, 0, sizeof(struct i2c_board_info));
1152 info.addr = apanel_addr;
1153 strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
1154 i2c_new_device(&priv->adapter, &info);
1155 }
Jean Delvare8eacfce2011-05-24 20:58:49 +02001156
Jean Delvaree7198fb2011-05-24 20:58:49 +02001157 if (dmi_name_in_vendors("FUJITSU"))
1158 dmi_walk(dmi_check_onboard_devices, &priv->adapter);
Jean Delvaree7198fb2011-05-24 20:58:49 +02001159}
Jean Delvare8eacfce2011-05-24 20:58:49 +02001160#else
1161static void __init input_apanel_init(void) {}
Bill Pemberton0b255e92012-11-27 15:59:38 -05001162static void i801_probe_optional_slaves(struct i801_priv *priv) {}
Jean Delvare8eacfce2011-05-24 20:58:49 +02001163#endif /* CONFIG_X86 && CONFIG_DMI */
Jean Delvaree7198fb2011-05-24 20:58:49 +02001164
Javier Martinez Canillas175c7082016-07-21 12:11:01 -04001165#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001166static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
1167 .gpio_chip = "gpio_ich",
1168 .values = { 0x02, 0x03 },
1169 .n_values = 2,
1170 .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
1171 .gpios = { 52, 53 },
1172 .n_gpios = 2,
1173};
1174
1175static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
1176 .gpio_chip = "gpio_ich",
1177 .values = { 0x02, 0x03, 0x01 },
1178 .n_values = 3,
1179 .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
1180 .gpios = { 52, 53 },
1181 .n_gpios = 2,
1182};
1183
Bill Pemberton0b255e92012-11-27 15:59:38 -05001184static const struct dmi_system_id mux_dmi_table[] = {
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001185 {
1186 .matches = {
1187 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1188 DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"),
1189 },
1190 .driver_data = &i801_mux_config_asus_z8_d12,
1191 },
1192 {
1193 .matches = {
1194 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1195 DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"),
1196 },
1197 .driver_data = &i801_mux_config_asus_z8_d12,
1198 },
1199 {
1200 .matches = {
1201 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1202 DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"),
1203 },
1204 .driver_data = &i801_mux_config_asus_z8_d12,
1205 },
1206 {
1207 .matches = {
1208 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1209 DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"),
1210 },
1211 .driver_data = &i801_mux_config_asus_z8_d12,
1212 },
1213 {
1214 .matches = {
1215 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1216 DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"),
1217 },
1218 .driver_data = &i801_mux_config_asus_z8_d12,
1219 },
1220 {
1221 .matches = {
1222 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1223 DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"),
1224 },
1225 .driver_data = &i801_mux_config_asus_z8_d12,
1226 },
1227 {
1228 .matches = {
1229 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1230 DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"),
1231 },
1232 .driver_data = &i801_mux_config_asus_z8_d18,
1233 },
1234 {
1235 .matches = {
1236 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1237 DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"),
1238 },
1239 .driver_data = &i801_mux_config_asus_z8_d18,
1240 },
1241 {
1242 .matches = {
1243 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1244 DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"),
1245 },
1246 .driver_data = &i801_mux_config_asus_z8_d12,
1247 },
1248 { }
1249};
1250
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001251/* Setup multiplexing if needed */
Bill Pemberton0b255e92012-11-27 15:59:38 -05001252static int i801_add_mux(struct i801_priv *priv)
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001253{
1254 struct device *dev = &priv->adapter.dev;
1255 const struct i801_mux_config *mux_config;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001256 struct i2c_mux_gpio_platform_data gpio_data;
Jean Delvaref82b8622012-10-05 22:23:54 +02001257 int err;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001258
1259 if (!priv->mux_drvdata)
1260 return 0;
1261 mux_config = priv->mux_drvdata;
1262
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001263 /* Prepare the platform data */
1264 memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
1265 gpio_data.parent = priv->adapter.nr;
1266 gpio_data.values = mux_config->values;
1267 gpio_data.n_values = mux_config->n_values;
1268 gpio_data.classes = mux_config->classes;
Jean Delvaref82b8622012-10-05 22:23:54 +02001269 gpio_data.gpio_chip = mux_config->gpio_chip;
1270 gpio_data.gpios = mux_config->gpios;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001271 gpio_data.n_gpios = mux_config->n_gpios;
1272 gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
1273
1274 /* Register the mux device */
1275 priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
Jean Delvaref82b8622012-10-05 22:23:54 +02001276 PLATFORM_DEVID_AUTO, &gpio_data,
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001277 sizeof(struct i2c_mux_gpio_platform_data));
1278 if (IS_ERR(priv->mux_pdev)) {
1279 err = PTR_ERR(priv->mux_pdev);
1280 priv->mux_pdev = NULL;
1281 dev_err(dev, "Failed to register i2c-mux-gpio device\n");
1282 return err;
1283 }
1284
1285 return 0;
1286}
1287
Bill Pemberton0b255e92012-11-27 15:59:38 -05001288static void i801_del_mux(struct i801_priv *priv)
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001289{
1290 if (priv->mux_pdev)
1291 platform_device_unregister(priv->mux_pdev);
1292}
1293
Bill Pemberton0b255e92012-11-27 15:59:38 -05001294static unsigned int i801_get_adapter_class(struct i801_priv *priv)
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001295{
1296 const struct dmi_system_id *id;
1297 const struct i801_mux_config *mux_config;
1298 unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
1299 int i;
1300
1301 id = dmi_first_match(mux_dmi_table);
1302 if (id) {
Jean Delvare28901f52012-10-28 21:37:01 +01001303 /* Remove branch classes from trunk */
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001304 mux_config = id->driver_data;
1305 for (i = 0; i < mux_config->n_values; i++)
1306 class &= ~mux_config->classes[i];
1307
1308 /* Remember for later */
1309 priv->mux_drvdata = mux_config;
1310 }
1311
1312 return class;
1313}
1314#else
1315static inline int i801_add_mux(struct i801_priv *priv) { return 0; }
1316static inline void i801_del_mux(struct i801_priv *priv) { }
1317
1318static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
1319{
1320 return I2C_CLASS_HWMON | I2C_CLASS_SPD;
1321}
1322#endif
1323
Mika Westerberg94246932015-08-06 13:46:25 +01001324static const struct itco_wdt_platform_data tco_platform_data = {
1325 .name = "Intel PCH",
1326 .version = 4,
1327};
1328
1329static DEFINE_SPINLOCK(p2sb_spinlock);
1330
1331static void i801_add_tco(struct i801_priv *priv)
1332{
1333 struct pci_dev *pci_dev = priv->pci_dev;
1334 struct resource tco_res[3], *res;
1335 struct platform_device *pdev;
1336 unsigned int devfn;
1337 u32 tco_base, tco_ctl;
1338 u32 base_addr, ctrl_val;
1339 u64 base64_addr;
Qiuxu Zhuobfd44732017-08-15 00:04:50 +08001340 u8 hidden;
Mika Westerberg94246932015-08-06 13:46:25 +01001341
1342 if (!(priv->features & FEATURE_TCO))
1343 return;
1344
1345 pci_read_config_dword(pci_dev, TCOBASE, &tco_base);
1346 pci_read_config_dword(pci_dev, TCOCTL, &tco_ctl);
1347 if (!(tco_ctl & TCOCTL_EN))
1348 return;
1349
1350 memset(tco_res, 0, sizeof(tco_res));
1351
1352 res = &tco_res[ICH_RES_IO_TCO];
1353 res->start = tco_base & ~1;
1354 res->end = res->start + 32 - 1;
1355 res->flags = IORESOURCE_IO;
1356
1357 /*
1358 * Power Management registers.
1359 */
1360 devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2);
1361 pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr);
1362
1363 res = &tco_res[ICH_RES_IO_SMI];
1364 res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF;
1365 res->end = res->start + 3;
1366 res->flags = IORESOURCE_IO;
1367
1368 /*
1369 * Enable the ACPI I/O space.
1370 */
1371 pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val);
1372 ctrl_val |= ACPICTRL_EN;
1373 pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val);
1374
1375 /*
1376 * We must access the NO_REBOOT bit over the Primary to Sideband
1377 * bridge (P2SB). The BIOS prevents the P2SB device from being
1378 * enumerated by the PCI subsystem, so we need to unhide/hide it
1379 * to lookup the P2SB BAR.
1380 */
1381 spin_lock(&p2sb_spinlock);
1382
1383 devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 1);
1384
Qiuxu Zhuobfd44732017-08-15 00:04:50 +08001385 /* Unhide the P2SB device, if it is hidden */
1386 pci_bus_read_config_byte(pci_dev->bus, devfn, 0xe1, &hidden);
1387 if (hidden)
1388 pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, 0x0);
Mika Westerberg94246932015-08-06 13:46:25 +01001389
1390 pci_bus_read_config_dword(pci_dev->bus, devfn, SBREG_BAR, &base_addr);
1391 base64_addr = base_addr & 0xfffffff0;
1392
1393 pci_bus_read_config_dword(pci_dev->bus, devfn, SBREG_BAR + 0x4, &base_addr);
1394 base64_addr |= (u64)base_addr << 32;
1395
Qiuxu Zhuobfd44732017-08-15 00:04:50 +08001396 /* Hide the P2SB device, if it was hidden before */
1397 if (hidden)
1398 pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden);
Mika Westerberg94246932015-08-06 13:46:25 +01001399 spin_unlock(&p2sb_spinlock);
1400
1401 res = &tco_res[ICH_RES_MEM_OFF];
1402 res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL;
1403 res->end = res->start + 3;
1404 res->flags = IORESOURCE_MEM;
1405
1406 pdev = platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
1407 tco_res, 3, &tco_platform_data,
1408 sizeof(tco_platform_data));
1409 if (IS_ERR(pdev)) {
1410 dev_warn(&pci_dev->dev, "failed to create iTCO device\n");
1411 return;
1412 }
1413
1414 priv->tco_pdev = pdev;
1415}
1416
Mika Westerberga7ae8192016-06-09 16:56:28 +03001417#ifdef CONFIG_ACPI
1418static acpi_status
1419i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
1420 u64 *value, void *handler_context, void *region_context)
1421{
1422 struct i801_priv *priv = handler_context;
1423 struct pci_dev *pdev = priv->pci_dev;
1424 acpi_status status;
1425
1426 /*
1427 * Once BIOS AML code touches the OpRegion we warn and inhibit any
1428 * further access from the driver itself. This device is now owned
1429 * by the system firmware.
1430 */
1431 mutex_lock(&priv->acpi_lock);
1432
1433 if (!priv->acpi_reserved) {
1434 priv->acpi_reserved = true;
1435
1436 dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
1437 dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n");
1438
1439 /*
1440 * BIOS is accessing the host controller so prevent it from
1441 * suspending automatically from now on.
1442 */
1443 pm_runtime_get_sync(&pdev->dev);
1444 }
1445
1446 if ((function & ACPI_IO_MASK) == ACPI_READ)
1447 status = acpi_os_read_port(address, (u32 *)value, bits);
1448 else
1449 status = acpi_os_write_port(address, (u32)*value, bits);
1450
1451 mutex_unlock(&priv->acpi_lock);
1452
1453 return status;
1454}
1455
1456static int i801_acpi_probe(struct i801_priv *priv)
1457{
1458 struct acpi_device *adev;
1459 acpi_status status;
1460
1461 adev = ACPI_COMPANION(&priv->pci_dev->dev);
1462 if (adev) {
1463 status = acpi_install_address_space_handler(adev->handle,
1464 ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler,
1465 NULL, priv);
1466 if (ACPI_SUCCESS(status))
1467 return 0;
1468 }
1469
1470 return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]);
1471}
1472
1473static void i801_acpi_remove(struct i801_priv *priv)
1474{
1475 struct acpi_device *adev;
1476
1477 adev = ACPI_COMPANION(&priv->pci_dev->dev);
1478 if (!adev)
1479 return;
1480
1481 acpi_remove_address_space_handler(adev->handle,
1482 ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler);
1483
1484 mutex_lock(&priv->acpi_lock);
1485 if (priv->acpi_reserved)
1486 pm_runtime_put(&priv->pci_dev->dev);
1487 mutex_unlock(&priv->acpi_lock);
1488}
1489#else
1490static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
1491static inline void i801_acpi_remove(struct i801_priv *priv) { }
1492#endif
1493
Bill Pemberton0b255e92012-11-27 15:59:38 -05001494static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495{
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001496 unsigned char temp;
Jean Delvareadff6872010-05-21 18:40:54 +02001497 int err, i;
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001498 struct i801_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499
Jarkko Nikula1621c592015-02-13 15:52:23 +02001500 priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001501 if (!priv)
1502 return -ENOMEM;
1503
1504 i2c_set_adapdata(&priv->adapter, priv);
1505 priv->adapter.owner = THIS_MODULE;
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001506 priv->adapter.class = i801_get_adapter_class(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001507 priv->adapter.algo = &smbus_algorithm;
Dustin Byford8eb5c872015-10-23 12:27:07 -07001508 priv->adapter.dev.parent = &dev->dev;
1509 ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev));
1510 priv->adapter.retries = 3;
Mika Westerberga7ae8192016-06-09 16:56:28 +03001511 mutex_init(&priv->acpi_lock);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001512
1513 priv->pci_dev = dev;
Jean Delvare250d1bd2006-12-10 21:21:33 +01001514 switch (dev->device) {
Mika Westerberg94246932015-08-06 13:46:25 +01001515 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS:
1516 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS:
Srinivas Pandruvada09a1de02017-05-18 11:23:06 +03001517 case PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS:
1518 case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS:
Alexandra Yates1a1503c2016-02-17 18:21:21 -08001519 case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS:
1520 case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS:
Jarkko Nikulacb09d942017-09-21 16:23:16 +03001521 case PCI_DEVICE_ID_INTEL_CDF_SMBUS:
Mika Westerberg84d7f2e2015-10-13 15:41:39 +03001522 case PCI_DEVICE_ID_INTEL_DNV_SMBUS:
Andy Shevchenko31158762016-09-23 11:56:01 +03001523 case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS:
Mika Westerberg0bff2a82018-06-28 16:08:24 +03001524 case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS:
Mika Westerberg94246932015-08-06 13:46:25 +01001525 priv->features |= FEATURE_I2C_BLOCK_READ;
1526 priv->features |= FEATURE_IRQ;
1527 priv->features |= FEATURE_SMBUS_PEC;
1528 priv->features |= FEATURE_BLOCK_BUFFER;
Mika Westerberg1f6dbb02016-09-20 15:30:53 +03001529 /* If we have ACPI based watchdog use that instead */
1530 if (!acpi_has_watchdog())
1531 priv->features |= FEATURE_TCO;
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +02001532 priv->features |= FEATURE_HOST_NOTIFY;
Mika Westerberg94246932015-08-06 13:46:25 +01001533 break;
1534
Jean Delvaree7198fb2011-05-24 20:58:49 +02001535 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0:
1536 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1:
1537 case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2:
James Ralstona3fc0ff2013-02-14 09:15:33 +00001538 case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0:
1539 case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1:
1540 case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2:
Jean Delvaree7198fb2011-05-24 20:58:49 +02001541 priv->features |= FEATURE_IDF;
1542 /* fall through */
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001543 default:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001544 priv->features |= FEATURE_I2C_BLOCK_READ;
Jean Delvare6676a842012-12-16 21:11:55 +01001545 priv->features |= FEATURE_IRQ;
Jean Delvare63420642008-01-27 18:14:50 +01001546 /* fall through */
1547 case PCI_DEVICE_ID_INTEL_82801DB_3:
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001548 priv->features |= FEATURE_SMBUS_PEC;
1549 priv->features |= FEATURE_BLOCK_BUFFER;
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001550 /* fall through */
1551 case PCI_DEVICE_ID_INTEL_82801CA_3:
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +02001552 priv->features |= FEATURE_HOST_NOTIFY;
1553 /* fall through */
Jean Delvaree0e8398c2010-05-21 18:40:55 +02001554 case PCI_DEVICE_ID_INTEL_82801BA_2:
1555 case PCI_DEVICE_ID_INTEL_82801AB_3:
1556 case PCI_DEVICE_ID_INTEL_82801AA_3:
Jean Delvare250d1bd2006-12-10 21:21:33 +01001557 break;
Jean Delvare250d1bd2006-12-10 21:21:33 +01001558 }
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001559
Jean Delvareadff6872010-05-21 18:40:54 +02001560 /* Disable features on user request */
1561 for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001562 if (priv->features & disable_features & (1 << i))
Jean Delvareadff6872010-05-21 18:40:54 +02001563 dev_notice(&dev->dev, "%s disabled by user\n",
1564 i801_feature_names[i]);
1565 }
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001566 priv->features &= ~disable_features;
Jean Delvareadff6872010-05-21 18:40:54 +02001567
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001568 err = pcim_enable_device(dev);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001569 if (err) {
1570 dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
1571 err);
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001572 return err;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001573 }
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001574 pcim_pin_device(dev);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001575
1576 /* Determine the address of the SMBus area */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001577 priv->smba = pci_resource_start(dev, SMBBAR);
1578 if (!priv->smba) {
Jarkko Nikula9cbbf3d2015-02-13 15:52:21 +02001579 dev_err(&dev->dev,
1580 "SMBus base address uninitialized, upgrade BIOS\n");
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001581 return -ENODEV;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001582 }
1583
Mika Westerberga7ae8192016-06-09 16:56:28 +03001584 if (i801_acpi_probe(priv))
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001585 return -ENODEV;
Jean Delvare54fb4a052008-07-14 22:38:33 +02001586
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001587 err = pcim_iomap_regions(dev, 1 << SMBBAR,
1588 dev_driver_string(&dev->dev));
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001589 if (err) {
Jarkko Nikula9cbbf3d2015-02-13 15:52:21 +02001590 dev_err(&dev->dev,
1591 "Failed to request SMBus region 0x%lx-0x%Lx\n",
1592 priv->smba,
Andrew Morton598736c2006-06-30 01:56:20 -07001593 (unsigned long long)pci_resource_end(dev, SMBBAR));
Mika Westerberga7ae8192016-06-09 16:56:28 +03001594 i801_acpi_remove(priv);
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001595 return err;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001596 }
1597
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001598 pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
1599 priv->original_hstcfg = temp;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001600 temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
1601 if (!(temp & SMBHSTCFG_HST_EN)) {
1602 dev_info(&dev->dev, "Enabling SMBus device\n");
1603 temp |= SMBHSTCFG_HST_EN;
1604 }
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001605 pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001606
Daniel Kurtz636752b2012-07-24 14:13:58 +02001607 if (temp & SMBHSTCFG_SMB_SMI_EN) {
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001608 dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001609 /* Disable SMBus interrupt feature if SMBus using SMI# */
1610 priv->features &= ~FEATURE_IRQ;
Daniel Kurtz636752b2012-07-24 14:13:58 +02001611 }
Jean Delvareba9ad2a2016-10-11 13:13:27 +02001612 if (temp & SMBHSTCFG_SPD_WD)
1613 dev_info(&dev->dev, "SPD Write Disable is set\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
Jean Delvarea0921b62008-01-27 18:14:50 +01001615 /* Clear special mode bits */
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001616 if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
1617 outb_p(inb_p(SMBAUXCTL(priv)) &
1618 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
Jean Delvarea0921b62008-01-27 18:14:50 +01001619
Jean Delvarea086bb82018-04-11 18:03:31 +02001620 /* Remember original Host Notify setting */
1621 if (priv->features & FEATURE_HOST_NOTIFY)
1622 priv->original_slvcmd = inb_p(SMBSLVCMD(priv));
1623
Jean Delvareb3b8df92014-11-12 10:20:40 +01001624 /* Default timeout in interrupt mode: 200 ms */
1625 priv->adapter.timeout = HZ / 5;
1626
Hans de Goede6e0c9502017-11-22 12:28:17 +01001627 if (dev->irq == IRQ_NOTCONNECTED)
1628 priv->features &= ~FEATURE_IRQ;
1629
Daniel Kurtz636752b2012-07-24 14:13:58 +02001630 if (priv->features & FEATURE_IRQ) {
Jean Delvareaeb8a3d2014-11-12 10:25:37 +01001631 u16 pcictl, pcists;
1632
1633 /* Complain if an interrupt is already pending */
1634 pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
1635 if (pcists & SMBPCISTS_INTS)
1636 dev_warn(&dev->dev, "An interrupt is pending!\n");
1637
1638 /* Check if interrupts have been disabled */
1639 pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl);
1640 if (pcictl & SMBPCICTL_INTDIS) {
1641 dev_info(&dev->dev, "Interrupts are disabled\n");
1642 priv->features &= ~FEATURE_IRQ;
1643 }
1644 }
1645
1646 if (priv->features & FEATURE_IRQ) {
Daniel Kurtz636752b2012-07-24 14:13:58 +02001647 init_waitqueue_head(&priv->waitq);
1648
Jarkko Nikula1621c592015-02-13 15:52:23 +02001649 err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
1650 IRQF_SHARED,
1651 dev_driver_string(&dev->dev), priv);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001652 if (err) {
1653 dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
1654 dev->irq, err);
Jean Delvareae944712014-11-12 10:24:07 +01001655 priv->features &= ~FEATURE_IRQ;
Daniel Kurtz636752b2012-07-24 14:13:58 +02001656 }
1657 }
Jean Delvareae944712014-11-12 10:24:07 +01001658 dev_info(&dev->dev, "SMBus using %s\n",
1659 priv->features & FEATURE_IRQ ? "PCI interrupt" : "polling");
Daniel Kurtz636752b2012-07-24 14:13:58 +02001660
Mika Westerberg94246932015-08-06 13:46:25 +01001661 i801_add_tco(priv);
1662
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001663 snprintf(priv->adapter.name, sizeof(priv->adapter.name),
1664 "SMBus I801 adapter at %04lx", priv->smba);
1665 err = i2c_add_adapter(&priv->adapter);
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001666 if (err) {
Mika Westerberga7ae8192016-06-09 16:56:28 +03001667 i801_acpi_remove(priv);
Jarkko Nikulafef220d2015-02-13 15:52:25 +02001668 return err;
Jean Delvare02dd7ae2006-06-12 21:53:41 +02001669 }
Jean Delvare1561bfe2009-01-07 14:29:17 +01001670
Benjamin Tissoires4d5538f2016-10-13 14:10:40 +02001671 i801_enable_host_notify(&priv->adapter);
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +02001672
Jean Delvaree7198fb2011-05-24 20:58:49 +02001673 i801_probe_optional_slaves(priv);
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001674 /* We ignore errors - multiplexing is optional */
1675 i801_add_mux(priv);
Jean Delvare1561bfe2009-01-07 14:29:17 +01001676
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001677 pci_set_drvdata(dev, priv);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001678
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +02001679 pm_runtime_set_autosuspend_delay(&dev->dev, 1000);
1680 pm_runtime_use_autosuspend(&dev->dev);
1681 pm_runtime_put_autosuspend(&dev->dev);
1682 pm_runtime_allow(&dev->dev);
1683
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001684 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685}
1686
Bill Pemberton0b255e92012-11-27 15:59:38 -05001687static void i801_remove(struct pci_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688{
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001689 struct i801_priv *priv = pci_get_drvdata(dev);
1690
Jarkko Nikulaa7401ca2016-03-10 14:12:22 +02001691 pm_runtime_forbid(&dev->dev);
1692 pm_runtime_get_noresume(&dev->dev);
1693
Benjamin Tissoires22e94bd2016-10-13 14:10:35 +02001694 i801_disable_host_notify(priv);
Jean Delvare3ad7ea12012-10-05 22:23:53 +02001695 i801_del_mux(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001696 i2c_del_adapter(&priv->adapter);
Mika Westerberga7ae8192016-06-09 16:56:28 +03001697 i801_acpi_remove(priv);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001698 pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
Daniel Kurtz636752b2012-07-24 14:13:58 +02001699
Mika Westerberg94246932015-08-06 13:46:25 +01001700 platform_device_unregister(priv->tco_pdev);
1701
Daniel Ritzd6fcb3b2006-06-27 18:40:54 +02001702 /*
1703 * do not call pci_disable_device(dev) since it can cause hard hangs on
1704 * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
1705 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706}
1707
Jean Delvaref7f6d912018-04-11 18:05:34 +02001708static void i801_shutdown(struct pci_dev *dev)
1709{
1710 struct i801_priv *priv = pci_get_drvdata(dev);
1711
1712 /* Restore config registers to avoid hard hang on some systems */
1713 i801_disable_host_notify(priv);
1714 pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
1715}
1716
Anders Roxell4b2f9bd52018-05-14 11:33:26 +02001717#ifdef CONFIG_PM_SLEEP
Jarkko Nikula2ee73c42016-03-10 14:12:21 +02001718static int i801_suspend(struct device *dev)
Jean Delvarea5aaea32007-03-22 19:49:01 +01001719{
Jarkko Nikula2ee73c42016-03-10 14:12:21 +02001720 struct pci_dev *pci_dev = to_pci_dev(dev);
1721 struct i801_priv *priv = pci_get_drvdata(pci_dev);
David Woodhouse0cd96eb2010-10-31 21:06:59 +01001722
Jarkko Nikula2ee73c42016-03-10 14:12:21 +02001723 pci_write_config_byte(pci_dev, SMBHSTCFG, priv->original_hstcfg);
Jean Delvarea5aaea32007-03-22 19:49:01 +01001724 return 0;
1725}
1726
Jarkko Nikula2ee73c42016-03-10 14:12:21 +02001727static int i801_resume(struct device *dev)
Jean Delvarea5aaea32007-03-22 19:49:01 +01001728{
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +02001729 struct pci_dev *pci_dev = to_pci_dev(dev);
1730 struct i801_priv *priv = pci_get_drvdata(pci_dev);
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +02001731
Benjamin Tissoires4d5538f2016-10-13 14:10:40 +02001732 i801_enable_host_notify(&priv->adapter);
Benjamin Tissoires7b0ed332016-06-24 16:39:49 +02001733
Jarkko Nikulaf85da3f2015-02-13 15:52:24 +02001734 return 0;
Jean Delvarea5aaea32007-03-22 19:49:01 +01001735}
Jean Delvarea5aaea32007-03-22 19:49:01 +01001736#endif
1737
Jean Delvarea9c80882018-04-25 11:53:40 +02001738static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume);
Jarkko Nikula2ee73c42016-03-10 14:12:21 +02001739
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740static struct pci_driver i801_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 .name = "i801_smbus",
1742 .id_table = i801_ids,
1743 .probe = i801_probe,
Bill Pemberton0b255e92012-11-27 15:59:38 -05001744 .remove = i801_remove,
Jean Delvaref7f6d912018-04-11 18:05:34 +02001745 .shutdown = i801_shutdown,
Jarkko Nikula2ee73c42016-03-10 14:12:21 +02001746 .driver = {
1747 .pm = &i801_pm_ops,
1748 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749};
1750
1751static int __init i2c_i801_init(void)
1752{
Jean Delvare6aa14642011-05-24 20:58:49 +02001753 if (dmi_name_in_vendors("FUJITSU"))
1754 input_apanel_init();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 return pci_register_driver(&i801_driver);
1756}
1757
1758static void __exit i2c_i801_exit(void)
1759{
1760 pci_unregister_driver(&i801_driver);
1761}
1762
Jean Delvare7c81c602014-01-29 20:40:08 +01001763MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, Jean Delvare <jdelvare@suse.de>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764MODULE_DESCRIPTION("I801 SMBus driver");
1765MODULE_LICENSE("GPL");
1766
1767module_init(i2c_i801_init);
1768module_exit(i2c_i801_exit);