diff options
| author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2010-10-27 07:44:03 -0400 |
|---|---|---|
| committer | Ben Dooks <ben-linux@fluff.org> | 2010-10-28 05:05:08 -0400 |
| commit | aa62f85d0c65712c24b4892e9eab929d5176cee2 (patch) | |
| tree | 2fe344b48a8ab3f01cf3759aaf0871df7f5623e8 | |
| parent | b18cae4224bde7e5a332c19bc99247b2098ea232 (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/Kconfig | 9 | ||||
| -rw-r--r-- | drivers/i2c/busses/Makefile | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-intel-mid.c | 1135 |
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 | ||
| 399 | config 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 | |||
| 399 | config I2C_IOP3XX | 408 | config 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 | |||
| 38 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o | 38 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o |
| 39 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o | 39 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o |
| 40 | obj-$(CONFIG_I2C_IMX) += i2c-imx.o | 40 | obj-$(CONFIG_I2C_IMX) += i2c-imx.o |
| 41 | obj-$(CONFIG_I2C_INTEL_MID) += i2c-intel-mid.o | ||
| 41 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o | 42 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o |
| 42 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o | 43 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o |
| 43 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o | 44 | obj-$(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 | ||
| 41 | enum platform_enum { | ||
| 42 | MOORESTOWN = 0, | ||
| 43 | MEDFIELD = 1, | ||
| 44 | }; | ||
| 45 | |||
| 46 | enum 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 | */ | ||
| 75 | struct 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) | ||
