aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2010-10-27 07:44:03 -0400
committerBen Dooks <ben-linux@fluff.org>2010-10-28 05:05:08 -0400
commitaa62f85d0c65712c24b4892e9eab929d5176cee2 (patch)
tree2fe344b48a8ab3f01cf3759aaf0871df7f5623e8
parentb18cae4224bde7e5a332c19bc99247b2098ea232 (diff)
i2c-intel-mid: support for Moorestown and Medfield platform
(Updated to address Ben's comments. With regard to the message segment restriction it's not something we hit on the actual platform so while I will investigate that further I don't think its a blocker to submission. At worst its a spot over-restrictive) From: Wen Wang <wen.w.wang@intel.com> Initial release of the driver. Updated and verified on hardware. Cleaned up as follows Alan Cox: Squash down the switches into tables, and use the PCI ident field. We could perhaps take this further and put the platform and port number into this. uint32t -> u32 bracketing of case statements spacing and '!' usage Check the speed (which is now 0/1/2) is valid and ignore otherwise. Fix remaining problems/suggestions from Jean's review Fix items from Ben's review Arjan van de Ven: Initial power management hooks Yong Wang <youg.y.wang@intel.com>: Shared IRQ support Wen Wang <wen.w.wang@intel.com>: D3 support Fixes for OCT test runs Interrupt optimisations Hong Liu <hong.liu@intel.com> The runtime PM code is working on the wrong device (i2c_adapter->dev). The correct one should be pci_dev->dev. This breaks attached i2c slave devices with runtime PM enabled. Slave device needs to runtime resume parent device before runtime resuming itself, but we always get error since we don't have pm_runtime callback for i2c_adapter->dev. Bin Yang <bin.yang@intel.com>: Update speed table Saadi Maalem <saadi.maalem@intel.com>: Clear all interrupts in the hardware init Celine Chotard <celinex.chotard@intel.com>: Correct ordering of clear/disable of IRQs Signed-off-by: Wen Wang <wen.w.wang@intel.com> Signed-off-by: Yong Wang <yong.y.wang@intel.com> Signed-off-by: Hong Liu <hong.liu@intel.com> Signed-off-by: Bin Yang <bin.yang@intel.com> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
-rw-r--r--drivers/i2c/busses/Kconfig9
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-intel-mid.c1135
3 files changed, 1145 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6539ac2907e9..8fcdfbae64bd 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -396,6 +396,15 @@ config I2C_IMX
396 This driver can also be built as a module. If so, the module 396 This driver can also be built as a module. If so, the module
397 will be called i2c-imx. 397 will be called i2c-imx.
398 398
399config I2C_INTEL_MID
400 tristate "Intel Moorestown/Medfield Platform I2C controller"
401 help
402 Say Y here if you have an Intel Moorestown/Medfield platform I2C
403 controller.
404
405 This support is also available as a module. If so, the module
406 will be called i2c-intel-mid.
407
399config I2C_IOP3XX 408config I2C_IOP3XX
400 tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" 409 tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
401 depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX 410 depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 033ad413f328..84cb16ae6f9e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
38obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o 38obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
39obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o 39obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
40obj-$(CONFIG_I2C_IMX) += i2c-imx.o 40obj-$(CONFIG_I2C_IMX) += i2c-imx.o
41obj-$(CONFIG_I2C_INTEL_MID) += i2c-intel-mid.o
41obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o 42obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
42obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o 43obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
43obj-$(CONFIG_I2C_MPC) += i2c-mpc.o 44obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c
new file mode 100644
index 000000000000..80f70d3a744d
--- /dev/null
+++ b/drivers/i2c/busses/i2c-intel-mid.c
@@ -0,0 +1,1135 @@
1/*
2 * Support for Moorestown/Medfield I2C chip
3 *
4 * Copyright (c) 2009 Intel Corporation.
5 * Copyright (c) 2009 Synopsys. Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License, version
9 * 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc., 51
18 * Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/err.h>
25#include <linux/slab.h>
26#include <linux/stat.h>
27#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/interrupt.h>
32#include <linux/pm_runtime.h>
33#include <linux/io.h>
34
35#define DRIVER_NAME "i2c-intel-mid"
36#define VERSION "Version 0.5ac2"
37#define PLATFORM "Moorestown/Medfield"
38
39/* Tables use: 0 Moorestown, 1 Medfield */
40#define NUM_PLATFORMS 2
41enum platform_enum {
42 MOORESTOWN = 0,
43 MEDFIELD = 1,
44};
45
46enum mid_i2c_status {
47 STATUS_IDLE = 0,
48 STATUS_READ_START,
49 STATUS_READ_IN_PROGRESS,
50 STATUS_READ_SUCCESS,
51 STATUS_WRITE_START,
52 STATUS_WRITE_SUCCESS,
53 STATUS_XFER_ABORT,
54 STATUS_STANDBY
55};
56
57/**
58 * struct intel_mid_i2c_private - per device I²C context
59 * @adap: core i2c layer adapter information
60 * @dev: device reference for power management
61 * @base: register base
62 * @speed: speed mode for this port
63 * @complete: completion object for transaction wait
64 * @abort: reason for last abort
65 * @rx_buf: pointer into working receive buffer
66 * @rx_buf_len: receive buffer length
67 * @status: adapter state machine
68 * @msg: the message we are currently processing
69 * @platform: the MID device type we are part of
70 * @lock: transaction serialization
71 *
72 * We allocate one of these per device we discover, it holds the core
73 * i2c layer objects and the data we need to track privately.
74 */
75struct intel_mid_i2c_private {
76 struct i2c_adapter adap;
77 struct device *dev;
78 void __iomem *base;
79 int speed;
80 struct completion complete;
81 int abort;
82 u8 *rx_buf;
83 int rx_buf_len;
84 enum mid_i2c_status status;
85 struct i2c_msg *msg;
86 enum platform_enum platform;
87 struct mutex lock;
88};
89
90#define NUM_SPEEDS 3
91
92#define ACTIVE 0
93#define STANDBY 1
94
95
96/* Control register */
97#define IC_CON 0x00
98#define SLV_DIS (1 << 6) /* Disable slave mode */
99#define RESTART (1 << 5) /* Send a Restart condition */
100#define ADDR_10BIT (1 << 4) /* 10-bit addressing */
101#define STANDARD_MODE (1 << 1) /* standard mode */
102#define FAST_MODE (2 << 1) /* fast mode */
103#define HIGH_MODE (3 << 1) /* high speed mode */
104#define MASTER_EN (1 << 0) /* Master mode */
105
106/* Target address register */
107#define IC_TAR 0x04
108#define IC_TAR_10BIT_ADDR (1 << 12) /* 10-bit addressing */
109#define IC_TAR_SPECIAL (1 << 11) /* Perform special I2C cmd */
110#define IC_TAR_GC_OR_START (1 << 10) /* 0: Gerneral Call Address */
111 /* 1: START BYTE */
112/* Slave Address Register */
113#define IC_SAR 0x08 /* Not used in Master mode */
114
115/* High Speed Master Mode Code Address Register */
116#define IC_HS_MADDR 0x0c
117
118/* Rx/Tx Data Buffer and Command Register */
119#define IC_DATA_CMD 0x10
120#define IC_RD (1 << 8) /* 1: Read 0: Write */
121
122/* Standard Speed Clock SCL High Count Register */
123#define IC_SS_SCL_HCNT 0x14
124
125/* Standard Speed Clock SCL Low Count Register */
126#define IC_SS_SCL_LCNT 0x18
127
128/* Fast Speed Clock SCL High Count Register */
129#define IC_FS_SCL_HCNT 0x1c
130
131/* Fast Spedd Clock SCL Low Count Register */
132#define IC_FS_SCL_LCNT 0x20
133
134/* High Speed Clock SCL High Count Register */
135#define IC_HS_SCL_HCNT 0x24
136
137/* High Speed Clock SCL Low Count Register */
138#define IC_HS_SCL_LCNT 0x28
139
140/* Interrupt Status Register */
141#define IC_INTR_STAT 0x2c /* Read only */
142#define R_GEN_CALL (1 << 11)
143#define R_START_DET (1 << 10)
144#define R_STOP_DET (1 << 9)
145#define R_ACTIVITY (1 << 8)
146#define R_RX_DONE (1 << 7)
147#define R_TX_ABRT (1 << 6)
148#define R_RD_REQ (1 << 5)