summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/i2c
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/drivers/i2c
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/drivers/i2c')
-rw-r--r--ANDROID_3.4.5/drivers/i2c/Kconfig121
-rw-r--r--ANDROID_3.4.5/drivers/i2c/Makefile14
-rw-r--r--ANDROID_3.4.5/drivers/i2c/algos/Kconfig25
-rw-r--r--ANDROID_3.4.5/drivers/i2c/algos/Makefile10
-rw-r--r--ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-bit.c671
-rw-r--r--ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pca.c566
-rw-r--r--ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.c442
-rw-r--r--ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.h77
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/algos/wmt-i2c-algo.c308
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/Kconfig931
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/Makefile93
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-acorn.c96
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1535.c552
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1563.c448
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ali15x3.c533
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756-s4882.c262
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756.c430
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-amd8111.c505
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-at91.c314
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-au1550.c434
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-bfin-twi.c797
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-cpm.c731
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-davinci.c830
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.c705
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.h105
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-pcidrv.c391
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-platdrv.c227
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-diolan-u2c.c522
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-eg20t.c1068
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-elektor.c347
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-gpio.c279
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-highlander.c487
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-hydra.c178
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-i801.c949
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.c818
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.h123
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-imx.c642
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-intel-mid.c1135
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.c531
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.h107
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-isch.c314
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ixp2000.c157
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-mpc.c758
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-mv64xxx.c618
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-mxs.c419
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2-s4985.c257
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2.c468
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-nomadik.c1068
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-nuc900.c708
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-ocores.c414
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-octeon.c638
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-omap.c1219
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-parport-light.c281
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.c306
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.h110
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pasemi.c433
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-isa.c229
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-platform.c293
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-piix4.c563
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pmcmsp.c643
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pnx.c733
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-powermac.c326
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-puv3.c294
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa-pci.c180
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa.c1308
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-s3c2410.c1161
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.c404
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.h79
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-scmi.c445
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sh7760.c567
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sh_mobile.c739
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sibyte.c198
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-simtec.c175
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sirf.c459
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sis5595.c434
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sis630.c533
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-sis96x.c344
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-stu300.c1057
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-stub.c222
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-taos-evm.c331
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-tegra.c791
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-tiny-usb.c271
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-versatile.c170
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-via.c180
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-viapro.c508
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-xiic.c812
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/i2c-xlr.c278
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/scx200_acb.c618
-rw-r--r--ANDROID_3.4.5/drivers/i2c/busses/scx200_i2c.c131
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-1.c1294
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-2.c1253
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-3.c1256
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-4.c1274
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus.c1254
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus-1.c661
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.c662
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.h24
-rwxr-xr-xANDROID_3.4.5/drivers/i2c/i2c-api.c216
-rw-r--r--ANDROID_3.4.5/drivers/i2c/i2c-boardinfo.c94
-rw-r--r--ANDROID_3.4.5/drivers/i2c/i2c-core.c2136
-rw-r--r--ANDROID_3.4.5/drivers/i2c/i2c-core.h34
-rw-r--r--ANDROID_3.4.5/drivers/i2c/i2c-dev.c652
-rw-r--r--ANDROID_3.4.5/drivers/i2c/i2c-mux.c164
-rw-r--r--ANDROID_3.4.5/drivers/i2c/i2c-smbus.c263
-rw-r--r--ANDROID_3.4.5/drivers/i2c/muxes/Kconfig40
-rw-r--r--ANDROID_3.4.5/drivers/i2c/muxes/Makefile8
-rw-r--r--ANDROID_3.4.5/drivers/i2c/muxes/gpio-i2cmux.c173
-rw-r--r--ANDROID_3.4.5/drivers/i2c/muxes/pca9541.c400
-rw-r--r--ANDROID_3.4.5/drivers/i2c/muxes/pca954x.c291
109 files changed, 0 insertions, 53597 deletions
diff --git a/ANDROID_3.4.5/drivers/i2c/Kconfig b/ANDROID_3.4.5/drivers/i2c/Kconfig
deleted file mode 100644
index dd2ba673..00000000
--- a/ANDROID_3.4.5/drivers/i2c/Kconfig
+++ /dev/null
@@ -1,121 +0,0 @@
-#
-# I2C subsystem configuration
-#
-
-menuconfig I2C
- tristate "I2C support"
- depends on HAS_IOMEM
- select RT_MUTEXES
- ---help---
- I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
- many micro controller applications and developed by Philips. SMBus,
- or System Management Bus is a subset of the I2C protocol. More
- information is contained in the directory <file:Documentation/i2c/>,
- especially in the file called "summary" there.
-
- Both I2C and SMBus are supported here. You will need this for
- hardware sensors support, and also for Video For Linux support.
-
- If you want I2C support, you should say Y here and also to the
- specific driver for your bus adapter(s) below.
-
- This I2C support can also be built as a module. If so, the module
- will be called i2c-core.
-
-if I2C
-
-config I2C_BOARDINFO
- boolean
- default y
-
-config I2C_COMPAT
- boolean "Enable compatibility bits for old user-space"
- default y
- help
- Say Y here if you intend to run lm-sensors 3.1.1 or older, or any
- other user-space package which expects i2c adapters to be class
- devices. If you don't know, say Y.
-
-config I2C_CHARDEV
- tristate "I2C device interface"
- help
- Say Y here to use i2c-* device files, usually found in the /dev
- directory on your system. They make it possible to have user-space
- programs use the I2C bus. Information on how to do this is
- contained in the file <file:Documentation/i2c/dev-interface>.
-
- This support is also available as a module. If so, the module
- will be called i2c-dev.
-
-config I2C_API
- tristate "I2C API support"
- help
- Say Y here if you want to use i2c interface simply in other modules.
-
- This support is also available as a module. If so, the module
- will be called i2c-api.
-
-config I2C_MUX
- tristate "I2C bus multiplexing support"
- depends on EXPERIMENTAL
- help
- Say Y here if you want the I2C core to support the ability to
- handle multiplexed I2C bus topologies, by presenting each
- multiplexed segment as a I2C adapter.
-
- This support is also available as a module. If so, the module
- will be called i2c-mux.
-
-source drivers/i2c/muxes/Kconfig
-
-config I2C_HELPER_AUTO
- bool "Autoselect pertinent helper modules"
- default y
- help
- Some I2C bus drivers require so-called "I2C algorithm" modules
- to work. These are basically software-only abstractions of generic
- I2C interfaces. This option will autoselect them so that you don't
- have to care.
-
- Unselect this only if you need to enable additional helper
- modules, for example for use with external I2C bus drivers.
-
- In doubt, say Y.
-
-config I2C_SMBUS
- tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
- help
- Say Y here if you want support for SMBus extensions to the I2C
- specification. At the moment, the only supported extension is
- the SMBus alert protocol.
-
- This support is also available as a module. If so, the module
- will be called i2c-smbus.
-
-source drivers/i2c/algos/Kconfig
-source drivers/i2c/busses/Kconfig
-
-config I2C_DEBUG_CORE
- bool "I2C Core debugging messages"
- help
- Say Y here if you want the I2C core to produce a bunch of debug
- messages to the system log. Select this if you are having a
- problem with I2C support and want to see more of what is going on.
-
-config I2C_DEBUG_ALGO
- bool "I2C Algorithm debugging messages"
- help
- Say Y here if you want the I2C algorithm drivers to produce a bunch
- of debug messages to the system log. Select this if you are having
- a problem with I2C support and want to see more of what is going
- on.
-
-config I2C_DEBUG_BUS
- bool "I2C Bus debugging messages"
- help
- Say Y here if you want the I2C bus drivers to produce a bunch of
- debug messages to the system log. Select this if you are having
- a problem with I2C support and want to see more of what is going
- on.
-
-endif # I2C
diff --git a/ANDROID_3.4.5/drivers/i2c/Makefile b/ANDROID_3.4.5/drivers/i2c/Makefile
deleted file mode 100644
index 38b383c4..00000000
--- a/ANDROID_3.4.5/drivers/i2c/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile for the i2c core.
-#
-
-obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
-obj-$(CONFIG_I2C) += i2c-core.o
-obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o
-obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
-obj-$(CONFIG_I2C_MUX) += i2c-mux.o
-obj-$(CONFIG_I2C_API) += i2c-api.o
-obj-y += algos/ busses/ muxes/
-
-ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG
-CFLAGS_i2c-core.o := -Wno-deprecated-declarations
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/Kconfig b/ANDROID_3.4.5/drivers/i2c/algos/Kconfig
deleted file mode 100644
index 39b0ade7..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/Kconfig
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# I2C algorithm drivers configuration
-#
-
-menu "I2C Algorithms"
- visible if !I2C_HELPER_AUTO
-
-config I2C_ALGOBIT
- tristate "I2C bit-banging interfaces"
-
-config I2C_ALGOPCF
- tristate "I2C PCF 8584 interfaces"
-
-config I2C_ALGOPCA
- tristate "I2C PCA 9564 interfaces"
-
-config I2C_ALGOWMT
- tristate "WMT I2C Algorithm"
- depends on ARCH_WMT && I2C
- help
- This supports the use of the WMT I2C interface found on WMT
- processors. Say Y if you have one of these. You should also say Y
- for the WMT I2C peripheral driver support below.
-
-endmenu
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/Makefile b/ANDROID_3.4.5/drivers/i2c/algos/Makefile
deleted file mode 100644
index d26856d2..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the i2c algorithms
-#
-
-obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
-obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
-obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
-
-ccflags-$(CONFIG_I2C_DEBUG_ALGO) := -DDEBUG
-obj-$(CONFIG_I2C_WMT) += wmt-i2c-algo.o
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-bit.c b/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-bit.c
deleted file mode 100644
index 7f0b8321..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-bit.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/* -------------------------------------------------------------------------
- * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters
- * -------------------------------------------------------------------------
- * Copyright (C) 1995-2000 Simon G. Vogl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA.
- * ------------------------------------------------------------------------- */
-
-/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
- <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-
-/* ----- global defines ----------------------------------------------- */
-
-#ifdef DEBUG
-#define bit_dbg(level, dev, format, args...) \
- do { \
- if (i2c_debug >= level) \
- dev_dbg(dev, format, ##args); \
- } while (0)
-#else
-#define bit_dbg(level, dev, format, args...) \
- do {} while (0)
-#endif /* DEBUG */
-
-/* ----- global variables --------------------------------------------- */
-
-static int bit_test; /* see if the line-setting functions work */
-module_param(bit_test, int, S_IRUGO);
-MODULE_PARM_DESC(bit_test, "lines testing - 0 off; 1 report; 2 fail if stuck");
-
-#ifdef DEBUG
-static int i2c_debug = 1;
-module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose");
-#endif
-
-/* --- setting states on the bus with the right timing: --------------- */
-
-#define setsda(adap, val) adap->setsda(adap->data, val)
-#define setscl(adap, val) adap->setscl(adap->data, val)
-#define getsda(adap) adap->getsda(adap->data)
-#define getscl(adap) adap->getscl(adap->data)
-
-static inline void sdalo(struct i2c_algo_bit_data *adap)
-{
- setsda(adap, 0);
- udelay((adap->udelay + 1) / 2);
-}
-
-static inline void sdahi(struct i2c_algo_bit_data *adap)
-{
- setsda(adap, 1);
- udelay((adap->udelay + 1) / 2);
-}
-
-static inline void scllo(struct i2c_algo_bit_data *adap)
-{
- setscl(adap, 0);
- udelay(adap->udelay / 2);
-}
-
-/*
- * Raise scl line, and do checking for delays. This is necessary for slower
- * devices.
- */
-static int sclhi(struct i2c_algo_bit_data *adap)
-{
- unsigned long start;
-
- setscl(adap, 1);
-
- /* Not all adapters have scl sense line... */
- if (!adap->getscl)
- goto done;
-
- start = jiffies;
- while (!getscl(adap)) {
- /* This hw knows how to read the clock line, so we wait
- * until it actually gets high. This is safer as some
- * chips may hold it low ("clock stretching") while they
- * are processing data internally.
- */
- if (time_after(jiffies, start + adap->timeout)) {
- /* Test one last time, as we may have been preempted
- * between last check and timeout test.
- */
- if (getscl(adap))
- break;
- return -ETIMEDOUT;
- }
- cpu_relax();
- }
-#ifdef DEBUG
- if (jiffies != start && i2c_debug >= 3)
- pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
- "high\n", jiffies - start);
-#endif
-
-done:
- udelay(adap->udelay);
- return 0;
-}
-
-
-/* --- other auxiliary functions -------------------------------------- */
-static void i2c_start(struct i2c_algo_bit_data *adap)
-{
- /* assert: scl, sda are high */
- setsda(adap, 0);
- udelay(adap->udelay);
- scllo(adap);
-}
-
-static void i2c_repstart(struct i2c_algo_bit_data *adap)
-{
- /* assert: scl is low */
- sdahi(adap);
- sclhi(adap);
- setsda(adap, 0);
- udelay(adap->udelay);
- scllo(adap);
-}
-
-
-static void i2c_stop(struct i2c_algo_bit_data *adap)
-{
- /* assert: scl is low */
- sdalo(adap);
- sclhi(adap);
- setsda(adap, 1);
- udelay(adap->udelay);
-}
-
-
-
-/* send a byte without start cond., look for arbitration,
- check ackn. from slave */
-/* returns:
- * 1 if the device acknowledged
- * 0 if the device did not ack
- * -ETIMEDOUT if an error occurred (while raising the scl line)
- */
-static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
-{
- int i;
- int sb;
- int ack;
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- /* assert: scl is low */
- for (i = 7; i >= 0; i--) {
- sb = (c >> i) & 1;
- setsda(adap, sb);
- udelay((adap->udelay + 1) / 2);
- if (sclhi(adap) < 0) { /* timed out */
- bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
- "timeout at bit #%d\n", (int)c, i);
- return -ETIMEDOUT;
- }
- /* FIXME do arbitration here:
- * if (sb && !getsda(adap)) -> ouch! Get out of here.
- *
- * Report a unique code, so higher level code can retry
- * the whole (combined) message and *NOT* issue STOP.
- */
- scllo(adap);
- }
- sdahi(adap);
- if (sclhi(adap) < 0) { /* timeout */
- bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
- "timeout at ack\n", (int)c);
- return -ETIMEDOUT;
- }
-
- /* read ack: SDA should be pulled down by slave, or it may
- * NAK (usually to report problems with the data we wrote).
- */
- ack = !getsda(adap); /* ack: sda is pulled low -> success */
- bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
- ack ? "A" : "NA");
-
- scllo(adap);
- return ack;
- /* assert: scl is low (sda undef) */
-}
-
-
-static int i2c_inb(struct i2c_adapter *i2c_adap)
-{
- /* read byte via i2c port, without start/stop sequence */
- /* acknowledge is sent in i2c_read. */
- int i;
- unsigned char indata = 0;
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- /* assert: scl is low */
- sdahi(adap);
- for (i = 0; i < 8; i++) {
- if (sclhi(adap) < 0) { /* timeout */
- bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
- "#%d\n", 7 - i);
- return -ETIMEDOUT;
- }
- indata *= 2;
- if (getsda(adap))
- indata |= 0x01;
- setscl(adap, 0);
- udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
- }
- /* assert: scl is low */
- return indata;
-}
-
-/*
- * Sanity check for the adapter hardware - check the reaction of
- * the bus lines only if it seems to be idle.
- */
-static int test_bus(struct i2c_adapter *i2c_adap)
-{
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- const char *name = i2c_adap->name;
- int scl, sda, ret;
-
- if (adap->pre_xfer) {
- ret = adap->pre_xfer(i2c_adap);
- if (ret < 0)
- return -ENODEV;
- }
-
- if (adap->getscl == NULL)
- pr_info("%s: Testing SDA only, SCL is not readable\n", name);
-
- sda = getsda(adap);
- scl = (adap->getscl == NULL) ? 1 : getscl(adap);
- if (!scl || !sda) {
- printk(KERN_WARNING
- "%s: bus seems to be busy (scl=%d, sda=%d)\n",
- name, scl, sda);
- goto bailout;
- }
-
- sdalo(adap);
- sda = getsda(adap);
- scl = (adap->getscl == NULL) ? 1 : getscl(adap);
- if (sda) {
- printk(KERN_WARNING "%s: SDA stuck high!\n", name);
- goto bailout;
- }
- if (!scl) {
- printk(KERN_WARNING "%s: SCL unexpected low "
- "while pulling SDA low!\n", name);
- goto bailout;
- }
-
- sdahi(adap);
- sda = getsda(adap);
- scl = (adap->getscl == NULL) ? 1 : getscl(adap);
- if (!sda) {
- printk(KERN_WARNING "%s: SDA stuck low!\n", name);
- goto bailout;
- }
- if (!scl) {
- printk(KERN_WARNING "%s: SCL unexpected low "
- "while pulling SDA high!\n", name);
- goto bailout;
- }
-
- scllo(adap);
- sda = getsda(adap);
- scl = (adap->getscl == NULL) ? 0 : getscl(adap);
- if (scl) {
- printk(KERN_WARNING "%s: SCL stuck high!\n", name);
- goto bailout;
- }
- if (!sda) {
- printk(KERN_WARNING "%s: SDA unexpected low "
- "while pulling SCL low!\n", name);
- goto bailout;
- }
-
- sclhi(adap);
- sda = getsda(adap);
- scl = (adap->getscl == NULL) ? 1 : getscl(adap);
- if (!scl) {
- printk(KERN_WARNING "%s: SCL stuck low!\n", name);
- goto bailout;
- }
- if (!sda) {
- printk(KERN_WARNING "%s: SDA unexpected low "
- "while pulling SCL high!\n", name);
- goto bailout;
- }
-
- if (adap->post_xfer)
- adap->post_xfer(i2c_adap);
-
- pr_info("%s: Test OK\n", name);
- return 0;
-bailout:
- sdahi(adap);
- sclhi(adap);
-
- if (adap->post_xfer)
- adap->post_xfer(i2c_adap);
-
- return -ENODEV;
-}
-
-/* ----- Utility functions
- */
-
-/* try_address tries to contact a chip for a number of
- * times before it gives up.
- * return values:
- * 1 chip answered
- * 0 chip did not answer
- * -x transmission error
- */
-static int try_address(struct i2c_adapter *i2c_adap,
- unsigned char addr, int retries)
-{
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- int i, ret = 0;
-
- for (i = 0; i <= retries; i++) {
- ret = i2c_outb(i2c_adap, addr);
- if (ret == 1 || i == retries)
- break;
- bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
- i2c_stop(adap);
- udelay(adap->udelay);
- yield();
- bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
- i2c_start(adap);
- }
- if (i && ret)
- bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
- "0x%02x: %s\n", i + 1,
- addr & 1 ? "read from" : "write to", addr >> 1,
- ret == 1 ? "success" : "failed, timeout?");
- return ret;
-}
-
-static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
-{
- const unsigned char *temp = msg->buf;
- int count = msg->len;
- unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
- int retval;
- int wrcount = 0;
-
- while (count > 0) {
- retval = i2c_outb(i2c_adap, *temp);
-
- /* OK/ACK; or ignored NAK */
- if ((retval > 0) || (nak_ok && (retval == 0))) {
- count--;
- temp++;
- wrcount++;
-
- /* A slave NAKing the master means the slave didn't like
- * something about the data it saw. For example, maybe
- * the SMBus PEC was wrong.
- */
- } else if (retval == 0) {
- dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");
- return -EIO;
-
- /* Timeout; or (someday) lost arbitration
- *
- * FIXME Lost ARB implies retrying the transaction from
- * the first message, after the "winning" master issues
- * its STOP. As a rule, upper layer code has no reason
- * to know or care about this ... it is *NOT* an error.
- */
- } else {
- dev_err(&i2c_adap->dev, "sendbytes: error %d\n",
- retval);
- return retval;
- }
- }
- return wrcount;
-}
-
-static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
-{
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- /* assert: sda is high */
- if (is_ack) /* send ack */
- setsda(adap, 0);
- udelay((adap->udelay + 1) / 2);
- if (sclhi(adap) < 0) { /* timeout */
- dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
- return -ETIMEDOUT;
- }
- scllo(adap);
- return 0;
-}
-
-static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
-{
- int inval;
- int rdcount = 0; /* counts bytes read */
- unsigned char *temp = msg->buf;
- int count = msg->len;
- const unsigned flags = msg->flags;
-
- while (count > 0) {
- inval = i2c_inb(i2c_adap);
- if (inval >= 0) {
- *temp = inval;
- rdcount++;
- } else { /* read timed out */
- break;
- }
-
- temp++;
- count--;
-
- /* Some SMBus transactions require that we receive the
- transaction length as the first read byte. */
- if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {
- if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
- if (!(flags & I2C_M_NO_RD_ACK))
- acknak(i2c_adap, 0);
- dev_err(&i2c_adap->dev, "readbytes: invalid "
- "block length (%d)\n", inval);
- return -EPROTO;
- }
- /* The original count value accounts for the extra
- bytes, that is, either 1 for a regular transaction,
- or 2 for a PEC transaction. */
- count += inval;
- msg->len += inval;
- }
-
- bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",
- inval,
- (flags & I2C_M_NO_RD_ACK)
- ? "(no ack/nak)"
- : (count ? "A" : "NA"));
-
- if (!(flags & I2C_M_NO_RD_ACK)) {
- inval = acknak(i2c_adap, count);
- if (inval < 0)
- return inval;
- }
- }
- return rdcount;
-}
-
-/* doAddress initiates the transfer by generating the start condition (in
- * try_address) and transmits the address in the necessary format to handle
- * reads, writes as well as 10bit-addresses.
- * returns:
- * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
- * -x an error occurred (like: -ENXIO if the device did not answer, or
- * -ETIMEDOUT, for example if the lines are stuck...)
- */
-static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
-{
- unsigned short flags = msg->flags;
- unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- unsigned char addr;
- int ret, retries;
-
- retries = nak_ok ? 0 : i2c_adap->retries;
-
- if (flags & I2C_M_TEN) {
- /* a ten bit address */
- addr = 0xf0 | ((msg->addr >> 7) & 0x06);
- bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
- /* try extended address code...*/
- ret = try_address(i2c_adap, addr, retries);
- if ((ret != 1) && !nak_ok) {
- dev_err(&i2c_adap->dev,
- "died at extended address code\n");
- return -ENXIO;
- }
- /* the remaining 8 bit address */
- ret = i2c_outb(i2c_adap, msg->addr & 0xff);
- if ((ret != 1) && !nak_ok) {
- /* the chip did not ack / xmission error occurred */
- dev_err(&i2c_adap->dev, "died at 2nd address code\n");
- return -ENXIO;
- }
- if (flags & I2C_M_RD) {
- bit_dbg(3, &i2c_adap->dev, "emitting repeated "
- "start condition\n");
- i2c_repstart(adap);
- /* okay, now switch into reading mode */
- addr |= 0x01;
- ret = try_address(i2c_adap, addr, retries);
- if ((ret != 1) && !nak_ok) {
- dev_err(&i2c_adap->dev,
- "died at repeated address code\n");
- return -EIO;
- }
- }
- } else { /* normal 7bit address */
- addr = msg->addr << 1;
- if (flags & I2C_M_RD)
- addr |= 1;
- if (flags & I2C_M_REV_DIR_ADDR)
- addr ^= 1;
- ret = try_address(i2c_adap, addr, retries);
- if ((ret != 1) && !nak_ok)
- return -ENXIO;
- }
-
- return 0;
-}
-
-static int bit_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg msgs[], int num)
-{
- struct i2c_msg *pmsg;
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- int i, ret;
- unsigned short nak_ok;
-
- if (adap->pre_xfer) {
- ret = adap->pre_xfer(i2c_adap);
- if (ret < 0)
- return ret;
- }
-
- bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
- i2c_start(adap);
- for (i = 0; i < num; i++) {
- pmsg = &msgs[i];
- nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
- if (!(pmsg->flags & I2C_M_NOSTART)) {
- if (i) {
- bit_dbg(3, &i2c_adap->dev, "emitting "
- "repeated start condition\n");
- i2c_repstart(adap);
- }
- ret = bit_doAddress(i2c_adap, pmsg);
- if ((ret != 0) && !nak_ok) {
- bit_dbg(1, &i2c_adap->dev, "NAK from "
- "device addr 0x%02x msg #%d\n",
- msgs[i].addr, i);
- goto bailout;
- }
- }
- if (pmsg->flags & I2C_M_RD) {
- /* read bytes into buffer*/
- ret = readbytes(i2c_adap, pmsg);
- if (ret >= 1)
- bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n",
- ret, ret == 1 ? "" : "s");
- if (ret < pmsg->len) {
- if (ret >= 0)
- ret = -EIO;
- goto bailout;
- }
- } else {
- /* write bytes from buffer */
- ret = sendbytes(i2c_adap, pmsg);
- if (ret >= 1)
- bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n",
- ret, ret == 1 ? "" : "s");
- if (ret < pmsg->len) {
- if (ret >= 0)
- ret = -EIO;
- goto bailout;
- }
- }
- }
- ret = i;
-
-bailout:
- bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
- i2c_stop(adap);
-
- if (adap->post_xfer)
- adap->post_xfer(i2c_adap);
- return ret;
-}
-
-static u32 bit_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
- I2C_FUNC_SMBUS_READ_BLOCK_DATA |
- I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
- I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
-}
-
-
-/* -----exported algorithm data: ------------------------------------- */
-
-const struct i2c_algorithm i2c_bit_algo = {
- .master_xfer = bit_xfer,
- .functionality = bit_func,
-};
-EXPORT_SYMBOL(i2c_bit_algo);
-
-/*
- * registering functions to load algorithms at runtime
- */
-static int __i2c_bit_add_bus(struct i2c_adapter *adap,
- int (*add_adapter)(struct i2c_adapter *))
-{
- struct i2c_algo_bit_data *bit_adap = adap->algo_data;
- int ret;
-
- if (bit_test) {
- ret = test_bus(adap);
- if (bit_test >= 2 && ret < 0)
- return -ENODEV;
- }
-
- /* register new adapter to i2c module... */
- adap->algo = &i2c_bit_algo;
- adap->retries = 3;
-
- ret = add_adapter(adap);
- if (ret < 0)
- return ret;
-
- /* Complain if SCL can't be read */
- if (bit_adap->getscl == NULL) {
- dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n");
- dev_warn(&adap->dev, "Bus may be unreliable\n");
- }
- return 0;
-}
-
-int i2c_bit_add_bus(struct i2c_adapter *adap)
-{
- return __i2c_bit_add_bus(adap, i2c_add_adapter);
-}
-EXPORT_SYMBOL(i2c_bit_add_bus);
-
-int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
-{
- return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter);
-}
-EXPORT_SYMBOL(i2c_bit_add_numbered_bus);
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pca.c b/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pca.c
deleted file mode 100644
index 73133b10..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pca.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters
- * Copyright (C) 2004 Arcom Control Systems
- * Copyright (C) 2008 Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-pca.h>
-
-#define DEB1(fmt, args...) do { if (i2c_debug >= 1) \
- printk(KERN_DEBUG fmt, ## args); } while (0)
-#define DEB2(fmt, args...) do { if (i2c_debug >= 2) \
- printk(KERN_DEBUG fmt, ## args); } while (0)
-#define DEB3(fmt, args...) do { if (i2c_debug >= 3) \
- printk(KERN_DEBUG fmt, ## args); } while (0)
-
-static int i2c_debug;
-
-#define pca_outw(adap, reg, val) adap->write_byte(adap->data, reg, val)
-#define pca_inw(adap, reg) adap->read_byte(adap->data, reg)
-
-#define pca_status(adap) pca_inw(adap, I2C_PCA_STA)
-#define pca_clock(adap) adap->i2c_clock
-#define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
-#define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
-#define pca_wait(adap) adap->wait_for_completion(adap->data)
-#define pca_reset(adap) adap->reset_chip(adap->data)
-
-static void pca9665_reset(void *pd)
-{
- struct i2c_algo_pca_data *adap = pd;
- pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
- pca_outw(adap, I2C_PCA_IND, 0xA5);
- pca_outw(adap, I2C_PCA_IND, 0x5A);
-}
-
-/*
- * Generate a start condition on the i2c bus.
- *
- * returns after the start condition has occurred
- */
-static int pca_start(struct i2c_algo_pca_data *adap)
-{
- int sta = pca_get_con(adap);
- DEB2("=== START\n");
- sta |= I2C_PCA_CON_STA;
- sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
- pca_set_con(adap, sta);
- return pca_wait(adap);
-}
-
-/*
- * Generate a repeated start condition on the i2c bus
- *
- * return after the repeated start condition has occurred
- */
-static int pca_repeated_start(struct i2c_algo_pca_data *adap)
-{
- int sta = pca_get_con(adap);
- DEB2("=== REPEATED START\n");
- sta |= I2C_PCA_CON_STA;
- sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
- pca_set_con(adap, sta);
- return pca_wait(adap);
-}
-
-/*
- * Generate a stop condition on the i2c bus
- *
- * returns after the stop condition has been generated
- *
- * STOPs do not generate an interrupt or set the SI flag, since the
- * part returns the idle state (0xf8). Hence we don't need to
- * pca_wait here.
- */
-static void pca_stop(struct i2c_algo_pca_data *adap)
-{
- int sta = pca_get_con(adap);
- DEB2("=== STOP\n");
- sta |= I2C_PCA_CON_STO;
- sta &= ~(I2C_PCA_CON_STA|I2C_PCA_CON_SI);
- pca_set_con(adap, sta);
-}
-
-/*
- * Send the slave address and R/W bit
- *
- * returns after the address has been sent
- */
-static int pca_address(struct i2c_algo_pca_data *adap,
- struct i2c_msg *msg)
-{
- int sta = pca_get_con(adap);
- int addr;
-
- addr = ((0x7f & msg->addr) << 1);
- if (msg->flags & I2C_M_RD)
- addr |= 1;
- DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
- msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
-
- pca_outw(adap, I2C_PCA_DAT, addr);
-
- sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
- pca_set_con(adap, sta);
-
- return pca_wait(adap);
-}
-
-/*
- * Transmit a byte.
- *
- * Returns after the byte has been transmitted
- */
-static int pca_tx_byte(struct i2c_algo_pca_data *adap,
- __u8 b)
-{
- int sta = pca_get_con(adap);
- DEB2("=== WRITE %#04x\n", b);
- pca_outw(adap, I2C_PCA_DAT, b);
-
- sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
- pca_set_con(adap, sta);
-
- return pca_wait(adap);
-}
-
-/*
- * Receive a byte
- *
- * returns immediately.
- */
-static void pca_rx_byte(struct i2c_algo_pca_data *adap,
- __u8 *b, int ack)
-{
- *b = pca_inw(adap, I2C_PCA_DAT);
- DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
-}
-
-/*
- * Setup ACK or NACK for next received byte and wait for it to arrive.
- *
- * Returns after next byte has arrived.
- */
-static int pca_rx_ack(struct i2c_algo_pca_data *adap,
- int ack)
-{
- int sta = pca_get_con(adap);
-
- sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI|I2C_PCA_CON_AA);
-
- if (ack)
- sta |= I2C_PCA_CON_AA;
-
- pca_set_con(adap, sta);
- return pca_wait(adap);
-}
-
-static int pca_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_pca_data *adap = i2c_adap->algo_data;
- struct i2c_msg *msg = NULL;
- int curmsg;
- int numbytes = 0;
- int state;
- int ret;
- int completed = 1;
- unsigned long timeout = jiffies + i2c_adap->timeout;
-
- while ((state = pca_status(adap)) != 0xf8) {
- if (time_before(jiffies, timeout)) {
- msleep(10);
- } else {
- dev_dbg(&i2c_adap->dev, "bus is not idle. status is "
- "%#04x\n", state);
- return -EBUSY;
- }
- }
-
- DEB1("{{{ XFER %d messages\n", num);
-
- if (i2c_debug >= 2) {
- for (curmsg = 0; curmsg < num; curmsg++) {
- int addr, i;
- msg = &msgs[curmsg];
-
- addr = (0x7f & msg->addr) ;
-
- if (msg->flags & I2C_M_RD)
- printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
- curmsg, msg->len, addr, (addr << 1) | 1);
- else {
- printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s",
- curmsg, msg->len, addr, addr << 1,
- msg->len == 0 ? "" : ", ");
- for (i = 0; i < msg->len; i++)
- printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", ");
- printk("]\n");
- }
- }
- }
-
- curmsg = 0;
- ret = -EIO;
- while (curmsg < num) {
- state = pca_status(adap);
-
- DEB3("STATE is 0x%02x\n", state);
- msg = &msgs[curmsg];
-
- switch (state) {
- case 0xf8: /* On reset or stop the bus is idle */
- completed = pca_start(adap);
- break;
-
- case 0x08: /* A START condition has been transmitted */
- case 0x10: /* A repeated start condition has been transmitted */
- completed = pca_address(adap, msg);
- break;
-
- case 0x18: /* SLA+W has been transmitted; ACK has been received */
- case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
- if (numbytes < msg->len) {
- completed = pca_tx_byte(adap,
- msg->buf[numbytes]);
- numbytes++;
- break;
- }
- curmsg++; numbytes = 0;
- if (curmsg == num)
- pca_stop(adap);
- else
- completed = pca_repeated_start(adap);
- break;
-
- case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
- DEB2("NOT ACK received after SLA+W\n");
- pca_stop(adap);
- ret = -ENXIO;
- goto out;
-
- case 0x40: /* SLA+R has been transmitted; ACK has been received */
- completed = pca_rx_ack(adap, msg->len > 1);
- break;
-
- case 0x50: /* Data bytes has been received; ACK has been returned */
- if (numbytes < msg->len) {
- pca_rx_byte(adap, &msg->buf[numbytes], 1);
- numbytes++;
- completed = pca_rx_ack(adap,
- numbytes < msg->len - 1);
- break;
- }
- curmsg++; numbytes = 0;
- if (curmsg == num)
- pca_stop(adap);
- else
- completed = pca_repeated_start(adap);
- break;
-
- case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
- DEB2("NOT ACK received after SLA+R\n");
- pca_stop(adap);
- ret = -ENXIO;
- goto out;
-
- case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */
- DEB2("NOT ACK received after data byte\n");
- pca_stop(adap);
- goto out;
-
- case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
- DEB2("Arbitration lost\n");
- /*
- * The PCA9564 data sheet (2006-09-01) says "A
- * START condition will be transmitted when the
- * bus becomes free (STOP or SCL and SDA high)"
- * when the STA bit is set (p. 11).
- *
- * In case this won't work, try pca_reset()
- * instead.
- */
- pca_start(adap);
- goto out;
-
- case 0x58: /* Data byte has been received; NOT ACK has been returned */
- if (numbytes == msg->len - 1) {
- pca_rx_byte(adap, &msg->buf[numbytes], 0);
- curmsg++; numbytes = 0;
- if (curmsg == num)
- pca_stop(adap);
- else
- completed = pca_repeated_start(adap);
- } else {
- DEB2("NOT ACK sent after data byte received. "
- "Not final byte. numbytes %d. len %d\n",
- numbytes, msg->len);
- pca_stop(adap);
- goto out;
- }
- break;
- case 0x70: /* Bus error - SDA stuck low */
- DEB2("BUS ERROR - SDA Stuck low\n");
- pca_reset(adap);
- goto out;
- case 0x90: /* Bus error - SCL stuck low */
- DEB2("BUS ERROR - SCL Stuck low\n");
- pca_reset(adap);
- goto out;
- case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */
- DEB2("BUS ERROR - Illegal START or STOP\n");
- pca_reset(adap);
- goto out;
- default:
- dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state);
- break;
- }
-
- if (!completed)
- goto out;
- }
-
- ret = curmsg;
- out:
- DEB1("}}} transferred %d/%d messages. "
- "status is %#04x. control is %#04x\n",
- curmsg, num, pca_status(adap),
- pca_get_con(adap));
- return ret;
-}
-
-static u32 pca_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm pca_algo = {
- .master_xfer = pca_xfer,
- .functionality = pca_func,
-};
-
-static unsigned int pca_probe_chip(struct i2c_adapter *adap)
-{
- struct i2c_algo_pca_data *pca_data = adap->algo_data;
- /* The trick here is to check if there is an indirect register
- * available. If there is one, we will read the value we first
- * wrote on I2C_PCA_IADR. Otherwise, we will read the last value
- * we wrote on I2C_PCA_ADR
- */
- pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
- pca_outw(pca_data, I2C_PCA_IND, 0xAA);
- pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO);
- pca_outw(pca_data, I2C_PCA_IND, 0x00);
- pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
- if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
- printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
- return I2C_PCA_CHIP_9665;
- } else {
- printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
- return I2C_PCA_CHIP_9564;
- }
-}
-
-static int pca_init(struct i2c_adapter *adap)
-{
- struct i2c_algo_pca_data *pca_data = adap->algo_data;
-
- adap->algo = &pca_algo;
-
- if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) {
- static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36};
- int clock;
-
- if (pca_data->i2c_clock > 7) {
- switch (pca_data->i2c_clock) {
- case 330000:
- pca_data->i2c_clock = I2C_PCA_CON_330kHz;
- break;
- case 288000:
- pca_data->i2c_clock = I2C_PCA_CON_288kHz;
- break;
- case 217000:
- pca_data->i2c_clock = I2C_PCA_CON_217kHz;
- break;
- case 146000:
- pca_data->i2c_clock = I2C_PCA_CON_146kHz;
- break;
- case 88000:
- pca_data->i2c_clock = I2C_PCA_CON_88kHz;
- break;
- case 59000:
- pca_data->i2c_clock = I2C_PCA_CON_59kHz;
- break;
- case 44000:
- pca_data->i2c_clock = I2C_PCA_CON_44kHz;
- break;
- case 36000:
- pca_data->i2c_clock = I2C_PCA_CON_36kHz;
- break;
- default:
- printk(KERN_WARNING
- "%s: Invalid I2C clock speed selected."
- " Using default 59kHz.\n", adap->name);
- pca_data->i2c_clock = I2C_PCA_CON_59kHz;
- }
- } else {
- printk(KERN_WARNING "%s: "
- "Choosing the clock frequency based on "
- "index is deprecated."
- " Use the nominal frequency.\n", adap->name);
- }
-
- pca_reset(pca_data);
-
- clock = pca_clock(pca_data);
- printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
- adap->name, freqs[clock]);
-
- pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
- } else {
- int clock;
- int mode;
- int tlow, thi;
- /* Values can be found on PCA9665 datasheet section 7.3.2.6 */
- int min_tlow, min_thi;
- /* These values are the maximum raise and fall values allowed
- * by the I2C operation mode (Standard, Fast or Fast+)
- * They are used (added) below to calculate the clock dividers
- * of PCA9665. Note that they are slightly different of the
- * real maximum, to allow the change on mode exactly on the
- * maximum clock rate for each mode
- */
- int raise_fall_time;
-
- /* Ignore the reset function from the module,
- * we can use the parallel bus reset
- */
- pca_data->reset_chip = pca9665_reset;
-
- if (pca_data->i2c_clock > 1265800) {
- printk(KERN_WARNING "%s: I2C clock speed too high."
- " Using 1265.8kHz.\n", adap->name);
- pca_data->i2c_clock = 1265800;
- }
-
- if (pca_data->i2c_clock < 60300) {
- printk(KERN_WARNING "%s: I2C clock speed too low."
- " Using 60.3kHz.\n", adap->name);
- pca_data->i2c_clock = 60300;
- }
-
- /* To avoid integer overflow, use clock/100 for calculations */
- clock = pca_clock(pca_data) / 100;
-
- if (pca_data->i2c_clock > 10000) {
- mode = I2C_PCA_MODE_TURBO;
- min_tlow = 14;
- min_thi = 5;
- raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
- } else if (pca_data->i2c_clock > 4000) {
- mode = I2C_PCA_MODE_FASTP;
- min_tlow = 17;
- min_thi = 9;
- raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
- } else if (pca_data->i2c_clock > 1000) {
- mode = I2C_PCA_MODE_FAST;
- min_tlow = 44;
- min_thi = 20;
- raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */
- } else {
- mode = I2C_PCA_MODE_STD;
- min_tlow = 157;
- min_thi = 134;
- raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */
- }
-
- /* The minimum clock that respects the thi/tlow = 134/157 is
- * 64800 Hz. Below that, we have to fix the tlow to 255 and
- * calculate the thi factor.
- */
- if (clock < 648) {
- tlow = 255;
- thi = 1000000 - clock * raise_fall_time;
- thi /= (I2C_PCA_OSC_PER * clock) - tlow;
- } else {
- tlow = (1000000 - clock * raise_fall_time) * min_tlow;
- tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow);
- thi = tlow * min_thi / min_tlow;
- }
-
- pca_reset(pca_data);
-
- printk(KERN_INFO
- "%s: Clock frequency is %dHz\n", adap->name, clock * 100);
-
- pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
- pca_outw(pca_data, I2C_PCA_IND, mode);
- pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
- pca_outw(pca_data, I2C_PCA_IND, tlow);
- pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
- pca_outw(pca_data, I2C_PCA_IND, thi);
-
- pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
- }
- udelay(500); /* 500 us for oscilator to stabilise */
-
- return 0;
-}
-
-/*
- * registering functions to load algorithms at runtime
- */
-int i2c_pca_add_bus(struct i2c_adapter *adap)
-{
- int rval;
-
- rval = pca_init(adap);
- if (rval)
- return rval;
-
- return i2c_add_adapter(adap);
-}
-EXPORT_SYMBOL(i2c_pca_add_bus);
-
-int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
-{
- int rval;
-
- rval = pca_init(adap);
- if (rval)
- return rval;
-
- return i2c_add_numbered_adapter(adap);
-}
-EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
-
-MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
- "Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
-MODULE_LICENSE("GPL");
-
-module_param(i2c_debug, int, 0);
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.c b/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.c
deleted file mode 100644
index 5c237952..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
- *
- * Copyright (C) 1995-1997 Simon G. Vogl
- * 1998-2000 Hans Berglund
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- *
- * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
- * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
- * <mbailey@littlefeet-inc.com>
- *
- * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
- * messages, proper stop/repstart signaling during receive, added detect code
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-pcf.h>
-#include "i2c-algo-pcf.h"
-
-
-#define DEB2(x) if (i2c_debug >= 2) x
-#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
-#define DEBPROTO(x) if (i2c_debug >= 9) x;
- /* debug the protocol by showing transferred bits */
-#define DEF_TIMEOUT 16
-
-/*
- * module parameters:
- */
-static int i2c_debug;
-
-/* setting states on the bus with the right timing: */
-
-#define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
-#define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
-#define get_own(adap) adap->getown(adap->data)
-#define get_clock(adap) adap->getclock(adap->data)
-#define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
-#define i2c_inb(adap) adap->getpcf(adap->data, 0)
-
-/* other auxiliary functions */
-
-static void i2c_start(struct i2c_algo_pcf_data *adap)
-{
- DEBPROTO(printk(KERN_DEBUG "S "));
- set_pcf(adap, 1, I2C_PCF_START);
-}
-
-static void i2c_repstart(struct i2c_algo_pcf_data *adap)
-{
- DEBPROTO(printk(" Sr "));
- set_pcf(adap, 1, I2C_PCF_REPSTART);
-}
-
-static void i2c_stop(struct i2c_algo_pcf_data *adap)
-{
- DEBPROTO(printk("P\n"));
- set_pcf(adap, 1, I2C_PCF_STOP);
-}
-
-static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
-{
- DEB2(printk(KERN_INFO
- "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
- *status));
- /*
- * Cleanup from LAB -- reset and enable ESO.
- * This resets the PCF8584; since we've lost the bus, no
- * further attempts should be made by callers to clean up
- * (no i2c_stop() etc.)
- */
- set_pcf(adap, 1, I2C_PCF_PIN);
- set_pcf(adap, 1, I2C_PCF_ESO);
- /*
- * We pause for a time period sufficient for any running
- * I2C transaction to complete -- the arbitration logic won't
- * work properly until the next START is seen.
- * It is assumed the bus driver or client has set a proper value.
- *
- * REVISIT: should probably use msleep instead of mdelay if we
- * know we can sleep.
- */
- if (adap->lab_mdelay)
- mdelay(adap->lab_mdelay);
-
- DEB2(printk(KERN_INFO
- "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
- get_pcf(adap, 1)));
-}
-
-static int wait_for_bb(struct i2c_algo_pcf_data *adap)
-{
-
- int timeout = DEF_TIMEOUT;
- int status;
-
- status = get_pcf(adap, 1);
-
- while (!(status & I2C_PCF_BB) && --timeout) {
- udelay(100); /* wait for 100 us */
- status = get_pcf(adap, 1);
- }
-
- if (timeout == 0) {
- printk(KERN_ERR "Timeout waiting for Bus Busy\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
-{
-
- int timeout = DEF_TIMEOUT;
-
- *status = get_pcf(adap, 1);
-
- while ((*status & I2C_PCF_PIN) && --timeout) {
- adap->waitforpin(adap->data);
- *status = get_pcf(adap, 1);
- }
- if (*status & I2C_PCF_LAB) {
- handle_lab(adap, status);
- return -EINTR;
- }
-
- if (timeout == 0)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-/*
- * This should perform the 'PCF8584 initialization sequence' as described
- * in the Philips IC12 data book (1995, Aug 29).
- * There should be a 30 clock cycle wait after reset, I assume this
- * has been fulfilled.
- * There should be a delay at the end equal to the longest I2C message
- * to synchronize the BB-bit (in multimaster systems). How long is
- * this? I assume 1 second is always long enough.
- *
- * vdovikin: added detect code for PCF8584
- */
-static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
-{
- unsigned char temp;
-
- DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
- get_pcf(adap, 1)));
-
- /* S1=0x80: S0 selected, serial interface off */
- set_pcf(adap, 1, I2C_PCF_PIN);
- /*
- * check to see S1 now used as R/W ctrl -
- * PCF8584 does that when ESO is zero
- */
- if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
- return -ENXIO; /* definitely not PCF8584 */
- }
-
- /* load own address in S0, effective address is (own << 1) */
- i2c_outb(adap, get_own(adap));
- /* check it's really written */
- if ((temp = i2c_inb(adap)) != get_own(adap)) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
- return -ENXIO;
- }
-
- /* S1=0xA0, next byte in S2 */
- set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
- /* check to see S2 now selected */
- if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
- return -ENXIO;
- }
-
- /* load clock register S2 */
- i2c_outb(adap, get_clock(adap));
- /* check it's really written, the only 5 lowest bits does matter */
- if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
- return -ENXIO;
- }
-
- /* Enable serial interface, idle, S0 selected */
- set_pcf(adap, 1, I2C_PCF_IDLE);
-
- /* check to see PCF is really idled and we can access status register */
- if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
- return -ENXIO;
- }
-
- printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
-
- return 0;
-}
-
-static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
- int count, int last)
-{
- struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
- int wrcount, status, timeout;
-
- for (wrcount=0; wrcount<count; ++wrcount) {
- DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
- buf[wrcount] & 0xff));
- i2c_outb(adap, buf[wrcount]);
- timeout = wait_for_pin(adap, &status);
- if (timeout) {
- if (timeout == -EINTR)
- return -EINTR; /* arbitration lost */
-
- i2c_stop(adap);
- dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
- return -EREMOTEIO; /* got a better one ?? */
- }
- if (status & I2C_PCF_LRB) {
- i2c_stop(adap);
- dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
- return -EREMOTEIO; /* got a better one ?? */
- }
- }
- if (last)
- i2c_stop(adap);
- else
- i2c_repstart(adap);
-
- return wrcount;
-}
-
-static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
- int count, int last)
-{
- int i, status;
- struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
- int wfp;
-
- /* increment number of bytes to read by one -- read dummy byte */
- for (i = 0; i <= count; i++) {
-
- if ((wfp = wait_for_pin(adap, &status))) {
- if (wfp == -EINTR)
- return -EINTR; /* arbitration lost */
-
- i2c_stop(adap);
- dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
- return -1;
- }
-
- if ((status & I2C_PCF_LRB) && (i != count)) {
- i2c_stop(adap);
- dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
- return -1;
- }
-
- if (i == count - 1) {
- set_pcf(adap, 1, I2C_PCF_ESO);
- } else if (i == count) {
- if (last)
- i2c_stop(adap);
- else
- i2c_repstart(adap);
- }
-
- if (i)
- buf[i - 1] = i2c_inb(adap);
- else
- i2c_inb(adap); /* dummy read */
- }
-
- return i - 1;
-}
-
-
-static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
- struct i2c_msg *msg)
-{
- unsigned short flags = msg->flags;
- unsigned char addr;
-
- addr = msg->addr << 1;
- if (flags & I2C_M_RD)
- addr |= 1;
- if (flags & I2C_M_REV_DIR_ADDR)
- addr ^= 1;
- i2c_outb(adap, addr);
-
- return 0;
-}
-
-static int pcf_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
- struct i2c_msg *pmsg;
- int i;
- int ret=0, timeout, status;
-
- if (adap->xfer_begin)
- adap->xfer_begin(adap->data);
-
- /* Check for bus busy */
- timeout = wait_for_bb(adap);
- if (timeout) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
- "Timeout waiting for BB in pcf_xfer\n");)
- i = -EIO;
- goto out;
- }
-
- for (i = 0;ret >= 0 && i < num; i++) {
- pmsg = &msgs[i];
-
- DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
- pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);)
-
- ret = pcf_doAddress(adap, pmsg);
-
- /* Send START */
- if (i == 0)
- i2c_start(adap);
-
- /* Wait for PIN (pending interrupt NOT) */
- timeout = wait_for_pin(adap, &status);
- if (timeout) {
- if (timeout == -EINTR) {
- /* arbitration lost */
- i = -EINTR;
- goto out;
- }
- i2c_stop(adap);
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
- "for PIN(1) in pcf_xfer\n");)
- i = -EREMOTEIO;
- goto out;
- }
-
- /* Check LRB (last rcvd bit - slave ack) */
- if (status & I2C_PCF_LRB) {
- i2c_stop(adap);
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
- i = -EREMOTEIO;
- goto out;
- }
-
- DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
- i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-
- if (pmsg->flags & I2C_M_RD) {
- ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
- if (ret != pmsg->len) {
- DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
- "only read %d bytes.\n",ret));
- } else {
- DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
- }
- } else {
- ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
- if (ret != pmsg->len) {
- DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
- "only wrote %d bytes.\n",ret));
- } else {
- DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret));
- }
- }
- }
-
-out:
- if (adap->xfer_end)
- adap->xfer_end(adap->data);
- return i;
-}
-
-static u32 pcf_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
- I2C_FUNC_PROTOCOL_MANGLING;
-}
-
-/* exported algorithm data: */
-static const struct i2c_algorithm pcf_algo = {
- .master_xfer = pcf_xfer,
- .functionality = pcf_func,
-};
-
-/*
- * registering functions to load algorithms at runtime
- */
-int i2c_pcf_add_bus(struct i2c_adapter *adap)
-{
- struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
- int rval;
-
- DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));
-
- /* register new adapter to i2c module... */
- adap->algo = &pcf_algo;
-
- if ((rval = pcf_init_8584(pcf_adap)))
- return rval;
-
- rval = i2c_add_adapter(adap);
-
- return rval;
-}
-EXPORT_SYMBOL(i2c_pcf_add_bus);
-
-MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
-MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
-MODULE_LICENSE("GPL");
-
-module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.h b/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.h
deleted file mode 100644
index 1ec703ee..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/i2c-algo-pcf.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -------------------------------------------------------------------- */
-/* i2c-pcf8584.h: PCF 8584 global defines */
-/* -------------------------------------------------------------------- */
-/* Copyright (C) 1996 Simon G. Vogl
- 1999 Hans Berglund
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA. */
-/* -------------------------------------------------------------------- */
-
-/* With some changes from Frodo Looijaard <frodol@dds.nl> */
-
-#ifndef I2C_PCF8584_H
-#define I2C_PCF8584_H 1
-
-/* ----- Control register bits ---------------------------------------- */
-#define I2C_PCF_PIN 0x80
-#define I2C_PCF_ESO 0x40
-#define I2C_PCF_ES1 0x20
-#define I2C_PCF_ES2 0x10
-#define I2C_PCF_ENI 0x08
-#define I2C_PCF_STA 0x04
-#define I2C_PCF_STO 0x02
-#define I2C_PCF_ACK 0x01
-
-#define I2C_PCF_START (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK)
-#define I2C_PCF_STOP (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STO | I2C_PCF_ACK)
-#define I2C_PCF_REPSTART ( I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK)
-#define I2C_PCF_IDLE (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ACK)
-
-/* ----- Status register bits ----------------------------------------- */
-/*#define I2C_PCF_PIN 0x80 as above*/
-
-#define I2C_PCF_INI 0x40 /* 1 if not initialized */
-#define I2C_PCF_STS 0x20
-#define I2C_PCF_BER 0x10
-#define I2C_PCF_AD0 0x08
-#define I2C_PCF_LRB 0x08
-#define I2C_PCF_AAS 0x04
-#define I2C_PCF_LAB 0x02
-#define I2C_PCF_BB 0x01
-
-/* ----- Chip clock frequencies --------------------------------------- */
-#define I2C_PCF_CLK3 0x00
-#define I2C_PCF_CLK443 0x10
-#define I2C_PCF_CLK6 0x14
-#define I2C_PCF_CLK 0x18
-#define I2C_PCF_CLK12 0x1c
-
-/* ----- transmission frequencies ------------------------------------- */
-#define I2C_PCF_TRNS90 0x00 /* 90 kHz */
-#define I2C_PCF_TRNS45 0x01 /* 45 kHz */
-#define I2C_PCF_TRNS11 0x02 /* 11 kHz */
-#define I2C_PCF_TRNS15 0x03 /* 1.5 kHz */
-
-
-/* ----- Access to internal registers according to ES1,ES2 ------------ */
-/* they are mapped to the data port ( a0 = 0 ) */
-/* available when ESO == 0 : */
-
-#define I2C_PCF_OWNADR 0
-#define I2C_PCF_INTREG I2C_PCF_ES2
-#define I2C_PCF_CLKREG I2C_PCF_ES1
-
-#endif /* I2C_PCF8584_H */
diff --git a/ANDROID_3.4.5/drivers/i2c/algos/wmt-i2c-algo.c b/ANDROID_3.4.5/drivers/i2c/algos/wmt-i2c-algo.c
deleted file mode 100755
index 3be850d2..00000000
--- a/ANDROID_3.4.5/drivers/i2c/algos/wmt-i2c-algo.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*++
- drivers/i2c/algos/wmt_i2c_algo.c
-
- Copyright (c) 2008 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-
-#define WMT_I2C_ALGO_C
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-/*
-#include <linux/i2c-id.h>
-*/
-
-#include <mach/hardware.h>
-#include <mach/wmt-i2c-bus.h>
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
- #define DPRINTK printk
-#else
- #define DPRINTK(x...)
-#endif
-
-#else
-#define DPRINTK printf
-
-#endif
-
-static struct i2c_adapter *wmt_i2c_adap[5];
-
-/*!*************************************************************************
-* wmt_i2c_valid_messages()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief verify the input message
-*
-* \retval 1 if success
-*/
-static int wmt_i2c_valid_messages(
- struct i2c_msg msgs[], /*!<; //[IN] transfer data */
- int num /*!<; //[IN] transfer data length */
-)
-{
- int i;
- if (num < 1 || num > MAX_MESSAGES) {
- DPRINTK(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n", MAX_MESSAGES, num);
- return -EINVAL;
- }
-
- /* check consistency of our messages */
- for (i = 0; i < num; i++) {
- if (&msgs[i] == NULL) {
- DPRINTK(KERN_INFO "Msgs is NULL\n");
- return -EINVAL;
- } else {
- if (msgs[i].buf == NULL) {
- DPRINTK(KERN_INFO "Length is less than zero\n");
- return -EINVAL;
- }
- }
- }
-
- return 1;
-}
-/*!*************************************************************************
-* wmt_i2c_do_xfer()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief
-*
-* \retval 0 if success
-*/
-static int wmt_i2c_do_xfer(
- struct i2c_adapter *i2c_adap, /*!<; //[IN] a pointer point to struct inode */
- struct i2c_msg msgs[], /*!<; //[IN] transfer data */
- int num /*!<; //[IN] transfer data length */
-)
-{
- int i;
- struct i2c_algo_wmt_data *adap;
- int ret = 0 ;
-
- adap = i2c_adap->algo_data;
-
- /*ret = adap->wait_bus_not_busy();*/
- for (i = 0 ; i < 10; ++i)
- ;
- if (ret < 0)
- return ret ;
-
- ret = adap->send_request(msgs, num, 0, 0, 0);
-
- return ret;
-
-}
-
-/*!*************************************************************************
-* wmt_i2c_xfer()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief Transfer (read/write) data to i2c bus, wmt_i2c_do_xfer will be called to transfer
-*
-* \retval 0 if success
-*/
-static int wmt_i2c_xfer(
- struct i2c_adapter *i2c_adap, /*!<; //[IN] a pointer point to struct inode */
- struct i2c_msg msgs[], /*!<; //[IN] transfer data */
- int num /*!<; //[IN] transfer data length */
-)
-{
- int ret ;
- int i ;
-
- ret = wmt_i2c_valid_messages(msgs, num);
- if (ret < 0)
- return ret ;
-
- for (i = i2c_adap->retries ; i >= 0; i--) {
-
- ret = wmt_i2c_do_xfer(i2c_adap, msgs, num);
- if (ret > 0)
- return ret ;
- DPRINTK(KERN_INFO"Retrying transmission \n");
- udelay(100);
- }
-
- DPRINTK(KERN_INFO"Retried %i times\n", i2c_adap->retries);
- return ret;
-
-}
-/*!*************************************************************************
-* wmt_i2c_functionality()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief
-*
-* \retval smbus functionality
-*/
-static u32 wmt_i2c_functionality(
- struct i2c_adapter *adapter /*!<; //[IN] a pointer point to struct inode */
-)
-{
- /* Emulate the SMBUS functions*/
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-/*
- * send i2c_msg into fifo of i2c bus
- * msg: transfer data content
- * msg_num:number of transferring msg
- * bus_id :used to indicate which bus do device want to access
- */
-int wmt_i2c_transfer(struct i2c_msg* msgs, int msg_num, int bus_id, void (*callback)(void *data), void *data)
-{
- struct i2c_algo_wmt_data *adap;
- int ret = 0 ;
-
- adap = wmt_i2c_adap[bus_id]->algo_data;
- ret = adap->send_request(msgs, msg_num, 1, callback, data);
- return ret;
-}
-
-#if 0
-/*!*************************************************************************
-* wmt_i2c_control()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief To set i2c transfer mode
-*
-* \retval 0 if success
-*/
-static int wmt_i2c_control(
- struct i2c_adapter *i2c_adap, /*!<; //[IN] a pointer point to struct inode */
- unsigned int cmd, /*!<; //[IN] standard or fast mode */
- unsigned long arg /*!<; //Not in used, but can't delete */
-)
-{
- int ret ;
- struct i2c_algo_wmt_data *adap = i2c_adap->algo_data;
-
- ret = 0 ;
- DPRINTK("wmt_i2c_control: cmd = 0x%8.8x \n", cmd);
-
- switch (cmd) {
- case I2C_SET_STANDARD_MODE:
- adap->set_mode(I2C_STANDARD_MODE);
- break ;
- case I2C_SET_FAST_MODE:
- adap->set_mode(I2C_FAST_MODE);
- break ;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-#endif
-
-
-struct i2c_algorithm wmt_i2c_algorithm = {
- .master_xfer = wmt_i2c_xfer,
- .functionality = wmt_i2c_functionality,
-};
-/*!*************************************************************************
-* wmt_i2c_add_bus()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief
-*
-* \retval NULL
-*/
-int wmt_i2c_add_bus(struct i2c_adapter *i2c_adap)
-{
- printk(KERN_INFO"i2c: adding %s.\n", i2c_adap->name);
-
- i2c_adap->algo = &wmt_i2c_algorithm;
- wmt_i2c_adap[i2c_adap->nr] = i2c_adap;
-
- /* register new adapter to i2c module... */
- /*
- i2c_add_adapter(i2c_adap);
- */
- i2c_add_numbered_adapter(i2c_adap);
-
- /* adap->reset();*/
-
- return 0;
-}
-/*!*************************************************************************
-* wmt_i2c_del_bus()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief
-*
-* \retval NULL
-*/
-int wmt_i2c_del_bus(struct i2c_adapter *i2c_adap)
-{
- int res;
- res = i2c_del_adapter(i2c_adap);
- if (res < 0)
- return res;
-
- printk(KERN_INFO "i2c: removing %s.\n", i2c_adap->name);
-
- return 0;
-}
-/*!*************************************************************************
-* wmt_i2c_algo_init()
-*
-* Private Function by Paul Kwong, 2007/1/12
-*/
-/*!
-* \brief
-*
-* \retval NULL
-*/
-static int __init wmt_i2c_algo_init(void)
-{
- printk(KERN_INFO "i2c: wmt algorithm module loaded.\n");
- return 0;
-}
-
-EXPORT_SYMBOL(wmt_i2c_add_bus);
-EXPORT_SYMBOL(wmt_i2c_del_bus);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT I2C ALGO Driver");
-MODULE_LICENSE("GPL");
-
-module_init(wmt_i2c_algo_init);
-
-#undef WMT_I2C_ALGO_C
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/Kconfig b/ANDROID_3.4.5/drivers/i2c/busses/Kconfig
deleted file mode 100644
index 1bfed463..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/Kconfig
+++ /dev/null
@@ -1,931 +0,0 @@
-#
-# Sensor device configuration
-#
-
-menu "I2C Hardware Bus support"
-
-comment "PC SMBus host controller drivers"
- depends on PCI
-
-config I2C_ALI1535
- tristate "ALI 1535"
- depends on PCI
- help
- If you say yes to this option, support will be included for the SMB
- Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB
- controller is part of the 7101 device, which is an ACPI-compliant
- Power Management Unit (PMU).
-
- This driver can also be built as a module. If so, the module
- will be called i2c-ali1535.
-
-config I2C_ALI1563
- tristate "ALI 1563"
- depends on PCI && EXPERIMENTAL
- help
- If you say yes to this option, support will be included for the SMB
- Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB
- controller is part of the 7101 device, which is an ACPI-compliant
- Power Management Unit (PMU).
-
- This driver can also be built as a module. If so, the module
- will be called i2c-ali1563.
-
-config I2C_ALI15X3
- tristate "ALI 15x3"
- depends on PCI
- help
- If you say yes to this option, support will be included for the
- Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-ali15x3.
-
-config I2C_AMD756
- tristate "AMD 756/766/768/8111 and nVidia nForce"
- depends on PCI
- help
- If you say yes to this option, support will be included for the AMD
- 756/766/768 mainboard I2C interfaces. The driver also includes
- support for the first (SMBus 1.0) I2C interface of the AMD 8111 and
- the nVidia nForce I2C interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-amd756.
-
-config I2C_AMD756_S4882
- tristate "SMBus multiplexing on the Tyan S4882"
- depends on I2C_AMD756 && X86 && EXPERIMENTAL
- help
- Enabling this option will add specific SMBus support for the Tyan
- S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed
- over 8 different channels, where the various memory module EEPROMs
- and temperature sensors live. Saying yes here will give you access
- to these in addition to the trunk.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-amd756-s4882.
-
-config I2C_AMD8111
- tristate "AMD 8111"
- depends on PCI
- help
- If you say yes to this option, support will be included for the
- second (SMBus 2.0) AMD 8111 mainboard I2C interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-amd8111.
-
-config I2C_I801
- tristate "Intel 82801 (ICH/PCH)"
- depends on PCI
- select CHECK_SIGNATURE if X86 && DMI
- help
- If you say yes to this option, support will be included for the Intel
- 801 family of mainboard I2C interfaces. Specifically, the following
- versions of the chipset are supported:
- 82801AA
- 82801AB
- 82801BA
- 82801CA/CAM
- 82801DB
- 82801EB/ER (ICH5/ICH5R)
- 6300ESB
- ICH6
- ICH7
- ESB2
- ICH8
- ICH9
- EP80579 (Tolapai)
- ICH10
- 5/3400 Series (PCH)
- 6 Series (PCH)
- Patsburg (PCH)
- DH89xxCC (PCH)
- Panther Point (PCH)
- Lynx Point (PCH)
-
- This driver can also be built as a module. If so, the module
- will be called i2c-i801.
-
-config I2C_ISCH
- tristate "Intel SCH SMBus 1.0"
- depends on PCI
- select LPC_SCH
- help
- Say Y here if you want to use SMBus controller on the Intel SCH
- based systems.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-isch.
-
-config I2C_PIIX4
- tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)"
- depends on PCI
- help
- If you say yes to this option, support will be included for the Intel
- PIIX4 family of mainboard I2C interfaces. Specifically, the following
- versions of the chipset are supported (note that Serverworks is part
- of Broadcom):
- Intel PIIX4
- Intel 440MX
- ATI IXP200
- ATI IXP300
- ATI IXP400
- ATI SB600
- ATI SB700
- ATI SB800
- AMD Hudson-2
- Serverworks OSB4
- Serverworks CSB5
- Serverworks CSB6
- Serverworks HT-1000
- Serverworks HT-1100
- SMSC Victory66
-
- This driver can also be built as a module. If so, the module
- will be called i2c-piix4.
-
-config I2C_NFORCE2
- tristate "Nvidia nForce2, nForce3 and nForce4"
- depends on PCI
- help
- If you say yes to this option, support will be included for the Nvidia
- nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-nforce2.
-
-config I2C_NFORCE2_S4985
- tristate "SMBus multiplexing on the Tyan S4985"
- depends on I2C_NFORCE2 && X86 && EXPERIMENTAL
- help
- Enabling this option will add specific SMBus support for the Tyan
- S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed
- over 4 different channels, where the various memory module EEPROMs
- live. Saying yes here will give you access to these in addition
- to the trunk.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-nforce2-s4985.
-
-config I2C_SIS5595
- tristate "SiS 5595"
- depends on PCI
- help
- If you say yes to this option, support will be included for the
- SiS5595 SMBus (a subset of I2C) interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-sis5595.
-
-config I2C_SIS630
- tristate "SiS 630/730"
- depends on PCI
- help
- If you say yes to this option, support will be included for the
- SiS630 and SiS730 SMBus (a subset of I2C) interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-sis630.
-
-config I2C_SIS96X
- tristate "SiS 96x"
- depends on PCI
- help
- If you say yes to this option, support will be included for the SiS
- 96x SMBus (a subset of I2C) interfaces. Specifically, the following
- chipsets are supported:
- 645/961
- 645DX/961
- 645DX/962
- 648/961
- 650/961
- 735
- 745
-
- This driver can also be built as a module. If so, the module
- will be called i2c-sis96x.
-
-config I2C_VIA
- tristate "VIA VT82C586B"
- depends on PCI && EXPERIMENTAL
- select I2C_ALGOBIT
- help
- If you say yes to this option, support will be included for the VIA
- 82C586B I2C interface
-
- This driver can also be built as a module. If so, the module
- will be called i2c-via.
-
-config I2C_VIAPRO
- tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx"
- depends on PCI
- help
- If you say yes to this option, support will be included for the VIA
- VT82C596 and later SMBus interface. Specifically, the following
- chipsets are supported:
- VT82C596A/B
- VT82C686A/B
- VT8231
- VT8233/A
- VT8235
- VT8237R/A/S
- VT8251
- CX700
- VX800/VX820
- VX855/VX875
-
- This driver can also be built as a module. If so, the module
- will be called i2c-viapro.
-
-if ACPI
-
-comment "ACPI drivers"
-
-config I2C_SCMI
- tristate "SMBus Control Method Interface"
- help
- This driver supports the SMBus Control Method Interface. It needs the
- BIOS to declare ACPI control methods as described in the SMBus Control
- Method Interface specification.
-
- To compile this driver as a module, choose M here:
- the module will be called i2c-scmi.
-
-endif # ACPI
-
-comment "Mac SMBus host controller drivers"
- depends on PPC_CHRP || PPC_PMAC
-
-config I2C_HYDRA
- tristate "CHRP Apple Hydra Mac I/O I2C interface"
- depends on PCI && PPC_CHRP && EXPERIMENTAL
- select I2C_ALGOBIT
- help
- This supports the use of the I2C interface in the Apple Hydra Mac
- I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you
- have such a machine.
-
- This support is also available as a module. If so, the module
- will be called i2c-hydra.
-
-config I2C_POWERMAC
- tristate "Powermac I2C interface"
- depends on PPC_PMAC
- default y
- help
- This exposes the various PowerMac i2c interfaces to the linux i2c
- layer and to userland. It is used by various drivers on the PowerMac
- platform, and should generally be enabled.
-
- This support is also available as a module. If so, the module
- will be called i2c-powermac.
-
-comment "I2C system bus drivers (mostly embedded / system-on-chip)"
-
-config I2C_AT91
- tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
- depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
- help
- This supports the use of the I2C interface on Atmel AT91
- processors.
-
- This driver is BROKEN because the controller which it uses
- will easily trigger RX overrun and TX underrun errors. Using
- low I2C clock rates may partially work around those issues
- on some systems. Another serious problem is that there is no
- documented way to issue repeated START conditions, as needed
- to support combined I2C messages. Use the i2c-gpio driver
- unless your system can cope with those limitations.
-
-config I2C_AU1550
- tristate "Au1550/Au1200/Au1300 SMBus interface"
- depends on MIPS_ALCHEMY
- help
- If you say yes to this option, support will be included for the
- Au1550/Au1200/Au1300 SMBus interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-au1550.
-
-config I2C_BLACKFIN_TWI
- tristate "Blackfin TWI I2C support"
- depends on BLACKFIN
- depends on !BF561 && !BF531 && !BF532 && !BF533
- help
- This is the I2C bus driver for Blackfin on-chip TWI interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-bfin-twi.
-
-config I2C_BLACKFIN_TWI_CLK_KHZ
- int "Blackfin TWI I2C clock (kHz)"
- depends on I2C_BLACKFIN_TWI
- range 21 400
- default 50
- help
- The unit of the TWI clock is kHz.
-
-config I2C_CPM
- tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
- depends on (CPM1 || CPM2) && OF_I2C
- help
- This supports the use of the I2C interface on Freescale
- processors with CPM1 or CPM2.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-cpm.
-
-config I2C_DAVINCI
- tristate "DaVinci I2C driver"
- depends on ARCH_DAVINCI
- help
- Support for TI DaVinci I2C controller driver.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-davinci.
-
- Please note that this driver might be needed to bring up other
- devices such as DaVinci NIC.
- For details please see http://www.ti.com/davinci
-
-config I2C_DESIGNWARE_PLATFORM
- tristate "Synopsys DesignWare Platfrom"
- depends on HAVE_CLK
- help
- If you say yes to this option, support will be included for the
- Synopsys DesignWare I2C adapter. Only master mode is supported.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-designware-platform.
-
-config I2C_DESIGNWARE_PCI
- tristate "Synopsys DesignWare PCI"
- depends on PCI
- help
- If you say yes to this option, support will be included for the
- Synopsys DesignWare I2C adapter. Only master mode is supported.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-designware-pci.
-
-config I2C_EG20T
- tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) I2C"
- depends on PCI
- help
- This driver is for PCH(Platform controller Hub) I2C of EG20T which
- is an IOH(Input/Output Hub) for x86 embedded processor.
- This driver can access PCH I2C bus device.
-
- This driver also can be used for LAPIS Semiconductor IOH(Input/
- Output Hub), ML7213, ML7223 and ML7831.
- ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is
- for MP(Media Phone) use and ML7831 IOH is for general purpose use.
- ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
- ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
-
-config I2C_GPIO
- tristate "GPIO-based bitbanging I2C"
- depends on GENERIC_GPIO
- select I2C_ALGOBIT
- help
- This is a very simple bitbanging I2C driver utilizing the
- arch-neutral GPIO API to control the SCL and SDA lines.
-
-config I2C_HIGHLANDER
- tristate "Highlander FPGA SMBus interface"
- depends on SH_HIGHLANDER
- help
- If you say yes to this option, support will be included for
- the SMBus interface located in the FPGA on various Highlander
- boards, particularly the R0P7780LC0011RL and R0P7785LC0011RL
- FPGAs. This is wholly unrelated to the SoC I2C.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-highlander.
-
-config I2C_IBM_IIC
- tristate "IBM PPC 4xx on-chip I2C interface"
- depends on 4xx
- help
- Say Y here if you want to use IIC peripheral found on
- embedded IBM PPC 4xx based systems.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-ibm_iic.
-
-config I2C_IMX
- tristate "IMX I2C interface"
- depends on ARCH_MXC
- help
- Say Y here if you want to use the IIC bus controller on
- the Freescale i.MX/MXC processors.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-imx.
-
-config I2C_INTEL_MID
- tristate "Intel Moorestown/Medfield Platform I2C controller"
- depends on PCI
- help
- Say Y here if you have an Intel Moorestown/Medfield platform I2C
- controller.
-
- This support is also available as a module. If so, the module
- will be called i2c-intel-mid.
-
-config I2C_IOP3XX
- tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
- depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
- help
- Say Y here if you want to use the IIC bus controller on
- the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-iop3xx.
-
-config I2C_IXP2000
- tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)"
- depends on ARCH_IXP2000
- select I2C_ALGOBIT
- help
- Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based
- system and are using GPIO lines for an I2C bus.
-
- This support is also available as a module. If so, the module
- will be called i2c-ixp2000.
-
- This driver is deprecated and will be dropped soon. Use i2c-gpio
- instead.
-
-config I2C_MPC
- tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
- depends on PPC
- help
- If you say yes to this option, support will be included for the
- built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
- MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-mpc.
-
-config I2C_MV64XXX
- tristate "Marvell mv64xxx I2C Controller"
- depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
- help
- If you say yes to this option, support will be included for the
- built-in I2C interface on the Marvell 64xxx line of host bridges.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-mv64xxx.
-
-config I2C_MXS
- tristate "Freescale i.MX28 I2C interface"
- depends on SOC_IMX28
- help
- Say Y here if you want to use the I2C bus controller on
- the Freescale i.MX28 processors.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-mxs.
-
-config I2C_NOMADIK
- tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"
- depends on PLAT_NOMADIK
- help
- If you say yes to this option, support will be included for the
- I2C interface from ST-Ericsson's Nomadik and Ux500 architectures.
-
-config I2C_NUC900
- tristate "NUC900 I2C Driver"
- depends on ARCH_W90X900
- help
- Say Y here to include support for I2C controller in the
- Winbond/Nuvoton NUC900 based System-on-Chip devices.
-
-config I2C_OCORES
- tristate "OpenCores I2C Controller"
- depends on EXPERIMENTAL
- help
- If you say yes to this option, support will be included for the
- OpenCores I2C controller. For details see
- http://www.opencores.org/projects.cgi/web/i2c/overview
-
- This driver can also be built as a module. If so, the module
- will be called i2c-ocores.
-
-config I2C_OMAP
- tristate "OMAP I2C adapter"
- depends on ARCH_OMAP
- default y if MACH_OMAP_H3 || MACH_OMAP_OSK
- help
- If you say yes to this option, support will be included for the
- I2C interface on the Texas Instruments OMAP1/2 family of processors.
- Like OMAP1510/1610/1710/5912 and OMAP242x.
- For details see http://www.ti.com/omap.
-
-config I2C_PASEMI
- tristate "PA Semi SMBus interface"
- depends on PPC_PASEMI && PCI
- help
- Supports the PA Semi PWRficient on-chip SMBus interfaces.
-
-config I2C_PCA_PLATFORM
- tristate "PCA9564/PCA9665 as platform device"
- select I2C_ALGOPCA
- default n
- help
- This driver supports a memory mapped Philips PCA9564/PCA9665
- parallel bus to I2C bus controller.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-pca-platform.
-
-config I2C_PMCMSP
- tristate "PMC MSP I2C TWI Controller"
- depends on PMC_MSP
- help
- This driver supports the PMC TWI controller on MSP devices.
-
- This driver can also be built as module. If so, the module
- will be called i2c-pmcmsp.
-
-config I2C_PNX
- tristate "I2C bus support for Philips PNX and NXP LPC targets"
- depends on ARCH_PNX4008 || ARCH_LPC32XX
- help
- This driver supports the Philips IP3204 I2C IP block master and/or
- slave controller
-
- This driver can also be built as a module. If so, the module
- will be called i2c-pnx.
-
-config I2C_PUV3
- tristate "PKUnity v3 I2C bus support"
- depends on UNICORE32 && ARCH_PUV3
- select I2C_ALGOBIT
- help
- This driver supports the I2C IP inside the PKUnity-v3 SoC.
- This I2C bus controller is under AMBA/AXI bus.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-puv3.
-
-config I2C_PXA
- tristate "Intel PXA2XX I2C adapter"
- depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF)
- help
- If you have devices in the PXA I2C bus, say yes to this option.
- This driver can also be built as a module. If so, the module
- will be called i2c-pxa.
-
-config I2C_PXA_PCI
- def_bool I2C_PXA && X86_32 && PCI && OF
-
-config I2C_PXA_SLAVE
- bool "Intel PXA2XX I2C Slave comms support"
- depends on I2C_PXA && !X86_32
- help
- Support I2C slave mode communications on the PXA I2C bus. This
- is necessary for systems where the PXA may be a target on the
- I2C bus.
-
-config HAVE_S3C2410_I2C
- bool
- help
- This will include I2C support for Samsung SoCs. If you want to
- include I2C support for any machine, kindly select this in the
- respective Kconfig file.
-
-config I2C_S3C2410
- tristate "S3C2410 I2C Driver"
- depends on HAVE_S3C2410_I2C
- help
- Say Y here to include support for I2C controller in the
- Samsung SoCs.
-
-config I2C_S6000
- tristate "S6000 I2C support"
- depends on XTENSA_VARIANT_S6000
- help
- This driver supports the on chip I2C device on the
- S6000 xtensa processor family.
-
- To compile this driver as a module, choose M here. The module
- will be called i2c-s6000.
-
-config I2C_SH7760
- tristate "Renesas SH7760 I2C Controller"
- depends on CPU_SUBTYPE_SH7760
- help
- This driver supports the 2 I2C interfaces on the Renesas SH7760.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-sh7760.
-
-config I2C_SH_MOBILE
- tristate "SuperH Mobile I2C Controller"
- depends on SUPERH || ARCH_SHMOBILE
- help
- If you say yes to this option, support will be included for the
- built-in I2C interface on the Renesas SH-Mobile processor.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-sh_mobile.
-
-config I2C_SIMTEC
- tristate "Simtec Generic I2C interface"
- select I2C_ALGOBIT
- help
- If you say yes to this option, support will be included for
- the Simtec Generic I2C interface. This driver is for the
- simple I2C bus used on newer Simtec products for general
- I2C, such as DDC on the Simtec BBD2016A.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-simtec.
-
-config I2C_SIRF
- tristate "CSR SiRFprimaII I2C interface"
- depends on ARCH_PRIMA2
- help
- If you say yes to this option, support will be included for the
- CSR SiRFprimaII I2C interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-sirf.
-
-config I2C_STU300
- tristate "ST Microelectronics DDC I2C interface"
- depends on MACH_U300
- default y if MACH_U300
- help
- If you say yes to this option, support will be included for the
- I2C interface from ST Microelectronics simply called "DDC I2C"
- supporting both I2C and DDC, used in e.g. the U300 series
- mobile platforms.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-stu300.
-
-config I2C_TEGRA
- tristate "NVIDIA Tegra internal I2C controller"
- depends on ARCH_TEGRA
- help
- If you say yes to this option, support will be included for the
- I2C controller embedded in NVIDIA Tegra SOCs
-
-config I2C_VERSATILE
- tristate "ARM Versatile/Realview I2C bus support"
- depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
- select I2C_ALGOBIT
- help
- Say yes if you want to support the I2C serial bus on ARMs Versatile
- range of platforms.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-versatile.
-
-config I2C_OCTEON
- tristate "Cavium OCTEON I2C bus support"
- depends on CPU_CAVIUM_OCTEON
- help
- Say yes if you want to support the I2C serial bus on Cavium
- OCTEON SOC.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-octeon.
-
-config I2C_XILINX
- tristate "Xilinx I2C Controller"
- depends on EXPERIMENTAL && HAS_IOMEM
- help
- If you say yes to this option, support will be included for the
- Xilinx I2C controller.
-
- This driver can also be built as a module. If so, the module
- will be called xilinx_i2c.
-
-config I2C_XLR
- tristate "XLR I2C support"
- depends on CPU_XLR
- help
- This driver enables support for the on-chip I2C interface of
- the Netlogic XLR/XLS MIPS processors.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-xlr.
-
-comment "External I2C/SMBus adapter drivers"
-
-config I2C_DIOLAN_U2C
- tristate "Diolan U2C-12 USB adapter"
- depends on USB
- help
- If you say yes to this option, support will be included for Diolan
- U2C-12, a USB to I2C interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-diolan-u2c.
-
-config I2C_PARPORT
- tristate "Parallel port adapter"
- depends on PARPORT
- select I2C_ALGOBIT
- select I2C_SMBUS
- help
- This supports parallel port I2C adapters such as the ones made by
- Philips or Velleman, Analog Devices evaluation boards, and more.
- Basically any adapter using the parallel port as an I2C bus with
- no extra chipset is supported by this driver, or could be.
-
- This driver is a replacement for (and was inspired by) an older
- driver named i2c-philips-par. The new driver supports more devices,
- and makes it easier to add support for new devices.
-
- An adapter type parameter is now mandatory. Please read the file
- Documentation/i2c/busses/i2c-parport for details.
-
- Another driver exists, named i2c-parport-light, which doesn't depend
- on the parport driver. This is meant for embedded systems. Don't say
- Y here if you intend to say Y or M there.
-
- This support is also available as a module. If so, the module
- will be called i2c-parport.
-
-config I2C_PARPORT_LIGHT
- tristate "Parallel port adapter (light)"
- select I2C_ALGOBIT
- select I2C_SMBUS
- help
- This supports parallel port I2C adapters such as the ones made by
- Philips or Velleman, Analog Devices evaluation boards, and more.
- Basically any adapter using the parallel port as an I2C bus with
- no extra chipset is supported by this driver, or could be.
-
- This driver is a light version of i2c-parport. It doesn't depend
- on the parport driver, and uses direct I/O access instead. This
- might be preferred on embedded systems where wasting memory for
- the clean but heavy parport handling is not an option. The
- drawback is a reduced portability and the impossibility to
- daisy-chain other parallel port devices.
-
- Don't say Y here if you said Y or M to i2c-parport. Saying M to
- both is possible but both modules should not be loaded at the same
- time.
-
- This support is also available as a module. If so, the module
- will be called i2c-parport-light.
-
-config I2C_TAOS_EVM
- tristate "TAOS evaluation module"
- depends on EXPERIMENTAL
- select SERIO
- select SERIO_SERPORT
- default n
- help
- This supports TAOS evaluation modules on serial port. In order to
- use this driver, you will need the inputattach tool, which is part
- of the input-utils package.
-
- If unsure, say N.
-
- This support is also available as a module. If so, the module
- will be called i2c-taos-evm.
-
-config I2C_TINY_USB
- tristate "Tiny-USB adapter"
- depends on USB
- help
- If you say yes to this option, support will be included for the
- i2c-tiny-usb, a simple do-it-yourself USB to I2C interface. See
- http://www.harbaum.org/till/i2c_tiny_usb for hardware details.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-tiny-usb.
-
-comment "Other I2C/SMBus bus drivers"
-
-config I2C_ACORN
- tristate "Acorn IOC/IOMD I2C bus support"
- depends on ARCH_ACORN
- default y
- select I2C_ALGOBIT
- help
- Say yes if you want to support the I2C bus on Acorn platforms.
-
- If you don't know, say Y.
-
-config I2C_ELEKTOR
- tristate "Elektor ISA card"
- depends on ISA && HAS_IOPORT && BROKEN_ON_SMP
- select I2C_ALGOPCF
- help
- This supports the PCF8584 ISA bus I2C adapter. Say Y if you own
- such an adapter.
-
- This support is also available as a module. If so, the module
- will be called i2c-elektor.
-
-config I2C_PCA_ISA
- tristate "PCA9564/PCA9665 on an ISA bus"
- depends on ISA
- select I2C_ALGOPCA
- default n
- help
- This driver supports ISA boards using the Philips PCA9564/PCA9665
- parallel bus to I2C bus controller.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-pca-isa.
-
- This device is almost undetectable and using this driver on a
- system which doesn't have this device will result in long
- delays when I2C/SMBus chip drivers are loaded (e.g. at boot
- time). If unsure, say N.
-
-config I2C_SIBYTE
- tristate "SiByte SMBus interface"
- depends on SIBYTE_SB1xxx_SOC
- help
- Supports the SiByte SOC on-chip I2C interfaces (2 channels).
-
-config I2C_STUB
- tristate "I2C/SMBus Test Stub"
- depends on EXPERIMENTAL && m
- default 'n'
- help
- This module may be useful to developers of SMBus client drivers,
- especially for certain kinds of sensor chips.
-
- If you do build this module, be sure to read the notes and warnings
- in <file:Documentation/i2c/i2c-stub>.
-
- If you don't know what to do here, definitely say N.
-
-config SCx200_I2C
- tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
- depends on SCx200_GPIO
- select I2C_ALGOBIT
- help
- Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
-
- If you don't know what to do here, say N.
-
- This support is also available as a module. If so, the module
- will be called scx200_i2c.
-
- This driver is deprecated and will be dropped soon. Use i2c-gpio
- (or scx200_acb) instead.
-
-config SCx200_I2C_SCL
- int "GPIO pin used for SCL"
- depends on SCx200_I2C
- default "12"
- help
- Enter the GPIO pin number used for the SCL signal. This value can
- also be specified with a module parameter.
-
-config SCx200_I2C_SDA
- int "GPIO pin used for SDA"
- depends on SCx200_I2C
- default "13"
- help
- Enter the GPIO pin number used for the SSA signal. This value can
- also be specified with a module parameter.
-
-config SCx200_ACB
- tristate "Geode ACCESS.bus support"
- depends on X86_32 && PCI
- help
- Enable the use of the ACCESS.bus controllers on the Geode SCx200 and
- SC1100 processors and the CS5535 and CS5536 Geode companion devices.
-
- If you don't know what to do here, say N.
-
- This support is also available as a module. If so, the module
- will be called scx200_acb.
-
-config I2C_WMT
- tristate "WonderMedia I2C Interface"
- depends on ARCH_WMT && I2C && I2C_ALGOWMT
- help
- This supports the use of the WMT I2C interface found on the WMT
- Say Y if you have one of these. You should also say Y for the WMT
- I2C peripheral driver support below.
-
- To compile this driver as a module, say M here: the
- modules will be called i2c-wmt and i2c-algo-wmt.
-config I2C1_WMT
- bool
- depends on ARCH_WMT && I2C && I2C_ALGOWMT
- default y
-config I2C_SLAVE_WMT
- bool "WonderMedia I2C-SLAVE Interface"
- depends on ARCH_WMT && I2C_WMT
- help
- This supports the use of the WMT I2C SLAVE interface found on the WMT
- Say Y if you have one of these. You should also say Y for the WMT
- I2C peripheral driver support below.
-endmenu
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/Makefile b/ANDROID_3.4.5/drivers/i2c/busses/Makefile
deleted file mode 100644
index 20082f63..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Makefile for the i2c bus drivers.
-#
-
-# ACPI drivers
-obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o
-
-# PC SMBus host controller drivers
-obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o
-obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o
-obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o
-obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
-obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
-obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
-obj-$(CONFIG_I2C_I801) += i2c-i801.o
-obj-$(CONFIG_I2C_ISCH) += i2c-isch.o
-obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
-obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o
-obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
-obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
-obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
-obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
-obj-$(CONFIG_I2C_VIA) += i2c-via.o
-obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
-
-# Mac SMBus host controller drivers
-obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
-obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
-
-# Embedded system I2C/SMBus host controller drivers
-obj-$(CONFIG_I2C_AT91) += i2c-at91.o
-obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
-obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
-obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
-obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
-obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
-i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o
-obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
-i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o
-obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
-obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
-obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
-obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
-obj-$(CONFIG_I2C_IMX) += i2c-imx.o
-obj-$(CONFIG_I2C_INTEL_MID) += i2c-intel-mid.o
-obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
-obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
-obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
-obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
-obj-$(CONFIG_I2C_MXS) += i2c-mxs.o
-obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
-obj-$(CONFIG_I2C_NUC900) += i2c-nuc900.o
-obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
-obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
-obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
-obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
-obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o
-obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
-obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
-obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
-obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
-obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
-obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
-obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
-obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
-obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
-obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
-obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
-obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o
-obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
-obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
-obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
-obj-$(CONFIG_I2C_XLR) += i2c-xlr.o
-
-# External I2C/SMBus adapter drivers
-obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
-obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
-obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
-obj-$(CONFIG_I2C_TAOS_EVM) += i2c-taos-evm.o
-obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
-
-# Other I2C/SMBus bus drivers
-obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o
-obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
-obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
-obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
-obj-$(CONFIG_I2C_STUB) += i2c-stub.o
-obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
-obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
-
-obj-$(CONFIG_I2C_WMT) += wmt-i2c-bus.o wmt-i2c-bus-1.o wmt-i2c-bus-2.o wmt-i2c-bus-3.o wmt-i2c-bus-4.o
-obj-$(CONFIG_I2C_SLAVE_WMT) += wmt-i2c-slave-bus.o wmt-i2c-slave-bus-1.o
-ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-acorn.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-acorn.c
deleted file mode 100644
index ed9f48d5..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-acorn.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * linux/drivers/acorn/char/i2c.c
- *
- * Copyright (C) 2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * ARM IOC/IOMD i2c driver.
- *
- * On Acorn machines, the following i2c devices are on the bus:
- * - PCF8583 real time clock & static RAM
- */
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/ioc.h>
-
-#define FORCE_ONES 0xdc
-#define SCL 0x02
-#define SDA 0x01
-
-/*
- * We must preserve all non-i2c output bits in IOC_CONTROL.
- * Note also that we need to preserve the value of SCL and
- * SDA outputs as well (which may be different from the
- * values read back from IOC_CONTROL).
- */
-static u_int force_ones;
-
-static void ioc_setscl(void *data, int state)
-{
- u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
- u_int ones = force_ones;
-
- if (state)
- ones |= SCL;
- else
- ones &= ~SCL;
-
- force_ones = ones;
-
- ioc_writeb(ioc_control | ones, IOC_CONTROL);
-}
-
-static void ioc_setsda(void *data, int state)
-{
- u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
- u_int ones = force_ones;
-
- if (state)
- ones |= SDA;
- else
- ones &= ~SDA;
-
- force_ones = ones;
-
- ioc_writeb(ioc_control | ones, IOC_CONTROL);
-}
-
-static int ioc_getscl(void *data)
-{
- return (ioc_readb(IOC_CONTROL) & SCL) != 0;
-}
-
-static int ioc_getsda(void *data)
-{
- return (ioc_readb(IOC_CONTROL) & SDA) != 0;
-}
-
-static struct i2c_algo_bit_data ioc_data = {
- .setsda = ioc_setsda,
- .setscl = ioc_setscl,
- .getsda = ioc_getsda,
- .getscl = ioc_getscl,
- .udelay = 80,
- .timeout = HZ,
-};
-
-static struct i2c_adapter ioc_ops = {
- .nr = 0,
- .algo_data = &ioc_data,
-};
-
-static int __init i2c_ioc_init(void)
-{
- force_ones = FORCE_ONES | SCL | SDA;
-
- return i2c_bit_add_numbered_bus(&ioc_ops);
-}
-
-module_init(i2c_ioc_init);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1535.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1535.c
deleted file mode 100644
index e66d248f..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1535.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * Copyright (c) 2000 Frodo Looijaard <frodol@dds.nl>,
- * Philip Edelbrock <phil@netroedge.com>,
- * Mark D. Studebaker <mdsxyz123@yahoo.com>,
- * Dan Eaton <dan.eaton@rocketlogix.com> and
- * Stephen Rousset <stephen.rousset@rocketlogix.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- This is the driver for the SMB Host controller on
- Acer Labs Inc. (ALI) M1535 South Bridge.
-
- The M1535 is a South bridge for portable systems.
- It is very similar to the M15x3 South bridges also produced
- by Acer Labs Inc. Some of the registers within the part
- have moved and some have been redefined slightly. Additionally,
- the sequencing of the SMBus transactions has been modified
- to be more consistent with the sequencing recommended by
- the manufacturer and observed through testing. These
- changes are reflected in this driver and can be identified
- by comparing this driver to the i2c-ali15x3 driver.
- For an overview of these chips see http://www.acerlabs.com
-
- The SMB controller is part of the 7101 device, which is an
- ACPI-compliant Power Management Unit (PMU).
-
- The whole 7101 device has to be enabled for the SMB to work.
- You can't just enable the SMB alone.
- The SMB and the ACPI have separate I/O spaces.
- We make sure that the SMB is enabled. We leave the ACPI alone.
-
- This driver controls the SMB Host only.
-
- This driver does not use interrupts.
-*/
-
-
-/* Note: we assume there can only be one ALI1535, with one SMBus interface */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-
-/* ALI1535 SMBus address offsets */
-#define SMBHSTSTS (0 + ali1535_smba)
-#define SMBHSTTYP (1 + ali1535_smba)
-#define SMBHSTPORT (2 + ali1535_smba)
-#define SMBHSTCMD (7 + ali1535_smba)
-#define SMBHSTADD (3 + ali1535_smba)
-#define SMBHSTDAT0 (4 + ali1535_smba)
-#define SMBHSTDAT1 (5 + ali1535_smba)
-#define SMBBLKDAT (6 + ali1535_smba)
-
-/* PCI Address Constants */
-#define SMBCOM 0x004
-#define SMBREV 0x008
-#define SMBCFG 0x0D1
-#define SMBBA 0x0E2
-#define SMBHSTCFG 0x0F0
-#define SMBCLK 0x0F2
-
-/* Other settings */
-#define MAX_TIMEOUT 500 /* times 1/100 sec */
-#define ALI1535_SMB_IOSIZE 32
-
-#define ALI1535_SMB_DEFAULTBASE 0x8040
-
-/* ALI1535 address lock bits */
-#define ALI1535_LOCK 0x06 /* dwe */
-
-/* ALI1535 command constants */
-#define ALI1535_QUICK 0x00
-#define ALI1535_BYTE 0x10
-#define ALI1535_BYTE_DATA 0x20
-#define ALI1535_WORD_DATA 0x30
-#define ALI1535_BLOCK_DATA 0x40
-#define ALI1535_I2C_READ 0x60
-
-#define ALI1535_DEV10B_EN 0x80 /* Enable 10-bit addressing in */
- /* I2C read */
-#define ALI1535_T_OUT 0x08 /* Time-out Command (write) */
-#define ALI1535_A_HIGH_BIT9 0x08 /* Bit 9 of 10-bit address in */
- /* Alert-Response-Address */
- /* (read) */
-#define ALI1535_KILL 0x04 /* Kill Command (write) */
-#define ALI1535_A_HIGH_BIT8 0x04 /* Bit 8 of 10-bit address in */
- /* Alert-Response-Address */
- /* (read) */
-
-#define ALI1535_D_HI_MASK 0x03 /* Mask for isolating bits 9-8 */
- /* of 10-bit address in I2C */
- /* Read Command */
-
-/* ALI1535 status register bits */
-#define ALI1535_STS_IDLE 0x04
-#define ALI1535_STS_BUSY 0x08 /* host busy */
-#define ALI1535_STS_DONE 0x10 /* transaction complete */
-#define ALI1535_STS_DEV 0x20 /* device error */
-#define ALI1535_STS_BUSERR 0x40 /* bus error */
-#define ALI1535_STS_FAIL 0x80 /* failed bus transaction */
-#define ALI1535_STS_ERR 0xE0 /* all the bad error bits */
-
-#define ALI1535_BLOCK_CLR 0x04 /* reset block data index */
-
-/* ALI1535 device address register bits */
-#define ALI1535_RD_ADDR 0x01 /* Read/Write Bit in Device */
- /* Address field */
- /* -> Write = 0 */
- /* -> Read = 1 */
-#define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */
-
-static struct pci_driver ali1535_driver;
-static unsigned long ali1535_smba;
-static unsigned short ali1535_offset;
-
-/* Detect whether a ALI1535 can be found, and initialize it, where necessary.
- Note the differences between kernels with the old PCI BIOS interface and
- newer kernels with the real PCI interface. In compat.h some things are
- defined to make the transition easier. */
-static int __devinit ali1535_setup(struct pci_dev *dev)
-{
- int retval;
- unsigned char temp;
-
- /* Check the following things:
- - SMB I/O address is initialized
- - Device is enabled
- - We can use the addresses
- */
-
- retval = pci_enable_device(dev);
- if (retval) {
- dev_err(&dev->dev, "ALI1535_smb can't enable device\n");
- goto exit;
- }
-
- /* Determine the address of the SMBus area */
- pci_read_config_word(dev, SMBBA, &ali1535_offset);
- dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset);
- ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
- if (ali1535_offset == 0) {
- dev_warn(&dev->dev,
- "ALI1535_smb region uninitialized - upgrade BIOS?\n");
- retval = -ENODEV;
- goto exit;
- }
-
- if (pci_resource_flags(dev, 0) & IORESOURCE_IO)
- ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset;
- else
- ali1535_smba = ali1535_offset;
-
- retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
- ali1535_driver.name);
- if (retval)
- goto exit;
-
- if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
- ali1535_driver.name)) {
- dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n",
- ali1535_smba);
- retval = -EBUSY;
- goto exit;
- }
-
- /* check if whole device is enabled */
- pci_read_config_byte(dev, SMBCFG, &temp);
- if ((temp & ALI1535_SMBIO_EN) == 0) {
- dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
- retval = -ENODEV;
- goto exit_free;
- }
-
- /* Is SMB Host controller enabled? */
- pci_read_config_byte(dev, SMBHSTCFG, &temp);
- if ((temp & 1) == 0) {
- dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
- retval = -ENODEV;
- goto exit_free;
- }
-
- /* set SMB clock to 74KHz as recommended in data sheet */
- pci_write_config_byte(dev, SMBCLK, 0x20);
-
- /*
- The interrupt routing for SMB is set up in register 0x77 in the
- 1533 ISA Bridge device, NOT in the 7101 device.
- Don't bother with finding the 1533 device and reading the register.
- if ((....... & 0x0F) == 1)
- dev_dbg(&dev->dev, "ALI1535 using Interrupt 9 for SMBus.\n");
- */
- pci_read_config_byte(dev, SMBREV, &temp);
- dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
- dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba);
-
- return 0;
-
-exit_free:
- release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
-exit:
- return retval;
-}
-
-static int ali1535_transaction(struct i2c_adapter *adap)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
- "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
- inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
- inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-
- /* get status */
- temp = inb_p(SMBHSTSTS);
-
- /* Make sure the SMBus host is ready to start transmitting */
- /* Check the busy bit first */
- if (temp & ALI1535_STS_BUSY) {
- /* If the host controller is still busy, it may have timed out
- * in the previous transaction, resulting in a "SMBus Timeout"
- * printk. I've tried the following to reset a stuck busy bit.
- * 1. Reset the controller with an KILL command. (this
- * doesn't seem to clear the controller if an external
- * device is hung)
- * 2. Reset the controller and the other SMBus devices with a
- * T_OUT command. (this clears the host busy bit if an
- * external device is hung, but it comes back upon a new
- * access to a device)
- * 3. Disable and reenable the controller in SMBHSTCFG. Worst
- * case, nothing seems to work except power reset.
- */
-
- /* Try resetting entire SMB bus, including other devices - This
- * may not work either - it clears the BUSY bit but then the
- * BUSY bit may come back on when you try and use the chip
- * again. If that's the case you are stuck.
- */
- dev_info(&adap->dev,
- "Resetting entire SMB Bus to clear busy condition (%02x)\n",
- temp);
- outb_p(ALI1535_T_OUT, SMBHSTTYP);
- temp = inb_p(SMBHSTSTS);
- }
-
- /* now check the error bits and the busy bit */
- if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
- /* do a clear-on-write */
- outb_p(0xFF, SMBHSTSTS);
- temp = inb_p(SMBHSTSTS);
- if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
- /* This is probably going to be correctable only by a
- * power reset as one of the bits now appears to be
- * stuck */
- /* This may be a bus or device with electrical problems. */
- dev_err(&adap->dev,
- "SMBus reset failed! (0x%02x) - controller or "
- "device on bus is probably hung\n", temp);
- return -EBUSY;
- }
- } else {
- /* check and clear done bit */
- if (temp & ALI1535_STS_DONE)
- outb_p(temp, SMBHSTSTS);
- }
-
- /* start the transaction by writing anything to the start register */
- outb_p(0xFF, SMBHSTPORT);
-
- /* We will always wait for a fraction of a second! */
- timeout = 0;
- do {
- usleep_range(1000, 2000);
- temp = inb_p(SMBHSTSTS);
- } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
- && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- result = -ETIMEDOUT;
- dev_err(&adap->dev, "SMBus Timeout!\n");
- }
-
- if (temp & ALI1535_STS_FAIL) {
- result = -EIO;
- dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
- }
-
- /* Unfortunately the ALI SMB controller maps "no response" and "bus
- * collision" into a single bit. No response is the usual case so don't
- * do a printk. This means that bus collisions go unreported.
- */
- if (temp & ALI1535_STS_BUSERR) {
- result = -ENXIO;
- dev_dbg(&adap->dev,
- "Error: no response or bus collision ADD=%02x\n",
- inb_p(SMBHSTADD));
- }
-
- /* haven't ever seen this */
- if (temp & ALI1535_STS_DEV) {
- result = -EIO;
- dev_err(&adap->dev, "Error: device error\n");
- }
-
- /* check to see if the "command complete" indication is set */
- if (!(temp & ALI1535_STS_DONE)) {
- result = -ETIMEDOUT;
- dev_err(&adap->dev, "Error: command never completed\n");
- }
-
- dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
- "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
- inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
- inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-
- /* take consequent actions for error conditions */
- if (!(temp & ALI1535_STS_DONE)) {
- /* issue "kill" to reset host controller */
- outb_p(ALI1535_KILL, SMBHSTTYP);
- outb_p(0xFF, SMBHSTSTS);
- } else if (temp & ALI1535_STS_ERR) {
- /* issue "timeout" to reset all devices on bus */
- outb_p(ALI1535_T_OUT, SMBHSTTYP);
- outb_p(0xFF, SMBHSTSTS);
- }
-
- return result;
-}
-
-/* Return negative errno on error. */
-static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- int i, len;
- int temp;
- int timeout;
- s32 result = 0;
-
- /* make sure SMBus is idle */
- temp = inb_p(SMBHSTSTS);
- for (timeout = 0;
- (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
- timeout++) {
- usleep_range(1000, 2000);
- temp = inb_p(SMBHSTSTS);
- }
- if (timeout >= MAX_TIMEOUT)
- dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
-
- /* clear status register (clear-on-write) */
- outb_p(0xFF, SMBHSTSTS);
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- size = ALI1535_QUICK;
- outb_p(size, SMBHSTTYP); /* output command */
- break;
- case I2C_SMBUS_BYTE:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- size = ALI1535_BYTE;
- outb_p(size, SMBHSTTYP); /* output command */
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, SMBHSTCMD);
- break;
- case I2C_SMBUS_BYTE_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- size = ALI1535_BYTE_DATA;
- outb_p(size, SMBHSTTYP); /* output command */
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMBHSTDAT0);
- break;
- case I2C_SMBUS_WORD_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- size = ALI1535_WORD_DATA;
- outb_p(size, SMBHSTTYP); /* output command */
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMBHSTDAT0);
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
- }
- break;
- case I2C_SMBUS_BLOCK_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- size = ALI1535_BLOCK_DATA;
- outb_p(size, SMBHSTTYP); /* output command */
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len < 0) {
- len = 0;
- data->block[0] = len;
- }
- if (len > 32) {
- len = 32;
- data->block[0] = len;
- }
- outb_p(len, SMBHSTDAT0);
- /* Reset SMBBLKDAT */
- outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
- for (i = 1; i <= len; i++)
- outb_p(data->block[i], SMBBLKDAT);
- }
- break;
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- result = -EOPNOTSUPP;
- goto EXIT;
- }
-
- result = ali1535_transaction(adap);
- if (result)
- goto EXIT;
-
- if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
- result = 0;
- goto EXIT;
- }
-
- switch (size) {
- case ALI1535_BYTE: /* Result put in SMBHSTDAT0 */
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case ALI1535_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case ALI1535_WORD_DATA:
- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
- break;
- case ALI1535_BLOCK_DATA:
- len = inb_p(SMBHSTDAT0);
- if (len > 32)
- len = 32;
- data->block[0] = len;
- /* Reset SMBBLKDAT */
- outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
- for (i = 1; i <= data->block[0]; i++) {
- data->block[i] = inb_p(SMBBLKDAT);
- dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
- len, i, data->block[i]);
- }
- break;
- }
-EXIT:
- return result;
-}
-
-
-static u32 ali1535_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = ali1535_access,
- .functionality = ali1535_func,
-};
-
-static struct i2c_adapter ali1535_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(ali1535_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
- { },
-};
-
-MODULE_DEVICE_TABLE(pci, ali1535_ids);
-
-static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- if (ali1535_setup(dev)) {
- dev_warn(&dev->dev,
- "ALI1535 not detected, module not inserted.\n");
- return -ENODEV;
- }
-
- /* set up the sysfs linkage to our parent device */
- ali1535_adapter.dev.parent = &dev->dev;
-
- snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
- "SMBus ALI1535 adapter at %04x", ali1535_offset);
- return i2c_add_adapter(&ali1535_adapter);
-}
-
-static void __devexit ali1535_remove(struct pci_dev *dev)
-{
- i2c_del_adapter(&ali1535_adapter);
- release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
-}
-
-static struct pci_driver ali1535_driver = {
- .name = "ali1535_smbus",
- .id_table = ali1535_ids,
- .probe = ali1535_probe,
- .remove = __devexit_p(ali1535_remove),
-};
-
-static int __init i2c_ali1535_init(void)
-{
- return pci_register_driver(&ali1535_driver);
-}
-
-static void __exit i2c_ali1535_exit(void)
-{
- pci_unregister_driver(&ali1535_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
- "Philip Edelbrock <phil@netroedge.com>, "
- "Mark D. Studebaker <mdsxyz123@yahoo.com> "
- "and Dan Eaton <dan.eaton@rocketlogix.com>");
-MODULE_DESCRIPTION("ALI1535 SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_ali1535_init);
-module_exit(i2c_ali1535_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1563.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1563.c
deleted file mode 100644
index 47ae0091..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali1563.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/**
- * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
- *
- * Copyright (C) 2004 Patrick Mochel
- * 2005 Rudolf Marek <r.marek@assembler.cz>
- *
- * The 1563 southbridge is deceptively similar to the 1533, with a
- * few notable exceptions. One of those happens to be the fact they
- * upgraded the i2c core to be 2.0 compliant, and happens to be almost
- * identical to the i2c controller found in the Intel 801 south
- * bridges.
- *
- * This driver is based on a mix of the 15x3, 1535, and i801 drivers,
- * with a little help from the ALi 1563 spec.
- *
- * This file is released under the GPLv2
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-
-#define ALI1563_MAX_TIMEOUT 500
-#define ALI1563_SMBBA 0x80
-#define ALI1563_SMB_IOEN 1
-#define ALI1563_SMB_HOSTEN 2
-#define ALI1563_SMB_IOSIZE 16
-
-#define SMB_HST_STS (ali1563_smba + 0)
-#define SMB_HST_CNTL1 (ali1563_smba + 1)
-#define SMB_HST_CNTL2 (ali1563_smba + 2)
-#define SMB_HST_CMD (ali1563_smba + 3)
-#define SMB_HST_ADD (ali1563_smba + 4)
-#define SMB_HST_DAT0 (ali1563_smba + 5)
-#define SMB_HST_DAT1 (ali1563_smba + 6)
-#define SMB_BLK_DAT (ali1563_smba + 7)
-
-#define HST_STS_BUSY 0x01
-#define HST_STS_INTR 0x02
-#define HST_STS_DEVERR 0x04
-#define HST_STS_BUSERR 0x08
-#define HST_STS_FAIL 0x10
-#define HST_STS_DONE 0x80
-#define HST_STS_BAD 0x1c
-
-
-#define HST_CNTL1_TIMEOUT 0x80
-#define HST_CNTL1_LAST 0x40
-
-#define HST_CNTL2_KILL 0x04
-#define HST_CNTL2_START 0x40
-#define HST_CNTL2_QUICK 0x00
-#define HST_CNTL2_BYTE 0x01
-#define HST_CNTL2_BYTE_DATA 0x02
-#define HST_CNTL2_WORD_DATA 0x03
-#define HST_CNTL2_BLOCK 0x05
-
-
-#define HST_CNTL2_SIZEMASK 0x38
-
-static struct pci_driver ali1563_pci_driver;
-static unsigned short ali1563_smba;
-
-static int ali1563_transaction(struct i2c_adapter * a, int size)
-{
- u32 data;
- int timeout;
- int status = -EIO;
-
- dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, "
- "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
- inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
- inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
- inb_p(SMB_HST_DAT1));
-
- data = inb_p(SMB_HST_STS);
- if (data & HST_STS_BAD) {
- dev_err(&a->dev, "ali1563: Trying to reset busy device\n");
- outb_p(data | HST_STS_BAD,SMB_HST_STS);
- data = inb_p(SMB_HST_STS);
- if (data & HST_STS_BAD)
- return -EBUSY;
- }
- outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2);
-
- timeout = ALI1563_MAX_TIMEOUT;
- do {
- msleep(1);
- } while (((data = inb_p(SMB_HST_STS)) & HST_STS_BUSY) && --timeout);
-
- dev_dbg(&a->dev, "Transaction (post): STS=%02x, CNTL1=%02x, "
- "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
- inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
- inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
- inb_p(SMB_HST_DAT1));
-
- if (timeout && !(data & HST_STS_BAD))
- return 0;
-
- if (!timeout) {
- dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n");
- /* Issue 'kill' to host controller */
- outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
- data = inb_p(SMB_HST_STS);
- status = -ETIMEDOUT;
- }
-
- /* device error - no response, ignore the autodetection case */
- if (data & HST_STS_DEVERR) {
- if (size != HST_CNTL2_QUICK)
- dev_err(&a->dev, "Device error!\n");
- status = -ENXIO;
- }
- /* bus collision */
- if (data & HST_STS_BUSERR) {
- dev_err(&a->dev, "Bus collision!\n");
- /* Issue timeout, hoping it helps */
- outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1);
- }
-
- if (data & HST_STS_FAIL) {
- dev_err(&a->dev, "Cleaning fail after KILL!\n");
- outb_p(0x0,SMB_HST_CNTL2);
- }
-
- return status;
-}
-
-static int ali1563_block_start(struct i2c_adapter * a)
-{
- u32 data;
- int timeout;
- int status = -EIO;
-
- dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, "
- "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
- inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
- inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
- inb_p(SMB_HST_DAT1));
-
- data = inb_p(SMB_HST_STS);
- if (data & HST_STS_BAD) {
- dev_warn(&a->dev,"ali1563: Trying to reset busy device\n");
- outb_p(data | HST_STS_BAD,SMB_HST_STS);
- data = inb_p(SMB_HST_STS);
- if (data & HST_STS_BAD)
- return -EBUSY;
- }
-
- /* Clear byte-ready bit */
- outb_p(data | HST_STS_DONE, SMB_HST_STS);
-
- /* Start transaction and wait for byte-ready bit to be set */
- outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2);
-
- timeout = ALI1563_MAX_TIMEOUT;
- do {
- msleep(1);
- } while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout);
-
- dev_dbg(&a->dev, "Block (post): STS=%02x, CNTL1=%02x, "
- "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
- inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
- inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
- inb_p(SMB_HST_DAT1));
-
- if (timeout && !(data & HST_STS_BAD))
- return 0;
-
- if (timeout == 0)
- status = -ETIMEDOUT;
-
- if (data & HST_STS_DEVERR)
- status = -ENXIO;
-
- dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n",
- timeout ? "" : "Timeout ",
- data & HST_STS_FAIL ? "Transaction Failed " : "",
- data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
- data & HST_STS_DEVERR ? "Device Error " : "",
- !(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
- return status;
-}
-
-static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw)
-{
- int i, len;
- int error = 0;
-
- /* Do we need this? */
- outb_p(HST_CNTL1_LAST,SMB_HST_CNTL1);
-
- if (rw == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len < 1)
- len = 1;
- else if (len > 32)
- len = 32;
- outb_p(len,SMB_HST_DAT0);
- outb_p(data->block[1],SMB_BLK_DAT);
- } else
- len = 32;
-
- outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_BLOCK, SMB_HST_CNTL2);
-
- for (i = 0; i < len; i++) {
- if (rw == I2C_SMBUS_WRITE) {
- outb_p(data->block[i + 1], SMB_BLK_DAT);
- if ((error = ali1563_block_start(a)))
- break;
- } else {
- if ((error = ali1563_block_start(a)))
- break;
- if (i == 0) {
- len = inb_p(SMB_HST_DAT0);
- if (len < 1)
- len = 1;
- else if (len > 32)
- len = 32;
- }
- data->block[i+1] = inb_p(SMB_BLK_DAT);
- }
- }
- /* Do we need this? */
- outb_p(HST_CNTL1_LAST,SMB_HST_CNTL1);
- return error;
-}
-
-static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
- unsigned short flags, char rw, u8 cmd,
- int size, union i2c_smbus_data * data)
-{
- int error = 0;
- int timeout;
- u32 reg;
-
- for (timeout = ALI1563_MAX_TIMEOUT; timeout; timeout--) {
- if (!(reg = inb_p(SMB_HST_STS) & HST_STS_BUSY))
- break;
- }
- if (!timeout)
- dev_warn(&a->dev,"SMBus not idle. HST_STS = %02x\n",reg);
- outb_p(0xff,SMB_HST_STS);
-
- /* Map the size to what the chip understands */
- switch (size) {
- case I2C_SMBUS_QUICK:
- size = HST_CNTL2_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- size = HST_CNTL2_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- size = HST_CNTL2_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- size = HST_CNTL2_WORD_DATA;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- size = HST_CNTL2_BLOCK;
- break;
- default:
- dev_warn(&a->dev, "Unsupported transaction %d\n", size);
- error = -EOPNOTSUPP;
- goto Done;
- }
-
- outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD);
- outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2);
-
- /* Write the command register */
-
- switch(size) {
- case HST_CNTL2_BYTE:
- if (rw== I2C_SMBUS_WRITE)
- /* Beware it uses DAT0 register and not CMD! */
- outb_p(cmd, SMB_HST_DAT0);
- break;
- case HST_CNTL2_BYTE_DATA:
- outb_p(cmd, SMB_HST_CMD);
- if (rw == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMB_HST_DAT0);
- break;
- case HST_CNTL2_WORD_DATA:
- outb_p(cmd, SMB_HST_CMD);
- if (rw == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMB_HST_DAT0);
- outb_p((data->word & 0xff00) >> 8, SMB_HST_DAT1);
- }
- break;
- case HST_CNTL2_BLOCK:
- outb_p(cmd, SMB_HST_CMD);
- error = ali1563_block(a,data,rw);
- goto Done;
- }
-
- if ((error = ali1563_transaction(a, size)))
- goto Done;
-
- if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))
- goto Done;
-
- switch (size) {
- case HST_CNTL2_BYTE: /* Result put in SMBHSTDAT0 */
- data->byte = inb_p(SMB_HST_DAT0);
- break;
- case HST_CNTL2_BYTE_DATA:
- data->byte = inb_p(SMB_HST_DAT0);
- break;
- case HST_CNTL2_WORD_DATA:
- data->word = inb_p(SMB_HST_DAT0) + (inb_p(SMB_HST_DAT1) << 8);
- break;
- }
-Done:
- return error;
-}
-
-static u32 ali1563_func(struct i2c_adapter * a)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-
-static int __devinit ali1563_setup(struct pci_dev * dev)
-{
- u16 ctrl;
-
- pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
-
- /* SMB I/O Base in high 12 bits and must be aligned with the
- * size of the I/O space. */
- ali1563_smba = ctrl & ~(ALI1563_SMB_IOSIZE - 1);
- if (!ali1563_smba) {
- dev_warn(&dev->dev,"ali1563_smba Uninitialized\n");
- goto Err;
- }
-
- /* Check if device is enabled */
- if (!(ctrl & ALI1563_SMB_HOSTEN)) {
- dev_warn(&dev->dev, "Host Controller not enabled\n");
- goto Err;
- }
- if (!(ctrl & ALI1563_SMB_IOEN)) {
- dev_warn(&dev->dev, "I/O space not enabled, trying manually\n");
- pci_write_config_word(dev, ALI1563_SMBBA,
- ctrl | ALI1563_SMB_IOEN);
- pci_read_config_word(dev, ALI1563_SMBBA, &ctrl);
- if (!(ctrl & ALI1563_SMB_IOEN)) {
- dev_err(&dev->dev, "I/O space still not enabled, "
- "giving up\n");
- goto Err;
- }
- }
-
- if (acpi_check_region(ali1563_smba, ALI1563_SMB_IOSIZE,
- ali1563_pci_driver.name))
- goto Err;
-
- if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
- ali1563_pci_driver.name)) {
- dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n",
- ali1563_smba);
- goto Err;
- }
- dev_info(&dev->dev, "Found ALi1563 SMBus at 0x%04x\n", ali1563_smba);
-
- return 0;
-Err:
- return -ENODEV;
-}
-
-static void ali1563_shutdown(struct pci_dev *dev)
-{
- release_region(ali1563_smba,ALI1563_SMB_IOSIZE);
-}
-
-static const struct i2c_algorithm ali1563_algorithm = {
- .smbus_xfer = ali1563_access,
- .functionality = ali1563_func,
-};
-
-static struct i2c_adapter ali1563_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &ali1563_algorithm,
-};
-
-static int __devinit ali1563_probe(struct pci_dev * dev,
- const struct pci_device_id * id_table)
-{
- int error;
-
- if ((error = ali1563_setup(dev)))
- goto exit;
- ali1563_adapter.dev.parent = &dev->dev;
- snprintf(ali1563_adapter.name, sizeof(ali1563_adapter.name),
- "SMBus ALi 1563 Adapter @ %04x", ali1563_smba);
- if ((error = i2c_add_adapter(&ali1563_adapter)))
- goto exit_shutdown;
- return 0;
-
-exit_shutdown:
- ali1563_shutdown(dev);
-exit:
- dev_warn(&dev->dev, "ALi1563 SMBus probe failed (%d)\n", error);
- return error;
-}
-
-static void __devexit ali1563_remove(struct pci_dev * dev)
-{
- i2c_del_adapter(&ali1563_adapter);
- ali1563_shutdown(dev);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(ali1563_id_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) },
- {},
-};
-
-MODULE_DEVICE_TABLE (pci, ali1563_id_table);
-
-static struct pci_driver ali1563_pci_driver = {
- .name = "ali1563_smbus",
- .id_table = ali1563_id_table,
- .probe = ali1563_probe,
- .remove = __devexit_p(ali1563_remove),
-};
-
-static int __init ali1563_init(void)
-{
- return pci_register_driver(&ali1563_pci_driver);
-}
-
-module_init(ali1563_init);
-
-static void __exit ali1563_exit(void)
-{
- pci_unregister_driver(&ali1563_pci_driver);
-}
-
-module_exit(ali1563_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali15x3.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali15x3.c
deleted file mode 100644
index 087ea9ca..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ali15x3.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- Copyright (c) 1999 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com> and
- Mark D. Studebaker <mdsxyz123@yahoo.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- This is the driver for the SMB Host controller on
- Acer Labs Inc. (ALI) M1541 and M1543C South Bridges.
-
- The M1543C is a South bridge for desktop systems.
- The M1533 is a South bridge for portable systems.
- They are part of the following ALI chipsets:
- "Aladdin Pro 2": Includes the M1621 Slot 1 North bridge
- with AGP and 100MHz CPU Front Side bus
- "Aladdin V": Includes the M1541 Socket 7 North bridge
- with AGP and 100MHz CPU Front Side bus
- "Aladdin IV": Includes the M1541 Socket 7 North bridge
- with host bus up to 83.3 MHz.
- For an overview of these chips see http://www.acerlabs.com
-
- The M1533/M1543C devices appear as FOUR separate devices
- on the PCI bus. An output of lspci will show something similar
- to the following:
-
- 00:02.0 USB Controller: Acer Laboratories Inc. M5237
- 00:03.0 Bridge: Acer Laboratories Inc. M7101
- 00:07.0 ISA bridge: Acer Laboratories Inc. M1533
- 00:0f.0 IDE interface: Acer Laboratories Inc. M5229
-
- The SMB controller is part of the 7101 device, which is an
- ACPI-compliant Power Management Unit (PMU).
-
- The whole 7101 device has to be enabled for the SMB to work.
- You can't just enable the SMB alone.
- The SMB and the ACPI have separate I/O spaces.
- We make sure that the SMB is enabled. We leave the ACPI alone.
-
- This driver controls the SMB Host only.
- The SMB Slave controller on the M15X3 is not enabled.
-
- This driver does not use interrupts.
-*/
-
-/* Note: we assume there can only be one ALI15X3, with one SMBus interface */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-/* ALI15X3 SMBus address offsets */
-#define SMBHSTSTS (0 + ali15x3_smba)
-#define SMBHSTCNT (1 + ali15x3_smba)
-#define SMBHSTSTART (2 + ali15x3_smba)
-#define SMBHSTCMD (7 + ali15x3_smba)
-#define SMBHSTADD (3 + ali15x3_smba)
-#define SMBHSTDAT0 (4 + ali15x3_smba)
-#define SMBHSTDAT1 (5 + ali15x3_smba)
-#define SMBBLKDAT (6 + ali15x3_smba)
-
-/* PCI Address Constants */
-#define SMBCOM 0x004
-#define SMBBA 0x014
-#define SMBATPC 0x05B /* used to unlock xxxBA registers */
-#define SMBHSTCFG 0x0E0
-#define SMBSLVC 0x0E1
-#define SMBCLK 0x0E2
-#define SMBREV 0x008
-
-/* Other settings */
-#define MAX_TIMEOUT 200 /* times 1/100 sec */
-#define ALI15X3_SMB_IOSIZE 32
-
-/* this is what the Award 1004 BIOS sets them to on a ASUS P5A MB.
- We don't use these here. If the bases aren't set to some value we
- tell user to upgrade BIOS and we fail.
-*/
-#define ALI15X3_SMB_DEFAULTBASE 0xE800
-
-/* ALI15X3 address lock bits */
-#define ALI15X3_LOCK 0x06
-
-/* ALI15X3 command constants */
-#define ALI15X3_ABORT 0x02
-#define ALI15X3_T_OUT 0x04
-#define ALI15X3_QUICK 0x00
-#define ALI15X3_BYTE 0x10
-#define ALI15X3_BYTE_DATA 0x20
-#define ALI15X3_WORD_DATA 0x30
-#define ALI15X3_BLOCK_DATA 0x40
-#define ALI15X3_BLOCK_CLR 0x80
-
-/* ALI15X3 status register bits */
-#define ALI15X3_STS_IDLE 0x04
-#define ALI15X3_STS_BUSY 0x08
-#define ALI15X3_STS_DONE 0x10
-#define ALI15X3_STS_DEV 0x20 /* device error */
-#define ALI15X3_STS_COLL 0x40 /* collision or no response */
-#define ALI15X3_STS_TERM 0x80 /* terminated by abort */
-#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */
-
-
-/* If force_addr is set to anything different from 0, we forcibly enable
- the device at the given address. */
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
- "Initialize the base address of the i2c controller");
-
-static struct pci_driver ali15x3_driver;
-static unsigned short ali15x3_smba;
-
-static int __devinit ali15x3_setup(struct pci_dev *ALI15X3_dev)
-{
- u16 a;
- unsigned char temp;
-
- /* Check the following things:
- - SMB I/O address is initialized
- - Device is enabled
- - We can use the addresses
- */
-
- /* Unlock the register.
- The data sheet says that the address registers are read-only
- if the lock bits are 1, but in fact the address registers
- are zero unless you clear the lock bits.
- */
- pci_read_config_byte(ALI15X3_dev, SMBATPC, &temp);
- if (temp & ALI15X3_LOCK) {
- temp &= ~ALI15X3_LOCK;
- pci_write_config_byte(ALI15X3_dev, SMBATPC, temp);
- }
-
- /* Determine the address of the SMBus area */
- pci_read_config_word(ALI15X3_dev, SMBBA, &ali15x3_smba);
- ali15x3_smba &= (0xffff & ~(ALI15X3_SMB_IOSIZE - 1));
- if (ali15x3_smba == 0 && force_addr == 0) {
- dev_err(&ALI15X3_dev->dev, "ALI15X3_smb region uninitialized "
- "- upgrade BIOS or use force_addr=0xaddr\n");
- return -ENODEV;
- }
-
- if(force_addr)
- ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);
-
- if (acpi_check_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
- ali15x3_driver.name))
- return -EBUSY;
-
- if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
- ali15x3_driver.name)) {
- dev_err(&ALI15X3_dev->dev,
- "ALI15X3_smb region 0x%x already in use!\n",
- ali15x3_smba);
- return -ENODEV;
- }
-
- if(force_addr) {
- dev_info(&ALI15X3_dev->dev, "forcing ISA address 0x%04X\n",
- ali15x3_smba);
- if (PCIBIOS_SUCCESSFUL != pci_write_config_word(ALI15X3_dev,
- SMBBA,
- ali15x3_smba))
- goto error;
- if (PCIBIOS_SUCCESSFUL != pci_read_config_word(ALI15X3_dev,
- SMBBA, &a))
- goto error;
- if ((a & ~(ALI15X3_SMB_IOSIZE - 1)) != ali15x3_smba) {
- /* make sure it works */
- dev_err(&ALI15X3_dev->dev,
- "force address failed - not supported?\n");
- goto error;
- }
- }
- /* check if whole device is enabled */
- pci_read_config_byte(ALI15X3_dev, SMBCOM, &temp);
- if ((temp & 1) == 0) {
- dev_info(&ALI15X3_dev->dev, "enabling SMBus device\n");
- pci_write_config_byte(ALI15X3_dev, SMBCOM, temp | 0x01);
- }
-
- /* Is SMB Host controller enabled? */
- pci_read_config_byte(ALI15X3_dev, SMBHSTCFG, &temp);
- if ((temp & 1) == 0) {
- dev_info(&ALI15X3_dev->dev, "enabling SMBus controller\n");
- pci_write_config_byte(ALI15X3_dev, SMBHSTCFG, temp | 0x01);
- }
-
- /* set SMB clock to 74KHz as recommended in data sheet */
- pci_write_config_byte(ALI15X3_dev, SMBCLK, 0x20);
-
- /*
- The interrupt routing for SMB is set up in register 0x77 in the
- 1533 ISA Bridge device, NOT in the 7101 device.
- Don't bother with finding the 1533 device and reading the register.
- if ((....... & 0x0F) == 1)
- dev_dbg(&ALI15X3_dev->dev, "ALI15X3 using Interrupt 9 for SMBus.\n");
- */
- pci_read_config_byte(ALI15X3_dev, SMBREV, &temp);
- dev_dbg(&ALI15X3_dev->dev, "SMBREV = 0x%X\n", temp);
- dev_dbg(&ALI15X3_dev->dev, "iALI15X3_smba = 0x%X\n", ali15x3_smba);
-
- return 0;
-error:
- release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
- return -ENODEV;
-}
-
-/* Another internally used function */
-static int ali15x3_transaction(struct i2c_adapter *adap)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS),
- inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
- inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-
- /* get status */
- temp = inb_p(SMBHSTSTS);
-
- /* Make sure the SMBus host is ready to start transmitting */
- /* Check the busy bit first */
- if (temp & ALI15X3_STS_BUSY) {
- /*
- If the host controller is still busy, it may have timed out in the
- previous transaction, resulting in a "SMBus Timeout" Dev.
- I've tried the following to reset a stuck busy bit.
- 1. Reset the controller with an ABORT command.
- (this doesn't seem to clear the controller if an external
- device is hung)
- 2. Reset the controller and the other SMBus devices with a
- T_OUT command. (this clears the host busy bit if an
- external device is hung, but it comes back upon a new access
- to a device)
- 3. Disable and reenable the controller in SMBHSTCFG
- Worst case, nothing seems to work except power reset.
- */
- /* Abort - reset the host controller */
- /*
- Try resetting entire SMB bus, including other devices -
- This may not work either - it clears the BUSY bit but
- then the BUSY bit may come back on when you try and use the chip again.
- If that's the case you are stuck.
- */
- dev_info(&adap->dev, "Resetting entire SMB Bus to "
- "clear busy condition (%02x)\n", temp);
- outb_p(ALI15X3_T_OUT, SMBHSTCNT);
- temp = inb_p(SMBHSTSTS);
- }
-
- /* now check the error bits and the busy bit */
- if (temp & (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
- /* do a clear-on-write */
- outb_p(0xFF, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) &
- (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
- /* this is probably going to be correctable only by a power reset
- as one of the bits now appears to be stuck */
- /* This may be a bus or device with electrical problems. */
- dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - "
- "controller or device on bus is probably hung\n",
- temp);
- return -EBUSY;
- }
- } else {
- /* check and clear done bit */
- if (temp & ALI15X3_STS_DONE) {
- outb_p(temp, SMBHSTSTS);
- }
- }
-
- /* start the transaction by writing anything to the start register */
- outb_p(0xFF, SMBHSTSTART);
-
- /* We will always wait for a fraction of a second! */
- timeout = 0;
- do {
- msleep(1);
- temp = inb_p(SMBHSTSTS);
- } while ((!(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)))
- && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- result = -ETIMEDOUT;
- dev_err(&adap->dev, "SMBus Timeout!\n");
- }
-
- if (temp & ALI15X3_STS_TERM) {
- result = -EIO;
- dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
- }
-
- /*
- Unfortunately the ALI SMB controller maps "no response" and "bus
- collision" into a single bit. No response is the usual case so don't
- do a printk.
- This means that bus collisions go unreported.
- */
- if (temp & ALI15X3_STS_COLL) {
- result = -ENXIO;
- dev_dbg(&adap->dev,
- "Error: no response or bus collision ADD=%02x\n",
- inb_p(SMBHSTADD));
- }
-
- /* haven't ever seen this */
- if (temp & ALI15X3_STS_DEV) {
- result = -EIO;
- dev_err(&adap->dev, "Error: device error\n");
- }
- dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS),
- inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
- inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
- return result;
-}
-
-/* Return negative errno on error. */
-static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data * data)
-{
- int i, len;
- int temp;
- int timeout;
-
- /* clear all the bits (clear-on-write) */
- outb_p(0xFF, SMBHSTSTS);
- /* make sure SMBus is idle */
- temp = inb_p(SMBHSTSTS);
- for (timeout = 0;
- (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE);
- timeout++) {
- msleep(1);
- temp = inb_p(SMBHSTSTS);
- }
- if (timeout >= MAX_TIMEOUT) {
- dev_err(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
- }
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- size = ALI15X3_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, SMBHSTCMD);
- size = ALI15X3_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMBHSTDAT0);
- size = ALI15X3_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMBHSTDAT0);
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
- }
- size = ALI15X3_WORD_DATA;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len < 0) {
- len = 0;
- data->block[0] = len;
- }
- if (len > 32) {
- len = 32;
- data->block[0] = len;
- }
- outb_p(len, SMBHSTDAT0);
- /* Reset SMBBLKDAT */
- outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);
- for (i = 1; i <= len; i++)
- outb_p(data->block[i], SMBBLKDAT);
- }
- size = ALI15X3_BLOCK_DATA;
- break;
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- outb_p(size, SMBHSTCNT); /* output command */
-
- temp = ali15x3_transaction(adap);
- if (temp)
- return temp;
-
- if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK))
- return 0;
-
-
- switch (size) {
- case ALI15X3_BYTE: /* Result put in SMBHSTDAT0 */
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case ALI15X3_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case ALI15X3_WORD_DATA:
- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
- break;
- case ALI15X3_BLOCK_DATA:
- len = inb_p(SMBHSTDAT0);
- if (len > 32)
- len = 32;
- data->block[0] = len;
- /* Reset SMBBLKDAT */
- outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);
- for (i = 1; i <= data->block[0]; i++) {
- data->block[i] = inb_p(SMBBLKDAT);
- dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
- len, i, data->block[i]);
- }
- break;
- }
- return 0;
-}
-
-static u32 ali15x3_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = ali15x3_access,
- .functionality = ali15x3_func,
-};
-
-static struct i2c_adapter ali15x3_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(ali15x3_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, ali15x3_ids);
-
-static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- if (ali15x3_setup(dev)) {
- dev_err(&dev->dev,
- "ALI15X3 not detected, module not inserted.\n");
- return -ENODEV;
- }
-
- /* set up the sysfs linkage to our parent device */
- ali15x3_adapter.dev.parent = &dev->dev;
-
- snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name),
- "SMBus ALI15X3 adapter at %04x", ali15x3_smba);
- return i2c_add_adapter(&ali15x3_adapter);
-}
-
-static void __devexit ali15x3_remove(struct pci_dev *dev)
-{
- i2c_del_adapter(&ali15x3_adapter);
- release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
-}
-
-static struct pci_driver ali15x3_driver = {
- .name = "ali15x3_smbus",
- .id_table = ali15x3_ids,
- .probe = ali15x3_probe,
- .remove = __devexit_p(ali15x3_remove),
-};
-
-static int __init i2c_ali15x3_init(void)
-{
- return pci_register_driver(&ali15x3_driver);
-}
-
-static void __exit i2c_ali15x3_exit(void)
-{
- pci_unregister_driver(&ali15x3_driver);
-}
-
-MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
- "Philip Edelbrock <phil@netroedge.com>, "
- "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("ALI15X3 SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_ali15x3_init);
-module_exit(i2c_ali15x3_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756-s4882.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756-s4882.c
deleted file mode 100644
index 378fcb5d..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756-s4882.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * i2c-amd756-s4882.c - i2c-amd756 extras for the Tyan S4882 motherboard
- *
- * Copyright (C) 2004, 2008 Jean Delvare <khali@linux-fr.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * We select the channels by sending commands to the Philips
- * PCA9556 chip at I2C address 0x18. The main adapter is used for
- * the non-multiplexed part of the bus, and 4 virtual adapters
- * are defined for the multiplexed addresses: 0x50-0x53 (memory
- * module EEPROM) located on channels 1-4, and 0x4c (LM63)
- * located on multiplexed channels 0 and 5-7. We define one
- * virtual adapter per CPU, which corresponds to two multiplexed
- * channels:
- * CPU0: virtual adapter 1, channels 1 and 0
- * CPU1: virtual adapter 2, channels 2 and 5
- * CPU2: virtual adapter 3, channels 3 and 6
- * CPU3: virtual adapter 4, channels 4 and 7
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-extern struct i2c_adapter amd756_smbus;
-
-static struct i2c_adapter *s4882_adapter;
-static struct i2c_algorithm *s4882_algo;
-
-/* Wrapper access functions for multiplexed SMBus */
-static DEFINE_MUTEX(amd756_lock);
-
-static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data * data)
-{
- int error;
-
- /* We exclude the multiplexed addresses */
- if (addr == 0x4c || (addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
- || addr == 0x18)
- return -ENXIO;
-
- mutex_lock(&amd756_lock);
-
- error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write,
- command, size, data);
-
- mutex_unlock(&amd756_lock);
-
- return error;
-}
-
-/* We remember the last used channels combination so as to only switch
- channels when it is really needed. This greatly reduces the SMBus
- overhead, but also assumes that nobody will be writing to the PCA9556
- in our back. */
-static u8 last_channels;
-
-static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data * data,
- u8 channels)
-{
- int error;
-
- /* We exclude the non-multiplexed addresses */
- if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
- return -ENXIO;
-
- mutex_lock(&amd756_lock);
-
- if (last_channels != channels) {
- union i2c_smbus_data mplxdata;
- mplxdata.byte = channels;
-
- error = amd756_smbus.algo->smbus_xfer(adap, 0x18, 0,
- I2C_SMBUS_WRITE, 0x01,
- I2C_SMBUS_BYTE_DATA,
- &mplxdata);
- if (error)
- goto UNLOCK;
- last_channels = channels;
- }
- error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write,
- command, size, data);
-
-UNLOCK:
- mutex_unlock(&amd756_lock);
- return error;
-}
-
-static s32 amd756_access_virt1(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data * data)
-{
- /* CPU0: channels 1 and 0 enabled */
- return amd756_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x03);
-}
-
-static s32 amd756_access_virt2(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data * data)
-{
- /* CPU1: channels 2 and 5 enabled */
- return amd756_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x24);
-}
-
-static s32 amd756_access_virt3(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data * data)
-{
- /* CPU2: channels 3 and 6 enabled */
- return amd756_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x48);
-}
-
-static s32 amd756_access_virt4(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data * data)
-{
- /* CPU3: channels 4 and 7 enabled */
- return amd756_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x90);
-}
-
-static int __init amd756_s4882_init(void)
-{
- int i, error;
- union i2c_smbus_data ioconfig;
-
- if (!amd756_smbus.dev.parent)
- return -ENODEV;
-
- /* Configure the PCA9556 multiplexer */
- ioconfig.byte = 0x00; /* All I/O to output mode */
- error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
- I2C_SMBUS_BYTE_DATA, &ioconfig);
- if (error) {
- dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
- error = -EIO;
- goto ERROR0;
- }
-
- /* Unregister physical bus */
- error = i2c_del_adapter(&amd756_smbus);
- if (error) {
- dev_err(&amd756_smbus.dev, "Physical bus removal failed\n");
- goto ERROR0;
- }
-
- printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n");
- /* Define the 5 virtual adapters and algorithms structures */
- if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter),
- GFP_KERNEL))) {
- error = -ENOMEM;
- goto ERROR1;
- }
- if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm),
- GFP_KERNEL))) {
- error = -ENOMEM;
- goto ERROR2;
- }
-
- /* Fill in the new structures */
- s4882_algo[0] = *(amd756_smbus.algo);
- s4882_algo[0].smbus_xfer = amd756_access_virt0;
- s4882_adapter[0] = amd756_smbus;
- s4882_adapter[0].algo = s4882_algo;
- s4882_adapter[0].dev.parent = amd756_smbus.dev.parent;
- for (i = 1; i < 5; i++) {
- s4882_algo[i] = *(amd756_smbus.algo);
- s4882_adapter[i] = amd756_smbus;
- snprintf(s4882_adapter[i].name, sizeof(s4882_adapter[i].name),
- "SMBus 8111 adapter (CPU%d)", i-1);
- s4882_adapter[i].algo = s4882_algo+i;
- s4882_adapter[i].dev.parent = amd756_smbus.dev.parent;
- }
- s4882_algo[1].smbus_xfer = amd756_access_virt1;
- s4882_algo[2].smbus_xfer = amd756_access_virt2;
- s4882_algo[3].smbus_xfer = amd756_access_virt3;
- s4882_algo[4].smbus_xfer = amd756_access_virt4;
-
- /* Register virtual adapters */
- for (i = 0; i < 5; i++) {
- error = i2c_add_adapter(s4882_adapter+i);
- if (error) {
- printk(KERN_ERR "i2c-amd756-s4882: "
- "Virtual adapter %d registration "
- "failed, module not inserted\n", i);
- for (i--; i >= 0; i--)
- i2c_del_adapter(s4882_adapter+i);
- goto ERROR3;
- }
- }
-
- return 0;
-
-ERROR3:
- kfree(s4882_algo);
- s4882_algo = NULL;
-ERROR2:
- kfree(s4882_adapter);
- s4882_adapter = NULL;
-ERROR1:
- /* Restore physical bus */
- i2c_add_adapter(&amd756_smbus);
-ERROR0:
- return error;
-}
-
-static void __exit amd756_s4882_exit(void)
-{
- if (s4882_adapter) {
- int i;
-
- for (i = 0; i < 5; i++)
- i2c_del_adapter(s4882_adapter+i);
- kfree(s4882_adapter);
- s4882_adapter = NULL;
- }
- kfree(s4882_algo);
- s4882_algo = NULL;
-
- /* Restore physical bus */
- if (i2c_add_adapter(&amd756_smbus))
- printk(KERN_ERR "i2c-amd756-s4882: "
- "Physical bus restoration failed\n");
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("S4882 SMBus multiplexing");
-MODULE_LICENSE("GPL");
-
-module_init(amd756_s4882_init);
-module_exit(amd756_s4882_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756.c
deleted file mode 100644
index eb778bf1..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd756.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
-
- Shamelessly ripped from i2c-piix4.c:
-
- Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- 2002-04-08: Added nForce support. (Csaba Halasz)
- 2002-10-03: Fixed nForce PnP I/O port. (Michael Steil)
- 2002-12-28: Rewritten into something that resembles a Linux driver (hch)
- 2003-11-29: Added back AMD8111 removed by the previous rewrite.
- (Philip Pokorny)
-*/
-
-/*
- Supports AMD756, AMD766, AMD768, AMD8111 and nVidia nForce
- Note: we assume there can only be one device, with one SMBus interface.
-*/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-/* AMD756 SMBus address offsets */
-#define SMB_ADDR_OFFSET 0xE0
-#define SMB_IOSIZE 16
-#define SMB_GLOBAL_STATUS (0x0 + amd756_ioport)
-#define SMB_GLOBAL_ENABLE (0x2 + amd756_ioport)
-#define SMB_HOST_ADDRESS (0x4 + amd756_ioport)
-#define SMB_HOST_DATA (0x6 + amd756_ioport)
-#define SMB_HOST_COMMAND (0x8 + amd756_ioport)
-#define SMB_HOST_BLOCK_DATA (0x9 + amd756_ioport)
-#define SMB_HAS_DATA (0xA + amd756_ioport)
-#define SMB_HAS_DEVICE_ADDRESS (0xC + amd756_ioport)
-#define SMB_HAS_HOST_ADDRESS (0xE + amd756_ioport)
-#define SMB_SNOOP_ADDRESS (0xF + amd756_ioport)
-
-/* PCI Address Constants */
-
-/* address of I/O space */
-#define SMBBA 0x058 /* mh */
-#define SMBBANFORCE 0x014
-
-/* general configuration */
-#define SMBGCFG 0x041 /* mh */
-
-/* silicon revision code */
-#define SMBREV 0x008
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-
-/* AMD756 constants */
-#define AMD756_QUICK 0x00
-#define AMD756_BYTE 0x01
-#define AMD756_BYTE_DATA 0x02
-#define AMD756_WORD_DATA 0x03
-#define AMD756_PROCESS_CALL 0x04
-#define AMD756_BLOCK_DATA 0x05
-
-static struct pci_driver amd756_driver;
-static unsigned short amd756_ioport;
-
-/*
- SMBUS event = I/O 28-29 bit 11
- see E0 for the status bits and enabled in E2
-
-*/
-#define GS_ABRT_STS (1 << 0)
-#define GS_COL_STS (1 << 1)
-#define GS_PRERR_STS (1 << 2)
-#define GS_HST_STS (1 << 3)
-#define GS_HCYC_STS (1 << 4)
-#define GS_TO_STS (1 << 5)
-#define GS_SMB_STS (1 << 11)
-
-#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \
- GS_HCYC_STS | GS_TO_STS )
-
-#define GE_CYC_TYPE_MASK (7)
-#define GE_HOST_STC (1 << 3)
-#define GE_ABORT (1 << 5)
-
-
-static int amd756_transaction(struct i2c_adapter *adap)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- dev_dbg(&adap->dev, "Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, "
- "DAT=%04x\n", inw_p(SMB_GLOBAL_STATUS),
- inw_p(SMB_GLOBAL_ENABLE), inw_p(SMB_HOST_ADDRESS),
- inb_p(SMB_HOST_DATA));
-
- /* Make sure the SMBus host is ready to start transmitting */
- if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) {
- dev_dbg(&adap->dev, "SMBus busy (%04x). Waiting...\n", temp);
- do {
- msleep(1);
- temp = inw_p(SMB_GLOBAL_STATUS);
- } while ((temp & (GS_HST_STS | GS_SMB_STS)) &&
- (timeout++ < MAX_TIMEOUT));
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- dev_dbg(&adap->dev, "Busy wait timeout (%04x)\n", temp);
- goto abort;
- }
- timeout = 0;
- }
-
- /* start the transaction by setting the start bit */
- outw_p(inw(SMB_GLOBAL_ENABLE) | GE_HOST_STC, SMB_GLOBAL_ENABLE);
-
- /* We will always wait for a fraction of a second! */
- do {
- msleep(1);
- temp = inw_p(SMB_GLOBAL_STATUS);
- } while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- dev_dbg(&adap->dev, "Completion timeout!\n");
- goto abort;
- }
-
- if (temp & GS_PRERR_STS) {
- result = -ENXIO;
- dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n");
- }
-
- if (temp & GS_COL_STS) {
- result = -EIO;
- dev_warn(&adap->dev, "SMBus collision!\n");
- }
-
- if (temp & GS_TO_STS) {
- result = -ETIMEDOUT;
- dev_dbg(&adap->dev, "SMBus protocol timeout!\n");
- }
-
- if (temp & GS_HCYC_STS)
- dev_dbg(&adap->dev, "SMBus protocol success!\n");
-
- outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
-
-#ifdef DEBUG
- if (((temp = inw_p(SMB_GLOBAL_STATUS)) & GS_CLEAR_STS) != 0x00) {
- dev_dbg(&adap->dev,
- "Failed reset at end of transaction (%04x)\n", temp);
- }
-#endif
-
- dev_dbg(&adap->dev,
- "Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n",
- inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE),
- inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA));
-
- return result;
-
- abort:
- dev_warn(&adap->dev, "Sending abort\n");
- outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
- msleep(100);
- outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
- return -EIO;
-}
-
-/* Return negative errno on error. */
-static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data * data)
-{
- int i, len;
- int status;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMB_HOST_ADDRESS);
- size = AMD756_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMB_HOST_ADDRESS);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, SMB_HOST_DATA);
- size = AMD756_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMB_HOST_ADDRESS);
- outb_p(command, SMB_HOST_COMMAND);
- if (read_write == I2C_SMBUS_WRITE)
- outw_p(data->byte, SMB_HOST_DATA);
- size = AMD756_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMB_HOST_ADDRESS);
- outb_p(command, SMB_HOST_COMMAND);
- if (read_write == I2C_SMBUS_WRITE)
- outw_p(data->word, SMB_HOST_DATA); /* TODO: endian???? */
- size = AMD756_WORD_DATA;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMB_HOST_ADDRESS);
- outb_p(command, SMB_HOST_COMMAND);
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len < 0)
- len = 0;
- if (len > 32)
- len = 32;
- outw_p(len, SMB_HOST_DATA);
- /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */
- for (i = 1; i <= len; i++)
- outb_p(data->block[i],
- SMB_HOST_BLOCK_DATA);
- }
- size = AMD756_BLOCK_DATA;
- break;
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- /* How about enabling interrupts... */
- outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
-
- status = amd756_transaction(adap);
- if (status)
- return status;
-
- if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK))
- return 0;
-
-
- switch (size) {
- case AMD756_BYTE:
- data->byte = inw_p(SMB_HOST_DATA);
- break;
- case AMD756_BYTE_DATA:
- data->byte = inw_p(SMB_HOST_DATA);
- break;
- case AMD756_WORD_DATA:
- data->word = inw_p(SMB_HOST_DATA); /* TODO: endian???? */
- break;
- case AMD756_BLOCK_DATA:
- data->block[0] = inw_p(SMB_HOST_DATA) & 0x3f;
- if(data->block[0] > 32)
- data->block[0] = 32;
- /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */
- for (i = 1; i <= data->block[0]; i++)
- data->block[i] = inb_p(SMB_HOST_BLOCK_DATA);
- break;
- }
-
- return 0;
-}
-
-static u32 amd756_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = amd756_access,
- .functionality = amd756_func,
-};
-
-struct i2c_adapter amd756_smbus = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 };
-static const char* chipname[] = {
- "AMD756", "AMD766", "AMD768",
- "nVidia nForce", "AMD8111",
-};
-
-static DEFINE_PCI_DEVICE_TABLE(amd756_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B),
- .driver_data = AMD756 },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413),
- .driver_data = AMD766 },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443),
- .driver_data = AMD768 },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS),
- .driver_data = AMD8111 },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS),
- .driver_data = NFORCE },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, amd756_ids);
-
-static int __devinit amd756_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- int nforce = (id->driver_data == NFORCE);
- int error;
- u8 temp;
-
- if (amd756_ioport) {
- dev_err(&pdev->dev, "Only one device supported "
- "(you have a strange motherboard, btw)\n");
- return -ENODEV;
- }
-
- if (nforce) {
- if (PCI_FUNC(pdev->devfn) != 1)
- return -ENODEV;
-
- pci_read_config_word(pdev, SMBBANFORCE, &amd756_ioport);
- amd756_ioport &= 0xfffc;
- } else { /* amd */
- if (PCI_FUNC(pdev->devfn) != 3)
- return -ENODEV;
-
- pci_read_config_byte(pdev, SMBGCFG, &temp);
- if ((temp & 128) == 0) {
- dev_err(&pdev->dev,
- "Error: SMBus controller I/O not enabled!\n");
- return -ENODEV;
- }
-
- /* Determine the address of the SMBus areas */
- /* Technically it is a dword but... */
- pci_read_config_word(pdev, SMBBA, &amd756_ioport);
- amd756_ioport &= 0xff00;
- amd756_ioport += SMB_ADDR_OFFSET;
- }
-
- error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
- amd756_driver.name);
- if (error)
- return -ENODEV;
-
- if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
- dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
- amd756_ioport);
- return -ENODEV;
- }
-
- pci_read_config_byte(pdev, SMBREV, &temp);
- dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
- dev_dbg(&pdev->dev, "AMD756_smba = 0x%X\n", amd756_ioport);
-
- /* set up the sysfs linkage to our parent device */
- amd756_smbus.dev.parent = &pdev->dev;
-
- snprintf(amd756_smbus.name, sizeof(amd756_smbus.name),
- "SMBus %s adapter at %04x", chipname[id->driver_data],
- amd756_ioport);
-
- error = i2c_add_adapter(&amd756_smbus);
- if (error) {
- dev_err(&pdev->dev,
- "Adapter registration failed, module not inserted\n");
- goto out_err;
- }
-
- return 0;
-
- out_err:
- release_region(amd756_ioport, SMB_IOSIZE);
- return error;
-}
-
-static void __devexit amd756_remove(struct pci_dev *dev)
-{
- i2c_del_adapter(&amd756_smbus);
- release_region(amd756_ioport, SMB_IOSIZE);
-}
-
-static struct pci_driver amd756_driver = {
- .name = "amd756_smbus",
- .id_table = amd756_ids,
- .probe = amd756_probe,
- .remove = __devexit_p(amd756_remove),
-};
-
-static int __init amd756_init(void)
-{
- return pci_register_driver(&amd756_driver);
-}
-
-static void __exit amd756_exit(void)
-{
- pci_unregister_driver(&amd756_driver);
-}
-
-MODULE_AUTHOR("Merlin Hughes <merlin@merlin.org>");
-MODULE_DESCRIPTION("AMD756/766/768/8111 and nVidia nForce SMBus driver");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(amd756_smbus);
-
-module_init(amd756_init)
-module_exit(amd756_exit)
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd8111.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd8111.c
deleted file mode 100644
index e5ac53b9..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-amd8111.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * SMBus 2.0 driver for AMD-8111 IO-Hub.
- *
- * Copyright (c) 2002 Vojtech Pavlik
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/acpi.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Vojtech Pavlik <vojtech@suse.cz>");
-MODULE_DESCRIPTION("AMD8111 SMBus 2.0 driver");
-
-struct amd_smbus {
- struct pci_dev *dev;
- struct i2c_adapter adapter;
- int base;
- int size;
-};
-
-static struct pci_driver amd8111_driver;
-
-/*
- * AMD PCI control registers definitions.
- */
-
-#define AMD_PCI_MISC 0x48
-
-#define AMD_PCI_MISC_SCI 0x04 /* deliver SCI */
-#define AMD_PCI_MISC_INT 0x02 /* deliver PCI IRQ */
-#define AMD_PCI_MISC_SPEEDUP 0x01 /* 16x clock speedup */
-
-/*
- * ACPI 2.0 chapter 13 PCI interface definitions.
- */
-
-#define AMD_EC_DATA 0x00 /* data register */
-#define AMD_EC_SC 0x04 /* status of controller */
-#define AMD_EC_CMD 0x04 /* command register */
-#define AMD_EC_ICR 0x08 /* interrupt control register */
-
-#define AMD_EC_SC_SMI 0x04 /* smi event pending */
-#define AMD_EC_SC_SCI 0x02 /* sci event pending */
-#define AMD_EC_SC_BURST 0x01 /* burst mode enabled */
-#define AMD_EC_SC_CMD 0x08 /* byte in data reg is command */
-#define AMD_EC_SC_IBF 0x02 /* data ready for embedded controller */
-#define AMD_EC_SC_OBF 0x01 /* data ready for host */
-
-#define AMD_EC_CMD_RD 0x80 /* read EC */
-#define AMD_EC_CMD_WR 0x81 /* write EC */
-#define AMD_EC_CMD_BE 0x82 /* enable burst mode */
-#define AMD_EC_CMD_BD 0x83 /* disable burst mode */
-#define AMD_EC_CMD_QR 0x84 /* query EC */
-
-/*
- * ACPI 2.0 chapter 13 access of registers of the EC
- */
-
-static int amd_ec_wait_write(struct amd_smbus *smbus)
-{
- int timeout = 500;
-
- while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
- udelay(1);
-
- if (!timeout) {
- dev_warn(&smbus->dev->dev,
- "Timeout while waiting for IBF to clear\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int amd_ec_wait_read(struct amd_smbus *smbus)
-{
- int timeout = 500;
-
- while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
- udelay(1);
-
- if (!timeout) {
- dev_warn(&smbus->dev->dev,
- "Timeout while waiting for OBF to set\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
- unsigned char *data)
-{
- int status;
-
- status = amd_ec_wait_write(smbus);
- if (status)
- return status;
- outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
-
- status = amd_ec_wait_write(smbus);
- if (status)
- return status;
- outb(address, smbus->base + AMD_EC_DATA);
-
- status = amd_ec_wait_read(smbus);
- if (status)
- return status;
- *data = inb(smbus->base + AMD_EC_DATA);
-
- return 0;
-}
-
-static int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
- unsigned char data)
-{
- int status;
-
- status = amd_ec_wait_write(smbus);
- if (status)
- return status;
- outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
-
- status = amd_ec_wait_write(smbus);
- if (status)
- return status;
- outb(address, smbus->base + AMD_EC_DATA);
-
- status = amd_ec_wait_write(smbus);
- if (status)
- return status;
- outb(data, smbus->base + AMD_EC_DATA);
-
- return 0;
-}
-
-/*
- * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
- */
-
-#define AMD_SMB_PRTCL 0x00 /* protocol, PEC */
-#define AMD_SMB_STS 0x01 /* status */
-#define AMD_SMB_ADDR 0x02 /* address */
-#define AMD_SMB_CMD 0x03 /* command */
-#define AMD_SMB_DATA 0x04 /* 32 data registers */
-#define AMD_SMB_BCNT 0x24 /* number of data bytes */
-#define AMD_SMB_ALRM_A 0x25 /* alarm address */
-#define AMD_SMB_ALRM_D 0x26 /* 2 bytes alarm data */
-
-#define AMD_SMB_STS_DONE 0x80
-#define AMD_SMB_STS_ALRM 0x40
-#define AMD_SMB_STS_RES 0x20
-#define AMD_SMB_STS_STATUS 0x1f
-
-#define AMD_SMB_STATUS_OK 0x00
-#define AMD_SMB_STATUS_FAIL 0x07
-#define AMD_SMB_STATUS_DNAK 0x10
-#define AMD_SMB_STATUS_DERR 0x11
-#define AMD_SMB_STATUS_CMD_DENY 0x12
-#define AMD_SMB_STATUS_UNKNOWN 0x13
-#define AMD_SMB_STATUS_ACC_DENY 0x17
-#define AMD_SMB_STATUS_TIMEOUT 0x18
-#define AMD_SMB_STATUS_NOTSUP 0x19
-#define AMD_SMB_STATUS_BUSY 0x1A
-#define AMD_SMB_STATUS_PEC 0x1F
-
-#define AMD_SMB_PRTCL_WRITE 0x00
-#define AMD_SMB_PRTCL_READ 0x01
-#define AMD_SMB_PRTCL_QUICK 0x02
-#define AMD_SMB_PRTCL_BYTE 0x04
-#define AMD_SMB_PRTCL_BYTE_DATA 0x06
-#define AMD_SMB_PRTCL_WORD_DATA 0x08
-#define AMD_SMB_PRTCL_BLOCK_DATA 0x0a
-#define AMD_SMB_PRTCL_PROC_CALL 0x0c
-#define AMD_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
-#define AMD_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
-#define AMD_SMB_PRTCL_PEC 0x80
-
-
-static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write, u8 command, int size,
- union i2c_smbus_data * data)
-{
- struct amd_smbus *smbus = adap->algo_data;
- unsigned char protocol, len, pec, temp[2];
- int i, status;
-
- protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
- : AMD_SMB_PRTCL_WRITE;
- pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- protocol |= AMD_SMB_PRTCL_QUICK;
- read_write = I2C_SMBUS_WRITE;
- break;
-
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_WRITE) {
- status = amd_ec_write(smbus, AMD_SMB_CMD,
- command);
- if (status)
- return status;
- }
- protocol |= AMD_SMB_PRTCL_BYTE;
- break;
-
- case I2C_SMBUS_BYTE_DATA:
- status = amd_ec_write(smbus, AMD_SMB_CMD, command);
- if (status)
- return status;
- if (read_write == I2C_SMBUS_WRITE) {
- status = amd_ec_write(smbus, AMD_SMB_DATA,
- data->byte);
- if (status)
- return status;
- }
- protocol |= AMD_SMB_PRTCL_BYTE_DATA;
- break;
-
- case I2C_SMBUS_WORD_DATA:
- status = amd_ec_write(smbus, AMD_SMB_CMD, command);
- if (status)
- return status;
- if (read_write == I2C_SMBUS_WRITE) {
- status = amd_ec_write(smbus, AMD_SMB_DATA,
- data->word & 0xff);
- if (status)
- return status;
- status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
- data->word >> 8);
- if (status)
- return status;
- }
- protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
- break;
-
- case I2C_SMBUS_BLOCK_DATA:
- status = amd_ec_write(smbus, AMD_SMB_CMD, command);
- if (status)
- return status;
- if (read_write == I2C_SMBUS_WRITE) {
- len = min_t(u8, data->block[0],
- I2C_SMBUS_BLOCK_MAX);
- status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
- if (status)
- return status;
- for (i = 0; i < len; i++) {
- status =
- amd_ec_write(smbus, AMD_SMB_DATA + i,
- data->block[i + 1]);
- if (status)
- return status;
- }
- }
- protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
- break;
-
- case I2C_SMBUS_I2C_BLOCK_DATA:
- len = min_t(u8, data->block[0],
- I2C_SMBUS_BLOCK_MAX);
- status = amd_ec_write(smbus, AMD_SMB_CMD, command);
- if (status)
- return status;
- status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
- if (status)
- return status;
- if (read_write == I2C_SMBUS_WRITE)
- for (i = 0; i < len; i++) {
- status =
- amd_ec_write(smbus, AMD_SMB_DATA + i,
- data->block[i + 1]);
- if (status)
- return status;
- }
- protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
- break;
-
- case I2C_SMBUS_PROC_CALL:
- status = amd_ec_write(smbus, AMD_SMB_CMD, command);
- if (status)
- return status;
- status = amd_ec_write(smbus, AMD_SMB_DATA,
- data->word & 0xff);
- if (status)
- return status;
- status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
- data->word >> 8);
- if (status)
- return status;
- protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
- read_write = I2C_SMBUS_READ;
- break;
-
- case I2C_SMBUS_BLOCK_PROC_CALL:
- len = min_t(u8, data->block[0],
- I2C_SMBUS_BLOCK_MAX - 1);
- status = amd_ec_write(smbus, AMD_SMB_CMD, command);
- if (status)
- return status;
- status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
- if (status)
- return status;
- for (i = 0; i < len; i++) {
- status = amd_ec_write(smbus, AMD_SMB_DATA + i,
- data->block[i + 1]);
- if (status)
- return status;
- }
- protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
- read_write = I2C_SMBUS_READ;
- break;
-
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- status = amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
- if (status)
- return status;
- status = amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
- if (status)
- return status;
-
- status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
- if (status)
- return status;
-
- if (~temp[0] & AMD_SMB_STS_DONE) {
- udelay(500);
- status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
- if (status)
- return status;
- }
-
- if (~temp[0] & AMD_SMB_STS_DONE) {
- msleep(1);
- status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
- if (status)
- return status;
- }
-
- if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
- return -EIO;
-
- if (read_write == I2C_SMBUS_WRITE)
- return 0;
-
- switch (size) {
- case I2C_SMBUS_BYTE:
- case I2C_SMBUS_BYTE_DATA:
- status = amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
- if (status)
- return status;
- break;
-
- case I2C_SMBUS_WORD_DATA:
- case I2C_SMBUS_PROC_CALL:
- status = amd_ec_read(smbus, AMD_SMB_DATA, temp + 0);
- if (status)
- return status;
- status = amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1);
- if (status)
- return status;
- data->word = (temp[1] << 8) | temp[0];
- break;
-
- case I2C_SMBUS_BLOCK_DATA:
- case I2C_SMBUS_BLOCK_PROC_CALL:
- status = amd_ec_read(smbus, AMD_SMB_BCNT, &len);
- if (status)
- return status;
- len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
- case I2C_SMBUS_I2C_BLOCK_DATA:
- for (i = 0; i < len; i++) {
- status = amd_ec_read(smbus, AMD_SMB_DATA + i,
- data->block + i + 1);
- if (status)
- return status;
- }
- data->block[0] = len;
- break;
- }
-
- return 0;
-}
-
-
-static u32 amd8111_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
- I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
- I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_PEC;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = amd8111_access,
- .functionality = amd8111_func,
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(amd8111_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, amd8111_ids);
-
-static int __devinit amd8111_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- struct amd_smbus *smbus;
- int error;
-
- if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
- return -ENODEV;
-
- smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
- if (!smbus)
- return -ENOMEM;
-
- smbus->dev = dev;
- smbus->base = pci_resource_start(dev, 0);
- smbus->size = pci_resource_len(dev, 0);
-
- error = acpi_check_resource_conflict(&dev->resource[0]);
- if (error) {
- error = -ENODEV;
- goto out_kfree;
- }
-
- if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
- error = -EBUSY;
- goto out_kfree;
- }
-
- smbus->adapter.owner = THIS_MODULE;
- snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
- "SMBus2 AMD8111 adapter at %04x", smbus->base);
- smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- smbus->adapter.algo = &smbus_algorithm;
- smbus->adapter.algo_data = smbus;
-
- /* set up the sysfs linkage to our parent device */
- smbus->adapter.dev.parent = &dev->dev;
-
- pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
- error = i2c_add_adapter(&smbus->adapter);
- if (error)
- goto out_release_region;
-
- pci_set_drvdata(dev, smbus);
- return 0;
-
- out_release_region:
- release_region(smbus->base, smbus->size);
- out_kfree:
- kfree(smbus);
- return error;
-}
-
-static void __devexit amd8111_remove(struct pci_dev *dev)
-{
- struct amd_smbus *smbus = pci_get_drvdata(dev);
-
- i2c_del_adapter(&smbus->adapter);
- release_region(smbus->base, smbus->size);
- kfree(smbus);
-}
-
-static struct pci_driver amd8111_driver = {
- .name = "amd8111_smbus2",
- .id_table = amd8111_ids,
- .probe = amd8111_probe,
- .remove = __devexit_p(amd8111_remove),
-};
-
-static int __init i2c_amd8111_init(void)
-{
- return pci_register_driver(&amd8111_driver);
-}
-
-static void __exit i2c_amd8111_exit(void)
-{
- pci_unregister_driver(&amd8111_driver);
-}
-
-module_init(i2c_amd8111_init);
-module_exit(i2c_amd8111_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-at91.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-at91.c
deleted file mode 100644
index 1679deef..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-at91.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
-
- Copyright (C) 2004 Rick Bronson
- Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
-
- Borrowed heavily from original work by:
- Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/at91_twi.h>
-#include <mach/board.h>
-#include <mach/cpu.h>
-
-#define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */
-
-
-static struct clk *twi_clk;
-static void __iomem *twi_base;
-
-#define at91_twi_read(reg) __raw_readl(twi_base + (reg))
-#define at91_twi_write(reg, val) __raw_writel((val), twi_base + (reg))
-
-
-/*
- * Initialize the TWI hardware registers.
- */
-static void __devinit at91_twi_hwinit(void)
-{
- unsigned long cdiv, ckdiv;
-
- at91_twi_write(AT91_TWI_IDR, 0xffffffff); /* Disable all interrupts */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST); /* Reset peripheral */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN); /* Set Master mode */
-
- /* Calcuate clock dividers */
- cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3;
- cdiv = cdiv + 1; /* round up */
- ckdiv = 0;
- while (cdiv > 255) {
- ckdiv++;
- cdiv = cdiv >> 1;
- }
-
- if (cpu_is_at91rm9200()) { /* AT91RM9200 Errata #22 */
- if (ckdiv > 5) {
- printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n");
- ckdiv = 5;
- }
- }
-
- at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv);
-}
-
-/*
- * Poll the i2c status register until the specified bit is set.
- * Returns 0 if timed out (100 msec).
- */
-static short at91_poll_status(unsigned long bit)
-{
- int loop_cntr = 10000;
-
- do {
- udelay(10);
- } while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0));
-
- return (loop_cntr > 0);
-}
-
-static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
- /* Send Start */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
-
- /* Read data */
- while (length--) {
- if (!length) /* need to send Stop before reading last byte */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
- if (!at91_poll_status(AT91_TWI_RXRDY)) {
- dev_dbg(&adap->dev, "RXRDY timeout\n");
- return -ETIMEDOUT;
- }
- *buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff);
- }
-
- return 0;
-}
-
-static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
- /* Load first byte into transmitter */
- at91_twi_write(AT91_TWI_THR, *buf++);
-
- /* Send Start */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
-
- do {
- if (!at91_poll_status(AT91_TWI_TXRDY)) {
- dev_dbg(&adap->dev, "TXRDY timeout\n");
- return -ETIMEDOUT;
- }
-
- length--; /* byte was transmitted */
-
- if (length > 0) /* more data to send? */
- at91_twi_write(AT91_TWI_THR, *buf++);
- } while (length);
-
- /* Send Stop */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
-
- return 0;
-}
-
-/*
- * Generic i2c master transfer entrypoint.
- *
- * Note: We do not use Atmel's feature of storing the "internal device address".
- * Instead the "internal device address" has to be written using a separate
- * i2c message.
- * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
- */
-static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
-{
- int i, ret;
-
- dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
-
- for (i = 0; i < num; i++) {
- dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
- pmsg->flags & I2C_M_RD ? "read" : "writ",
- pmsg->len, pmsg->len > 1 ? "s" : "",
- pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr);
-
- at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16)
- | ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
-
- if (pmsg->len && pmsg->buf) { /* sanity check */
- if (pmsg->flags & I2C_M_RD)
- ret = xfer_read(adap, pmsg->buf, pmsg->len);
- else
- ret = xfer_write(adap, pmsg->buf, pmsg->len);
-
- if (ret)
- return ret;
-
- /* Wait until transfer is finished */
- if (!at91_poll_status(AT91_TWI_TXCOMP)) {
- dev_dbg(&adap->dev, "TXCOMP timeout\n");
- return -ETIMEDOUT;
- }
- }
- dev_dbg(&adap->dev, "transfer complete\n");
- pmsg++; /* next message */
- }
- return i;
-}
-
-/*
- * Return list of supported functionality.
- */
-static u32 at91_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm at91_algorithm = {
- .master_xfer = at91_xfer,
- .functionality = at91_func,
-};
-
-/*
- * Main initialization routine.
- */
-static int __devinit at91_i2c_probe(struct platform_device *pdev)
-{
- struct i2c_adapter *adapter;
- struct resource *res;
- int rc;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
-
- if (!request_mem_region(res->start, resource_size(res), "at91_i2c"))
- return -EBUSY;
-
- twi_base = ioremap(res->start, resource_size(res));
- if (!twi_base) {
- rc = -ENOMEM;
- goto fail0;
- }
-
- twi_clk = clk_get(NULL, "twi_clk");
- if (IS_ERR(twi_clk)) {
- dev_err(&pdev->dev, "no clock defined\n");
- rc = -ENODEV;
- goto fail1;
- }
-
- adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
- if (adapter == NULL) {
- dev_err(&pdev->dev, "can't allocate inteface!\n");
- rc = -ENOMEM;
- goto fail2;
- }
- snprintf(adapter->name, sizeof(adapter->name), "AT91");
- adapter->algo = &at91_algorithm;
- adapter->class = I2C_CLASS_HWMON;
- adapter->dev.parent = &pdev->dev;
- /* adapter->id == 0 ... only one TWI controller for now */
-
- platform_set_drvdata(pdev, adapter);
-
- clk_enable(twi_clk); /* enable peripheral clock */
- at91_twi_hwinit(); /* initialize TWI controller */
-
- rc = i2c_add_numbered_adapter(adapter);
- if (rc) {
- dev_err(&pdev->dev, "Adapter %s registration failed\n",
- adapter->name);
- goto fail3;
- }
-
- dev_info(&pdev->dev, "AT91 i2c bus driver.\n");
- return 0;
-
-fail3:
- platform_set_drvdata(pdev, NULL);
- kfree(adapter);
- clk_disable(twi_clk);
-fail2:
- clk_put(twi_clk);
-fail1:
- iounmap(twi_base);
-fail0:
- release_mem_region(res->start, resource_size(res));
-
- return rc;
-}
-
-static int __devexit at91_i2c_remove(struct platform_device *pdev)
-{
- struct i2c_adapter *adapter = platform_get_drvdata(pdev);
- struct resource *res;
- int rc;
-
- rc = i2c_del_adapter(adapter);
- platform_set_drvdata(pdev, NULL);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- iounmap(twi_base);
- release_mem_region(res->start, resource_size(res));
-
- clk_disable(twi_clk); /* disable peripheral clock */
- clk_put(twi_clk);
-
- return rc;
-}
-
-#ifdef CONFIG_PM
-
-/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
-
-static int at91_i2c_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
- clk_disable(twi_clk);
- return 0;
-}
-
-static int at91_i2c_resume(struct platform_device *pdev)
-{
- return clk_enable(twi_clk);
-}
-
-#else
-#define at91_i2c_suspend NULL
-#define at91_i2c_resume NULL
-#endif
-
-static struct platform_driver at91_i2c_driver = {
- .probe = at91_i2c_probe,
- .remove = __devexit_p(at91_i2c_remove),
- .suspend = at91_i2c_suspend,
- .resume = at91_i2c_resume,
- .driver = {
- .name = "at91_i2c",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(at91_i2c_driver);
-
-MODULE_AUTHOR("Rick Bronson");
-MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:at91_i2c");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-au1550.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-au1550.c
deleted file mode 100644
index 582d616d..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-au1550.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * i2c-au1550.c: SMBus (i2c) adapter for Alchemy PSC interface
- * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com>
- *
- * 2.6 port by Matt Porter <mporter@kernel.crashing.org>
- *
- * The documentation describes this as an SMBus controller, but it doesn't
- * understand any of the SMBus protocol in hardware. It's really an I2C
- * controller that could emulate most of the SMBus in software.
- *
- * This is just a skeleton adapter to use with the Au1550 PSC
- * algorithm. It was developed for the Pb1550, but will work with
- * any Au1550 board that has a similar PSC configuration.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#define PSC_SEL 0x00
-#define PSC_CTRL 0x04
-#define PSC_SMBCFG 0x08
-#define PSC_SMBMSK 0x0C
-#define PSC_SMBPCR 0x10
-#define PSC_SMBSTAT 0x14
-#define PSC_SMBEVNT 0x18
-#define PSC_SMBTXRX 0x1C
-#define PSC_SMBTMR 0x20
-
-struct i2c_au1550_data {
- void __iomem *psc_base;
- int xfer_timeout;
- struct i2c_adapter adap;
- struct resource *ioarea;
-};
-
-static inline void WR(struct i2c_au1550_data *a, int r, unsigned long v)
-{
- __raw_writel(v, a->psc_base + r);
- wmb();
-}
-
-static inline unsigned long RD(struct i2c_au1550_data *a, int r)
-{
- return __raw_readl(a->psc_base + r);
-}
-
-static int wait_xfer_done(struct i2c_au1550_data *adap)
-{
- int i;
-
- /* Wait for Tx Buffer Empty */
- for (i = 0; i < adap->xfer_timeout; i++) {
- if (RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_TE)
- return 0;
-
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int wait_ack(struct i2c_au1550_data *adap)
-{
- unsigned long stat;
-
- if (wait_xfer_done(adap))
- return -ETIMEDOUT;
-
- stat = RD(adap, PSC_SMBEVNT);
- if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-static int wait_master_done(struct i2c_au1550_data *adap)
-{
- int i;
-
- /* Wait for Master Done. */
- for (i = 0; i < 2 * adap->xfer_timeout; i++) {
- if ((RD(adap, PSC_SMBEVNT) & PSC_SMBEVNT_MD) != 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int
-do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q)
-{
- unsigned long stat;
-
- /* Reset the FIFOs, clear events. */
- stat = RD(adap, PSC_SMBSTAT);
- WR(adap, PSC_SMBEVNT, PSC_SMBEVNT_ALLCLR);
-
- if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) {
- WR(adap, PSC_SMBPCR, PSC_SMBPCR_DC);
- while ((RD(adap, PSC_SMBPCR) & PSC_SMBPCR_DC) != 0)
- cpu_relax();
- udelay(50);
- }
-
- /* Write out the i2c chip address and specify operation */
- addr <<= 1;
- if (rd)
- addr |= 1;
-
- /* zero-byte xfers stop immediately */
- if (q)
- addr |= PSC_SMBTXRX_STP;
-
- /* Put byte into fifo, start up master. */
- WR(adap, PSC_SMBTXRX, addr);
- WR(adap, PSC_SMBPCR, PSC_SMBPCR_MS);
- if (wait_ack(adap))
- return -EIO;
- return (q) ? wait_master_done(adap) : 0;
-}
-
-static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out)
-{
- int j;
-
- if (wait_xfer_done(adap))
- return -EIO;
-
- j = adap->xfer_timeout * 100;
- do {
- j--;
- if (j <= 0)
- return -EIO;
-
- if ((RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_RE) == 0)
- j = 0;
- else
- udelay(1);
- } while (j > 0);
-
- *out = RD(adap, PSC_SMBTXRX);
-
- return 0;
-}
-
-static int i2c_read(struct i2c_au1550_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- if (len == 0)
- return 0;
-
- /* A read is performed by stuffing the transmit fifo with
- * zero bytes for timing, waiting for bytes to appear in the
- * receive fifo, then reading the bytes.
- */
- i = 0;
- while (i < (len - 1)) {
- WR(adap, PSC_SMBTXRX, 0);
- if (wait_for_rx_byte(adap, &buf[i]))
- return -EIO;
-
- i++;
- }
-
- /* The last byte has to indicate transfer done. */
- WR(adap, PSC_SMBTXRX, PSC_SMBTXRX_STP);
- if (wait_master_done(adap))
- return -EIO;
-
- buf[i] = (unsigned char)(RD(adap, PSC_SMBTXRX) & 0xff);
- return 0;
-}
-
-static int i2c_write(struct i2c_au1550_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
- unsigned long data;
-
- if (len == 0)
- return 0;
-
- i = 0;
- while (i < (len-1)) {
- data = buf[i];
- WR(adap, PSC_SMBTXRX, data);
- if (wait_ack(adap))
- return -EIO;
- i++;
- }
-
- /* The last byte has to indicate transfer done. */
- data = buf[i];
- data |= PSC_SMBTXRX_STP;
- WR(adap, PSC_SMBTXRX, data);
- if (wait_master_done(adap))
- return -EIO;
- return 0;
-}
-
-static int
-au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
-{
- struct i2c_au1550_data *adap = i2c_adap->algo_data;
- struct i2c_msg *p;
- int i, err = 0;
-
- WR(adap, PSC_CTRL, PSC_CTRL_ENABLE);
-
- for (i = 0; !err && i < num; i++) {
- p = &msgs[i];
- err = do_address(adap, p->addr, p->flags & I2C_M_RD,
- (p->len == 0));
- if (err || !p->len)
- continue;
- if (p->flags & I2C_M_RD)
- err = i2c_read(adap, p->buf, p->len);
- else
- err = i2c_write(adap, p->buf, p->len);
- }
-
- /* Return the number of messages processed, or the error code.
- */
- if (err == 0)
- err = num;
-
- WR(adap, PSC_CTRL, PSC_CTRL_SUSPEND);
-
- return err;
-}
-
-static u32 au1550_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm au1550_algo = {
- .master_xfer = au1550_xfer,
- .functionality = au1550_func,
-};
-
-static void i2c_au1550_setup(struct i2c_au1550_data *priv)
-{
- unsigned long cfg;
-
- WR(priv, PSC_CTRL, PSC_CTRL_DISABLE);
- WR(priv, PSC_SEL, PSC_SEL_PS_SMBUSMODE);
- WR(priv, PSC_SMBCFG, 0);
- WR(priv, PSC_CTRL, PSC_CTRL_ENABLE);
- while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0)
- cpu_relax();
-
- cfg = PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE;
- WR(priv, PSC_SMBCFG, cfg);
-
- /* Divide by 8 to get a 6.25 MHz clock. The later protocol
- * timings are based on this clock.
- */
- cfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
- WR(priv, PSC_SMBCFG, cfg);
- WR(priv, PSC_SMBMSK, PSC_SMBMSK_ALLMASK);
-
- /* Set the protocol timer values. See Table 71 in the
- * Au1550 Data Book for standard timing values.
- */
- WR(priv, PSC_SMBTMR, PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \
- PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \
- PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \
- PSC_SMBTMR_SET_CH(15));
-
- cfg |= PSC_SMBCFG_DE_ENABLE;
- WR(priv, PSC_SMBCFG, cfg);
- while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0)
- cpu_relax();
-
- WR(priv, PSC_CTRL, PSC_CTRL_SUSPEND);
-}
-
-static void i2c_au1550_disable(struct i2c_au1550_data *priv)
-{
- WR(priv, PSC_SMBCFG, 0);
- WR(priv, PSC_CTRL, PSC_CTRL_DISABLE);
-}
-
-/*
- * registering functions to load algorithms at runtime
- * Prior to calling us, the 50MHz clock frequency and routing
- * must have been set up for the PSC indicated by the adapter.
- */
-static int __devinit
-i2c_au1550_probe(struct platform_device *pdev)
-{
- struct i2c_au1550_data *priv;
- struct resource *r;
- int ret;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- ret = -ENODEV;
- goto out;
- }
-
- priv = kzalloc(sizeof(struct i2c_au1550_data), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- goto out;
- }
-
- priv->ioarea = request_mem_region(r->start, resource_size(r),
- pdev->name);
- if (!priv->ioarea) {
- ret = -EBUSY;
- goto out_mem;
- }
-
- priv->psc_base = ioremap(r->start, resource_size(r));
- if (!priv->psc_base) {
- ret = -EIO;
- goto out_map;
- }
- priv->xfer_timeout = 200;
-
- priv->adap.nr = pdev->id;
- priv->adap.algo = &au1550_algo;
- priv->adap.algo_data = priv;
- priv->adap.dev.parent = &pdev->dev;
- strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));
-
- /* Now, set up the PSC for SMBus PIO mode. */
- i2c_au1550_setup(priv);
-
- ret = i2c_add_numbered_adapter(&priv->adap);
- if (ret == 0) {
- platform_set_drvdata(pdev, priv);
- return 0;
- }
-
- i2c_au1550_disable(priv);
- iounmap(priv->psc_base);
-out_map:
- release_resource(priv->ioarea);
- kfree(priv->ioarea);
-out_mem:
- kfree(priv);
-out:
- return ret;
-}
-
-static int __devexit i2c_au1550_remove(struct platform_device *pdev)
-{
- struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
-
- platform_set_drvdata(pdev, NULL);
- i2c_del_adapter(&priv->adap);
- i2c_au1550_disable(priv);
- iounmap(priv->psc_base);
- release_resource(priv->ioarea);
- kfree(priv->ioarea);
- kfree(priv);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int i2c_au1550_suspend(struct device *dev)
-{
- struct i2c_au1550_data *priv = dev_get_drvdata(dev);
-
- i2c_au1550_disable(priv);
-
- return 0;
-}
-
-static int i2c_au1550_resume(struct device *dev)
-{
- struct i2c_au1550_data *priv = dev_get_drvdata(dev);
-
- i2c_au1550_setup(priv);
-
- return 0;
-}
-
-static const struct dev_pm_ops i2c_au1550_pmops = {
- .suspend = i2c_au1550_suspend,
- .resume = i2c_au1550_resume,
-};
-
-#define AU1XPSC_SMBUS_PMOPS (&i2c_au1550_pmops)
-
-#else
-#define AU1XPSC_SMBUS_PMOPS NULL
-#endif
-
-static struct platform_driver au1xpsc_smbus_driver = {
- .driver = {
- .name = "au1xpsc_smbus",
- .owner = THIS_MODULE,
- .pm = AU1XPSC_SMBUS_PMOPS,
- },
- .probe = i2c_au1550_probe,
- .remove = __devexit_p(i2c_au1550_remove),
-};
-
-module_platform_driver(au1xpsc_smbus_driver);
-
-MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
-MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:au1xpsc_smbus");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-bfin-twi.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-bfin-twi.c
deleted file mode 100644
index cdb59e5b..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-bfin-twi.c
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Blackfin On-Chip Two Wire Interface Driver
- *
- * Copyright 2005-2007 Analog Devices Inc.
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-
-#include <asm/blackfin.h>
-#include <asm/portmux.h>
-#include <asm/irq.h>
-
-/* SMBus mode*/
-#define TWI_I2C_MODE_STANDARD 1
-#define TWI_I2C_MODE_STANDARDSUB 2
-#define TWI_I2C_MODE_COMBINED 3
-#define TWI_I2C_MODE_REPEAT 4
-
-struct bfin_twi_iface {
- int irq;
- spinlock_t lock;
- char read_write;
- u8 command;
- u8 *transPtr;
- int readNum;
- int writeNum;
- int cur_mode;
- int manual_stop;
- int result;
- struct i2c_adapter adap;
- struct completion complete;
- struct i2c_msg *pmsg;
- int msg_num;
- int cur_msg;
- u16 saved_clkdiv;
- u16 saved_control;
- void __iomem *regs_base;
-};
-
-
-#define DEFINE_TWI_REG(reg, off) \
-static inline u16 read_##reg(struct bfin_twi_iface *iface) \
- { return bfin_read16(iface->regs_base + (off)); } \
-static inline void write_##reg(struct bfin_twi_iface *iface, u16 v) \
- { bfin_write16(iface->regs_base + (off), v); }
-
-DEFINE_TWI_REG(CLKDIV, 0x00)
-DEFINE_TWI_REG(CONTROL, 0x04)
-DEFINE_TWI_REG(SLAVE_CTL, 0x08)
-DEFINE_TWI_REG(SLAVE_STAT, 0x0C)
-DEFINE_TWI_REG(SLAVE_ADDR, 0x10)
-DEFINE_TWI_REG(MASTER_CTL, 0x14)
-DEFINE_TWI_REG(MASTER_STAT, 0x18)
-DEFINE_TWI_REG(MASTER_ADDR, 0x1C)
-DEFINE_TWI_REG(INT_STAT, 0x20)
-DEFINE_TWI_REG(INT_MASK, 0x24)
-DEFINE_TWI_REG(FIFO_CTL, 0x28)
-DEFINE_TWI_REG(FIFO_STAT, 0x2C)
-DEFINE_TWI_REG(XMT_DATA8, 0x80)
-DEFINE_TWI_REG(XMT_DATA16, 0x84)
-DEFINE_TWI_REG(RCV_DATA8, 0x88)
-DEFINE_TWI_REG(RCV_DATA16, 0x8C)
-
-static const u16 pin_req[2][3] = {
- {P_TWI0_SCL, P_TWI0_SDA, 0},
- {P_TWI1_SCL, P_TWI1_SDA, 0},
-};
-
-static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
- unsigned short twi_int_status)
-{
- unsigned short mast_stat = read_MASTER_STAT(iface);
-
- if (twi_int_status & XMTSERV) {
- /* Transmit next data */
- if (iface->writeNum > 0) {
- SSYNC();
- write_XMT_DATA8(iface, *(iface->transPtr++));
- iface->writeNum--;
- }
- /* start receive immediately after complete sending in
- * combine mode.
- */
- else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) | MDIR | RSTART);
- else if (iface->manual_stop)
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) | STOP);
- else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
- iface->cur_msg + 1 < iface->msg_num) {
- if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) | RSTART | MDIR);
- else
- write_MASTER_CTL(iface,
- (read_MASTER_CTL(iface) | RSTART) & ~MDIR);
- }
- }
- if (twi_int_status & RCVSERV) {
- if (iface->readNum > 0) {
- /* Receive next data */
- *(iface->transPtr) = read_RCV_DATA8(iface);
- if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
- /* Change combine mode into sub mode after
- * read first data.
- */
- iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
- /* Get read number from first byte in block
- * combine mode.
- */
- if (iface->readNum == 1 && iface->manual_stop)
- iface->readNum = *iface->transPtr + 1;
- }
- iface->transPtr++;
- iface->readNum--;
- } else if (iface->manual_stop) {
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) | STOP);
- } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
- iface->cur_msg + 1 < iface->msg_num) {
- if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) | RSTART | MDIR);
- else
- write_MASTER_CTL(iface,
- (read_MASTER_CTL(iface) | RSTART) & ~MDIR);
- }
- }
- if (twi_int_status & MERR) {
- write_INT_MASK(iface, 0);
- write_MASTER_STAT(iface, 0x3e);
- write_MASTER_CTL(iface, 0);
- iface->result = -EIO;
-
- if (mast_stat & LOSTARB)
- dev_dbg(&iface->adap.dev, "Lost Arbitration\n");
- if (mast_stat & ANAK)
- dev_dbg(&iface->adap.dev, "Address Not Acknowledged\n");
- if (mast_stat & DNAK)
- dev_dbg(&iface->adap.dev, "Data Not Acknowledged\n");
- if (mast_stat & BUFRDERR)
- dev_dbg(&iface->adap.dev, "Buffer Read Error\n");
- if (mast_stat & BUFWRERR)
- dev_dbg(&iface->adap.dev, "Buffer Write Error\n");
-
- /* Faulty slave devices, may drive SDA low after a transfer
- * finishes. To release the bus this code generates up to 9
- * extra clocks until SDA is released.
- */
-
- if (read_MASTER_STAT(iface) & SDASEN) {
- int cnt = 9;
- do {
- write_MASTER_CTL(iface, SCLOVR);
- udelay(6);
- write_MASTER_CTL(iface, 0);
- udelay(6);
- } while ((read_MASTER_STAT(iface) & SDASEN) && cnt--);
-
- write_MASTER_CTL(iface, SDAOVR | SCLOVR);
- udelay(6);
- write_MASTER_CTL(iface, SDAOVR);
- udelay(6);
- write_MASTER_CTL(iface, 0);
- }
-
- /* If it is a quick transfer, only address without data,
- * not an err, return 1.
- */
- if (iface->cur_mode == TWI_I2C_MODE_STANDARD &&
- iface->transPtr == NULL &&
- (twi_int_status & MCOMP) && (mast_stat & DNAK))
- iface->result = 1;
-
- complete(&iface->complete);
- return;
- }
- if (twi_int_status & MCOMP) {
- if ((read_MASTER_CTL(iface) & MEN) == 0 &&
- (iface->cur_mode == TWI_I2C_MODE_REPEAT ||
- iface->cur_mode == TWI_I2C_MODE_COMBINED)) {
- iface->result = -1;
- write_INT_MASK(iface, 0);
- write_MASTER_CTL(iface, 0);
- } else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
- if (iface->readNum == 0) {
- /* set the read number to 1 and ask for manual
- * stop in block combine mode
- */
- iface->readNum = 1;
- iface->manual_stop = 1;
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) | (0xff << 6));
- } else {
- /* set the readd number in other
- * combine mode.
- */
- write_MASTER_CTL(iface,
- (read_MASTER_CTL(iface) &
- (~(0xff << 6))) |
- (iface->readNum << 6));
- }
- /* remove restart bit and enable master receive */
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) & ~RSTART);
- } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
- iface->cur_msg+1 < iface->msg_num) {
- iface->cur_msg++;
- iface->transPtr = iface->pmsg[iface->cur_msg].buf;
- iface->writeNum = iface->readNum =
- iface->pmsg[iface->cur_msg].len;
- /* Set Transmit device address */
- write_MASTER_ADDR(iface,
- iface->pmsg[iface->cur_msg].addr);
- if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD)
- iface->read_write = I2C_SMBUS_READ;
- else {
- iface->read_write = I2C_SMBUS_WRITE;
- /* Transmit first data */
- if (iface->writeNum > 0) {
- write_XMT_DATA8(iface,
- *(iface->transPtr++));
- iface->writeNum--;
- }
- }
-
- if (iface->pmsg[iface->cur_msg].len <= 255)
- write_MASTER_CTL(iface,
- (read_MASTER_CTL(iface) &
- (~(0xff << 6))) |
- (iface->pmsg[iface->cur_msg].len << 6));
- else {
- write_MASTER_CTL(iface,
- (read_MASTER_CTL(iface) |
- (0xff << 6)));
- iface->manual_stop = 1;
- }
- /* remove restart bit and enable master receive */
- write_MASTER_CTL(iface,
- read_MASTER_CTL(iface) & ~RSTART);
- } else {
- iface->result = 1;
- write_INT_MASK(iface, 0);
- write_MASTER_CTL(iface, 0);
- }
- }
- complete(&iface->complete);
-}
-
-/* Interrupt handler */
-static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)
-{
- struct bfin_twi_iface *iface = dev_id;
- unsigned long flags;
- unsigned short twi_int_status;
-
- spin_lock_irqsave(&iface->lock, flags);
- while (1) {
- twi_int_status = read_INT_STAT(iface);
- if (!twi_int_status)
- break;
- /* Clear interrupt status */
- write_INT_STAT(iface, twi_int_status);
- bfin_twi_handle_interrupt(iface, twi_int_status);
- SSYNC();
- }
- spin_unlock_irqrestore(&iface->lock, flags);
- return IRQ_HANDLED;
-}
-
-/*
- * One i2c master transfer
- */
-static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
-{
- struct bfin_twi_iface *iface = adap->algo_data;
- struct i2c_msg *pmsg;
- int rc = 0;
-
- if (!(read_CONTROL(iface) & TWI_ENA))
- return -ENXIO;
-
- while (read_MASTER_STAT(iface) & BUSBUSY)
- yield();
-
- iface->pmsg = msgs;
- iface->msg_num = num;
- iface->cur_msg = 0;
-
- pmsg = &msgs[0];
- if (pmsg->flags & I2C_M_TEN) {
- dev_err(&adap->dev, "10 bits addr not supported!\n");
- return -EINVAL;
- }
-
- iface->cur_mode = TWI_I2C_MODE_REPEAT;
- iface->manual_stop = 0;
- iface->transPtr = pmsg->buf;
- iface->writeNum = iface->readNum = pmsg->len;
- iface->result = 0;
- init_completion(&(iface->complete));
- /* Set Transmit device address */
- write_MASTER_ADDR(iface, pmsg->addr);
-
- /* FIFO Initiation. Data in FIFO should be
- * discarded before start a new operation.
- */
- write_FIFO_CTL(iface, 0x3);
- SSYNC();
- write_FIFO_CTL(iface, 0);
- SSYNC();
-
- if (pmsg->flags & I2C_M_RD)
- iface->read_write = I2C_SMBUS_READ;
- else {
- iface->read_write = I2C_SMBUS_WRITE;
- /* Transmit first data */
- if (iface->writeNum > 0) {
- write_XMT_DATA8(iface, *(iface->transPtr++));
- iface->writeNum--;
- SSYNC();
- }
- }
-
- /* clear int stat */
- write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
-
- /* Interrupt mask . Enable XMT, RCV interrupt */
- write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
- SSYNC();
-
- if (pmsg->len <= 255)
- write_MASTER_CTL(iface, pmsg->len << 6);
- else {
- write_MASTER_CTL(iface, 0xff << 6);
- iface->manual_stop = 1;
- }
-
- /* Master enable */
- write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
- ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
- ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
- SSYNC();
-
- while (!iface->result) {
- if (!wait_for_completion_timeout(&iface->complete,
- adap->timeout)) {
- iface->result = -1;
- dev_err(&adap->dev, "master transfer timeout\n");
- }
- }
-
- if (iface->result == 1)
- rc = iface->cur_msg + 1;
- else
- rc = iface->result;
-
- return rc;
-}
-
-/*
- * Generic i2c master transfer entrypoint
- */
-static int bfin_twi_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
-{
- return bfin_twi_do_master_xfer(adap, msgs, num);
-}
-
-/*
- * One I2C SMBus transfer
- */
-int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data *data)
-{
- struct bfin_twi_iface *iface = adap->algo_data;
- int rc = 0;
-
- if (!(read_CONTROL(iface) & TWI_ENA))
- return -ENXIO;
-
- while (read_MASTER_STAT(iface) & BUSBUSY)
- yield();
-
- iface->writeNum = 0;
- iface->readNum = 0;
-
- /* Prepare datas & select mode */
- switch (size) {
- case I2C_SMBUS_QUICK:
- iface->transPtr = NULL;
- iface->cur_mode = TWI_I2C_MODE_STANDARD;
- break;
- case I2C_SMBUS_BYTE:
- if (data == NULL)
- iface->transPtr = NULL;
- else {
- if (read_write == I2C_SMBUS_READ)
- iface->readNum = 1;
- else
- iface->writeNum = 1;
- iface->transPtr = &data->byte;
- }
- iface->cur_mode = TWI_I2C_MODE_STANDARD;
- break;
- case I2C_SMBUS_BYTE_DATA:
- if (read_write == I2C_SMBUS_READ) {
- iface->readNum = 1;
- iface->cur_mode = TWI_I2C_MODE_COMBINED;
- } else {
- iface->writeNum = 1;
- iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
- }
- iface->transPtr = &data->byte;
- break;
- case I2C_SMBUS_WORD_DATA:
- if (read_write == I2C_SMBUS_READ) {
- iface->readNum = 2;
- iface->cur_mode = TWI_I2C_MODE_COMBINED;
- } else {
- iface->writeNum = 2;
- iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
- }
- iface->transPtr = (u8 *)&data->word;
- break;
- case I2C_SMBUS_PROC_CALL:
- iface->writeNum = 2;
- iface->readNum = 2;
- iface->cur_mode = TWI_I2C_MODE_COMBINED;
- iface->transPtr = (u8 *)&data->word;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- if (read_write == I2C_SMBUS_READ) {
- iface->readNum = 0;
- iface->cur_mode = TWI_I2C_MODE_COMBINED;
- } else {
- iface->writeNum = data->block[0] + 1;
- iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
- }
- iface->transPtr = data->block;
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- if (read_write == I2C_SMBUS_READ) {
- iface->readNum = data->block[0];
- iface->cur_mode = TWI_I2C_MODE_COMBINED;
- } else {
- iface->writeNum = data->block[0];
- iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
- }
- iface->transPtr = (u8 *)&data->block[1];
- break;
- default:
- return -1;
- }
-
- iface->result = 0;
- iface->manual_stop = 0;
- iface->read_write = read_write;
- iface->command = command;
- init_completion(&(iface->complete));
-
- /* FIFO Initiation. Data in FIFO should be discarded before
- * start a new operation.
- */
- write_FIFO_CTL(iface, 0x3);
- SSYNC();
- write_FIFO_CTL(iface, 0);
-
- /* clear int stat */
- write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
-
- /* Set Transmit device address */
- write_MASTER_ADDR(iface, addr);
- SSYNC();
-
- switch (iface->cur_mode) {
- case TWI_I2C_MODE_STANDARDSUB:
- write_XMT_DATA8(iface, iface->command);
- write_INT_MASK(iface, MCOMP | MERR |
- ((iface->read_write == I2C_SMBUS_READ) ?
- RCVSERV : XMTSERV));
- SSYNC();
-
- if (iface->writeNum + 1 <= 255)
- write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
- else {
- write_MASTER_CTL(iface, 0xff << 6);
- iface->manual_stop = 1;
- }
- /* Master enable */
- write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
- ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
- break;
- case TWI_I2C_MODE_COMBINED:
- write_XMT_DATA8(iface, iface->command);
- write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
- SSYNC();
-
- if (iface->writeNum > 0)
- write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
- else
- write_MASTER_CTL(iface, 0x1 << 6);
- /* Master enable */
- write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
- ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
- break;
- default:
- write_MASTER_CTL(iface, 0);
- if (size != I2C_SMBUS_QUICK) {
- /* Don't access xmit data register when this is a
- * read operation.
- */
- if (iface->read_write != I2C_SMBUS_READ) {
- if (iface->writeNum > 0) {
- write_XMT_DATA8(iface,
- *(iface->transPtr++));
- if (iface->writeNum <= 255)
- write_MASTER_CTL(iface,
- iface->writeNum << 6);
- else {
- write_MASTER_CTL(iface,
- 0xff << 6);
- iface->manual_stop = 1;
- }
- iface->writeNum--;
- } else {
- write_XMT_DATA8(iface, iface->command);
- write_MASTER_CTL(iface, 1 << 6);
- }
- } else {
- if (iface->readNum > 0 && iface->readNum <= 255)
- write_MASTER_CTL(iface,
- iface->readNum << 6);
- else if (iface->readNum > 255) {
- write_MASTER_CTL(iface, 0xff << 6);
- iface->manual_stop = 1;
- } else
- break;
- }
- }
- write_INT_MASK(iface, MCOMP | MERR |
- ((iface->read_write == I2C_SMBUS_READ) ?
- RCVSERV : XMTSERV));
- SSYNC();
-
- /* Master enable */
- write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
- ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
- ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
- break;
- }
- SSYNC();
-
- while (!iface->result) {
- if (!wait_for_completion_timeout(&iface->complete,
- adap->timeout)) {
- iface->result = -1;
- dev_err(&adap->dev, "smbus transfer timeout\n");
- }
- }
-
- rc = (iface->result >= 0) ? 0 : -1;
-
- return rc;
-}
-
-/*
- * Generic I2C SMBus transfer entrypoint
- */
-int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data *data)
-{
- return bfin_twi_do_smbus_xfer(adap, addr, flags,
- read_write, command, size, data);
-}
-
-/*
- * Return what the adapter supports
- */
-static u32 bfin_twi_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
- I2C_FUNC_I2C | I2C_FUNC_SMBUS_I2C_BLOCK;
-}
-
-static struct i2c_algorithm bfin_twi_algorithm = {
- .master_xfer = bfin_twi_master_xfer,
- .smbus_xfer = bfin_twi_smbus_xfer,
- .functionality = bfin_twi_functionality,
-};
-
-static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
-
- iface->saved_clkdiv = read_CLKDIV(iface);
- iface->saved_control = read_CONTROL(iface);
-
- free_irq(iface->irq, iface);
-
- /* Disable TWI */
- write_CONTROL(iface, iface->saved_control & ~TWI_ENA);
-
- return 0;
-}
-
-static int i2c_bfin_twi_resume(struct platform_device *pdev)
-{
- struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
-
- int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
- 0, pdev->name, iface);
- if (rc) {
- dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
- return -ENODEV;
- }
-
- /* Resume TWI interface clock as specified */
- write_CLKDIV(iface, iface->saved_clkdiv);
-
- /* Resume TWI */
- write_CONTROL(iface, iface->saved_control);
-
- return 0;
-}
-
-static int i2c_bfin_twi_probe(struct platform_device *pdev)
-{
- struct bfin_twi_iface *iface;
- struct i2c_adapter *p_adap;
- struct resource *res;
- int rc;
- unsigned int clkhilow;
-
- iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL);
- if (!iface) {
- dev_err(&pdev->dev, "Cannot allocate memory\n");
- rc = -ENOMEM;
- goto out_error_nomem;
- }
-
- spin_lock_init(&(iface->lock));
-
- /* Find and map our resources */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
- rc = -ENOENT;
- goto out_error_get_res;
- }
-
- iface->regs_base = ioremap(res->start, resource_size(res));
- if (iface->regs_base == NULL) {
- dev_err(&pdev->dev, "Cannot map IO\n");
- rc = -ENXIO;
- goto out_error_ioremap;
- }
-
- iface->irq = platform_get_irq(pdev, 0);
- if (iface->irq < 0) {
- dev_err(&pdev->dev, "No IRQ specified\n");
- rc = -ENOENT;
- goto out_error_no_irq;
- }
-
- p_adap = &iface->adap;
- p_adap->nr = pdev->id;
- strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
- p_adap->algo = &bfin_twi_algorithm;
- p_adap->algo_data = iface;
- p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- p_adap->dev.parent = &pdev->dev;
- p_adap->timeout = 5 * HZ;
- p_adap->retries = 3;
-
- rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
- if (rc) {
- dev_err(&pdev->dev, "Can't setup pin mux!\n");
- goto out_error_pin_mux;
- }
-
- rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
- 0, pdev->name, iface);
- if (rc) {
- dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
- rc = -ENODEV;
- goto out_error_req_irq;
- }
-
- /* Set TWI internal clock as 10MHz */
- write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F);
-
- /*
- * We will not end up with a CLKDIV=0 because no one will specify
- * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250)
- */
- clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2;
-
- /* Set Twi interface clock as specified */
- write_CLKDIV(iface, (clkhilow << 8) | clkhilow);
-
- /* Enable TWI */
- write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
- SSYNC();
-
- rc = i2c_add_numbered_adapter(p_adap);
- if (rc < 0) {
- dev_err(&pdev->dev, "Can't add i2c adapter!\n");
- goto out_error_add_adapter;
- }
-
- platform_set_drvdata(pdev, iface);
-
- dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, "
- "regs_base@%p\n", iface->regs_base);
-
- return 0;
-
-out_error_add_adapter:
- free_irq(iface->irq, iface);
-out_error_req_irq:
-out_error_no_irq:
- peripheral_free_list(pin_req[pdev->id]);
-out_error_pin_mux:
- iounmap(iface->regs_base);
-out_error_ioremap:
-out_error_get_res:
- kfree(iface);
-out_error_nomem:
- return rc;
-}
-
-static int i2c_bfin_twi_remove(struct platform_device *pdev)
-{
- struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
-
- platform_set_drvdata(pdev, NULL);
-
- i2c_del_adapter(&(iface->adap));
- free_irq(iface->irq, iface);
- peripheral_free_list(pin_req[pdev->id]);
- iounmap(iface->regs_base);
- kfree(iface);
-
- return 0;
-}
-
-static struct platform_driver i2c_bfin_twi_driver = {
- .probe = i2c_bfin_twi_probe,
- .remove = i2c_bfin_twi_remove,
- .suspend = i2c_bfin_twi_suspend,
- .resume = i2c_bfin_twi_resume,
- .driver = {
- .name = "i2c-bfin-twi",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init i2c_bfin_twi_init(void)
-{
- return platform_driver_register(&i2c_bfin_twi_driver);
-}
-
-static void __exit i2c_bfin_twi_exit(void)
-{
- platform_driver_unregister(&i2c_bfin_twi_driver);
-}
-
-subsys_initcall(i2c_bfin_twi_init);
-module_exit(i2c_bfin_twi_exit);
-
-MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
-MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:i2c-bfin-twi");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-cpm.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-cpm.c
deleted file mode 100644
index c1e1096b..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-cpm.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * Freescale CPM1/CPM2 I2C interface.
- * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
- *
- * moved into proper i2c interface;
- * Brad Parker (brad@heeltoe.com)
- *
- * Parts from dbox2_i2c.c (cvs.tuxbox.org)
- * (C) 2000-2001 Felix Domke (tmbinc@gmx.net), Gillem (htoa@gmx.net)
- *
- * (C) 2007 Montavista Software, Inc.
- * Vitaly Bordug <vitb@kernel.crashing.org>
- *
- * Converted to of_platform_device. Renamed to i2c-cpm.c.
- * (C) 2007,2008 Jochen Friedrich <jochen@scram.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/stddef.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/dma-mapping.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/of_i2c.h>
-#include <sysdev/fsl_soc.h>
-#include <asm/cpm.h>
-
-/* Try to define this if you have an older CPU (earlier than rev D4) */
-/* However, better use a GPIO based bitbang driver in this case :/ */
-#undef I2C_CHIP_ERRATA
-
-#define CPM_MAX_READ 513
-#define CPM_MAXBD 4
-
-#define I2C_EB (0x10) /* Big endian mode */
-#define I2C_EB_CPM2 (0x30) /* Big endian mode, memory snoop */
-
-#define DPRAM_BASE ((u8 __iomem __force *)cpm_muram_addr(0))
-
-/* I2C parameter RAM. */
-struct i2c_ram {
- ushort rbase; /* Rx Buffer descriptor base address */
- ushort tbase; /* Tx Buffer descriptor base address */
- u_char rfcr; /* Rx function code */
- u_char tfcr; /* Tx function code */
- ushort mrblr; /* Max receive buffer length */
- uint rstate; /* Internal */
- uint rdp; /* Internal */
- ushort rbptr; /* Rx Buffer descriptor pointer */
- ushort rbc; /* Internal */
- uint rxtmp; /* Internal */
- uint tstate; /* Internal */
- uint tdp; /* Internal */
- ushort tbptr; /* Tx Buffer descriptor pointer */
- ushort tbc; /* Internal */
- uint txtmp; /* Internal */
- char res1[4]; /* Reserved */
- ushort rpbase; /* Relocation pointer */
- char res2[2]; /* Reserved */
-};
-
-#define I2COM_START 0x80
-#define I2COM_MASTER 0x01
-#define I2CER_TXE 0x10
-#define I2CER_BUSY 0x04
-#define I2CER_TXB 0x02
-#define I2CER_RXB 0x01
-#define I2MOD_EN 0x01
-
-/* I2C Registers */
-struct i2c_reg {
- u8 i2mod;
- u8 res1[3];
- u8 i2add;
- u8 res2[3];
- u8 i2brg;
- u8 res3[3];
- u8 i2com;
- u8 res4[3];
- u8 i2cer;
- u8 res5[3];
- u8 i2cmr;
-};
-
-struct cpm_i2c {
- char *base;
- struct platform_device *ofdev;
- struct i2c_adapter adap;
- uint dp_addr;
- int version; /* CPM1=1, CPM2=2 */
- int irq;
- int cp_command;
- int freq;
- struct i2c_reg __iomem *i2c_reg;
- struct i2c_ram __iomem *i2c_ram;
- u16 i2c_addr;
- wait_queue_head_t i2c_wait;
- cbd_t __iomem *tbase;
- cbd_t __iomem *rbase;
- u_char *txbuf[CPM_MAXBD];
- u_char *rxbuf[CPM_MAXBD];
- u32 txdma[CPM_MAXBD];
- u32 rxdma[CPM_MAXBD];
-};
-
-static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
-{
- struct cpm_i2c *cpm;
- struct i2c_reg __iomem *i2c_reg;
- struct i2c_adapter *adap = dev_id;
- int i;
-
- cpm = i2c_get_adapdata(dev_id);
- i2c_reg = cpm->i2c_reg;
-
- /* Clear interrupt. */
- i = in_8(&i2c_reg->i2cer);
- out_8(&i2c_reg->i2cer, i);
-
- dev_dbg(&adap->dev, "Interrupt: %x\n", i);
-
- wake_up(&cpm->i2c_wait);
-
- return i ? IRQ_HANDLED : IRQ_NONE;
-}
-
-static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
-{
- struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
-
- /* Set up the I2C parameters in the parameter ram. */
- out_be16(&i2c_ram->tbase, (u8 __iomem *)cpm->tbase - DPRAM_BASE);
- out_be16(&i2c_ram->rbase, (u8 __iomem *)cpm->rbase - DPRAM_BASE);
-
- if (cpm->version == 1) {
- out_8(&i2c_ram->tfcr, I2C_EB);
- out_8(&i2c_ram->rfcr, I2C_EB);
- } else {
- out_8(&i2c_ram->tfcr, I2C_EB_CPM2);
- out_8(&i2c_ram->rfcr, I2C_EB_CPM2);
- }
-
- out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
-
- out_be32(&i2c_ram->rstate, 0);
- out_be32(&i2c_ram->rdp, 0);
- out_be16(&i2c_ram->rbptr, 0);
- out_be16(&i2c_ram->rbc, 0);
- out_be32(&i2c_ram->rxtmp, 0);
- out_be32(&i2c_ram->tstate, 0);
- out_be32(&i2c_ram->tdp, 0);
- out_be16(&i2c_ram->tbptr, 0);
- out_be16(&i2c_ram->tbc, 0);
- out_be32(&i2c_ram->txtmp, 0);
-}
-
-static void cpm_i2c_force_close(struct i2c_adapter *adap)
-{
- struct cpm_i2c *cpm = i2c_get_adapdata(adap);
- struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
-
- dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
-
- cpm_command(cpm->cp_command, CPM_CR_CLOSE_RX_BD);
-
- out_8(&i2c_reg->i2cmr, 0x00); /* Disable all interrupts */
- out_8(&i2c_reg->i2cer, 0xff);
-}
-
-static void cpm_i2c_parse_message(struct i2c_adapter *adap,
- struct i2c_msg *pmsg, int num, int tx, int rx)
-{
- cbd_t __iomem *tbdf;
- cbd_t __iomem *rbdf;
- u_char addr;
- u_char *tb;
- u_char *rb;
- struct cpm_i2c *cpm = i2c_get_adapdata(adap);
-
- tbdf = cpm->tbase + tx;
- rbdf = cpm->rbase + rx;
-
- addr = pmsg->addr << 1;
- if (pmsg->flags & I2C_M_RD)
- addr |= 1;
-
- tb = cpm->txbuf[tx];
- rb = cpm->rxbuf[rx];
-
- /* Align read buffer */
- rb = (u_char *) (((ulong) rb + 1) & ~1);
-
- tb[0] = addr; /* Device address byte w/rw flag */
-
- out_be16(&tbdf->cbd_datlen, pmsg->len + 1);
- out_be16(&tbdf->cbd_sc, 0);
-
- if (!(pmsg->flags & I2C_M_NOSTART))
- setbits16(&tbdf->cbd_sc, BD_I2C_START);
-
- if (tx + 1 == num)
- setbits16(&tbdf->cbd_sc, BD_SC_LAST | BD_SC_WRAP);
-
- if (pmsg->flags & I2C_M_RD) {
- /*
- * To read, we need an empty buffer of the proper length.
- * All that is used is the first byte for address, the remainder
- * is just used for timing (and doesn't really have to exist).
- */
-
- dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
-
- out_be16(&rbdf->cbd_datlen, 0);
- out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT);
-
- if (rx + 1 == CPM_MAXBD)
- setbits16(&rbdf->cbd_sc, BD_SC_WRAP);
-
- eieio();
- setbits16(&tbdf->cbd_sc, BD_SC_READY);
- } else {
- dev_dbg(&adap->dev, "cpm_i2c_write(abyte=0x%x)\n", addr);
-
- memcpy(tb+1, pmsg->buf, pmsg->len);
-
- eieio();
- setbits16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_INTRPT);
- }
-}
-
-static int cpm_i2c_check_message(struct i2c_adapter *adap,
- struct i2c_msg *pmsg, int tx, int rx)
-{
- cbd_t __iomem *tbdf;
- cbd_t __iomem *rbdf;
- u_char *tb;
- u_char *rb;
- struct cpm_i2c *cpm = i2c_get_adapdata(adap);
-
- tbdf = cpm->tbase + tx;
- rbdf = cpm->rbase + rx;
-
- tb = cpm->txbuf[tx];
- rb = cpm->rxbuf[rx];
-
- /* Align read buffer */
- rb = (u_char *) (((uint) rb + 1) & ~1);
-
- eieio();
- if (pmsg->flags & I2C_M_RD) {
- dev_dbg(&adap->dev, "tx sc 0x%04x, rx sc 0x%04x\n",
- in_be16(&tbdf->cbd_sc), in_be16(&rbdf->cbd_sc));
-
- if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) {
- dev_dbg(&adap->dev, "I2C read; No ack\n");
- return -ENXIO;
- }
- if (in_be16(&rbdf->cbd_sc) & BD_SC_EMPTY) {
- dev_err(&adap->dev,
- "I2C read; complete but rbuf empty\n");
- return -EREMOTEIO;
- }
- if (in_be16(&rbdf->cbd_sc) & BD_SC_OV) {
- dev_err(&adap->dev, "I2C read; Overrun\n");
- return -EREMOTEIO;
- }
- memcpy(pmsg->buf, rb, pmsg->len);
- } else {
- dev_dbg(&adap->dev, "tx sc %d 0x%04x\n", tx,
- in_be16(&tbdf->cbd_sc));
-
- if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) {
- dev_dbg(&adap->dev, "I2C write; No ack\n");
- return -ENXIO;
- }
- if (in_be16(&tbdf->cbd_sc) & BD_SC_UN) {
- dev_err(&adap->dev, "I2C write; Underrun\n");
- return -EIO;
- }
- if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {
- dev_err(&adap->dev, "I2C write; Collision\n");
- return -EIO;
- }
- }
- return 0;
-}
-
-static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct cpm_i2c *cpm = i2c_get_adapdata(adap);
- struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
- struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
- struct i2c_msg *pmsg;
- int ret, i;
- int tptr;
- int rptr;
- cbd_t __iomem *tbdf;
- cbd_t __iomem *rbdf;
-
- if (num > CPM_MAXBD)
- return -EINVAL;
-
- /* Check if we have any oversized READ requests */
- for (i = 0; i < num; i++) {
- pmsg = &msgs[i];
- if (pmsg->len >= CPM_MAX_READ)
- return -EINVAL;
- }
-
- /* Reset to use first buffer */
- out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
- out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
-
- tbdf = cpm->tbase;
- rbdf = cpm->rbase;
-
- tptr = 0;
- rptr = 0;
-
- while (tptr < num) {
- pmsg = &msgs[tptr];
- dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);
-
- cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
- if (pmsg->flags & I2C_M_RD)
- rptr++;
- tptr++;
- }
- /* Start transfer now */
- /* Enable RX/TX/Error interupts */
- out_8(&i2c_reg->i2cmr, I2CER_TXE | I2CER_TXB | I2CER_RXB);
- out_8(&i2c_reg->i2cer, 0xff); /* Clear interrupt status */
- /* Chip bug, set enable here */
- setbits8(&i2c_reg->i2mod, I2MOD_EN); /* Enable */
- /* Begin transmission */
- setbits8(&i2c_reg->i2com, I2COM_START);
-
- tptr = 0;
- rptr = 0;
-
- while (tptr < num) {
- /* Check for outstanding messages */
- dev_dbg(&adap->dev, "test ready.\n");
- pmsg = &msgs[tptr];
- if (pmsg->flags & I2C_M_RD)
- ret = wait_event_timeout(cpm->i2c_wait,
- (in_be16(&tbdf[tptr].cbd_sc) & BD_SC_NAK) ||
- !(in_be16(&rbdf[rptr].cbd_sc) & BD_SC_EMPTY),
- 1 * HZ);
- else
- ret = wait_event_timeout(cpm->i2c_wait,
- !(in_be16(&tbdf[tptr].cbd_sc) & BD_SC_READY),
- 1 * HZ);
- if (ret == 0) {
- ret = -EREMOTEIO;
- dev_err(&adap->dev, "I2C transfer: timeout\n");
- goto out_err;
- }
- if (ret > 0) {
- dev_dbg(&adap->dev, "ready.\n");
- ret = cpm_i2c_check_message(adap, pmsg, tptr, rptr);
- tptr++;
- if (pmsg->flags & I2C_M_RD)
- rptr++;
- if (ret)
- goto out_err;
- }
- }
-#ifdef I2C_CHIP_ERRATA
- /*
- * Chip errata, clear enable. This is not needed on rev D4 CPUs.
- * Disabling I2C too early may cause too short stop condition
- */
- udelay(4);
- clrbits8(&i2c_reg->i2mod, I2MOD_EN);
-#endif
- return (num);
-
-out_err:
- cpm_i2c_force_close(adap);
-#ifdef I2C_CHIP_ERRATA
- /*
- * Chip errata, clear enable. This is not needed on rev D4 CPUs.
- */
- clrbits8(&i2c_reg->i2mod, I2MOD_EN);
-#endif
- return ret;
-}
-
-static u32 cpm_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
-}
-
-/* -----exported algorithm data: ------------------------------------- */
-
-static const struct i2c_algorithm cpm_i2c_algo = {
- .master_xfer = cpm_i2c_xfer,
- .functionality = cpm_i2c_func,
-};
-
-static const struct i2c_adapter cpm_ops = {
- .owner = THIS_MODULE,
- .name = "i2c-cpm",
- .algo = &cpm_i2c_algo,
-};
-
-static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
-{
- struct platform_device *ofdev = cpm->ofdev;
- const u32 *data;
- int len, ret, i;
- void __iomem *i2c_base;
- cbd_t __iomem *tbdf;
- cbd_t __iomem *rbdf;
- unsigned char brg;
-
- dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n");
-
- init_waitqueue_head(&cpm->i2c_wait);
-
- cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
- if (!cpm->irq)
- return -EINVAL;
-
- /* Install interrupt handler. */
- ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
- &cpm->adap);
- if (ret)
- return ret;
-
- /* I2C parameter RAM */
- i2c_base = of_iomap(ofdev->dev.of_node, 1);
- if (i2c_base == NULL) {
- ret = -EINVAL;
- goto out_irq;
- }
-
- if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm1-i2c")) {
-
- /* Check for and use a microcode relocation patch. */
- cpm->i2c_ram = i2c_base;
- cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
-
- /*
- * Maybe should use cpm_muram_alloc instead of hardcoding
- * this in micropatch.c
- */
- if (cpm->i2c_addr) {
- cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
- iounmap(i2c_base);
- }
-
- cpm->version = 1;
-
- } else if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm2-i2c")) {
- cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
- cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
- out_be16(i2c_base, cpm->i2c_addr);
- iounmap(i2c_base);
-
- cpm->version = 2;
-
- } else {
- iounmap(i2c_base);
- ret = -EINVAL;
- goto out_irq;
- }
-
- /* I2C control/status registers */
- cpm->i2c_reg = of_iomap(ofdev->dev.of_node, 0);
- if (cpm->i2c_reg == NULL) {
- ret = -EINVAL;
- goto out_ram;
- }
-
- data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len);
- if (!data || len != 4) {
- ret = -EINVAL;
- goto out_reg;
- }
- cpm->cp_command = *data;
-
- data = of_get_property(ofdev->dev.of_node, "linux,i2c-class", &len);
- if (data && len == 4)
- cpm->adap.class = *data;
-
- data = of_get_property(ofdev->dev.of_node, "clock-frequency", &len);
- if (data && len == 4)
- cpm->freq = *data;
- else
- cpm->freq = 60000; /* use 60kHz i2c clock by default */
-
- /*
- * Allocate space for CPM_MAXBD transmit and receive buffer
- * descriptors in the DP ram.
- */
- cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
- if (!cpm->dp_addr) {
- ret = -ENOMEM;
- goto out_reg;
- }
-
- cpm->tbase = cpm_muram_addr(cpm->dp_addr);
- cpm->rbase = cpm_muram_addr(cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
-
- /* Allocate TX and RX buffers */
-
- tbdf = cpm->tbase;
- rbdf = cpm->rbase;
-
- for (i = 0; i < CPM_MAXBD; i++) {
- cpm->rxbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev,
- CPM_MAX_READ + 1,
- &cpm->rxdma[i], GFP_KERNEL);
- if (!cpm->rxbuf[i]) {
- ret = -ENOMEM;
- goto out_muram;
- }
- out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1));
-
- cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
- if (!cpm->txbuf[i]) {
- ret = -ENOMEM;
- goto out_muram;
- }
- out_be32(&tbdf[i].cbd_bufaddr, cpm->txdma[i]);
- }
-
- /* Initialize Tx/Rx parameters. */
-
- cpm_reset_i2c_params(cpm);
-
- dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n",
- cpm->i2c_ram, cpm->i2c_addr, cpm->freq);
- dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n",
- (u8 __iomem *)cpm->tbase - DPRAM_BASE,
- (u8 __iomem *)cpm->rbase - DPRAM_BASE);
-
- cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
-
- /*
- * Select an invalid address. Just make sure we don't use loopback mode
- */
- out_8(&cpm->i2c_reg->i2add, 0x7f << 1);
-
- /*
- * PDIV is set to 00 in i2mod, so brgclk/32 is used as input to the
- * i2c baud rate generator. This is divided by 2 x (DIV + 3) to get
- * the actual i2c bus frequency.
- */
- brg = get_brgfreq() / (32 * 2 * cpm->freq) - 3;
- out_8(&cpm->i2c_reg->i2brg, brg);
-
- out_8(&cpm->i2c_reg->i2mod, 0x00);
- out_8(&cpm->i2c_reg->i2com, I2COM_MASTER); /* Master mode */
-
- /* Disable interrupts. */
- out_8(&cpm->i2c_reg->i2cmr, 0);
- out_8(&cpm->i2c_reg->i2cer, 0xff);
-
- return 0;
-
-out_muram:
- for (i = 0; i < CPM_MAXBD; i++) {
- if (cpm->rxbuf[i])
- dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
- cpm->rxbuf[i], cpm->rxdma[i]);
- if (cpm->txbuf[i])
- dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
- cpm->txbuf[i], cpm->txdma[i]);
- }
- cpm_muram_free(cpm->dp_addr);
-out_reg:
- iounmap(cpm->i2c_reg);
-out_ram:
- if ((cpm->version == 1) && (!cpm->i2c_addr))
- iounmap(cpm->i2c_ram);
- if (cpm->version == 2)
- cpm_muram_free(cpm->i2c_addr);
-out_irq:
- free_irq(cpm->irq, &cpm->adap);
- return ret;
-}
-
-static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
-{
- int i;
-
- /* Shut down I2C. */
- clrbits8(&cpm->i2c_reg->i2mod, I2MOD_EN);
-
- /* Disable interrupts */
- out_8(&cpm->i2c_reg->i2cmr, 0);
- out_8(&cpm->i2c_reg->i2cer, 0xff);
-
- free_irq(cpm->irq, &cpm->adap);
-
- /* Free all memory */
- for (i = 0; i < CPM_MAXBD; i++) {
- dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
- cpm->rxbuf[i], cpm->rxdma[i]);
- dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
- cpm->txbuf[i], cpm->txdma[i]);
- }
-
- cpm_muram_free(cpm->dp_addr);
- iounmap(cpm->i2c_reg);
-
- if ((cpm->version == 1) && (!cpm->i2c_addr))
- iounmap(cpm->i2c_ram);
- if (cpm->version == 2)
- cpm_muram_free(cpm->i2c_addr);
-}
-
-static int __devinit cpm_i2c_probe(struct platform_device *ofdev)
-{
- int result, len;
- struct cpm_i2c *cpm;
- const u32 *data;
-
- cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
- if (!cpm)
- return -ENOMEM;
-
- cpm->ofdev = ofdev;
-
- dev_set_drvdata(&ofdev->dev, cpm);
-
- cpm->adap = cpm_ops;
- i2c_set_adapdata(&cpm->adap, cpm);
- cpm->adap.dev.parent = &ofdev->dev;
- cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node);
-
- result = cpm_i2c_setup(cpm);
- if (result) {
- dev_err(&ofdev->dev, "Unable to init hardware\n");
- goto out_free;
- }
-
- /* register new adapter to i2c module... */
-
- data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len);
- cpm->adap.nr = (data && len == 4) ? be32_to_cpup(data) : -1;
- result = i2c_add_numbered_adapter(&cpm->adap);
-
- if (result < 0) {
- dev_err(&ofdev->dev, "Unable to register with I2C\n");
- goto out_shut;
- }
-
- dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
- cpm->adap.name);
-
- /*
- * register OF I2C devices
- */
- of_i2c_register_devices(&cpm->adap);
-
- return 0;
-out_shut:
- cpm_i2c_shutdown(cpm);
-out_free:
- dev_set_drvdata(&ofdev->dev, NULL);
- kfree(cpm);
-
- return result;
-}
-
-static int __devexit cpm_i2c_remove(struct platform_device *ofdev)
-{
- struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
-
- i2c_del_adapter(&cpm->adap);
-
- cpm_i2c_shutdown(cpm);
-
- dev_set_drvdata(&ofdev->dev, NULL);
- kfree(cpm);
-
- return 0;
-}
-
-static const struct of_device_id cpm_i2c_match[] = {
- {
- .compatible = "fsl,cpm1-i2c",
- },
- {
- .compatible = "fsl,cpm2-i2c",
- },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, cpm_i2c_match);
-
-static struct platform_driver cpm_i2c_driver = {
- .probe = cpm_i2c_probe,
- .remove = __devexit_p(cpm_i2c_remove),
- .driver = {
- .name = "fsl-i2c-cpm",
- .owner = THIS_MODULE,
- .of_match_table = cpm_i2c_match,
- },
-};
-
-module_platform_driver(cpm_i2c_driver);
-
-MODULE_AUTHOR("Jochen Friedrich <jochen@scram.de>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-davinci.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-davinci.c
deleted file mode 100644
index 79b4bcb3..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-davinci.c
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * TI DAVINCI I2C adapter driver.
- *
- * Copyright (C) 2006 Texas Instruments.
- * Copyright (C) 2007 MontaVista Software Inc.
- *
- * Updated by Vinod & Sudhakar Feb 2005
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ----------------------------------------------------------------------------
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/cpufreq.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-
-/* ----- global defines ----------------------------------------------- */
-
-#define DAVINCI_I2C_TIMEOUT (1*HZ)
-#define DAVINCI_I2C_MAX_TRIES 2
-#define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
- DAVINCI_I2C_IMR_SCD | \
- DAVINCI_I2C_IMR_ARDY | \
- DAVINCI_I2C_IMR_NACK | \
- DAVINCI_I2C_IMR_AL)
-
-#define DAVINCI_I2C_OAR_REG 0x00
-#define DAVINCI_I2C_IMR_REG 0x04
-#define DAVINCI_I2C_STR_REG 0x08
-#define DAVINCI_I2C_CLKL_REG 0x0c
-#define DAVINCI_I2C_CLKH_REG 0x10
-#define DAVINCI_I2C_CNT_REG 0x14
-#define DAVINCI_I2C_DRR_REG 0x18
-#define DAVINCI_I2C_SAR_REG 0x1c
-#define DAVINCI_I2C_DXR_REG 0x20
-#define DAVINCI_I2C_MDR_REG 0x24
-#define DAVINCI_I2C_IVR_REG 0x28
-#define DAVINCI_I2C_EMDR_REG 0x2c
-#define DAVINCI_I2C_PSC_REG 0x30
-
-#define DAVINCI_I2C_IVR_AAS 0x07
-#define DAVINCI_I2C_IVR_SCD 0x06
-#define DAVINCI_I2C_IVR_XRDY 0x05
-#define DAVINCI_I2C_IVR_RDR 0x04
-#define DAVINCI_I2C_IVR_ARDY 0x03
-#define DAVINCI_I2C_IVR_NACK 0x02
-#define DAVINCI_I2C_IVR_AL 0x01
-
-#define DAVINCI_I2C_STR_BB BIT(12)
-#define DAVINCI_I2C_STR_RSFULL BIT(11)
-#define DAVINCI_I2C_STR_SCD BIT(5)
-#define DAVINCI_I2C_STR_ARDY BIT(2)
-#define DAVINCI_I2C_STR_NACK BIT(1)
-#define DAVINCI_I2C_STR_AL BIT(0)
-
-#define DAVINCI_I2C_MDR_NACK BIT(15)
-#define DAVINCI_I2C_MDR_STT BIT(13)
-#define DAVINCI_I2C_MDR_STP BIT(11)
-#define DAVINCI_I2C_MDR_MST BIT(10)
-#define DAVINCI_I2C_MDR_TRX BIT(9)
-#define DAVINCI_I2C_MDR_XA BIT(8)
-#define DAVINCI_I2C_MDR_RM BIT(7)
-#define DAVINCI_I2C_MDR_IRS BIT(5)
-
-#define DAVINCI_I2C_IMR_AAS BIT(6)
-#define DAVINCI_I2C_IMR_SCD BIT(5)
-#define DAVINCI_I2C_IMR_XRDY BIT(4)
-#define DAVINCI_I2C_IMR_RRDY BIT(3)
-#define DAVINCI_I2C_IMR_ARDY BIT(2)
-#define DAVINCI_I2C_IMR_NACK BIT(1)
-#define DAVINCI_I2C_IMR_AL BIT(0)
-
-struct davinci_i2c_dev {
- struct device *dev;
- void __iomem *base;
- struct completion cmd_complete;
- struct clk *clk;
- int cmd_err;
- u8 *buf;
- size_t buf_len;
- int irq;
- int stop;
- u8 terminate;
- struct i2c_adapter adapter;
-#ifdef CONFIG_CPU_FREQ
- struct completion xfr_complete;
- struct notifier_block freq_transition;
-#endif
-};
-
-/* default platform data to use if not supplied in the platform_device */
-static struct davinci_i2c_platform_data davinci_i2c_platform_data_default = {
- .bus_freq = 100,
- .bus_delay = 0,
-};
-
-static inline void davinci_i2c_write_reg(struct davinci_i2c_dev *i2c_dev,
- int reg, u16 val)
-{
- __raw_writew(val, i2c_dev->base + reg);
-}
-
-static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
-{
- return __raw_readw(i2c_dev->base + reg);
-}
-
-/* Generate a pulse on the i2c clock pin. */
-static void generic_i2c_clock_pulse(unsigned int scl_pin)
-{
- u16 i;
-
- if (scl_pin) {
- /* Send high and low on the SCL line */
- for (i = 0; i < 9; i++) {
- gpio_set_value(scl_pin, 0);
- udelay(20);
- gpio_set_value(scl_pin, 1);
- udelay(20);
- }
- }
-}
-
-/* This routine does i2c bus recovery as specified in the
- * i2c protocol Rev. 03 section 3.16 titled "Bus clear"
- */
-static void i2c_recover_bus(struct davinci_i2c_dev *dev)
-{
- u32 flag = 0;
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
-
- dev_err(dev->dev, "initiating i2c bus recovery\n");
- /* Send NACK to the slave */
- flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- flag |= DAVINCI_I2C_MDR_NACK;
- /* write the data into mode register */
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
- if (pdata)
- generic_i2c_clock_pulse(pdata->scl_pin);
- /* Send STOP */
- flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- flag |= DAVINCI_I2C_MDR_STP;
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-}
-
-static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
- int val)
-{
- u16 w;
-
- w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
- if (!val) /* put I2C into reset */
- w &= ~DAVINCI_I2C_MDR_IRS;
- else /* take I2C out of reset */
- w |= DAVINCI_I2C_MDR_IRS;
-
- davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
-}
-
-static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
-{
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
- u16 psc;
- u32 clk;
- u32 d;
- u32 clkh;
- u32 clkl;
- u32 input_clock = clk_get_rate(dev->clk);
-
- /* NOTE: I2C Clock divider programming info
- * As per I2C specs the following formulas provide prescaler
- * and low/high divider values
- * input clk --> PSC Div -----------> ICCL/H Div --> output clock
- * module clk
- *
- * output clk = module clk / (PSC + 1) [ (ICCL + d) + (ICCH + d) ]
- *
- * Thus,
- * (ICCL + ICCH) = clk = (input clk / ((psc +1) * output clk)) - 2d;
- *
- * where if PSC == 0, d = 7,
- * if PSC == 1, d = 6
- * if PSC > 1 , d = 5
- */
-
- /* get minimum of 7 MHz clock, but max of 12 MHz */
- psc = (input_clock / 7000000) - 1;
- if ((input_clock / (psc + 1)) > 12000000)
- psc++; /* better to run under spec than over */
- d = (psc >= 2) ? 5 : 7 - psc;
-
- clk = ((input_clock / (psc + 1)) / (pdata->bus_freq * 1000)) - (d << 1);
- clkh = clk >> 1;
- clkl = clk - clkh;
-
- davinci_i2c_write_reg(dev, DAVINCI_I2C_PSC_REG, psc);
- davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
- davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
-
- dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
-}
-
-/*
- * This function configures I2C and brings I2C out of reset.
- * This function is called during I2C init function. This function
- * also gets called if I2C encounters any errors.
- */
-static int i2c_davinci_init(struct davinci_i2c_dev *dev)
-{
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
-
- if (!pdata)
- pdata = &davinci_i2c_platform_data_default;
-
- /* put I2C into reset */
- davinci_i2c_reset_ctrl(dev, 0);
-
- /* compute clock dividers */
- i2c_davinci_calc_clk_dividers(dev);
-
- /* Respond at reserved "SMBus Host" slave address" (and zero);
- * we seem to have no option to not respond...
- */
- davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
-
- dev_dbg(dev->dev, "PSC = %d\n",
- davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
- dev_dbg(dev->dev, "CLKL = %d\n",
- davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG));
- dev_dbg(dev->dev, "CLKH = %d\n",
- davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG));
- dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n",
- pdata->bus_freq, pdata->bus_delay);
-
- /* Take the I2C module out of reset: */
- davinci_i2c_reset_ctrl(dev, 1);
-
- /* Enable interrupts */
- davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
-
- return 0;
-}
-
-/*
- * Waiting for bus not busy
- */
-static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
- char allow_sleep)
-{
- unsigned long timeout;
- static u16 to_cnt;
-
- timeout = jiffies + dev->adapter.timeout;
- while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
- & DAVINCI_I2C_STR_BB) {
- if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
- if (time_after(jiffies, timeout)) {
- dev_warn(dev->dev,
- "timeout waiting for bus ready\n");
- to_cnt++;
- return -ETIMEDOUT;
- } else {
- to_cnt = 0;
- i2c_recover_bus(dev);
- i2c_davinci_init(dev);
- }
- }
- if (allow_sleep)
- schedule_timeout(1);
- }
-
- return 0;
-}
-
-/*
- * Low level master read/write transaction. This function is called
- * from i2c_davinci_xfer.
- */
-static int
-i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
-{
- struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
- u32 flag;
- u16 w;
- int r;
-
- if (!pdata)
- pdata = &davinci_i2c_platform_data_default;
- /* Introduce a delay, required for some boards (e.g Davinci EVM) */
- if (pdata->bus_delay)
- udelay(pdata->bus_delay);
-
- /* set the slave address */
- davinci_i2c_write_reg(dev, DAVINCI_I2C_SAR_REG, msg->addr);
-
- dev->buf = msg->buf;
- dev->buf_len = msg->len;
- dev->stop = stop;
-
- davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len);
-
- INIT_COMPLETION(dev->cmd_complete);
- dev->cmd_err = 0;
-
- /* Take I2C out of reset and configure it as master */
- flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST;
-
- /* if the slave address is ten bit address, enable XA bit */
- if (msg->flags & I2C_M_TEN)
- flag |= DAVINCI_I2C_MDR_XA;
- if (!(msg->flags & I2C_M_RD))
- flag |= DAVINCI_I2C_MDR_TRX;
- if (msg->len == 0)
- flag |= DAVINCI_I2C_MDR_RM;
-
- /* Enable receive or transmit interrupts */
- w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
- if (msg->flags & I2C_M_RD)
- w |= DAVINCI_I2C_IMR_RRDY;
- else
- w |= DAVINCI_I2C_IMR_XRDY;
- davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
-
- dev->terminate = 0;
-
- /*
- * Write mode register first as needed for correct behaviour
- * on OMAP-L138, but don't set STT yet to avoid a race with XRDY
- * occurring before we have loaded DXR
- */
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-
- /*
- * First byte should be set here, not after interrupt,
- * because transmit-data-ready interrupt can come before
- * NACK-interrupt during sending of previous message and
- * ICDXR may have wrong data
- * It also saves us one interrupt, slightly faster
- */
- if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) {
- davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++);
- dev->buf_len--;
- }
-
- /* Set STT to begin transmit now DXR is loaded */
- flag |= DAVINCI_I2C_MDR_STT;
- if (stop && msg->len != 0)
- flag |= DAVINCI_I2C_MDR_STP;
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-
- r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
- dev->adapter.timeout);
- if (r == 0) {
- dev_err(dev->dev, "controller timed out\n");
- i2c_recover_bus(dev);
- i2c_davinci_init(dev);
- dev->buf_len = 0;
- return -ETIMEDOUT;
- }
- if (dev->buf_len) {
- /* This should be 0 if all bytes were transferred
- * or dev->cmd_err denotes an error.
- * A signal may have aborted the transfer.
- */
- if (r >= 0) {
- dev_err(dev->dev, "abnormal termination buf_len=%i\n",
- dev->buf_len);
- r = -EREMOTEIO;
- }
- dev->terminate = 1;
- wmb();
- dev->buf_len = 0;
- }
- if (r < 0)
- return r;
-
- /* no error */
- if (likely(!dev->cmd_err))
- return msg->len;
-
- /* We have an error */
- if (dev->cmd_err & DAVINCI_I2C_STR_AL) {
- i2c_davinci_init(dev);
- return -EIO;
- }
-
- if (dev->cmd_err & DAVINCI_I2C_STR_NACK) {
- if (msg->flags & I2C_M_IGNORE_NAK)
- return msg->len;
- if (stop) {
- w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- w |= DAVINCI_I2C_MDR_STP;
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
- }
- return -EREMOTEIO;
- }
- return -EIO;
-}
-
-/*
- * Prepare controller for a transaction and call i2c_davinci_xfer_msg
- */
-static int
-i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-{
- struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
- int i;
- int ret;
-
- dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
-
- ret = i2c_davinci_wait_bus_not_busy(dev, 1);
- if (ret < 0) {
- dev_warn(dev->dev, "timeout waiting for bus ready\n");
- return ret;
- }
-
- for (i = 0; i < num; i++) {
- ret = i2c_davinci_xfer_msg(adap, &msgs[i], (i == (num - 1)));
- dev_dbg(dev->dev, "%s [%d/%d] ret: %d\n", __func__, i + 1, num,
- ret);
- if (ret < 0)
- return ret;
- }
-
-#ifdef CONFIG_CPU_FREQ
- complete(&dev->xfr_complete);
-#endif
-
- return num;
-}
-
-static u32 i2c_davinci_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static void terminate_read(struct davinci_i2c_dev *dev)
-{
- u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- w |= DAVINCI_I2C_MDR_NACK;
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
-
- /* Throw away data */
- davinci_i2c_read_reg(dev, DAVINCI_I2C_DRR_REG);
- if (!dev->terminate)
- dev_err(dev->dev, "RDR IRQ while no data requested\n");
-}
-static void terminate_write(struct davinci_i2c_dev *dev)
-{
- u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- w |= DAVINCI_I2C_MDR_RM | DAVINCI_I2C_MDR_STP;
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
-
- if (!dev->terminate)
- dev_dbg(dev->dev, "TDR IRQ while no data to send\n");
-}
-
-/*
- * Interrupt service routine. This gets called whenever an I2C interrupt
- * occurs.
- */
-static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
-{
- struct davinci_i2c_dev *dev = dev_id;
- u32 stat;
- int count = 0;
- u16 w;
-
- while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
- dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
- if (count++ == 100) {
- dev_warn(dev->dev, "Too much work in one IRQ\n");
- break;
- }
-
- switch (stat) {
- case DAVINCI_I2C_IVR_AL:
- /* Arbitration lost, must retry */
- dev->cmd_err |= DAVINCI_I2C_STR_AL;
- dev->buf_len = 0;
- complete(&dev->cmd_complete);
- break;
-
- case DAVINCI_I2C_IVR_NACK:
- dev->cmd_err |= DAVINCI_I2C_STR_NACK;
- dev->buf_len = 0;
- complete(&dev->cmd_complete);
- break;
-
- case DAVINCI_I2C_IVR_ARDY:
- davinci_i2c_write_reg(dev,
- DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY);
- if (((dev->buf_len == 0) && (dev->stop != 0)) ||
- (dev->cmd_err & DAVINCI_I2C_STR_NACK)) {
- w = davinci_i2c_read_reg(dev,
- DAVINCI_I2C_MDR_REG);
- w |= DAVINCI_I2C_MDR_STP;
- davinci_i2c_write_reg(dev,
- DAVINCI_I2C_MDR_REG, w);
- }
- complete(&dev->cmd_complete);
- break;
-
- case DAVINCI_I2C_IVR_RDR:
- if (dev->buf_len) {
- *dev->buf++ =
- davinci_i2c_read_reg(dev,
- DAVINCI_I2C_DRR_REG);
- dev->buf_len--;
- if (dev->buf_len)
- continue;
-
- davinci_i2c_write_reg(dev,
- DAVINCI_I2C_STR_REG,
- DAVINCI_I2C_IMR_RRDY);
- } else {
- /* signal can terminate transfer */
- terminate_read(dev);
- }
- break;
-
- case DAVINCI_I2C_IVR_XRDY:
- if (dev->buf_len) {
- davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG,
- *dev->buf++);
- dev->buf_len--;
- if (dev->buf_len)
- continue;
-
- w = davinci_i2c_read_reg(dev,
- DAVINCI_I2C_IMR_REG);
- w &= ~DAVINCI_I2C_IMR_XRDY;
- davinci_i2c_write_reg(dev,
- DAVINCI_I2C_IMR_REG,
- w);
- } else {
- /* signal can terminate transfer */
- terminate_write(dev);
- }
- break;
-
- case DAVINCI_I2C_IVR_SCD:
- davinci_i2c_write_reg(dev,
- DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_SCD);
- complete(&dev->cmd_complete);
- break;
-
- case DAVINCI_I2C_IVR_AAS:
- dev_dbg(dev->dev, "Address as slave interrupt\n");
- break;
-
- default:
- dev_warn(dev->dev, "Unrecognized irq stat %d\n", stat);
- break;
- }
- }
-
- return count ? IRQ_HANDLED : IRQ_NONE;
-}
-
-#ifdef CONFIG_CPU_FREQ
-static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
- unsigned long val, void *data)
-{
- struct davinci_i2c_dev *dev;
-
- dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
- if (val == CPUFREQ_PRECHANGE) {
- wait_for_completion(&dev->xfr_complete);
- davinci_i2c_reset_ctrl(dev, 0);
- } else if (val == CPUFREQ_POSTCHANGE) {
- i2c_davinci_calc_clk_dividers(dev);
- davinci_i2c_reset_ctrl(dev, 1);
- }
-
- return 0;
-}
-
-static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
-{
- dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition;
-
- return cpufreq_register_notifier(&dev->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
-{
- cpufreq_unregister_notifier(&dev->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-#else
-static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
-{
- return 0;
-}
-
-static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
-{
-}
-#endif
-
-static struct i2c_algorithm i2c_davinci_algo = {
- .master_xfer = i2c_davinci_xfer,
- .functionality = i2c_davinci_func,
-};
-
-static int davinci_i2c_probe(struct platform_device *pdev)
-{
- struct davinci_i2c_dev *dev;
- struct i2c_adapter *adap;
- struct resource *mem, *irq, *ioarea;
- int r;
-
- /* NOTE: driver uses the static register mapping */
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "no mem resource?\n");
- return -ENODEV;
- }
-
- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!irq) {
- dev_err(&pdev->dev, "no irq resource?\n");
- return -ENODEV;
- }
-
- ioarea = request_mem_region(mem->start, resource_size(mem),
- pdev->name);
- if (!ioarea) {
- dev_err(&pdev->dev, "I2C region already claimed\n");
- return -EBUSY;
- }
-
- dev = kzalloc(sizeof(struct davinci_i2c_dev), GFP_KERNEL);
- if (!dev) {
- r = -ENOMEM;
- goto err_release_region;
- }
-
- init_completion(&dev->cmd_complete);
-#ifdef CONFIG_CPU_FREQ
- init_completion(&dev->xfr_complete);
-#endif
- dev->dev = get_device(&pdev->dev);
- dev->irq = irq->start;
- platform_set_drvdata(pdev, dev);
-
- dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk)) {
- r = -ENODEV;
- goto err_free_mem;
- }
- clk_enable(dev->clk);
-
- dev->base = ioremap(mem->start, resource_size(mem));
- if (!dev->base) {
- r = -EBUSY;
- goto err_mem_ioremap;
- }
-
- i2c_davinci_init(dev);
-
- r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev);
- if (r) {
- dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
- goto err_unuse_clocks;
- }
-
- r = i2c_davinci_cpufreq_register(dev);
- if (r) {
- dev_err(&pdev->dev, "failed to register cpufreq\n");
- goto err_free_irq;
- }
-
- adap = &dev->adapter;
- i2c_set_adapdata(adap, dev);
- adap->owner = THIS_MODULE;
- adap->class = I2C_CLASS_HWMON;
- strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
- adap->algo = &i2c_davinci_algo;
- adap->dev.parent = &pdev->dev;
- adap->timeout = DAVINCI_I2C_TIMEOUT;
-
- adap->nr = pdev->id;
- r = i2c_add_numbered_adapter(adap);
- if (r) {
- dev_err(&pdev->dev, "failure adding adapter\n");
- goto err_free_irq;
- }
-
- return 0;
-
-err_free_irq:
- free_irq(dev->irq, dev);
-err_unuse_clocks:
- iounmap(dev->base);
-err_mem_ioremap:
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
-err_free_mem:
- platform_set_drvdata(pdev, NULL);
- put_device(&pdev->dev);
- kfree(dev);
-err_release_region:
- release_mem_region(mem->start, resource_size(mem));
-
- return r;
-}
-
-static int davinci_i2c_remove(struct platform_device *pdev)
-{
- struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
- struct resource *mem;
-
- i2c_davinci_cpufreq_deregister(dev);
-
- platform_set_drvdata(pdev, NULL);
- i2c_del_adapter(&dev->adapter);
- put_device(&pdev->dev);
-
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
-
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
- free_irq(dev->irq, dev);
- iounmap(dev->base);
- kfree(dev);
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int davinci_i2c_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-
- /* put I2C into reset */
- davinci_i2c_reset_ctrl(i2c_dev, 0);
- clk_disable(i2c_dev->clk);
-
- return 0;
-}
-
-static int davinci_i2c_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-
- clk_enable(i2c_dev->clk);
- /* take I2C out of reset */
- davinci_i2c_reset_ctrl(i2c_dev, 1);
-
- return 0;
-}
-
-static const struct dev_pm_ops davinci_i2c_pm = {
- .suspend = davinci_i2c_suspend,
- .resume = davinci_i2c_resume,
-};
-
-#define davinci_i2c_pm_ops (&davinci_i2c_pm)
-#else
-#define davinci_i2c_pm_ops NULL
-#endif
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:i2c_davinci");
-
-static struct platform_driver davinci_i2c_driver = {
- .probe = davinci_i2c_probe,
- .remove = davinci_i2c_remove,
- .driver = {
- .name = "i2c_davinci",
- .owner = THIS_MODULE,
- .pm = davinci_i2c_pm_ops,
- },
-};
-
-/* I2C may be needed to bring up other drivers */
-static int __init davinci_i2c_init_driver(void)
-{
- return platform_driver_register(&davinci_i2c_driver);
-}
-subsys_initcall(davinci_i2c_init_driver);
-
-static void __exit davinci_i2c_exit_driver(void)
-{
- platform_driver_unregister(&davinci_i2c_driver);
-}
-module_exit(davinci_i2c_exit_driver);
-
-MODULE_AUTHOR("Texas Instruments India");
-MODULE_DESCRIPTION("TI DaVinci I2C bus adapter");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.c
deleted file mode 100644
index df879924..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Synopsys DesignWare I2C adapter driver (master only).
- *
- * Based on the TI DAVINCI I2C adapter driver.
- *
- * Copyright (C) 2006 Texas Instruments.
- * Copyright (C) 2007 MontaVista Software Inc.
- * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ----------------------------------------------------------------------------
- *
- */
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/delay.h>
-#include "i2c-designware-core.h"
-
-/*
- * Registers offset
- */
-#define DW_IC_CON 0x0
-#define DW_IC_TAR 0x4
-#define DW_IC_DATA_CMD 0x10
-#define DW_IC_SS_SCL_HCNT 0x14
-#define DW_IC_SS_SCL_LCNT 0x18
-#define DW_IC_FS_SCL_HCNT 0x1c
-#define DW_IC_FS_SCL_LCNT 0x20
-#define DW_IC_INTR_STAT 0x2c
-#define DW_IC_INTR_MASK 0x30
-#define DW_IC_RAW_INTR_STAT 0x34
-#define DW_IC_RX_TL 0x38
-#define DW_IC_TX_TL 0x3c
-#define DW_IC_CLR_INTR 0x40
-#define DW_IC_CLR_RX_UNDER 0x44
-#define DW_IC_CLR_RX_OVER 0x48
-#define DW_IC_CLR_TX_OVER 0x4c
-#define DW_IC_CLR_RD_REQ 0x50
-#define DW_IC_CLR_TX_ABRT 0x54
-#define DW_IC_CLR_RX_DONE 0x58
-#define DW_IC_CLR_ACTIVITY 0x5c
-#define DW_IC_CLR_STOP_DET 0x60
-#define DW_IC_CLR_START_DET 0x64
-#define DW_IC_CLR_GEN_CALL 0x68
-#define DW_IC_ENABLE 0x6c
-#define DW_IC_STATUS 0x70
-#define DW_IC_TXFLR 0x74
-#define DW_IC_RXFLR 0x78
-#define DW_IC_TX_ABRT_SOURCE 0x80
-#define DW_IC_COMP_PARAM_1 0xf4
-#define DW_IC_COMP_TYPE 0xfc
-#define DW_IC_COMP_TYPE_VALUE 0x44570140
-
-#define DW_IC_INTR_RX_UNDER 0x001
-#define DW_IC_INTR_RX_OVER 0x002
-#define DW_IC_INTR_RX_FULL 0x004
-#define DW_IC_INTR_TX_OVER 0x008
-#define DW_IC_INTR_TX_EMPTY 0x010
-#define DW_IC_INTR_RD_REQ 0x020
-#define DW_IC_INTR_TX_ABRT 0x040
-#define DW_IC_INTR_RX_DONE 0x080
-#define DW_IC_INTR_ACTIVITY 0x100
-#define DW_IC_INTR_STOP_DET 0x200
-#define DW_IC_INTR_START_DET 0x400
-#define DW_IC_INTR_GEN_CALL 0x800
-
-#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
- DW_IC_INTR_TX_EMPTY | \
- DW_IC_INTR_TX_ABRT | \
- DW_IC_INTR_STOP_DET)
-
-#define DW_IC_STATUS_ACTIVITY 0x1
-
-#define DW_IC_ERR_TX_ABRT 0x1
-
-/*
- * status codes
- */
-#define STATUS_IDLE 0x0
-#define STATUS_WRITE_IN_PROGRESS 0x1
-#define STATUS_READ_IN_PROGRESS 0x2
-
-#define TIMEOUT 20 /* ms */
-
-/*
- * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register
- *
- * only expected abort codes are listed here
- * refer to the datasheet for the full list
- */
-#define ABRT_7B_ADDR_NOACK 0
-#define ABRT_10ADDR1_NOACK 1
-#define ABRT_10ADDR2_NOACK 2
-#define ABRT_TXDATA_NOACK 3
-#define ABRT_GCALL_NOACK 4
-#define ABRT_GCALL_READ 5
-#define ABRT_SBYTE_ACKDET 7
-#define ABRT_SBYTE_NORSTRT 9
-#define ABRT_10B_RD_NORSTRT 10
-#define ABRT_MASTER_DIS 11
-#define ARB_LOST 12
-
-#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
-#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
-#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
-#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
-#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
-#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
-#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
-#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
-#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
-#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
-#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)
-
-#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
- DW_IC_TX_ABRT_10ADDR1_NOACK | \
- DW_IC_TX_ABRT_10ADDR2_NOACK | \
- DW_IC_TX_ABRT_TXDATA_NOACK | \
- DW_IC_TX_ABRT_GCALL_NOACK)
-
-static char *abort_sources[] = {
- [ABRT_7B_ADDR_NOACK] =
- "slave address not acknowledged (7bit mode)",
- [ABRT_10ADDR1_NOACK] =
- "first address byte not acknowledged (10bit mode)",
- [ABRT_10ADDR2_NOACK] =
- "second address byte not acknowledged (10bit mode)",
- [ABRT_TXDATA_NOACK] =
- "data not acknowledged",
- [ABRT_GCALL_NOACK] =
- "no acknowledgement for a general call",
- [ABRT_GCALL_READ] =
- "read after general call",
- [ABRT_SBYTE_ACKDET] =
- "start byte acknowledged",
- [ABRT_SBYTE_NORSTRT] =
- "trying to send start byte when restart is disabled",
- [ABRT_10B_RD_NORSTRT] =
- "trying to read when restart is disabled (10bit mode)",
- [ABRT_MASTER_DIS] =
- "trying to use disabled adapter",
- [ARB_LOST] =
- "lost arbitration",
-};
-
-u32 dw_readl(struct dw_i2c_dev *dev, int offset)
-{
- u32 value = readl(dev->base + offset);
-
- if (dev->swab)
- return swab32(value);
- else
- return value;
-}
-
-void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
-{
- if (dev->swab)
- b = swab32(b);
-
- writel(b, dev->base + offset);
-}
-
-static u32
-i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
-{
- /*
- * DesignWare I2C core doesn't seem to have solid strategy to meet
- * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec
- * will result in violation of the tHD;STA spec.
- */
- if (cond)
- /*
- * Conditional expression:
- *
- * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH
- *
- * This is based on the DW manuals, and represents an ideal
- * configuration. The resulting I2C bus speed will be
- * faster than any of the others.
- *
- * If your hardware is free from tHD;STA issue, try this one.
- */
- return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset;
- else
- /*
- * Conditional expression:
- *
- * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf)
- *
- * This is just experimental rule; the tHD;STA period turned
- * out to be proportinal to (_HCNT + 3). With this setting,
- * we could meet both tHIGH and tHD;STA timing specs.
- *
- * If unsure, you'd better to take this alternative.
- *
- * The reason why we need to take into account "tf" here,
- * is the same as described in i2c_dw_scl_lcnt().
- */
- return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset;
-}
-
-static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
-{
- /*
- * Conditional expression:
- *
- * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf)
- *
- * DW I2C core starts counting the SCL CNTs for the LOW period
- * of the SCL clock (tLOW) as soon as it pulls the SCL line.
- * In order to meet the tLOW timing spec, we need to take into
- * account the fall time of SCL signal (tf). Default tf value
- * should be 0.3 us, for safety.
- */
- return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset;
-}
-
-/**
- * i2c_dw_init() - initialize the designware i2c master hardware
- * @dev: device private data
- *
- * This functions configures and enables the I2C master.
- * This function is called during I2C init function, and in case of timeout at
- * run time.
- */
-int i2c_dw_init(struct dw_i2c_dev *dev)
-{
- u32 input_clock_khz;
- u32 hcnt, lcnt;
- u32 reg;
-
- input_clock_khz = dev->get_clk_rate_khz(dev);
-
- /* Configure register endianess access */
- reg = dw_readl(dev, DW_IC_COMP_TYPE);
- if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
- dev->swab = 1;
- reg = DW_IC_COMP_TYPE_VALUE;
- }
-
- if (reg != DW_IC_COMP_TYPE_VALUE) {
- dev_err(dev->dev, "Unknown Synopsys component type: "
- "0x%08x\n", reg);
- return -ENODEV;
- }
-
- /* Disable the adapter */
- dw_writel(dev, 0, DW_IC_ENABLE);
-
- /* set standard and fast speed deviders for high/low periods */
-
- /* Standard-mode */
- hcnt = i2c_dw_scl_hcnt(input_clock_khz,
- 40, /* tHD;STA = tHIGH = 4.0 us */
- 3, /* tf = 0.3 us */
- 0, /* 0: DW default, 1: Ideal */
- 0); /* No offset */
- lcnt = i2c_dw_scl_lcnt(input_clock_khz,
- 47, /* tLOW = 4.7 us */
- 3, /* tf = 0.3 us */
- 0); /* No offset */
- dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT);
- dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
- dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
-
- /* Fast-mode */
- hcnt = i2c_dw_scl_hcnt(input_clock_khz,
- 6, /* tHD;STA = tHIGH = 0.6 us */
- 3, /* tf = 0.3 us */
- 0, /* 0: DW default, 1: Ideal */
- 0); /* No offset */
- lcnt = i2c_dw_scl_lcnt(input_clock_khz,
- 13, /* tLOW = 1.3 us */
- 3, /* tf = 0.3 us */
- 0); /* No offset */
- dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT);
- dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
- dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
-
- /* Configure Tx/Rx FIFO threshold levels */
- dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL);
- dw_writel(dev, 0, DW_IC_RX_TL);
-
- /* configure the i2c master */
- dw_writel(dev, dev->master_cfg , DW_IC_CON);
- return 0;
-}
-
-/*
- * Waiting for bus not busy
- */
-static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev)
-{
- int timeout = TIMEOUT;
-
- while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) {
- if (timeout <= 0) {
- dev_warn(dev->dev, "timeout waiting for bus ready\n");
- return -ETIMEDOUT;
- }
- timeout--;
- mdelay(1);
- }
-
- return 0;
-}
-
-static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
-{
- struct i2c_msg *msgs = dev->msgs;
- u32 ic_con;
-
- /* Disable the adapter */
- dw_writel(dev, 0, DW_IC_ENABLE);
-
- /* set the slave (target) address */
- dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR);
-
- /* if the slave address is ten bit address, enable 10BITADDR */
- ic_con = dw_readl(dev, DW_IC_CON);
- if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
- ic_con |= DW_IC_CON_10BITADDR_MASTER;
- else
- ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
- dw_writel(dev, ic_con, DW_IC_CON);
-
- /* Enable the adapter */
- dw_writel(dev, 1, DW_IC_ENABLE);
-
- /* Enable interrupts */
- dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK);
-}
-
-/*
- * Initiate (and continue) low level master read/write transaction.
- * This function is only called from i2c_dw_isr, and pumping i2c_msg
- * messages into the tx buffer. Even if the size of i2c_msg data is
- * longer than the size of the tx buffer, it handles everything.
- */
-void
-i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
-{
- struct i2c_msg *msgs = dev->msgs;
- u32 intr_mask;
- int tx_limit, rx_limit;
- u32 addr = msgs[dev->msg_write_idx].addr;
- u32 buf_len = dev->tx_buf_len;
- u8 *buf = dev->tx_buf;
-
- intr_mask = DW_IC_INTR_DEFAULT_MASK;
-
- for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
- /*
- * if target address has changed, we need to
- * reprogram the target address in the i2c
- * adapter when we are done with this transfer
- */
- if (msgs[dev->msg_write_idx].addr != addr) {
- dev_err(dev->dev,
- "%s: invalid target address\n", __func__);
- dev->msg_err = -EINVAL;
- break;
- }
-
- if (msgs[dev->msg_write_idx].len == 0) {
- dev_err(dev->dev,
- "%s: invalid message length\n", __func__);
- dev->msg_err = -EINVAL;
- break;
- }
-
- if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
- /* new i2c_msg */
- buf = msgs[dev->msg_write_idx].buf;
- buf_len = msgs[dev->msg_write_idx].len;
- }
-
- tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR);
- rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR);
-
- while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
- if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
- dw_writel(dev, 0x100, DW_IC_DATA_CMD);
- rx_limit--;
- } else
- dw_writel(dev, *buf++, DW_IC_DATA_CMD);
- tx_limit--; buf_len--;
- }
-
- dev->tx_buf = buf;
- dev->tx_buf_len = buf_len;
-
- if (buf_len > 0) {
- /* more bytes to be written */
- dev->status |= STATUS_WRITE_IN_PROGRESS;
- break;
- } else
- dev->status &= ~STATUS_WRITE_IN_PROGRESS;
- }
-
- /*
- * If i2c_msg index search is completed, we don't need TX_EMPTY
- * interrupt any more.
- */
- if (dev->msg_write_idx == dev->msgs_num)
- intr_mask &= ~DW_IC_INTR_TX_EMPTY;
-
- if (dev->msg_err)
- intr_mask = 0;
-
- dw_writel(dev, intr_mask, DW_IC_INTR_MASK);
-}
-
-static void
-i2c_dw_read(struct dw_i2c_dev *dev)
-{
- struct i2c_msg *msgs = dev->msgs;
- int rx_valid;
-
- for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) {
- u32 len;
- u8 *buf;
-
- if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD))
- continue;
-
- if (!(dev->status & STATUS_READ_IN_PROGRESS)) {
- len = msgs[dev->msg_read_idx].len;
- buf = msgs[dev->msg_read_idx].buf;
- } else {
- len = dev->rx_buf_len;
- buf = dev->rx_buf;
- }
-
- rx_valid = dw_readl(dev, DW_IC_RXFLR);
-
- for (; len > 0 && rx_valid > 0; len--, rx_valid--)
- *buf++ = dw_readl(dev, DW_IC_DATA_CMD);
-
- if (len > 0) {
- dev->status |= STATUS_READ_IN_PROGRESS;
- dev->rx_buf_len = len;
- dev->rx_buf = buf;
- return;
- } else
- dev->status &= ~STATUS_READ_IN_PROGRESS;
- }
-}
-
-static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
-{
- unsigned long abort_source = dev->abort_source;
- int i;
-
- if (abort_source & DW_IC_TX_ABRT_NOACK) {
- for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
- dev_dbg(dev->dev,
- "%s: %s\n", __func__, abort_sources[i]);
- return -EREMOTEIO;
- }
-
- for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
- dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
-
- if (abort_source & DW_IC_TX_ARB_LOST)
- return -EAGAIN;
- else if (abort_source & DW_IC_TX_ABRT_GCALL_READ)
- return -EINVAL; /* wrong msgs[] data */
- else
- return -EIO;
-}
-
-/*
- * Prepare controller for a transaction and call i2c_dw_xfer_msg
- */
-int
-i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-{
- struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
- int ret;
-
- dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
-
- mutex_lock(&dev->lock);
- pm_runtime_get_sync(dev->dev);
-
- INIT_COMPLETION(dev->cmd_complete);
- dev->msgs = msgs;
- dev->msgs_num = num;
- dev->cmd_err = 0;
- dev->msg_write_idx = 0;
- dev->msg_read_idx = 0;
- dev->msg_err = 0;
- dev->status = STATUS_IDLE;
- dev->abort_source = 0;
-
- ret = i2c_dw_wait_bus_not_busy(dev);
- if (ret < 0)
- goto done;
-
- /* start the transfers */
- i2c_dw_xfer_init(dev);
-
- /* wait for tx to complete */
- ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ);
- if (ret == 0) {
- dev_err(dev->dev, "controller timed out\n");
- i2c_dw_init(dev);
- ret = -ETIMEDOUT;
- goto done;
- } else if (ret < 0)
- goto done;
-
- if (dev->msg_err) {
- ret = dev->msg_err;
- goto done;
- }
-
- /* no error */
- if (likely(!dev->cmd_err)) {
- /* Disable the adapter */
- dw_writel(dev, 0, DW_IC_ENABLE);
- ret = num;
- goto done;
- }
-
- /* We have an error */
- if (dev->cmd_err == DW_IC_ERR_TX_ABRT) {
- ret = i2c_dw_handle_tx_abort(dev);
- goto done;
- }
- ret = -EIO;
-
-done:
- pm_runtime_put(dev->dev);
- mutex_unlock(&dev->lock);
-
- return ret;
-}
-
-u32 i2c_dw_func(struct i2c_adapter *adap)
-{
- struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
- return dev->functionality;
-}
-
-static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
-{
- u32 stat;
-
- /*
- * The IC_INTR_STAT register just indicates "enabled" interrupts.
- * Ths unmasked raw version of interrupt status bits are available
- * in the IC_RAW_INTR_STAT register.
- *
- * That is,
- * stat = dw_readl(IC_INTR_STAT);
- * equals to,
- * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK);
- *
- * The raw version might be useful for debugging purposes.
- */
- stat = dw_readl(dev, DW_IC_INTR_STAT);
-
- /*
- * Do not use the IC_CLR_INTR register to clear interrupts, or
- * you'll miss some interrupts, triggered during the period from
- * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR).
- *
- * Instead, use the separately-prepared IC_CLR_* registers.
- */
- if (stat & DW_IC_INTR_RX_UNDER)
- dw_readl(dev, DW_IC_CLR_RX_UNDER);
- if (stat & DW_IC_INTR_RX_OVER)
- dw_readl(dev, DW_IC_CLR_RX_OVER);
- if (stat & DW_IC_INTR_TX_OVER)
- dw_readl(dev, DW_IC_CLR_TX_OVER);
- if (stat & DW_IC_INTR_RD_REQ)
- dw_readl(dev, DW_IC_CLR_RD_REQ);
- if (stat & DW_IC_INTR_TX_ABRT) {
- /*
- * The IC_TX_ABRT_SOURCE register is cleared whenever
- * the IC_CLR_TX_ABRT is read. Preserve it beforehand.
- */
- dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE);
- dw_readl(dev, DW_IC_CLR_TX_ABRT);
- }
- if (stat & DW_IC_INTR_RX_DONE)
- dw_readl(dev, DW_IC_CLR_RX_DONE);
- if (stat & DW_IC_INTR_ACTIVITY)
- dw_readl(dev, DW_IC_CLR_ACTIVITY);
- if (stat & DW_IC_INTR_STOP_DET)
- dw_readl(dev, DW_IC_CLR_STOP_DET);
- if (stat & DW_IC_INTR_START_DET)
- dw_readl(dev, DW_IC_CLR_START_DET);
- if (stat & DW_IC_INTR_GEN_CALL)
- dw_readl(dev, DW_IC_CLR_GEN_CALL);
-
- return stat;
-}
-
-/*
- * Interrupt service routine. This gets called whenever an I2C interrupt
- * occurs.
- */
-irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
-{
- struct dw_i2c_dev *dev = dev_id;
- u32 stat, enabled;
-
- enabled = dw_readl(dev, DW_IC_ENABLE);
- stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
- dev_dbg(dev->dev, "%s: %s enabled= 0x%x stat=0x%x\n", __func__,
- dev->adapter.name, enabled, stat);
- if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY))
- return IRQ_NONE;
-
- stat = i2c_dw_read_clear_intrbits(dev);
-
- if (stat & DW_IC_INTR_TX_ABRT) {
- dev->cmd_err |= DW_IC_ERR_TX_ABRT;
- dev->status = STATUS_IDLE;
-
- /*
- * Anytime TX_ABRT is set, the contents of the tx/rx
- * buffers are flushed. Make sure to skip them.
- */
- dw_writel(dev, 0, DW_IC_INTR_MASK);
- goto tx_aborted;
- }
-
- if (stat & DW_IC_INTR_RX_FULL)
- i2c_dw_read(dev);
-
- if (stat & DW_IC_INTR_TX_EMPTY)
- i2c_dw_xfer_msg(dev);
-
- /*
- * No need to modify or disable the interrupt mask here.
- * i2c_dw_xfer_msg() will take care of it according to
- * the current transmit status.
- */
-
-tx_aborted:
- if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
- complete(&dev->cmd_complete);
-
- return IRQ_HANDLED;
-}
-
-void i2c_dw_enable(struct dw_i2c_dev *dev)
-{
- /* Enable the adapter */
- dw_writel(dev, 1, DW_IC_ENABLE);
-}
-
-u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev)
-{
- return dw_readl(dev, DW_IC_ENABLE);
-}
-
-void i2c_dw_disable(struct dw_i2c_dev *dev)
-{
- /* Disable controller */
- dw_writel(dev, 0, DW_IC_ENABLE);
-
- /* Disable all interupts */
- dw_writel(dev, 0, DW_IC_INTR_MASK);
- dw_readl(dev, DW_IC_CLR_INTR);
-}
-
-void i2c_dw_clear_int(struct dw_i2c_dev *dev)
-{
- dw_readl(dev, DW_IC_CLR_INTR);
-}
-
-void i2c_dw_disable_int(struct dw_i2c_dev *dev)
-{
- dw_writel(dev, 0, DW_IC_INTR_MASK);
-}
-
-u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev)
-{
- return dw_readl(dev, DW_IC_COMP_PARAM_1);
-}
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.h b/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.h
deleted file mode 100644
index 02d1a2dd..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-core.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Synopsys DesignWare I2C adapter driver (master only).
- *
- * Based on the TI DAVINCI I2C adapter driver.
- *
- * Copyright (C) 2006 Texas Instruments.
- * Copyright (C) 2007 MontaVista Software Inc.
- * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ----------------------------------------------------------------------------
- *
- */
-
-
-#define DW_IC_CON_MASTER 0x1
-#define DW_IC_CON_SPEED_STD 0x2
-#define DW_IC_CON_SPEED_FAST 0x4
-#define DW_IC_CON_10BITADDR_MASTER 0x10
-#define DW_IC_CON_RESTART_EN 0x20
-#define DW_IC_CON_SLAVE_DISABLE 0x40
-
-
-/**
- * struct dw_i2c_dev - private i2c-designware data
- * @dev: driver model device node
- * @base: IO registers pointer
- * @cmd_complete: tx completion indicator
- * @lock: protect this struct and IO registers
- * @clk: input reference clock
- * @cmd_err: run time hadware error code
- * @msgs: points to an array of messages currently being transfered
- * @msgs_num: the number of elements in msgs
- * @msg_write_idx: the element index of the current tx message in the msgs
- * array
- * @tx_buf_len: the length of the current tx buffer
- * @tx_buf: the current tx buffer
- * @msg_read_idx: the element index of the current rx message in the msgs
- * array
- * @rx_buf_len: the length of the current rx buffer
- * @rx_buf: the current rx buffer
- * @msg_err: error status of the current transfer
- * @status: i2c master status, one of STATUS_*
- * @abort_source: copy of the TX_ABRT_SOURCE register
- * @irq: interrupt number for the i2c master
- * @adapter: i2c subsystem adapter node
- * @tx_fifo_depth: depth of the hardware tx fifo
- * @rx_fifo_depth: depth of the hardware rx fifo
- */
-struct dw_i2c_dev {
- struct device *dev;
- void __iomem *base;
- struct completion cmd_complete;
- struct mutex lock;
- struct clk *clk;
- u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev);
- struct dw_pci_controller *controller;
- int cmd_err;
- struct i2c_msg *msgs;
- int msgs_num;
- int msg_write_idx;
- u32 tx_buf_len;
- u8 *tx_buf;
- int msg_read_idx;
- u32 rx_buf_len;
- u8 *rx_buf;
- int msg_err;
- unsigned int status;
- u32 abort_source;
- int irq;
- int swab;
- struct i2c_adapter adapter;
- u32 functionality;
- u32 master_cfg;
- unsigned int tx_fifo_depth;
- unsigned int rx_fifo_depth;
-};
-
-extern u32 dw_readl(struct dw_i2c_dev *dev, int offset);
-extern void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
-extern int i2c_dw_init(struct dw_i2c_dev *dev);
-extern int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
- int num);
-extern u32 i2c_dw_func(struct i2c_adapter *adap);
-extern irqreturn_t i2c_dw_isr(int this_irq, void *dev_id);
-extern void i2c_dw_enable(struct dw_i2c_dev *dev);
-extern u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev);
-extern void i2c_dw_disable(struct dw_i2c_dev *dev);
-extern void i2c_dw_clear_int(struct dw_i2c_dev *dev);
-extern void i2c_dw_disable_int(struct dw_i2c_dev *dev);
-extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-pcidrv.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-pcidrv.c
deleted file mode 100644
index 00e8f213..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Synopsys DesignWare I2C adapter driver (master only).
- *
- * Based on the TI DAVINCI I2C adapter driver.
- *
- * Copyright (C) 2006 Texas Instruments.
- * Copyright (C) 2007 MontaVista Software Inc.
- * Copyright (C) 2009 Provigent Ltd.
- * Copyright (C) 2011 Intel corporation.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ----------------------------------------------------------------------------
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/pm_runtime.h>
-#include "i2c-designware-core.h"
-
-#define DRIVER_NAME "i2c-designware-pci"
-
-enum dw_pci_ctl_id_t {
- moorestown_0,
- moorestown_1,
- moorestown_2,
-
- medfield_0,
- medfield_1,
- medfield_2,
- medfield_3,
- medfield_4,
- medfield_5,
-};
-
-struct dw_pci_controller {
- u32 bus_num;
- u32 bus_cfg;
- u32 tx_fifo_depth;
- u32 rx_fifo_depth;
- u32 clk_khz;
-};
-
-#define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \
- DW_IC_CON_SLAVE_DISABLE | \
- DW_IC_CON_RESTART_EN)
-
-static struct dw_pci_controller dw_pci_controllers[] = {
- [moorestown_0] = {
- .bus_num = 0,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [moorestown_1] = {
- .bus_num = 1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [moorestown_2] = {
- .bus_num = 2,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [medfield_0] = {
- .bus_num = 0,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [medfield_1] = {
- .bus_num = 1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [medfield_2] = {
- .bus_num = 2,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [medfield_3] = {
- .bus_num = 3,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_STD,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [medfield_4] = {
- .bus_num = 4,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
- [medfield_5] = {
- .bus_num = 5,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .clk_khz = 25000,
- },
-};
-static struct i2c_algorithm i2c_dw_algo = {
- .master_xfer = i2c_dw_xfer,
- .functionality = i2c_dw_func,
-};
-
-static int i2c_dw_pci_suspend(struct device *dev)
-{
- struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
- struct dw_i2c_dev *i2c = pci_get_drvdata(pdev);
- int err;
-
-
- i2c_dw_disable(i2c);
-
- err = pci_save_state(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_save_state failed\n");
- return err;
- }
-
- err = pci_set_power_state(pdev, PCI_D3hot);
- if (err) {
- dev_err(&pdev->dev, "pci_set_power_state failed\n");
- return err;
- }
-
- return 0;
-}
-
-static int i2c_dw_pci_resume(struct device *dev)
-{
- struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
- struct dw_i2c_dev *i2c = pci_get_drvdata(pdev);
- int err;
- u32 enabled;
-
- enabled = i2c_dw_is_enabled(i2c);
- if (enabled)
- return 0;
-
- err = pci_set_power_state(pdev, PCI_D0);
- if (err) {
- dev_err(&pdev->dev, "pci_set_power_state() failed\n");
- return err;
- }
-
- pci_restore_state(pdev);
-
- i2c_dw_init(i2c);
- return 0;
-}
-
-static int i2c_dw_pci_runtime_idle(struct device *dev)
-{
- int err = pm_schedule_suspend(dev, 500);
- dev_dbg(dev, "runtime_idle called\n");
-
- if (err != 0)
- return 0;
- return -EBUSY;
-}
-
-static const struct dev_pm_ops i2c_dw_pm_ops = {
- .resume = i2c_dw_pci_resume,
- .suspend = i2c_dw_pci_suspend,
- SET_RUNTIME_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume,
- i2c_dw_pci_runtime_idle)
-};
-
-static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
-{
- return dev->controller->clk_khz;
-}
-
-static int __devinit i2c_dw_pci_probe(struct pci_dev *pdev,
-const struct pci_device_id *id)
-{
- struct dw_i2c_dev *dev;
- struct i2c_adapter *adap;
- unsigned long start, len;
- void __iomem *base;
- int r;
- struct dw_pci_controller *controller;
-
- if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) {
- printk(KERN_ERR "dw_i2c_pci_probe: invalid driver data %ld\n",
- id->driver_data);
- return -EINVAL;
- }
-
- controller = &dw_pci_controllers[id->driver_data];
-
- r = pci_enable_device(pdev);
- if (r) {
- dev_err(&pdev->dev, "Failed to enable I2C PCI device (%d)\n",
- r);
- goto exit;
- }
-
- /* Determine the address of the I2C area */
- start = pci_resource_start(pdev, 0);
- len = pci_resource_len(pdev, 0);
- if (!start || len == 0) {
- dev_err(&pdev->dev, "base address not set\n");
- r = -ENODEV;
- goto exit;
- }
-
- r = pci_request_region(pdev, 0, DRIVER_NAME);
- if (r) {
- dev_err(&pdev->dev, "failed to request I2C region "
- "0x%lx-0x%lx\n", start,
- (unsigned long)pci_resource_end(pdev, 0));
- goto exit;
- }
-
- base = ioremap_nocache(start, len);
- if (!base) {
- dev_err(&pdev->dev, "I/O memory remapping failed\n");
- r = -ENOMEM;
- goto err_release_region;
- }
-
-
- dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL);
- if (!dev) {
- r = -ENOMEM;
- goto err_release_region;
- }
-
- init_completion(&dev->cmd_complete);
- mutex_init(&dev->lock);
- dev->clk = NULL;
- dev->controller = controller;
- dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
- dev->base = base;
- dev->dev = get_device(&pdev->dev);
- dev->functionality =
- I2C_FUNC_I2C |
- I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK;
- dev->master_cfg = controller->bus_cfg;
-
- pci_set_drvdata(pdev, dev);
-
- dev->tx_fifo_depth = controller->tx_fifo_depth;
- dev->rx_fifo_depth = controller->rx_fifo_depth;
- r = i2c_dw_init(dev);
- if (r)
- goto err_iounmap;
-
- adap = &dev->adapter;
- i2c_set_adapdata(adap, dev);
- adap->owner = THIS_MODULE;
- adap->class = 0;
- adap->algo = &i2c_dw_algo;
- adap->dev.parent = &pdev->dev;
- adap->nr = controller->bus_num;
- snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci-%d",
- adap->nr);
-
- r = request_irq(pdev->irq, i2c_dw_isr, IRQF_SHARED, adap->name, dev);
- if (r) {
- dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
- goto err_iounmap;
- }
-
- i2c_dw_disable_int(dev);
- i2c_dw_clear_int(dev);
- r = i2c_add_numbered_adapter(adap);
- if (r) {
- dev_err(&pdev->dev, "failure adding adapter\n");
- goto err_free_irq;
- }
-
- pm_runtime_put_noidle(&pdev->dev);
- pm_runtime_allow(&pdev->dev);
-
- return 0;
-
-err_free_irq:
- free_irq(pdev->irq, dev);
-err_iounmap:
- iounmap(dev->base);
- pci_set_drvdata(pdev, NULL);
- put_device(&pdev->dev);
- kfree(dev);
-err_release_region:
- pci_release_region(pdev, 0);
-exit:
- return r;
-}
-
-static void __devexit i2c_dw_pci_remove(struct pci_dev *pdev)
-{
- struct dw_i2c_dev *dev = pci_get_drvdata(pdev);
-
- i2c_dw_disable(dev);
- pm_runtime_forbid(&pdev->dev);
- pm_runtime_get_noresume(&pdev->dev);
-
- pci_set_drvdata(pdev, NULL);
- i2c_del_adapter(&dev->adapter);
- put_device(&pdev->dev);
-
- free_irq(dev->irq, dev);
- kfree(dev);
- pci_release_region(pdev, 0);
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("i2c_designware-pci");
-
-static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = {
- /* Moorestown */
- { PCI_VDEVICE(INTEL, 0x0802), moorestown_0 },
- { PCI_VDEVICE(INTEL, 0x0803), moorestown_1 },
- { PCI_VDEVICE(INTEL, 0x0804), moorestown_2 },
- /* Medfield */
- { PCI_VDEVICE(INTEL, 0x0817), medfield_3,},
- { PCI_VDEVICE(INTEL, 0x0818), medfield_4 },
- { PCI_VDEVICE(INTEL, 0x0819), medfield_5 },
- { PCI_VDEVICE(INTEL, 0x082C), medfield_0 },
- { PCI_VDEVICE(INTEL, 0x082D), medfield_1 },
- { PCI_VDEVICE(INTEL, 0x082E), medfield_2 },
- { 0,}
-};
-MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
-
-static struct pci_driver dw_i2c_driver = {
- .name = DRIVER_NAME,
- .id_table = i2_designware_pci_ids,
- .probe = i2c_dw_pci_probe,
- .remove = __devexit_p(i2c_dw_pci_remove),
- .driver = {
- .pm = &i2c_dw_pm_ops,
- },
-};
-
-static int __init dw_i2c_init_driver(void)
-{
- return pci_register_driver(&dw_i2c_driver);
-}
-module_init(dw_i2c_init_driver);
-
-static void __exit dw_i2c_exit_driver(void)
-{
- pci_unregister_driver(&dw_i2c_driver);
-}
-module_exit(dw_i2c_exit_driver);
-
-MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
-MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-platdrv.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-platdrv.c
deleted file mode 100644
index 4ba589ab..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-designware-platdrv.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Synopsys DesignWare I2C adapter driver (master only).
- *
- * Based on the TI DAVINCI I2C adapter driver.
- *
- * Copyright (C) 2006 Texas Instruments.
- * Copyright (C) 2007 MontaVista Software Inc.
- * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ----------------------------------------------------------------------------
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/of_i2c.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include "i2c-designware-core.h"
-
-static struct i2c_algorithm i2c_dw_algo = {
- .master_xfer = i2c_dw_xfer,
- .functionality = i2c_dw_func,
-};
-static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
-{
- return clk_get_rate(dev->clk)/1000;
-}
-
-static int __devinit dw_i2c_probe(struct platform_device *pdev)
-{
- struct dw_i2c_dev *dev;
- struct i2c_adapter *adap;
- struct resource *mem, *ioarea;
- int irq, r;
-
- /* NOTE: driver uses the static register mapping */
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "no mem resource?\n");
- return -EINVAL;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no irq resource?\n");
- return irq; /* -ENXIO */
- }
-
- ioarea = request_mem_region(mem->start, resource_size(mem),
- pdev->name);
- if (!ioarea) {
- dev_err(&pdev->dev, "I2C region already claimed\n");
- return -EBUSY;
- }
-
- dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL);
- if (!dev) {
- r = -ENOMEM;
- goto err_release_region;
- }
-
- init_completion(&dev->cmd_complete);
- mutex_init(&dev->lock);
- dev->dev = get_device(&pdev->dev);
- dev->irq = irq;
- platform_set_drvdata(pdev, dev);
-
- dev->clk = clk_get(&pdev->dev, NULL);
- dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
-
- if (IS_ERR(dev->clk)) {
- r = -ENODEV;
- goto err_free_mem;
- }
- clk_enable(dev->clk);
-
- dev->functionality =
- I2C_FUNC_I2C |
- I2C_FUNC_10BIT_ADDR |
- I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK;
- dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
- DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
-
- dev->base = ioremap(mem->start, resource_size(mem));
- if (dev->base == NULL) {
- dev_err(&pdev->dev, "failure mapping io resources\n");
- r = -EBUSY;
- goto err_unuse_clocks;
- }
- {
- u32 param1 = i2c_dw_read_comp_param(dev);
-
- dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1;
- dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1;
- }
- r = i2c_dw_init(dev);
- if (r)
- goto err_iounmap;
-
- i2c_dw_disable_int(dev);
- r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
- if (r) {
- dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
- goto err_iounmap;
- }
-
- adap = &dev->adapter;
- i2c_set_adapdata(adap, dev);
- adap->owner = THIS_MODULE;
- adap->class = I2C_CLASS_HWMON;
- strlcpy(adap->name, "Synopsys DesignWare I2C adapter",
- sizeof(adap->name));
- adap->algo = &i2c_dw_algo;
- adap->dev.parent = &pdev->dev;
- adap->dev.of_node = pdev->dev.of_node;
-
- adap->nr = pdev->id;
- r = i2c_add_numbered_adapter(adap);
- if (r) {
- dev_err(&pdev->dev, "failure adding adapter\n");
- goto err_free_irq;
- }
- of_i2c_register_devices(adap);
-
- return 0;
-
-err_free_irq:
- free_irq(dev->irq, dev);
-err_iounmap:
- iounmap(dev->base);
-err_unuse_clocks:
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
-err_free_mem:
- platform_set_drvdata(pdev, NULL);
- put_device(&pdev->dev);
- kfree(dev);
-err_release_region:
- release_mem_region(mem->start, resource_size(mem));
-
- return r;
-}
-
-static int __devexit dw_i2c_remove(struct platform_device *pdev)
-{
- struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
- struct resource *mem;
-
- platform_set_drvdata(pdev, NULL);
- i2c_del_adapter(&dev->adapter);
- put_device(&pdev->dev);
-
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
-
- i2c_dw_disable(dev);
- free_irq(dev->irq, dev);
- kfree(dev);
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
- return 0;
-}
-
-#ifdef CONFIG_OF
-static const struct of_device_id dw_i2c_of_match[] = {
- { .compatible = "snps,designware-i2c", },
- {},
-};
-MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
-#endif
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:i2c_designware");
-
-static struct platform_driver dw_i2c_driver = {
- .remove = __devexit_p(dw_i2c_remove),
- .driver = {
- .name = "i2c_designware",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(dw_i2c_of_match),
- },
-};
-
-static int __init dw_i2c_init_driver(void)
-{
- return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe);
-}
-subsys_initcall(dw_i2c_init_driver);
-
-static void __exit dw_i2c_exit_driver(void)
-{
- platform_driver_unregister(&dw_i2c_driver);
-}
-module_exit(dw_i2c_exit_driver);
-
-MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
-MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-diolan-u2c.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-diolan-u2c.c
deleted file mode 100644
index 7eb19a52..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-diolan-u2c.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Driver for the Diolan u2c-12 USB-I2C adapter
- *
- * Copyright (c) 2010-2011 Ericsson AB
- *
- * Derived from:
- * i2c-tiny-usb.c
- * Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-
-#define DRIVER_NAME "i2c-diolan-u2c"
-
-#define USB_VENDOR_ID_DIOLAN 0x0abf
-#define USB_DEVICE_ID_DIOLAN_U2C 0x3370
-
-#define DIOLAN_OUT_EP 0x02
-#define DIOLAN_IN_EP 0x84
-
-/* commands via USB, must match command ids in the firmware */
-#define CMD_I2C_READ 0x01
-#define CMD_I2C_WRITE 0x02
-#define CMD_I2C_SCAN 0x03 /* Returns list of detected devices */
-#define CMD_I2C_RELEASE_SDA 0x04
-#define CMD_I2C_RELEASE_SCL 0x05
-#define CMD_I2C_DROP_SDA 0x06
-#define CMD_I2C_DROP_SCL 0x07
-#define CMD_I2C_READ_SDA 0x08
-#define CMD_I2C_READ_SCL 0x09
-#define CMD_GET_FW_VERSION 0x0a
-#define CMD_GET_SERIAL 0x0b
-#define CMD_I2C_START 0x0c
-#define CMD_I2C_STOP 0x0d
-#define CMD_I2C_REPEATED_START 0x0e
-#define CMD_I2C_PUT_BYTE 0x0f
-#define CMD_I2C_GET_BYTE 0x10
-#define CMD_I2C_PUT_ACK 0x11
-#define CMD_I2C_GET_ACK 0x12
-#define CMD_I2C_PUT_BYTE_ACK 0x13
-#define CMD_I2C_GET_BYTE_ACK 0x14
-#define CMD_I2C_SET_SPEED 0x1b
-#define CMD_I2C_GET_SPEED 0x1c
-#define CMD_I2C_SET_CLK_SYNC 0x24
-#define CMD_I2C_GET_CLK_SYNC 0x25
-#define CMD_I2C_SET_CLK_SYNC_TO 0x26
-#define CMD_I2C_GET_CLK_SYNC_TO 0x27
-
-#define RESP_OK 0x00
-#define RESP_FAILED 0x01
-#define RESP_BAD_MEMADDR 0x04
-#define RESP_DATA_ERR 0x05
-#define RESP_NOT_IMPLEMENTED 0x06
-#define RESP_NACK 0x07
-#define RESP_TIMEOUT 0x09
-
-#define U2C_I2C_SPEED_FAST 0 /* 400 kHz */
-#define U2C_I2C_SPEED_STD 1 /* 100 kHz */
-#define U2C_I2C_SPEED_2KHZ 242 /* 2 kHz, minimum speed */
-#define U2C_I2C_SPEED(f) ((DIV_ROUND_UP(1000000, (f)) - 10) / 2 + 1)
-
-#define U2C_I2C_FREQ_FAST 400000
-#define U2C_I2C_FREQ_STD 100000
-#define U2C_I2C_FREQ(s) (1000000 / (2 * (s - 1) + 10))
-
-#define DIOLAN_USB_TIMEOUT 100 /* in ms */
-#define DIOLAN_SYNC_TIMEOUT 20 /* in ms */
-
-#define DIOLAN_OUTBUF_LEN 128
-#define DIOLAN_FLUSH_LEN (DIOLAN_OUTBUF_LEN - 4)
-#define DIOLAN_INBUF_LEN 256 /* Maximum supported receive length */
-
-/* Structure to hold all of our device specific stuff */
-struct i2c_diolan_u2c {
- u8 obuffer[DIOLAN_OUTBUF_LEN]; /* output buffer */
- u8 ibuffer[DIOLAN_INBUF_LEN]; /* input buffer */
- struct usb_device *usb_dev; /* the usb device for this device */
- struct usb_interface *interface;/* the interface for this device */
- struct i2c_adapter adapter; /* i2c related things */
- int olen; /* Output buffer length */
- int ocount; /* Number of enqueued messages */
-};
-
-static uint frequency = U2C_I2C_FREQ_STD; /* I2C clock frequency in Hz */
-
-module_param(frequency, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(frequency, "I2C clock frequency in hertz");
-
-/* usb layer */
-
-/* Send command to device, and get response. */
-static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)
-{
- int ret = 0;
- int actual;
- int i;
-
- if (!dev->olen || !dev->ocount)
- return -EINVAL;
-
- ret = usb_bulk_msg(dev->usb_dev,
- usb_sndbulkpipe(dev->usb_dev, DIOLAN_OUT_EP),
- dev->obuffer, dev->olen, &actual,
- DIOLAN_USB_TIMEOUT);
- if (!ret) {
- for (i = 0; i < dev->ocount; i++) {
- int tmpret;
-
- tmpret = usb_bulk_msg(dev->usb_dev,
- usb_rcvbulkpipe(dev->usb_dev,
- DIOLAN_IN_EP),
- dev->ibuffer,
- sizeof(dev->ibuffer), &actual,
- DIOLAN_USB_TIMEOUT);
- /*
- * Stop command processing if a previous command
- * returned an error.
- * Note that we still need to retrieve all messages.
- */
- if (ret < 0)
- continue;
- ret = tmpret;
- if (ret == 0 && actual > 0) {
- switch (dev->ibuffer[actual - 1]) {
- case RESP_NACK:
- /*
- * Return ENXIO if NACK was received as
- * response to the address phase,
- * EIO otherwise
- */
- ret = i == 1 ? -ENXIO : -EIO;
- break;
- case RESP_TIMEOUT:
- ret = -ETIMEDOUT;
- break;
- case RESP_OK:
- /* strip off return code */
- ret = actual - 1;
- break;
- default:
- ret = -EIO;
- break;
- }
- }
- }
- }
- dev->olen = 0;
- dev->ocount = 0;
- return ret;
-}
-
-static int diolan_write_cmd(struct i2c_diolan_u2c *dev, bool flush)
-{
- if (flush || dev->olen >= DIOLAN_FLUSH_LEN)
- return diolan_usb_transfer(dev);
- return 0;
-}
-
-/* Send command (no data) */
-static int diolan_usb_cmd(struct i2c_diolan_u2c *dev, u8 command, bool flush)
-{
- dev->obuffer[dev->olen++] = command;
- dev->ocount++;
- return diolan_write_cmd(dev, flush);
-}
-
-/* Send command with one byte of data */
-static int diolan_usb_cmd_data(struct i2c_diolan_u2c *dev, u8 command, u8 data,
- bool flush)
-{
- dev->obuffer[dev->olen++] = command;
- dev->obuffer[dev->olen++] = data;
- dev->ocount++;
- return diolan_write_cmd(dev, flush);
-}
-
-/* Send command with two bytes of data */
-static int diolan_usb_cmd_data2(struct i2c_diolan_u2c *dev, u8 command, u8 d1,
- u8 d2, bool flush)
-{
- dev->obuffer[dev->olen++] = command;
- dev->obuffer[dev->olen++] = d1;
- dev->obuffer[dev->olen++] = d2;
- dev->ocount++;
- return diolan_write_cmd(dev, flush);
-}
-
-/*
- * Flush input queue.
- * If we don't do this at startup and the controller has queued up
- * messages which were not retrieved, it will stop responding
- * at some point.
- */
-static void diolan_flush_input(struct i2c_diolan_u2c *dev)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- int actual = 0;
- int ret;
-
- ret = usb_bulk_msg(dev->usb_dev,
- usb_rcvbulkpipe(dev->usb_dev, DIOLAN_IN_EP),
- dev->ibuffer, sizeof(dev->ibuffer), &actual,
- DIOLAN_USB_TIMEOUT);
- if (ret < 0 || actual == 0)
- break;
- }
- if (i == 10)
- dev_err(&dev->interface->dev, "Failed to flush input buffer\n");
-}
-
-static int diolan_i2c_start(struct i2c_diolan_u2c *dev)
-{
- return diolan_usb_cmd(dev, CMD_I2C_START, false);
-}
-
-static int diolan_i2c_repeated_start(struct i2c_diolan_u2c *dev)
-{
- return diolan_usb_cmd(dev, CMD_I2C_REPEATED_START, false);
-}
-
-static int diolan_i2c_stop(struct i2c_diolan_u2c *dev)
-{
- return diolan_usb_cmd(dev, CMD_I2C_STOP, true);
-}
-
-static int diolan_i2c_get_byte_ack(struct i2c_diolan_u2c *dev, bool ack,
- u8 *byte)
-{
- int ret;
-
- ret = diolan_usb_cmd_data(dev, CMD_I2C_GET_BYTE_ACK, ack, true);
- if (ret > 0)
- *byte = dev->ibuffer[0];
- else if (ret == 0)
- ret = -EIO;
-
- return ret;
-}
-
-static int diolan_i2c_put_byte_ack(struct i2c_diolan_u2c *dev, u8 byte)
-{
- return diolan_usb_cmd_data(dev, CMD_I2C_PUT_BYTE_ACK, byte, false);
-}
-
-static int diolan_set_speed(struct i2c_diolan_u2c *dev, u8 speed)
-{
- return diolan_usb_cmd_data(dev, CMD_I2C_SET_SPEED, speed, true);
-}
-
-/* Enable or disable clock synchronization (stretching) */
-static int diolan_set_clock_synch(struct i2c_diolan_u2c *dev, bool enable)
-{
- return diolan_usb_cmd_data(dev, CMD_I2C_SET_CLK_SYNC, enable, true);
-}
-
-/* Set clock synchronization timeout in ms */
-static int diolan_set_clock_synch_timeout(struct i2c_diolan_u2c *dev, int ms)
-{
- int to_val = ms * 10;
-
- return diolan_usb_cmd_data2(dev, CMD_I2C_SET_CLK_SYNC_TO,
- to_val & 0xff, (to_val >> 8) & 0xff, true);
-}
-
-static void diolan_fw_version(struct i2c_diolan_u2c *dev)
-{
- int ret;
-
- ret = diolan_usb_cmd(dev, CMD_GET_FW_VERSION, true);
- if (ret >= 2)
- dev_info(&dev->interface->dev,
- "Diolan U2C firmware version %u.%u\n",
- (unsigned int)dev->ibuffer[0],
- (unsigned int)dev->ibuffer[1]);
-}
-
-static void diolan_get_serial(struct i2c_diolan_u2c *dev)
-{
- int ret;
- u32 serial;
-
- ret = diolan_usb_cmd(dev, CMD_GET_SERIAL, true);
- if (ret >= 4) {
- serial = le32_to_cpu(*(u32 *)dev->ibuffer);
- dev_info(&dev->interface->dev,
- "Diolan U2C serial number %u\n", serial);
- }
-}
-
-static int diolan_init(struct i2c_diolan_u2c *dev)
-{
- int speed, ret;
-
- if (frequency >= 200000) {
- speed = U2C_I2C_SPEED_FAST;
- frequency = U2C_I2C_FREQ_FAST;
- } else if (frequency >= 100000 || frequency == 0) {
- speed = U2C_I2C_SPEED_STD;
- frequency = U2C_I2C_FREQ_STD;
- } else {
- speed = U2C_I2C_SPEED(frequency);
- if (speed > U2C_I2C_SPEED_2KHZ)
- speed = U2C_I2C_SPEED_2KHZ;
- frequency = U2C_I2C_FREQ(speed);
- }
-
- dev_info(&dev->interface->dev,
- "Diolan U2C at USB bus %03d address %03d speed %d Hz\n",
- dev->usb_dev->bus->busnum, dev->usb_dev->devnum, frequency);
-
- diolan_flush_input(dev);
- diolan_fw_version(dev);
- diolan_get_serial(dev);
-
- /* Set I2C speed */
- ret = diolan_set_speed(dev, speed);
- if (ret < 0)
- return ret;
-
- /* Configure I2C clock synchronization */
- ret = diolan_set_clock_synch(dev, speed != U2C_I2C_SPEED_FAST);
- if (ret < 0)
- return ret;
-
- if (speed != U2C_I2C_SPEED_FAST)
- ret = diolan_set_clock_synch_timeout(dev, DIOLAN_SYNC_TIMEOUT);
-
- return ret;
-}
-
-/* i2c layer */
-
-static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
- int num)
-{
- struct i2c_diolan_u2c *dev = i2c_get_adapdata(adapter);
- struct i2c_msg *pmsg;
- int i, j;
- int ret, sret;
-
- ret = diolan_i2c_start(dev);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < num; i++) {
- pmsg = &msgs[i];
- if (i) {
- ret = diolan_i2c_repeated_start(dev);
- if (ret < 0)
- goto abort;
- }
- if (pmsg->flags & I2C_M_RD) {
- ret =
- diolan_i2c_put_byte_ack(dev, (pmsg->addr << 1) | 1);
- if (ret < 0)
- goto abort;
- for (j = 0; j < pmsg->len; j++) {
- u8 byte;
- bool ack = j < pmsg->len - 1;
-
- /*
- * Don't send NACK if this is the first byte
- * of a SMBUS_BLOCK message.
- */
- if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN))
- ack = true;
-
- ret = diolan_i2c_get_byte_ack(dev, ack, &byte);
- if (ret < 0)
- goto abort;
- /*
- * Adjust count if first received byte is length
- */
- if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN)) {
- if (byte == 0
- || byte > I2C_SMBUS_BLOCK_MAX) {
- ret = -EPROTO;
- goto abort;
- }
- pmsg->len += byte;
- }
- pmsg->buf[j] = byte;
- }
- } else {
- ret = diolan_i2c_put_byte_ack(dev, pmsg->addr << 1);
- if (ret < 0)
- goto abort;
- for (j = 0; j < pmsg->len; j++) {
- ret = diolan_i2c_put_byte_ack(dev,
- pmsg->buf[j]);
- if (ret < 0)
- goto abort;
- }
- }
- }
-abort:
- sret = diolan_i2c_stop(dev);
- if (sret < 0 && ret >= 0)
- ret = sret;
- return ret;
-}
-
-/*
- * Return list of supported functionality.
- */
-static u32 diolan_usb_func(struct i2c_adapter *a)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
- I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
-}
-
-static const struct i2c_algorithm diolan_usb_algorithm = {
- .master_xfer = diolan_usb_xfer,
- .functionality = diolan_usb_func,
-};
-
-/* device layer */
-
-static const struct usb_device_id diolan_u2c_table[] = {
- { USB_DEVICE(USB_VENDOR_ID_DIOLAN, USB_DEVICE_ID_DIOLAN_U2C) },
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, diolan_u2c_table);
-
-static void diolan_u2c_free(struct i2c_diolan_u2c *dev)
-{
- usb_put_dev(dev->usb_dev);
- kfree(dev);
-}
-
-static int diolan_u2c_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct i2c_diolan_u2c *dev;
- int ret;
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&interface->dev, "no memory for device state\n");
- ret = -ENOMEM;
- goto error;
- }
-
- dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
- dev->interface = interface;
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- /* setup i2c adapter description */
- dev->adapter.owner = THIS_MODULE;
- dev->adapter.class = I2C_CLASS_HWMON;
- dev->adapter.algo = &diolan_usb_algorithm;
- i2c_set_adapdata(&dev->adapter, dev);
- snprintf(dev->adapter.name, sizeof(dev->adapter.name),
- DRIVER_NAME " at bus %03d device %03d",
- dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
-
- dev->adapter.dev.parent = &dev->interface->dev;
-
- /* initialize diolan i2c interface */
- ret = diolan_init(dev);
- if (ret < 0) {
- dev_err(&interface->dev, "failed to initialize adapter\n");
- goto error_free;
- }
-
- /* and finally attach to i2c layer */
- ret = i2c_add_adapter(&dev->adapter);
- if (ret < 0) {
- dev_err(&interface->dev, "failed to add I2C adapter\n");
- goto error_free;
- }
-
- dev_dbg(&interface->dev, "connected " DRIVER_NAME "\n");
-
- return 0;
-
-error_free:
- usb_set_intfdata(interface, NULL);
- diolan_u2c_free(dev);
-error:
- return ret;
-}
-
-static void diolan_u2c_disconnect(struct usb_interface *interface)
-{
- struct i2c_diolan_u2c *dev = usb_get_intfdata(interface);
-
- i2c_del_adapter(&dev->adapter);
- usb_set_intfdata(interface, NULL);
- diolan_u2c_free(dev);
-
- dev_dbg(&interface->dev, "disconnected\n");
-}
-
-static struct usb_driver diolan_u2c_driver = {
- .name = DRIVER_NAME,
- .probe = diolan_u2c_probe,
- .disconnect = diolan_u2c_disconnect,
- .id_table = diolan_u2c_table,
-};
-
-module_usb_driver(diolan_u2c_driver);
-
-MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
-MODULE_DESCRIPTION(DRIVER_NAME " driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-eg20t.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-eg20t.c
deleted file mode 100644
index c811289b..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-eg20t.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/fs.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-#include <linux/ktime.h>
-#include <linux/slab.h>
-
-#define PCH_EVENT_SET 0 /* I2C Interrupt Event Set Status */
-#define PCH_EVENT_NONE 1 /* I2C Interrupt Event Clear Status */
-#define PCH_MAX_CLK 100000 /* Maximum Clock speed in MHz */
-#define PCH_BUFFER_MODE_ENABLE 0x0002 /* flag for Buffer mode enable */
-#define PCH_EEPROM_SW_RST_MODE_ENABLE 0x0008 /* EEPROM SW RST enable flag */
-
-#define PCH_I2CSADR 0x00 /* I2C slave address register */
-#define PCH_I2CCTL 0x04 /* I2C control register */
-#define PCH_I2CSR 0x08 /* I2C status register */
-#define PCH_I2CDR 0x0C /* I2C data register */
-#define PCH_I2CMON 0x10 /* I2C bus monitor register */
-#define PCH_I2CBC 0x14 /* I2C bus transfer rate setup counter */
-#define PCH_I2CMOD 0x18 /* I2C mode register */
-#define PCH_I2CBUFSLV 0x1C /* I2C buffer mode slave address register */
-#define PCH_I2CBUFSUB 0x20 /* I2C buffer mode subaddress register */
-#define PCH_I2CBUFFOR 0x24 /* I2C buffer mode format register */
-#define PCH_I2CBUFCTL 0x28 /* I2C buffer mode control register */
-#define PCH_I2CBUFMSK 0x2C /* I2C buffer mode interrupt mask register */
-#define PCH_I2CBUFSTA 0x30 /* I2C buffer mode status register */
-#define PCH_I2CBUFLEV 0x34 /* I2C buffer mode level register */
-#define PCH_I2CESRFOR 0x38 /* EEPROM software reset mode format register */
-#define PCH_I2CESRCTL 0x3C /* EEPROM software reset mode ctrl register */
-#define PCH_I2CESRMSK 0x40 /* EEPROM software reset mode */
-#define PCH_I2CESRSTA 0x44 /* EEPROM software reset mode status register */
-#define PCH_I2CTMR 0x48 /* I2C timer register */
-#define PCH_I2CSRST 0xFC /* I2C reset register */
-#define PCH_I2CNF 0xF8 /* I2C noise filter register */
-
-#define BUS_IDLE_TIMEOUT 20
-#define PCH_I2CCTL_I2CMEN 0x0080
-#define TEN_BIT_ADDR_DEFAULT 0xF000
-#define TEN_BIT_ADDR_MASK 0xF0
-#define PCH_START 0x0020
-#define PCH_RESTART 0x0004
-#define PCH_ESR_START 0x0001
-#define PCH_BUFF_START 0x1
-#define PCH_REPSTART 0x0004
-#define PCH_ACK 0x0008
-#define PCH_GETACK 0x0001
-#define CLR_REG 0x0
-#define I2C_RD 0x1
-#define I2CMCF_BIT 0x0080
-#define I2CMIF_BIT 0x0002
-#define I2CMAL_BIT 0x0010
-#define I2CBMFI_BIT 0x0001
-#define I2CBMAL_BIT 0x0002
-#define I2CBMNA_BIT 0x0004
-#define I2CBMTO_BIT 0x0008
-#define I2CBMIS_BIT 0x0010
-#define I2CESRFI_BIT 0X0001
-#define I2CESRTO_BIT 0x0002
-#define I2CESRFIIE_BIT 0x1
-#define I2CESRTOIE_BIT 0x2
-#define I2CBMDZ_BIT 0x0040
-#define I2CBMAG_BIT 0x0020
-#define I2CMBB_BIT 0x0020
-#define BUFFER_MODE_MASK (I2CBMFI_BIT | I2CBMAL_BIT | I2CBMNA_BIT | \
- I2CBMTO_BIT | I2CBMIS_BIT)
-#define I2C_ADDR_MSK 0xFF
-#define I2C_MSB_2B_MSK 0x300
-#define FAST_MODE_CLK 400
-#define FAST_MODE_EN 0x0001
-#define SUB_ADDR_LEN_MAX 4
-#define BUF_LEN_MAX 32
-#define PCH_BUFFER_MODE 0x1
-#define EEPROM_SW_RST_MODE 0x0002
-#define NORMAL_INTR_ENBL 0x0300
-#define EEPROM_RST_INTR_ENBL (I2CESRFIIE_BIT | I2CESRTOIE_BIT)
-#define EEPROM_RST_INTR_DISBL 0x0
-#define BUFFER_MODE_INTR_ENBL 0x001F
-#define BUFFER_MODE_INTR_DISBL 0x0
-#define NORMAL_MODE 0x0
-#define BUFFER_MODE 0x1
-#define EEPROM_SR_MODE 0x2
-#define I2C_TX_MODE 0x0010
-#define PCH_BUF_TX 0xFFF7
-#define PCH_BUF_RD 0x0008
-#define I2C_ERROR_MASK (I2CESRTO_EVENT | I2CBMIS_EVENT | I2CBMTO_EVENT | \
- I2CBMNA_EVENT | I2CBMAL_EVENT | I2CMAL_EVENT)
-#define I2CMAL_EVENT 0x0001
-#define I2CMCF_EVENT 0x0002
-#define I2CBMFI_EVENT 0x0004
-#define I2CBMAL_EVENT 0x0008
-#define I2CBMNA_EVENT 0x0010
-#define I2CBMTO_EVENT 0x0020
-#define I2CBMIS_EVENT 0x0040
-#define I2CESRFI_EVENT 0x0080
-#define I2CESRTO_EVENT 0x0100
-#define PCI_DEVICE_ID_PCH_I2C 0x8817
-
-#define pch_dbg(adap, fmt, arg...) \
- dev_dbg(adap->pch_adapter.dev.parent, "%s :" fmt, __func__, ##arg)
-
-#define pch_err(adap, fmt, arg...) \
- dev_err(adap->pch_adapter.dev.parent, "%s :" fmt, __func__, ##arg)
-
-#define pch_pci_err(pdev, fmt, arg...) \
- dev_err(&pdev->dev, "%s :" fmt, __func__, ##arg)
-
-#define pch_pci_dbg(pdev, fmt, arg...) \
- dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
-
-/*
-Set the number of I2C instance max
-Intel EG20T PCH : 1ch
-LAPIS Semiconductor ML7213 IOH : 2ch
-LAPIS Semiconductor ML7831 IOH : 1ch
-*/
-#define PCH_I2C_MAX_DEV 2
-
-/**
- * struct i2c_algo_pch_data - for I2C driver functionalities
- * @pch_adapter: stores the reference to i2c_adapter structure
- * @p_adapter_info: stores the reference to adapter_info structure
- * @pch_base_address: specifies the remapped base address
- * @pch_buff_mode_en: specifies if buffer mode is enabled
- * @pch_event_flag: specifies occurrence of interrupt events
- * @pch_i2c_xfer_in_progress: specifies whether the transfer is completed
- */
-struct i2c_algo_pch_data {
- struct i2c_adapter pch_adapter;
- struct adapter_info *p_adapter_info;
- void __iomem *pch_base_address;
- int pch_buff_mode_en;
- u32 pch_event_flag;
- bool pch_i2c_xfer_in_progress;
-};
-
-/**
- * struct adapter_info - This structure holds the adapter information for the
- PCH i2c controller
- * @pch_data: stores a list of i2c_algo_pch_data
- * @pch_i2c_suspended: specifies whether the system is suspended or not
- * perhaps with more lines and words.
- * @ch_num: specifies the number of i2c instance
- *
- * pch_data has as many elements as maximum I2C channels
- */
-struct adapter_info {
- struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
- bool pch_i2c_suspended;
- int ch_num;
-};
-
-
-static int pch_i2c_speed = 100; /* I2C bus speed in Kbps */
-static int pch_clk = 50000; /* specifies I2C clock speed in KHz */
-static wait_queue_head_t pch_event;
-static DEFINE_MUTEX(pch_mutex);
-
-/* Definition for ML7213 by LAPIS Semiconductor */
-#define PCI_VENDOR_ID_ROHM 0x10DB
-#define PCI_DEVICE_ID_ML7213_I2C 0x802D
-#define PCI_DEVICE_ID_ML7223_I2C 0x8010
-#define PCI_DEVICE_ID_ML7831_I2C 0x8817
-
-static DEFINE_PCI_DEVICE_TABLE(pch_pcidev_id) = {
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_I2C), 1, },
- {0,}
-};
-
-static irqreturn_t pch_i2c_handler(int irq, void *pData);
-
-static inline void pch_setbit(void __iomem *addr, u32 offset, u32 bitmask)
-{
- u32 val;
- val = ioread32(addr + offset);
- val |= bitmask;
- iowrite32(val, addr + offset);
-}
-
-static inline void pch_clrbit(void __iomem *addr, u32 offset, u32 bitmask)
-{
- u32 val;
- val = ioread32(addr + offset);
- val &= (~bitmask);
- iowrite32(val, addr + offset);
-}
-
-/**
- * pch_i2c_init() - hardware initialization of I2C module
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_init(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- u32 pch_i2cbc;
- u32 pch_i2ctmr;
- u32 reg_value;
-
- /* reset I2C controller */
- iowrite32(0x01, p + PCH_I2CSRST);
- msleep(20);
- iowrite32(0x0, p + PCH_I2CSRST);
-
- /* Initialize I2C registers */
- iowrite32(0x21, p + PCH_I2CNF);
-
- pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_I2CCTL_I2CMEN);
-
- if (pch_i2c_speed != 400)
- pch_i2c_speed = 100;
-
- reg_value = PCH_I2CCTL_I2CMEN;
- if (pch_i2c_speed == FAST_MODE_CLK) {
- reg_value |= FAST_MODE_EN;
- pch_dbg(adap, "Fast mode enabled\n");
- }
-
- if (pch_clk > PCH_MAX_CLK)
- pch_clk = 62500;
-
- pch_i2cbc = (pch_clk + (pch_i2c_speed * 4)) / (pch_i2c_speed * 8);
- /* Set transfer speed in I2CBC */
- iowrite32(pch_i2cbc, p + PCH_I2CBC);
-
- pch_i2ctmr = (pch_clk) / 8;
- iowrite32(pch_i2ctmr, p + PCH_I2CTMR);
-
- reg_value |= NORMAL_INTR_ENBL; /* Enable interrupts in normal mode */
- iowrite32(reg_value, p + PCH_I2CCTL);
-
- pch_dbg(adap,
- "I2CCTL=%x pch_i2cbc=%x pch_i2ctmr=%x Enable interrupts\n",
- ioread32(p + PCH_I2CCTL), pch_i2cbc, pch_i2ctmr);
-
- init_waitqueue_head(&pch_event);
-}
-
-static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
-{
- return cmp1.tv64 < cmp2.tv64;
-}
-
-/**
- * pch_i2c_wait_for_bus_idle() - check the status of bus.
- * @adap: Pointer to struct i2c_algo_pch_data.
- * @timeout: waiting time counter (ms).
- */
-static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
- s32 timeout)
-{
- void __iomem *p = adap->pch_base_address;
- int schedule = 0;
- unsigned long end = jiffies + msecs_to_jiffies(timeout);
-
- while (ioread32(p + PCH_I2CSR) & I2CMBB_BIT) {
- if (time_after(jiffies, end)) {
- pch_dbg(adap, "I2CSR = %x\n", ioread32(p + PCH_I2CSR));
- pch_err(adap, "%s: Timeout Error.return%d\n",
- __func__, -ETIME);
- pch_i2c_init(adap);
-
- return -ETIME;
- }
-
- if (!schedule)
- /* Retry after some usecs */
- udelay(5);
- else
- /* Wait a bit more without consuming CPU */
- usleep_range(20, 1000);
-
- schedule = 1;
- }
-
- return 0;
-}
-
-/**
- * pch_i2c_start() - Generate I2C start condition in normal mode.
- * @adap: Pointer to struct i2c_algo_pch_data.
- *
- * Generate I2C start condition in normal mode by setting I2CCTL.I2CMSTA to 1.
- */
-static void pch_i2c_start(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
- pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
-}
-
-/**
- * pch_i2c_wait_for_xfer_complete() - initiates a wait for the tx complete event
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
-{
- long ret;
- ret = wait_event_timeout(pch_event,
- (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
-
- if (ret == 0) {
- pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
- adap->pch_event_flag = 0;
- return -ETIMEDOUT;
- }
-
- if (adap->pch_event_flag & I2C_ERROR_MASK) {
- pch_err(adap, "error bits set: %x\n", adap->pch_event_flag);
- adap->pch_event_flag = 0;
- return -EIO;
- }
-
- adap->pch_event_flag = 0;
-
- return 0;
-}
-
-/**
- * pch_i2c_getack() - to confirm ACK/NACK
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static s32 pch_i2c_getack(struct i2c_algo_pch_data *adap)
-{
- u32 reg_val;
- void __iomem *p = adap->pch_base_address;
- reg_val = ioread32(p + PCH_I2CSR) & PCH_GETACK;
-
- if (reg_val != 0) {
- pch_err(adap, "return%d\n", -EPROTO);
- return -EPROTO;
- }
-
- return 0;
-}
-
-/**
- * pch_i2c_stop() - generate stop condition in normal mode.
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_stop(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
- /* clear the start bit */
- pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
-}
-
-/**
- * pch_i2c_repstart() - generate repeated start condition in normal mode
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_repstart(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
- pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_REPSTART);
-}
-
-/**
- * pch_i2c_writebytes() - write data to I2C bus in normal mode
- * @i2c_adap: Pointer to the struct i2c_adapter.
- * @last: specifies whether last message or not.
- * In the case of compound mode it will be 1 for last message,
- * otherwise 0.
- * @first: specifies whether first message or not.
- * 1 for first message otherwise 0.
- */
-static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, u32 last, u32 first)
-{
- struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
- u8 *buf;
- u32 length;
- u32 addr;
- u32 addr_2_msb;
- u32 addr_8_lsb;
- s32 wrcount;
- s32 rtn;
- void __iomem *p = adap->pch_base_address;
-
- length = msgs->len;
- buf = msgs->buf;
- addr = msgs->addr;
-
- /* enable master tx */
- pch_setbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);
-
- pch_dbg(adap, "I2CCTL = %x msgs->len = %d\n", ioread32(p + PCH_I2CCTL),
- length);
-
- if (first) {
- if (pch_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -ETIME)
- return -ETIME;
- }
-
- if (msgs->flags & I2C_M_TEN) {
- addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7) & 0x06;
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
- if (first)
- pch_i2c_start(adap);
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave address"
- "setting\n");
- return -EIO;
- }
- addr_8_lsb = (addr & I2C_ADDR_MSK);
- iowrite32(addr_8_lsb, p + PCH_I2CDR);
- } else if (rtn == -EIO) { /* Arbitration Lost */
- pch_err(adap, "Lost Arbitration\n");
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMAL_BIT);
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMIF_BIT);
- pch_i2c_init(adap);
- return -EAGAIN;
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
- } else {
- /* set 7 bit slave address and R/W bit as 0 */
- iowrite32(addr << 1, p + PCH_I2CDR);
- if (first)
- pch_i2c_start(adap);
- }
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave address"
- "setting\n");
- return -EIO;
- }
- } else if (rtn == -EIO) { /* Arbitration Lost */
- pch_err(adap, "Lost Arbitration\n");
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT);
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
- pch_i2c_init(adap);
- return -EAGAIN;
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
-
- for (wrcount = 0; wrcount < length; ++wrcount) {
- /* write buffer value to I2C data register */
- iowrite32(buf[wrcount], p + PCH_I2CDR);
- pch_dbg(adap, "writing %x to Data register\n", buf[wrcount]);
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave address"
- "setting\n");
- return -EIO;
- }
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMCF_BIT);
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMIF_BIT);
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
- }
-
- /* check if this is the last message */
- if (last)
- pch_i2c_stop(adap);
- else
- pch_i2c_repstart(adap);
-
- pch_dbg(adap, "return=%d\n", wrcount);
-
- return wrcount;
-}
-
-/**
- * pch_i2c_sendack() - send ACK
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_sendack(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
- pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_ACK);
-}
-
-/**
- * pch_i2c_sendnack() - send NACK
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_sendnack(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
- pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_ACK);
-}
-
-/**
- * pch_i2c_restart() - Generate I2C restart condition in normal mode.
- * @adap: Pointer to struct i2c_algo_pch_data.
- *
- * Generate I2C restart condition in normal mode by setting I2CCTL.I2CRSTA.
- */
-static void pch_i2c_restart(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
- pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
- pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_RESTART);
-}
-
-/**
- * pch_i2c_readbytes() - read data from I2C bus in normal mode.
- * @i2c_adap: Pointer to the struct i2c_adapter.
- * @msgs: Pointer to i2c_msg structure.
- * @last: specifies whether last message or not.
- * @first: specifies whether first message or not.
- */
-static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- u32 last, u32 first)
-{
- struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
-
- u8 *buf;
- u32 count;
- u32 length;
- u32 addr;
- u32 addr_2_msb;
- u32 addr_8_lsb;
- void __iomem *p = adap->pch_base_address;
- s32 rtn;
-
- length = msgs->len;
- buf = msgs->buf;
- addr = msgs->addr;
-
- /* enable master reception */
- pch_clrbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);
-
- if (first) {
- if (pch_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -ETIME)
- return -ETIME;
- }
-
- if (msgs->flags & I2C_M_TEN) {
- addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7);
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
- if (first)
- pch_i2c_start(adap);
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave address"
- "setting\n");
- return -EIO;
- }
- addr_8_lsb = (addr & I2C_ADDR_MSK);
- iowrite32(addr_8_lsb, p + PCH_I2CDR);
- } else if (rtn == -EIO) { /* Arbitration Lost */
- pch_err(adap, "Lost Arbitration\n");
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMAL_BIT);
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMIF_BIT);
- pch_i2c_init(adap);
- return -EAGAIN;
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
- pch_i2c_restart(adap);
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave address"
- "setting\n");
- return -EIO;
- }
- addr_2_msb |= I2C_RD;
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK,
- p + PCH_I2CDR);
- } else if (rtn == -EIO) { /* Arbitration Lost */
- pch_err(adap, "Lost Arbitration\n");
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMAL_BIT);
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
- I2CMIF_BIT);
- pch_i2c_init(adap);
- return -EAGAIN;
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
- } else {
- /* 7 address bits + R/W bit */
- addr = (((addr) << 1) | (I2C_RD));
- iowrite32(addr, p + PCH_I2CDR);
- }
-
- /* check if it is the first message */
- if (first)
- pch_i2c_start(adap);
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave address"
- "setting\n");
- return -EIO;
- }
- } else if (rtn == -EIO) { /* Arbitration Lost */
- pch_err(adap, "Lost Arbitration\n");
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT);
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
- pch_i2c_init(adap);
- return -EAGAIN;
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
-
- if (length == 0) {
- pch_i2c_stop(adap);
- ioread32(p + PCH_I2CDR); /* Dummy read needs */
-
- count = length;
- } else {
- int read_index;
- int loop;
- pch_i2c_sendack(adap);
-
- /* Dummy read */
- for (loop = 1, read_index = 0; loop < length; loop++) {
- buf[read_index] = ioread32(p + PCH_I2CDR);
-
- if (loop != 1)
- read_index++;
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave"
- "address setting\n");
- return -EIO;
- }
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
-
- } /* end for */
-
- pch_i2c_sendnack(adap);
-
- buf[read_index] = ioread32(p + PCH_I2CDR); /* Read final - 1 */
-
- if (length != 1)
- read_index++;
-
- rtn = pch_i2c_wait_for_xfer_complete(adap);
- if (rtn == 0) {
- if (pch_i2c_getack(adap)) {
- pch_dbg(adap, "Receive NACK for slave"
- "address setting\n");
- return -EIO;
- }
- } else { /* wait-event timeout */
- pch_i2c_stop(adap);
- return -ETIME;
- }
-
- if (last)
- pch_i2c_stop(adap);
- else
- pch_i2c_repstart(adap);
-
- buf[read_index++] = ioread32(p + PCH_I2CDR); /* Read Final */
- count = read_index;
- }
-
- return count;
-}
-
-/**
- * pch_i2c_cb() - Interrupt handler Call back function
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_cb(struct i2c_algo_pch_data *adap)
-{
- u32 sts;
- void __iomem *p = adap->pch_base_address;
-
- sts = ioread32(p + PCH_I2CSR);
- sts &= (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT);
- if (sts & I2CMAL_BIT)
- adap->pch_event_flag |= I2CMAL_EVENT;
-
- if (sts & I2CMCF_BIT)
- adap->pch_event_flag |= I2CMCF_EVENT;
-
- /* clear the applicable bits */
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, sts);
-
- pch_dbg(adap, "PCH_I2CSR = %x\n", ioread32(p + PCH_I2CSR));
-
- wake_up(&pch_event);
-}
-
-/**
- * pch_i2c_handler() - interrupt handler for the PCH I2C controller
- * @irq: irq number.
- * @pData: cookie passed back to the handler function.
- */
-static irqreturn_t pch_i2c_handler(int irq, void *pData)
-{
- u32 reg_val;
- int flag;
- int i;
- struct adapter_info *adap_info = pData;
- void __iomem *p;
- u32 mode;
-
- for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
- p = adap_info->pch_data[i].pch_base_address;
- mode = ioread32(p + PCH_I2CMOD);
- mode &= BUFFER_MODE | EEPROM_SR_MODE;
- if (mode != NORMAL_MODE) {
- pch_err(adap_info->pch_data,
- "I2C-%d mode(%d) is not supported\n", mode, i);
- continue;
- }
- reg_val = ioread32(p + PCH_I2CSR);
- if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT)) {
- pch_i2c_cb(&adap_info->pch_data[i]);
- flag = 1;
- }
- }
-
- return flag ? IRQ_HANDLED : IRQ_NONE;
-}
-
-/**
- * pch_i2c_xfer() - Reading adnd writing data through I2C bus
- * @i2c_adap: Pointer to the struct i2c_adapter.
- * @msgs: Pointer to i2c_msg structure.
- * @num: number of messages.
- */
-static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, s32 num)
-{
- struct i2c_msg *pmsg;
- u32 i = 0;
- u32 status;
- s32 ret;
-
- struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
-
- ret = mutex_lock_interruptible(&pch_mutex);
- if (ret)
- return -ERESTARTSYS;
-
- if (adap->p_adapter_info->pch_i2c_suspended) {
- mutex_unlock(&pch_mutex);
- return -EBUSY;
- }
-
- pch_dbg(adap, "adap->p_adapter_info->pch_i2c_suspended is %d\n",
- adap->p_adapter_info->pch_i2c_suspended);
- /* transfer not completed */
- adap->pch_i2c_xfer_in_progress = true;
-
- for (i = 0; i < num && ret >= 0; i++) {
- pmsg = &msgs[i];
- pmsg->flags |= adap->pch_buff_mode_en;
- status = pmsg->flags;
- pch_dbg(adap,
- "After invoking I2C_MODE_SEL :flag= 0x%x\n", status);
-
- if ((status & (I2C_M_RD)) != false) {
- ret = pch_i2c_readbytes(i2c_adap, pmsg, (i + 1 == num),
- (i == 0));
- } else {
- ret = pch_i2c_writebytes(i2c_adap, pmsg, (i + 1 == num),
- (i == 0));
- }
- }
-
- adap->pch_i2c_xfer_in_progress = false; /* transfer completed */
-
- mutex_unlock(&pch_mutex);
-
- return (ret < 0) ? ret : num;
-}
-
-/**
- * pch_i2c_func() - return the functionality of the I2C driver
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static u32 pch_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
-}
-
-static struct i2c_algorithm pch_algorithm = {
- .master_xfer = pch_i2c_xfer,
- .functionality = pch_i2c_func
-};
-
-/**
- * pch_i2c_disbl_int() - Disable PCH I2C interrupts
- * @adap: Pointer to struct i2c_algo_pch_data.
- */
-static void pch_i2c_disbl_int(struct i2c_algo_pch_data *adap)
-{
- void __iomem *p = adap->pch_base_address;
-
- pch_clrbit(adap->pch_base_address, PCH_I2CCTL, NORMAL_INTR_ENBL);
-
- iowrite32(EEPROM_RST_INTR_DISBL, p + PCH_I2CESRMSK);
-
- iowrite32(BUFFER_MODE_INTR_DISBL, p + PCH_I2CBUFMSK);
-}
-
-static int __devinit pch_i2c_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- void __iomem *base_addr;
- int ret;
- int i, j;
- struct adapter_info *adap_info;
- struct i2c_adapter *pch_adap;
-
- pch_pci_dbg(pdev, "Entered.\n");
-
- adap_info = kzalloc((sizeof(struct adapter_info)), GFP_KERNEL);
- if (adap_info == NULL) {
- pch_pci_err(pdev, "Memory allocation FAILED\n");
- return -ENOMEM;
- }
-
- ret = pci_enable_device(pdev);
- if (ret) {
- pch_pci_err(pdev, "pci_enable_device FAILED\n");
- goto err_pci_enable;
- }
-
- ret = pci_request_regions(pdev, KBUILD_MODNAME);
- if (ret) {
- pch_pci_err(pdev, "pci_request_regions FAILED\n");
- goto err_pci_req;
- }
-
- base_addr = pci_iomap(pdev, 1, 0);
-
- if (base_addr == NULL) {
- pch_pci_err(pdev, "pci_iomap FAILED\n");
- ret = -ENOMEM;
- goto err_pci_iomap;
- }
-
- /* Set the number of I2C channel instance */
- adap_info->ch_num = id->driver_data;
-
- ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
- KBUILD_MODNAME, adap_info);
- if (ret) {
- pch_pci_err(pdev, "request_irq FAILED\n");
- goto err_request_irq;
- }
-
- for (i = 0; i < adap_info->ch_num; i++) {
- pch_adap = &adap_info->pch_data[i].pch_adapter;
- adap_info->pch_i2c_suspended = false;
-
- adap_info->pch_data[i].p_adapter_info = adap_info;
-
- pch_adap->owner = THIS_MODULE;
- pch_adap->class = I2C_CLASS_HWMON;
- strcpy(pch_adap->name, KBUILD_MODNAME);
- pch_adap->algo = &pch_algorithm;
- pch_adap->algo_data = &adap_info->pch_data[i];
-
- /* base_addr + offset; */
- adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
-
- pch_adap->dev.parent = &pdev->dev;
-
- pch_i2c_init(&adap_info->pch_data[i]);
-
- pch_adap->nr = i;
- ret = i2c_add_numbered_adapter(pch_adap);
- if (ret) {
- pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
- goto err_add_adapter;
- }
- }
-
- pci_set_drvdata(pdev, adap_info);
- pch_pci_dbg(pdev, "returns %d.\n", ret);
- return 0;
-
-err_add_adapter:
- for (j = 0; j < i; j++)
- i2c_del_adapter(&adap_info->pch_data[j].pch_adapter);
- free_irq(pdev->irq, adap_info);
-err_request_irq:
- pci_iounmap(pdev, base_addr);
-err_pci_iomap:
- pci_release_regions(pdev);
-err_pci_req:
- pci_disable_device(pdev);
-err_pci_enable:
- kfree(adap_info);
- return ret;
-}
-
-static void __devexit pch_i2c_remove(struct pci_dev *pdev)
-{
- int i;
- struct adapter_info *adap_info = pci_get_drvdata(pdev);
-
- free_irq(pdev->irq, adap_info);
-
- for (i = 0; i < adap_info->ch_num; i++) {
- pch_i2c_disbl_int(&adap_info->pch_data[i]);
- i2c_del_adapter(&adap_info->pch_data[i].pch_adapter);
- }
-
- if (adap_info->pch_data[0].pch_base_address)
- pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
-
- for (i = 0; i < adap_info->ch_num; i++)
- adap_info->pch_data[i].pch_base_address = 0;
-
- pci_set_drvdata(pdev, NULL);
-
- pci_release_regions(pdev);
-
- pci_disable_device(pdev);
- kfree(adap_info);
-}
-
-#ifdef CONFIG_PM
-static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- int ret;
- int i;
- struct adapter_info *adap_info = pci_get_drvdata(pdev);
- void __iomem *p = adap_info->pch_data[0].pch_base_address;
-
- adap_info->pch_i2c_suspended = true;
-
- for (i = 0; i < adap_info->ch_num; i++) {
- while ((adap_info->pch_data[i].pch_i2c_xfer_in_progress)) {
- /* Wait until all channel transfers are completed */
- msleep(20);
- }
- }
-
- /* Disable the i2c interrupts */
- for (i = 0; i < adap_info->ch_num; i++)
- pch_i2c_disbl_int(&adap_info->pch_data[i]);
-
- pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
- "invoked function pch_i2c_disbl_int successfully\n",
- ioread32(p + PCH_I2CSR), ioread32(p + PCH_I2CBUFSTA),
- ioread32(p + PCH_I2CESRSTA));
-
- ret = pci_save_state(pdev);
-
- if (ret) {
- pch_pci_err(pdev, "pci_save_state\n");
- return ret;
- }
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static int pch_i2c_resume(struct pci_dev *pdev)
-{
- int i;
- struct adapter_info *adap_info = pci_get_drvdata(pdev);
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- if (pci_enable_device(pdev) < 0) {
- pch_pci_err(pdev, "pch_i2c_resume:pci_enable_device FAILED\n");
- return -EIO;
- }
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
-
- for (i = 0; i < adap_info->ch_num; i++)
- pch_i2c_init(&adap_info->pch_data[i]);
-
- adap_info->pch_i2c_suspended = false;
-
- return 0;
-}
-#else
-#define pch_i2c_suspend NULL
-#define pch_i2c_resume NULL
-#endif
-
-static struct pci_driver pch_pcidriver = {
- .name = KBUILD_MODNAME,
- .id_table = pch_pcidev_id,
- .probe = pch_i2c_probe,
- .remove = __devexit_p(pch_i2c_remove),
- .suspend = pch_i2c_suspend,
- .resume = pch_i2c_resume
-};
-
-static int __init pch_pci_init(void)
-{
- return pci_register_driver(&pch_pcidriver);
-}
-module_init(pch_pci_init);
-
-static void __exit pch_pci_exit(void)
-{
- pci_unregister_driver(&pch_pcidriver);
-}
-module_exit(pch_pci_exit);
-
-MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tomoya MORINAGA. <tomoya.rohm@gmail.com>");
-module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
-module_param(pch_clk, int, (S_IRUSR | S_IWUSR));
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-elektor.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-elektor.c
deleted file mode 100644
index 37e2e82a..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-elektor.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 1995-97 Simon G. Vogl
- 1998-99 Hans Berglund
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
- Frodo Looijaard <frodol@dds.nl> */
-
-/* Partially rewriten by Oleg I. Vdovikin for mmapped support of
- for Alpha Processor Inc. UP-2000(+) boards */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/wait.h>
-
-#include <linux/isa.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-pcf.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-
-#include "../algos/i2c-algo-pcf.h"
-
-#define DEFAULT_BASE 0x330
-
-static int base;
-static u8 __iomem *base_iomem;
-
-static int irq;
-static int clock = 0x1c;
-static int own = 0x55;
-static int mmapped;
-
-/* vdovikin: removed static struct i2c_pcf_isa gpi; code -
- this module in real supports only one device, due to missing arguments
- in some functions, called from the algo-pcf module. Sometimes it's
- need to be rewriten - but for now just remove this for simpler reading */
-
-static wait_queue_head_t pcf_wait;
-static int pcf_pending;
-static spinlock_t lock;
-
-static struct i2c_adapter pcf_isa_ops;
-
-/* ----- local functions ---------------------------------------------- */
-
-static void pcf_isa_setbyte(void *data, int ctl, int val)
-{
- u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem;
-
- /* enable irq if any specified for serial operation */
- if (ctl && irq && (val & I2C_PCF_ESO)) {
- val |= I2C_PCF_ENI;
- }
-
- pr_debug("%s: Write %p 0x%02X\n", pcf_isa_ops.name, address, val);
- iowrite8(val, address);
-#ifdef __alpha__
- /* API UP2000 needs some hardware fudging to make the write stick */
- iowrite8(val, address);
-#endif
-}
-
-static int pcf_isa_getbyte(void *data, int ctl)
-{
- u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem;
- int val = ioread8(address);
-
- pr_debug("%s: Read %p 0x%02X\n", pcf_isa_ops.name, address, val);
- return (val);
-}
-
-static int pcf_isa_getown(void *data)
-{
- return (own);
-}
-
-
-static int pcf_isa_getclock(void *data)
-{
- return (clock);
-}
-
-static void pcf_isa_waitforpin(void *data)
-{
- DEFINE_WAIT(wait);
- int timeout = 2;
- unsigned long flags;
-
- if (irq > 0) {
- spin_lock_irqsave(&lock, flags);
- if (pcf_pending == 0) {
- spin_unlock_irqrestore(&lock, flags);
- prepare_to_wait(&pcf_wait, &wait, TASK_INTERRUPTIBLE);
- if (schedule_timeout(timeout*HZ)) {
- spin_lock_irqsave(&lock, flags);
- if (pcf_pending == 1) {
- pcf_pending = 0;
- }
- spin_unlock_irqrestore(&lock, flags);
- }
- finish_wait(&pcf_wait, &wait);
- } else {
- pcf_pending = 0;
- spin_unlock_irqrestore(&lock, flags);
- }
- } else {
- udelay(100);
- }
-}
-
-
-static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id) {
- spin_lock(&lock);
- pcf_pending = 1;
- spin_unlock(&lock);
- wake_up_interruptible(&pcf_wait);
- return IRQ_HANDLED;
-}
-
-
-static int pcf_isa_init(void)
-{
- spin_lock_init(&lock);
- if (!mmapped) {
- if (!request_region(base, 2, pcf_isa_ops.name)) {
- printk(KERN_ERR "%s: requested I/O region (%#x:2) is "
- "in use\n", pcf_isa_ops.name, base);
- return -ENODEV;
- }
- base_iomem = ioport_map(base, 2);
- if (!base_iomem) {
- printk(KERN_ERR "%s: remap of I/O region %#x failed\n",
- pcf_isa_ops.name, base);
- release_region(base, 2);
- return -ENODEV;
- }
- } else {
- if (!request_mem_region(base, 2, pcf_isa_ops.name)) {
- printk(KERN_ERR "%s: requested memory region (%#x:2) "
- "is in use\n", pcf_isa_ops.name, base);
- return -ENODEV;
- }
- base_iomem = ioremap(base, 2);
- if (base_iomem == NULL) {
- printk(KERN_ERR "%s: remap of memory region %#x "
- "failed\n", pcf_isa_ops.name, base);
- release_mem_region(base, 2);
- return -ENODEV;
- }
- }
- pr_debug("%s: registers %#x remapped to %p\n", pcf_isa_ops.name, base,
- base_iomem);
-
- if (irq > 0) {
- if (request_irq(irq, pcf_isa_handler, 0, pcf_isa_ops.name,
- NULL) < 0) {
- printk(KERN_ERR "%s: Request irq%d failed\n",
- pcf_isa_ops.name, irq);
- irq = 0;
- } else
- enable_irq(irq);
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_pcf_data pcf_isa_data = {
- .setpcf = pcf_isa_setbyte,
- .getpcf = pcf_isa_getbyte,
- .getown = pcf_isa_getown,
- .getclock = pcf_isa_getclock,
- .waitforpin = pcf_isa_waitforpin,
-};
-
-static struct i2c_adapter pcf_isa_ops = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo_data = &pcf_isa_data,
- .name = "i2c-elektor",
-};
-
-static int __devinit elektor_match(struct device *dev, unsigned int id)
-{
-#ifdef __alpha__
- /* check to see we have memory mapped PCF8584 connected to the
- Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
- if (base == 0) {
- struct pci_dev *cy693_dev;
-
- cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ,
- PCI_DEVICE_ID_CONTAQ_82C693, NULL);
- if (cy693_dev) {
- unsigned char config;
- /* yeap, we've found cypress, let's check config */
- if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
-
- dev_dbg(dev, "found cy82c693, config "
- "register 0x47 = 0x%02x\n", config);
-
- /* UP2000 board has this register set to 0xe1,
- but the most significant bit as seems can be
- reset during the proper initialisation
- sequence if guys from API decides to do that
- (so, we can even enable Tsunami Pchip
- window for the upper 1 Gb) */
-
- /* so just check for ROMCS at 0xe0000,
- ROMCS enabled for writes
- and external XD Bus buffer in use. */
- if ((config & 0x7f) == 0x61) {
- /* seems to be UP2000 like board */
- base = 0xe0000;
- mmapped = 1;
- /* UP2000 drives ISA with
- 8.25 MHz (PCI/4) clock
- (this can be read from cypress) */
- clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
- dev_info(dev, "found API UP2000 like "
- "board, will probe PCF8584 "
- "later\n");
- }
- }
- pci_dev_put(cy693_dev);
- }
- }
-#endif
-
- /* sanity checks for mmapped I/O */
- if (mmapped && base < 0xc8000) {
- dev_err(dev, "incorrect base address (%#x) specified "
- "for mmapped I/O\n", base);
- return 0;
- }
-
- if (base == 0) {
- base = DEFAULT_BASE;
- }
- return 1;
-}
-
-static int __devinit elektor_probe(struct device *dev, unsigned int id)
-{
- init_waitqueue_head(&pcf_wait);
- if (pcf_isa_init())
- return -ENODEV;
- pcf_isa_ops.dev.parent = dev;
- if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
- goto fail;
-
- dev_info(dev, "found device at %#x\n", base);
-
- return 0;
-
- fail:
- if (irq > 0) {
- disable_irq(irq);
- free_irq(irq, NULL);
- }
-
- if (!mmapped) {
- ioport_unmap(base_iomem);
- release_region(base, 2);
- } else {
- iounmap(base_iomem);
- release_mem_region(base, 2);
- }
- return -ENODEV;
-}
-
-static int __devexit elektor_remove(struct device *dev, unsigned int id)
-{
- i2c_del_adapter(&pcf_isa_ops);
-
- if (irq > 0) {
- disable_irq(irq);
- free_irq(irq, NULL);
- }
-
- if (!mmapped) {
- ioport_unmap(base_iomem);
- release_region(base, 2);
- } else {
- iounmap(base_iomem);
- release_mem_region(base, 2);
- }
-
- return 0;
-}
-
-static struct isa_driver i2c_elektor_driver = {
- .match = elektor_match,
- .probe = elektor_probe,
- .remove = __devexit_p(elektor_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = "i2c-elektor",
- },
-};
-
-static int __init i2c_pcfisa_init(void)
-{
- return isa_register_driver(&i2c_elektor_driver, 1);
-}
-
-static void __exit i2c_pcfisa_exit(void)
-{
- isa_unregister_driver(&i2c_elektor_driver);
-}
-
-MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
-MODULE_LICENSE("GPL");
-
-module_param(base, int, 0);
-module_param(irq, int, 0);
-module_param(clock, int, 0);
-module_param(own, int, 0);
-module_param(mmapped, int, 0);
-
-module_init(i2c_pcfisa_init);
-module_exit(i2c_pcfisa_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-gpio.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-gpio.c
deleted file mode 100644
index c0330a41..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-gpio.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Bitbanging I2C bus driver using the GPIO API
- *
- * Copyright (C) 2007 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/i2c-gpio.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
-
-struct i2c_gpio_private_data {
- struct i2c_adapter adap;
- struct i2c_algo_bit_data bit_data;
- struct i2c_gpio_platform_data pdata;
-};
-
-/* Toggle SDA by changing the direction of the pin */
-static void i2c_gpio_setsda_dir(void *data, int state)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- if (state)
- gpio_direction_input(pdata->sda_pin);
- else
- gpio_direction_output(pdata->sda_pin, 0);
-}
-
-/*
- * Toggle SDA by changing the output value of the pin. This is only
- * valid for pins configured as open drain (i.e. setting the value
- * high effectively turns off the output driver.)
- */
-static void i2c_gpio_setsda_val(void *data, int state)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- gpio_set_value(pdata->sda_pin, state);
-}
-
-/* Toggle SCL by changing the direction of the pin. */
-static void i2c_gpio_setscl_dir(void *data, int state)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- if (state)
- gpio_direction_input(pdata->scl_pin);
- else
- gpio_direction_output(pdata->scl_pin, 0);
-}
-
-/*
- * Toggle SCL by changing the output value of the pin. This is used
- * for pins that are configured as open drain and for output-only
- * pins. The latter case will break the i2c protocol, but it will
- * often work in practice.
- */
-static void i2c_gpio_setscl_val(void *data, int state)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- gpio_set_value(pdata->scl_pin, state);
-}
-
-static int i2c_gpio_getsda(void *data)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- return gpio_get_value(pdata->sda_pin);
-}
-
-static int i2c_gpio_getscl(void *data)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- return gpio_get_value(pdata->scl_pin);
-}
-
-static int __devinit of_i2c_gpio_probe(struct device_node *np,
- struct i2c_gpio_platform_data *pdata)
-{
- u32 reg;
-
- if (of_gpio_count(np) < 2)
- return -ENODEV;
-
- pdata->sda_pin = of_get_gpio(np, 0);
- pdata->scl_pin = of_get_gpio(np, 1);
-
- if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) {
- pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
- np->full_name, pdata->sda_pin, pdata->scl_pin);
- return -ENODEV;
- }
-
- of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
-
- if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
- pdata->timeout = msecs_to_jiffies(reg);
-
- pdata->sda_is_open_drain =
- of_property_read_bool(np, "i2c-gpio,sda-open-drain");
- pdata->scl_is_open_drain =
- of_property_read_bool(np, "i2c-gpio,scl-open-drain");
- pdata->scl_is_output_only =
- of_property_read_bool(np, "i2c-gpio,scl-output-only");
-
- return 0;
-}
-
-static int __devinit i2c_gpio_probe(struct platform_device *pdev)
-{
- struct i2c_gpio_private_data *priv;
- struct i2c_gpio_platform_data *pdata;
- struct i2c_algo_bit_data *bit_data;
- struct i2c_adapter *adap;
- int ret;
-
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- adap = &priv->adap;
- bit_data = &priv->bit_data;
- pdata = &priv->pdata;
-
- if (pdev->dev.of_node) {
- ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata);
- if (ret)
- return ret;
- } else {
- if (!pdev->dev.platform_data)
- return -ENXIO;
- memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
- }
-
- ret = gpio_request(pdata->sda_pin, "sda");
- if (ret)
- goto err_request_sda;
- ret = gpio_request(pdata->scl_pin, "scl");
- if (ret)
- goto err_request_scl;
-
- if (pdata->sda_is_open_drain) {
- gpio_direction_output(pdata->sda_pin, 1);
- bit_data->setsda = i2c_gpio_setsda_val;
- } else {
- gpio_direction_input(pdata->sda_pin);
- bit_data->setsda = i2c_gpio_setsda_dir;
- }
-
- if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
- gpio_direction_output(pdata->scl_pin, 1);
- bit_data->setscl = i2c_gpio_setscl_val;
- } else {
- gpio_direction_input(pdata->scl_pin);
- bit_data->setscl = i2c_gpio_setscl_dir;
- }
-
- if (!pdata->scl_is_output_only)
- bit_data->getscl = i2c_gpio_getscl;
- bit_data->getsda = i2c_gpio_getsda;
-
- if (pdata->udelay)
- bit_data->udelay = pdata->udelay;
- else if (pdata->scl_is_output_only)
- bit_data->udelay = 50; /* 10 kHz */
- else
- bit_data->udelay = 5; /* 100 kHz */
-
- if (pdata->timeout)
- bit_data->timeout = pdata->timeout;
- else
- bit_data->timeout = HZ / 10; /* 100 ms */
-
- bit_data->data = pdata;
-
- adap->owner = THIS_MODULE;
- snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
- adap->algo_data = bit_data;
- adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- adap->dev.parent = &pdev->dev;
- adap->dev.of_node = pdev->dev.of_node;
-
- /*
- * If "dev->id" is negative we consider it as zero.
- * The reason to do so is to avoid sysfs names that only make
- * sense when there are multiple adapters.
- */
- adap->nr = (pdev->id != -1) ? pdev->id : 0;
- ret = i2c_bit_add_numbered_bus(adap);
- if (ret)
- goto err_add_bus;
-
- of_i2c_register_devices(adap);
-
- platform_set_drvdata(pdev, priv);
-
- dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
- pdata->sda_pin, pdata->scl_pin,
- pdata->scl_is_output_only
- ? ", no clock stretching" : "");
-
- return 0;
-
-err_add_bus:
- gpio_free(pdata->scl_pin);
-err_request_scl:
- gpio_free(pdata->sda_pin);
-err_request_sda:
- return ret;
-}
-
-static int __devexit i2c_gpio_remove(struct platform_device *pdev)
-{
- struct i2c_gpio_private_data *priv;
- struct i2c_gpio_platform_data *pdata;
- struct i2c_adapter *adap;
-
- priv = platform_get_drvdata(pdev);
- adap = &priv->adap;
- pdata = &priv->pdata;
-
- i2c_del_adapter(adap);
- gpio_free(pdata->scl_pin);
- gpio_free(pdata->sda_pin);
-
- return 0;
-}
-
-#if defined(CONFIG_OF)
-static const struct of_device_id i2c_gpio_dt_ids[] = {
- { .compatible = "i2c-gpio", },
- { /* sentinel */ }
-};
-
-MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids);
-#endif
-
-static struct platform_driver i2c_gpio_driver = {
- .driver = {
- .name = "i2c-gpio",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(i2c_gpio_dt_ids),
- },
- .probe = i2c_gpio_probe,
- .remove = __devexit_p(i2c_gpio_remove),
-};
-
-static int __init i2c_gpio_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&i2c_gpio_driver);
- if (ret)
- printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
-
- return ret;
-}
-subsys_initcall(i2c_gpio_init);
-
-static void __exit i2c_gpio_exit(void)
-{
- platform_driver_unregister(&i2c_gpio_driver);
-}
-module_exit(i2c_gpio_exit);
-
-MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
-MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:i2c-gpio");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-highlander.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-highlander.c
deleted file mode 100644
index 19515df6..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-highlander.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Renesas Solutions Highlander FPGA I2C/SMBus support.
- *
- * Supported devices: R0P7780LC0011RL, R0P7785LC0011RL
- *
- * Copyright (C) 2008 Paul Mundt
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Copyright (C) 2008 Atom Create Engineering Co., Ltd.
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License version 2. See the file "COPYING" in the main directory
- * of this archive for more details.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/completion.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#define SMCR 0x00
-#define SMCR_START (1 << 0)
-#define SMCR_IRIC (1 << 1)
-#define SMCR_BBSY (1 << 2)
-#define SMCR_ACKE (1 << 3)
-#define SMCR_RST (1 << 4)
-#define SMCR_IEIC (1 << 6)
-
-#define SMSMADR 0x02
-
-#define SMMR 0x04
-#define SMMR_MODE0 (1 << 0)
-#define SMMR_MODE1 (1 << 1)
-#define SMMR_CAP (1 << 3)
-#define SMMR_TMMD (1 << 4)
-#define SMMR_SP (1 << 7)
-
-#define SMSADR 0x06
-#define SMTRDR 0x46
-
-struct highlander_i2c_dev {
- struct device *dev;
- void __iomem *base;
- struct i2c_adapter adapter;
- struct completion cmd_complete;
- unsigned long last_read_time;
- int irq;
- u8 *buf;
- size_t buf_len;
-};
-
-static bool iic_force_poll, iic_force_normal;
-static int iic_timeout = 1000, iic_read_delay;
-
-static inline void highlander_i2c_irq_enable(struct highlander_i2c_dev *dev)
-{
- iowrite16(ioread16(dev->base + SMCR) | SMCR_IEIC, dev->base + SMCR);
-}
-
-static inline void highlander_i2c_irq_disable(struct highlander_i2c_dev *dev)
-{
- iowrite16(ioread16(dev->base + SMCR) & ~SMCR_IEIC, dev->base + SMCR);
-}
-
-static inline void highlander_i2c_start(struct highlander_i2c_dev *dev)
-{
- iowrite16(ioread16(dev->base + SMCR) | SMCR_START, dev->base + SMCR);
-}
-
-static inline void highlander_i2c_done(struct highlander_i2c_dev *dev)
-{
- iowrite16(ioread16(dev->base + SMCR) | SMCR_IRIC, dev->base + SMCR);
-}
-
-static void highlander_i2c_setup(struct highlander_i2c_dev *dev)
-{
- u16 smmr;
-
- smmr = ioread16(dev->base + SMMR);
- smmr |= SMMR_TMMD;
-
- if (iic_force_normal)
- smmr &= ~SMMR_SP;
- else
- smmr |= SMMR_SP;
-
- iowrite16(smmr, dev->base + SMMR);
-}
-
-static void smbus_write_data(u8 *src, u16 *dst, int len)
-{
- for (; len > 1; len -= 2) {
- *dst++ = be16_to_cpup((__be16 *)src);
- src += 2;
- }
-
- if (len)
- *dst = *src << 8;
-}
-
-static void smbus_read_data(u16 *src, u8 *dst, int len)
-{
- for (; len > 1; len -= 2) {
- *(__be16 *)dst = cpu_to_be16p(src++);
- dst += 2;
- }
-
- if (len)
- *dst = *src >> 8;
-}
-
-static void highlander_i2c_command(struct highlander_i2c_dev *dev,
- u8 command, int len)
-{
- unsigned int i;
- u16 cmd = (command << 8) | command;
-
- for (i = 0; i < len; i += 2) {
- if (len - i == 1)
- cmd = command << 8;
- iowrite16(cmd, dev->base + SMSADR + i);
- dev_dbg(dev->dev, "command data[%x] 0x%04x\n", i/2, cmd);
- }
-}
-
-static int highlander_i2c_wait_for_bbsy(struct highlander_i2c_dev *dev)
-{
- unsigned long timeout;
-
- timeout = jiffies + msecs_to_jiffies(iic_timeout);
- while (ioread16(dev->base + SMCR) & SMCR_BBSY) {
- if (time_after(jiffies, timeout)) {
- dev_warn(dev->dev, "timeout waiting for bus ready\n");
- return -ETIMEDOUT;
- }
-
- msleep(1);
- }
-
- return 0;
-}
-
-static int highlander_i2c_reset(struct highlander_i2c_dev *dev)
-{
- iowrite16(ioread16(dev->base + SMCR) | SMCR_RST, dev->base + SMCR);
- return highlander_i2c_wait_for_bbsy(dev);
-}
-
-static int highlander_i2c_wait_for_ack(struct highlander_i2c_dev *dev)
-{
- u16 tmp = ioread16(dev->base + SMCR);
-
- if ((tmp & (SMCR_IRIC | SMCR_ACKE)) == SMCR_ACKE) {
- dev_warn(dev->dev, "ack abnormality\n");
- return highlander_i2c_reset(dev);
- }
-
- return 0;
-}
-
-static irqreturn_t highlander_i2c_irq(int irq, void *dev_id)
-{
- struct highlander_i2c_dev *dev = dev_id;
-
- highlander_i2c_done(dev);
- complete(&dev->cmd_complete);
-
- return IRQ_HANDLED;
-}
-
-static void highlander_i2c_poll(struct highlander_i2c_dev *dev)
-{
- unsigned long timeout;
- u16 smcr;
-
- timeout = jiffies + msecs_to_jiffies(iic_timeout);
- for (;;) {
- smcr = ioread16(dev->base + SMCR);
-
- /*
- * Don't bother checking ACKE here, this and the reset
- * are handled in highlander_i2c_wait_xfer_done() when
- * waiting for the ACK.
- */
-
- if (smcr & SMCR_IRIC)
- return;
- if (time_after(jiffies, timeout))
- break;
-
- cpu_relax();
- cond_resched();
- }
-
- dev_err(dev->dev, "polling timed out\n");
-}
-
-static inline int highlander_i2c_wait_xfer_done(struct highlander_i2c_dev *dev)
-{
- if (dev->irq)
- wait_for_completion_timeout(&dev->cmd_complete,
- msecs_to_jiffies(iic_timeout));
- else
- /* busy looping, the IRQ of champions */
- highlander_i2c_poll(dev);
-
- return highlander_i2c_wait_for_ack(dev);
-}
-
-static int highlander_i2c_read(struct highlander_i2c_dev *dev)
-{
- int i, cnt;
- u16 data[16];
-
- if (highlander_i2c_wait_for_bbsy(dev))
- return -EAGAIN;
-
- highlander_i2c_start(dev);
-
- if (highlander_i2c_wait_xfer_done(dev)) {
- dev_err(dev->dev, "Arbitration loss\n");
- return -EAGAIN;
- }
-
- /*
- * The R0P7780LC0011RL FPGA needs a significant delay between
- * data read cycles, otherwise the transceiver gets confused and
- * garbage is returned when the read is subsequently aborted.
- *
- * It is not sufficient to wait for BBSY.
- *
- * While this generally only applies to the older SH7780-based
- * Highlanders, the same issue can be observed on SH7785 ones,
- * albeit less frequently. SH7780-based Highlanders may need
- * this to be as high as 1000 ms.
- */
- if (iic_read_delay && time_before(jiffies, dev->last_read_time +
- msecs_to_jiffies(iic_read_delay)))
- msleep(jiffies_to_msecs((dev->last_read_time +
- msecs_to_jiffies(iic_read_delay)) - jiffies));
-
- cnt = (dev->buf_len + 1) >> 1;
- for (i = 0; i < cnt; i++) {
- data[i] = ioread16(dev->base + SMTRDR + (i * sizeof(u16)));
- dev_dbg(dev->dev, "read data[%x] 0x%04x\n", i, data[i]);
- }
-
- smbus_read_data(data, dev->buf, dev->buf_len);
-
- dev->last_read_time = jiffies;
-
- return 0;
-}
-
-static int highlander_i2c_write(struct highlander_i2c_dev *dev)
-{
- int i, cnt;
- u16 data[16];
-
- smbus_write_data(dev->buf, data, dev->buf_len);
-
- cnt = (dev->buf_len + 1) >> 1;
- for (i = 0; i < cnt; i++) {
- iowrite16(data[i], dev->base + SMTRDR + (i * sizeof(u16)));
- dev_dbg(dev->dev, "write data[%x] 0x%04x\n", i, data[i]);
- }
-
- if (highlander_i2c_wait_for_bbsy(dev))
- return -EAGAIN;
-
- highlander_i2c_start(dev);
-
- return highlander_i2c_wait_xfer_done(dev);
-}
-
-static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data)
-{
- struct highlander_i2c_dev *dev = i2c_get_adapdata(adap);
- u16 tmp;
-
- init_completion(&dev->cmd_complete);
-
- dev_dbg(dev->dev, "addr %04x, command %02x, read_write %d, size %d\n",
- addr, command, read_write, size);
-
- /*
- * Set up the buffer and transfer size
- */
- switch (size) {
- case I2C_SMBUS_BYTE_DATA:
- dev->buf = &data->byte;
- dev->buf_len = 1;
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- dev->buf = &data->block[1];
- dev->buf_len = data->block[0];
- break;
- default:
- dev_err(dev->dev, "unsupported command %d\n", size);
- return -EINVAL;
- }
-
- /*
- * Encode the mode setting
- */
- tmp = ioread16(dev->base + SMMR);
- tmp &= ~(SMMR_MODE0 | SMMR_MODE1);
-
- switch (dev->buf_len) {
- case 1:
- /* default */
- break;
- case 8:
- tmp |= SMMR_MODE0;
- break;
- case 16:
- tmp |= SMMR_MODE1;
- break;
- case 32:
- tmp |= (SMMR_MODE0 | SMMR_MODE1);
- break;
- default:
- dev_err(dev->dev, "unsupported xfer size %d\n", dev->buf_len);
- return -EINVAL;
- }
-
- iowrite16(tmp, dev->base + SMMR);
-
- /* Ensure we're in a sane state */
- highlander_i2c_done(dev);
-
- /* Set slave address */
- iowrite16((addr << 1) | read_write, dev->base + SMSMADR);
-
- highlander_i2c_command(dev, command, dev->buf_len);
-
- if (read_write == I2C_SMBUS_READ)
- return highlander_i2c_read(dev);
- else
- return highlander_i2c_write(dev);
-}
-
-static u32 highlander_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;
-}
-
-static const struct i2c_algorithm highlander_i2c_algo = {
- .smbus_xfer = highlander_i2c_smbus_xfer,
- .functionality = highlander_i2c_func,
-};
-
-static int __devinit highlander_i2c_probe(struct platform_device *pdev)
-{
- struct highlander_i2c_dev *dev;
- struct i2c_adapter *adap;
- struct resource *res;
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (unlikely(!res)) {
- dev_err(&pdev->dev, "no mem resource\n");
- return -ENODEV;
- }
-
- dev = kzalloc(sizeof(struct highlander_i2c_dev), GFP_KERNEL);
- if (unlikely(!dev))
- return -ENOMEM;
-
- dev->base = ioremap_nocache(res->start, resource_size(res));
- if (unlikely(!dev->base)) {
- ret = -ENXIO;
- goto err;
- }
-
- dev->dev = &pdev->dev;
- platform_set_drvdata(pdev, dev);
-
- dev->irq = platform_get_irq(pdev, 0);
- if (iic_force_poll)
- dev->irq = 0;
-
- if (dev->irq) {
- ret = request_irq(dev->irq, highlander_i2c_irq, 0,
- pdev->name, dev);
- if (unlikely(ret))
- goto err_unmap;
-
- highlander_i2c_irq_enable(dev);
- } else {
- dev_notice(&pdev->dev, "no IRQ, using polling mode\n");
- highlander_i2c_irq_disable(dev);
- }
-
- dev->last_read_time = jiffies; /* initial read jiffies */
-
- highlander_i2c_setup(dev);
-
- adap = &dev->adapter;
- i2c_set_adapdata(adap, dev);
- adap->owner = THIS_MODULE;
- adap->class = I2C_CLASS_HWMON;
- strlcpy(adap->name, "HL FPGA I2C adapter", sizeof(adap->name));
- adap->algo = &highlander_i2c_algo;
- adap->dev.parent = &pdev->dev;
- adap->nr = pdev->id;
-
- /*
- * Reset the adapter
- */
- ret = highlander_i2c_reset(dev);
- if (unlikely(ret)) {
- dev_err(&pdev->dev, "controller didn't come up\n");
- goto err_free_irq;
- }
-
- ret = i2c_add_numbered_adapter(adap);
- if (unlikely(ret)) {
- dev_err(&pdev->dev, "failure adding adapter\n");
- goto err_free_irq;
- }
-
- return 0;
-
-err_free_irq:
- if (dev->irq)
- free_irq(dev->irq, dev);
-err_unmap:
- iounmap(dev->base);
-err:
- kfree(dev);
-
- platform_set_drvdata(pdev, NULL);
-
- return ret;
-}
-
-static int __devexit highlander_i2c_remove(struct platform_device *pdev)
-{
- struct highlander_i2c_dev *dev = platform_get_drvdata(pdev);
-
- i2c_del_adapter(&dev->adapter);
-
- if (dev->irq)
- free_irq(dev->irq, dev);
-
- iounmap(dev->base);
- kfree(dev);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver highlander_i2c_driver = {
- .driver = {
- .name = "i2c-highlander",
- .owner = THIS_MODULE,
- },
-
- .probe = highlander_i2c_probe,
- .remove = __devexit_p(highlander_i2c_remove),
-};
-
-module_platform_driver(highlander_i2c_driver);
-
-MODULE_AUTHOR("Paul Mundt");
-MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter");
-MODULE_LICENSE("GPL v2");
-
-module_param(iic_force_poll, bool, 0);
-module_param(iic_force_normal, bool, 0);
-module_param(iic_timeout, int, 0);
-module_param(iic_read_delay, int, 0);
-
-MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
-MODULE_PARM_DESC(iic_force_normal,
- "Force normal mode (100 kHz), default is fast mode (400 kHz)");
-MODULE_PARM_DESC(iic_timeout, "Set timeout value in msecs (default 1000 ms)");
-MODULE_PARM_DESC(iic_read_delay,
- "Delay between data read cycles (default 0 ms)");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-hydra.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-hydra.c
deleted file mode 100644
index c527de17..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-hydra.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- i2c Support for the Apple `Hydra' Mac I/O
-
- Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
-
- Based on i2c Support for Via Technologies 82C586B South Bridge
- Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <asm/hydra.h>
-
-
-#define HYDRA_CPD_PD0 0x00000001 /* CachePD lines */
-#define HYDRA_CPD_PD1 0x00000002
-#define HYDRA_CPD_PD2 0x00000004
-#define HYDRA_CPD_PD3 0x00000008
-
-#define HYDRA_SCLK HYDRA_CPD_PD0
-#define HYDRA_SDAT HYDRA_CPD_PD1
-#define HYDRA_SCLK_OE 0x00000010
-#define HYDRA_SDAT_OE 0x00000020
-
-static inline void pdregw(void *data, u32 val)
-{
- struct Hydra *hydra = (struct Hydra *)data;
- writel(val, &hydra->CachePD);
-}
-
-static inline u32 pdregr(void *data)
-{
- struct Hydra *hydra = (struct Hydra *)data;
- return readl(&hydra->CachePD);
-}
-
-static void hydra_bit_setscl(void *data, int state)
-{
- u32 val = pdregr(data);
- if (state)
- val &= ~HYDRA_SCLK_OE;
- else {
- val &= ~HYDRA_SCLK;
- val |= HYDRA_SCLK_OE;
- }
- pdregw(data, val);
-}
-
-static void hydra_bit_setsda(void *data, int state)
-{
- u32 val = pdregr(data);
- if (state)
- val &= ~HYDRA_SDAT_OE;
- else {
- val &= ~HYDRA_SDAT;
- val |= HYDRA_SDAT_OE;
- }
- pdregw(data, val);
-}
-
-static int hydra_bit_getscl(void *data)
-{
- return (pdregr(data) & HYDRA_SCLK) != 0;
-}
-
-static int hydra_bit_getsda(void *data)
-{
- return (pdregr(data) & HYDRA_SDAT) != 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct i2c_algo_bit_data hydra_bit_data = {
- .setsda = hydra_bit_setsda,
- .setscl = hydra_bit_setscl,
- .getsda = hydra_bit_getsda,
- .getscl = hydra_bit_getscl,
- .udelay = 5,
- .timeout = HZ
-};
-
-static struct i2c_adapter hydra_adap = {
- .owner = THIS_MODULE,
- .name = "Hydra i2c",
- .algo_data = &hydra_bit_data,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(hydra_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, hydra_ids);
-
-static int __devinit hydra_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- unsigned long base = pci_resource_start(dev, 0);
- int res;
-
- if (!request_mem_region(base+offsetof(struct Hydra, CachePD), 4,
- hydra_adap.name))
- return -EBUSY;
-
- hydra_bit_data.data = pci_ioremap_bar(dev, 0);
- if (hydra_bit_data.data == NULL) {
- release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
- return -ENODEV;
- }
-
- pdregw(hydra_bit_data.data, 0); /* clear SCLK_OE and SDAT_OE */
- hydra_adap.dev.parent = &dev->dev;
- res = i2c_bit_add_bus(&hydra_adap);
- if (res < 0) {
- iounmap(hydra_bit_data.data);
- release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
- return res;
- }
- return 0;
-}
-
-static void __devexit hydra_remove(struct pci_dev *dev)
-{
- pdregw(hydra_bit_data.data, 0); /* clear SCLK_OE and SDAT_OE */
- i2c_del_adapter(&hydra_adap);
- iounmap(hydra_bit_data.data);
- release_mem_region(pci_resource_start(dev, 0)+
- offsetof(struct Hydra, CachePD), 4);
-}
-
-
-static struct pci_driver hydra_driver = {
- .name = "hydra_smbus",
- .id_table = hydra_ids,
- .probe = hydra_probe,
- .remove = __devexit_p(hydra_remove),
-};
-
-static int __init i2c_hydra_init(void)
-{
- return pci_register_driver(&hydra_driver);
-}
-
-
-static void __exit i2c_hydra_exit(void)
-{
- pci_unregister_driver(&hydra_driver);
-}
-
-
-
-MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
-MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_hydra_init);
-module_exit(i2c_hydra_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-i801.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-i801.c
deleted file mode 100644
index ae2945a5..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-i801.c
+++ /dev/null
@@ -1,949 +0,0 @@
-/*
- Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
- <mdsxyz123@yahoo.com>
- Copyright (C) 2007 - 2012 Jean Delvare <khali@linux-fr.org>
- Copyright (C) 2010 Intel Corporation,
- David Woodhouse <dwmw2@infradead.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- Supports the following Intel I/O Controller Hubs (ICH):
-
- I/O Block I2C
- region SMBus Block proc. block
- Chip name PCI ID size PEC buffer call read
- ----------------------------------------------------------------------
- 82801AA (ICH) 0x2413 16 no no no no
- 82801AB (ICH0) 0x2423 16 no no no no
- 82801BA (ICH2) 0x2443 16 no no no no
- 82801CA (ICH3) 0x2483 32 soft no no no
- 82801DB (ICH4) 0x24c3 32 hard yes no no
- 82801E (ICH5) 0x24d3 32 hard yes yes yes
- 6300ESB 0x25a4 32 hard yes yes yes
- 82801F (ICH6) 0x266a 32 hard yes yes yes
- 6310ESB/6320ESB 0x269b 32 hard yes yes yes
- 82801G (ICH7) 0x27da 32 hard yes yes yes
- 82801H (ICH8) 0x283e 32 hard yes yes yes
- 82801I (ICH9) 0x2930 32 hard yes yes yes
- EP80579 (Tolapai) 0x5032 32 hard yes yes yes
- ICH10 0x3a30 32 hard yes yes yes
- ICH10 0x3a60 32 hard yes yes yes
- 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes
- 6 Series (PCH) 0x1c22 32 hard yes yes yes
- Patsburg (PCH) 0x1d22 32 hard yes yes yes
- Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes
- Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes
- Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes
- DH89xxCC (PCH) 0x2330 32 hard yes yes yes
- Panther Point (PCH) 0x1e22 32 hard yes yes yes
- Lynx Point (PCH) 0x8c22 32 hard yes yes yes
-
- Features supported by this driver:
- Software PEC no
- Hardware PEC yes
- Block buffer yes
- Block process call transaction no
- I2C block read transaction yes (doesn't use the block buffer)
- Slave mode no
-
- See the file Documentation/i2c/busses/i2c-i801 for details.
-*/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-#include <linux/dmi.h>
-#include <linux/slab.h>
-
-/* I801 SMBus address offsets */
-#define SMBHSTSTS(p) (0 + (p)->smba)
-#define SMBHSTCNT(p) (2 + (p)->smba)
-#define SMBHSTCMD(p) (3 + (p)->smba)
-#define SMBHSTADD(p) (4 + (p)->smba)
-#define SMBHSTDAT0(p) (5 + (p)->smba)
-#define SMBHSTDAT1(p) (6 + (p)->smba)
-#define SMBBLKDAT(p) (7 + (p)->smba)
-#define SMBPEC(p) (8 + (p)->smba) /* ICH3 and later */
-#define SMBAUXSTS(p) (12 + (p)->smba) /* ICH4 and later */
-#define SMBAUXCTL(p) (13 + (p)->smba) /* ICH4 and later */
-
-/* PCI Address Constants */
-#define SMBBAR 4
-#define SMBHSTCFG 0x040
-
-/* Host configuration bits for SMBHSTCFG */
-#define SMBHSTCFG_HST_EN 1
-#define SMBHSTCFG_SMB_SMI_EN 2
-#define SMBHSTCFG_I2C_EN 4
-
-/* Auxiliary control register bits, ICH4+ only */
-#define SMBAUXCTL_CRC 1
-#define SMBAUXCTL_E32B 2
-
-/* kill bit for SMBHSTCNT */
-#define SMBHSTCNT_KILL 2
-
-/* Other settings */
-#define MAX_RETRIES 400
-#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */
-
-/* I801 command constants */
-#define I801_QUICK 0x00
-#define I801_BYTE 0x04
-#define I801_BYTE_DATA 0x08
-#define I801_WORD_DATA 0x0C
-#define I801_PROC_CALL 0x10 /* unimplemented */
-#define I801_BLOCK_DATA 0x14
-#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
-#define I801_BLOCK_LAST 0x34
-#define I801_I2C_BLOCK_LAST 0x38 /* ICH5 and later */
-#define I801_START 0x40
-#define I801_PEC_EN 0x80 /* ICH3 and later */
-
-/* I801 Hosts Status register bits */
-#define SMBHSTSTS_BYTE_DONE 0x80
-#define SMBHSTSTS_INUSE_STS 0x40
-#define SMBHSTSTS_SMBALERT_STS 0x20
-#define SMBHSTSTS_FAILED 0x10
-#define SMBHSTSTS_BUS_ERR 0x08
-#define SMBHSTSTS_DEV_ERR 0x04
-#define SMBHSTSTS_INTR 0x02
-#define SMBHSTSTS_HOST_BUSY 0x01
-
-#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \
- SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \
- SMBHSTSTS_INTR)
-
-/* Older devices have their ID defined in <linux/pci_ids.h> */
-#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
-#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
-/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
-#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70
-#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
-#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72
-#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
-#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
-#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
-#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
-
-struct i801_priv {
- struct i2c_adapter adapter;
- unsigned long smba;
- unsigned char original_hstcfg;
- struct pci_dev *pci_dev;
- unsigned int features;
-};
-
-static struct pci_driver i801_driver;
-
-#define FEATURE_SMBUS_PEC (1 << 0)
-#define FEATURE_BLOCK_BUFFER (1 << 1)
-#define FEATURE_BLOCK_PROC (1 << 2)
-#define FEATURE_I2C_BLOCK_READ (1 << 3)
-/* Not really a feature, but it's convenient to handle it as such */
-#define FEATURE_IDF (1 << 15)
-
-static const char *i801_feature_names[] = {
- "SMBus PEC",
- "Block buffer",
- "Block process call",
- "I2C block read",
-};
-
-static unsigned int disable_features;
-module_param(disable_features, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(disable_features, "Disable selected driver features");
-
-/* Make sure the SMBus host is ready to start transmitting.
- Return 0 if it is, -EBUSY if it is not. */
-static int i801_check_pre(struct i801_priv *priv)
-{
- int status;
-
- status = inb_p(SMBHSTSTS(priv));
- if (status & SMBHSTSTS_HOST_BUSY) {
- dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n");
- return -EBUSY;
- }
-
- status &= STATUS_FLAGS;
- if (status) {
- dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n",
- status);
- outb_p(status, SMBHSTSTS(priv));
- status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
- if (status) {
- dev_err(&priv->pci_dev->dev,
- "Failed clearing status flags (%02x)\n",
- status);
- return -EBUSY;
- }
- }
-
- return 0;
-}
-
-/* Convert the status register to an error code, and clear it. */
-static int i801_check_post(struct i801_priv *priv, int status, int timeout)
-{
- int result = 0;
-
- /* If the SMBus is still busy, we give up */
- if (timeout) {
- dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
- /* try to stop the current command */
- dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
- outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
- SMBHSTCNT(priv));
- usleep_range(1000, 2000);
- outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
- SMBHSTCNT(priv));
-
- /* Check if it worked */
- status = inb_p(SMBHSTSTS(priv));
- if ((status & SMBHSTSTS_HOST_BUSY) ||
- !(status & SMBHSTSTS_FAILED))
- dev_err(&priv->pci_dev->dev,
- "Failed terminating the transaction\n");
- outb_p(STATUS_FLAGS, SMBHSTSTS(priv));
- return -ETIMEDOUT;
- }
-
- if (status & SMBHSTSTS_FAILED) {
- result = -EIO;
- dev_err(&priv->pci_dev->dev, "Transaction failed\n");
- }
- if (status & SMBHSTSTS_DEV_ERR) {
- result = -ENXIO;
- dev_dbg(&priv->pci_dev->dev, "No response\n");
- }
- if (status & SMBHSTSTS_BUS_ERR) {
- result = -EAGAIN;
- dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
- }
-
- if (result) {
- /* Clear error flags */
- outb_p(status & STATUS_FLAGS, SMBHSTSTS(priv));
- status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
- if (status) {
- dev_warn(&priv->pci_dev->dev, "Failed clearing status "
- "flags at end of transaction (%02x)\n",
- status);
- }
- }
-
- return result;
-}
-
-static int i801_transaction(struct i801_priv *priv, int xact)
-{
- int status;
- int result;
- int timeout = 0;
-
- result = i801_check_pre(priv);
- if (result < 0)
- return result;
-
- /* the current contents of SMBHSTCNT can be overwritten, since PEC,
- * INTREN, SMBSCMD are passed in xact */
- outb_p(xact | I801_START, SMBHSTCNT(priv));
-
- /* We will always wait for a fraction of a second! */
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_RETRIES));
-
- result = i801_check_post(priv, status, timeout > MAX_RETRIES);
- if (result < 0)
- return result;
-
- outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
- return 0;
-}
-
-/* wait for INTR bit as advised by Intel */
-static void i801_wait_hwpec(struct i801_priv *priv)
-{
- int timeout = 0;
- int status;
-
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- } while ((!(status & SMBHSTSTS_INTR))
- && (timeout++ < MAX_RETRIES));
-
- if (timeout > MAX_RETRIES)
- dev_dbg(&priv->pci_dev->dev, "PEC Timeout!\n");
-
- outb_p(status, SMBHSTSTS(priv));
-}
-
-static int i801_block_transaction_by_block(struct i801_priv *priv,
- union i2c_smbus_data *data,
- char read_write, int hwpec)
-{
- int i, len;
- int status;
-
- inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
-
- /* Use 32-byte buffer to process this transaction */
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- outb_p(len, SMBHSTDAT0(priv));
- for (i = 0; i < len; i++)
- outb_p(data->block[i+1], SMBBLKDAT(priv));
- }
-
- status = i801_transaction(priv, I801_BLOCK_DATA | ENABLE_INT9 |
- I801_PEC_EN * hwpec);
- if (status)
- return status;
-
- if (read_write == I2C_SMBUS_READ) {
- len = inb_p(SMBHSTDAT0(priv));
- if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
- return -EPROTO;
-
- data->block[0] = len;
- for (i = 0; i < len; i++)
- data->block[i + 1] = inb_p(SMBBLKDAT(priv));
- }
- return 0;
-}
-
-static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
- union i2c_smbus_data *data,
- char read_write, int command,
- int hwpec)
-{
- int i, len;
- int smbcmd;
- int status;
- int result;
- int timeout;
-
- result = i801_check_pre(priv);
- if (result < 0)
- return result;
-
- len = data->block[0];
-
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(len, SMBHSTDAT0(priv));
- outb_p(data->block[1], SMBBLKDAT(priv));
- }
-
- for (i = 1; i <= len; i++) {
- if (i == len && read_write == I2C_SMBUS_READ) {
- if (command == I2C_SMBUS_I2C_BLOCK_DATA)
- smbcmd = I801_I2C_BLOCK_LAST;
- else
- smbcmd = I801_BLOCK_LAST;
- } else {
- if (command == I2C_SMBUS_I2C_BLOCK_DATA
- && read_write == I2C_SMBUS_READ)
- smbcmd = I801_I2C_BLOCK_DATA;
- else
- smbcmd = I801_BLOCK_DATA;
- }
- outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT(priv));
-
- if (i == 1)
- outb_p(inb(SMBHSTCNT(priv)) | I801_START,
- SMBHSTCNT(priv));
-
- /* We will always wait for a fraction of a second! */
- timeout = 0;
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- } while ((!(status & SMBHSTSTS_BYTE_DONE))
- && (timeout++ < MAX_RETRIES));
-
- result = i801_check_post(priv, status, timeout > MAX_RETRIES);
- if (result < 0)
- return result;
-
- if (i == 1 && read_write == I2C_SMBUS_READ
- && command != I2C_SMBUS_I2C_BLOCK_DATA) {
- len = inb_p(SMBHSTDAT0(priv));
- if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
- dev_err(&priv->pci_dev->dev,
- "Illegal SMBus block read size %d\n",
- len);
- /* Recover */
- while (inb_p(SMBHSTSTS(priv)) &
- SMBHSTSTS_HOST_BUSY)
- outb_p(SMBHSTSTS_BYTE_DONE,
- SMBHSTSTS(priv));
- outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
- return -EPROTO;
- }
- data->block[0] = len;
- }
-
- /* Retrieve/store value in SMBBLKDAT */
- if (read_write == I2C_SMBUS_READ)
- data->block[i] = inb_p(SMBBLKDAT(priv));
- if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
- outb_p(data->block[i+1], SMBBLKDAT(priv));
-
- /* signals SMBBLKDAT ready */
- outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS(priv));
- }
-
- return 0;
-}
-
-static int i801_set_block_buffer_mode(struct i801_priv *priv)
-{
- outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
- if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0)
- return -EIO;
- return 0;
-}
-
-/* Block transaction function */
-static int i801_block_transaction(struct i801_priv *priv,
- union i2c_smbus_data *data, char read_write,
- int command, int hwpec)
-{
- int result = 0;
- unsigned char hostc;
-
- if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
- if (read_write == I2C_SMBUS_WRITE) {
- /* set I2C_EN bit in configuration register */
- pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
- pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
- hostc | SMBHSTCFG_I2C_EN);
- } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
- dev_err(&priv->pci_dev->dev,
- "I2C block read is unsupported!\n");
- return -EOPNOTSUPP;
- }
- }
-
- if (read_write == I2C_SMBUS_WRITE
- || command == I2C_SMBUS_I2C_BLOCK_DATA) {
- if (data->block[0] < 1)
- data->block[0] = 1;
- if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
- data->block[0] = I2C_SMBUS_BLOCK_MAX;
- } else {
- data->block[0] = 32; /* max for SMBus block reads */
- }
-
- /* Experience has shown that the block buffer can only be used for
- SMBus (not I2C) block transactions, even though the datasheet
- doesn't mention this limitation. */
- if ((priv->features & FEATURE_BLOCK_BUFFER)
- && command != I2C_SMBUS_I2C_BLOCK_DATA
- && i801_set_block_buffer_mode(priv) == 0)
- result = i801_block_transaction_by_block(priv, data,
- read_write, hwpec);
- else
- result = i801_block_transaction_byte_by_byte(priv, data,
- read_write,
- command, hwpec);
-
- if (result == 0 && hwpec)
- i801_wait_hwpec(priv);
-
- if (command == I2C_SMBUS_I2C_BLOCK_DATA
- && read_write == I2C_SMBUS_WRITE) {
- /* restore saved configuration register value */
- pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
- }
- return result;
-}
-
-/* Return negative errno on error. */
-static s32 i801_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- int hwpec;
- int block = 0;
- int ret, xact = 0;
- struct i801_priv *priv = i2c_get_adapdata(adap);
-
- hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
- && size != I2C_SMBUS_QUICK
- && size != I2C_SMBUS_I2C_BLOCK_DATA;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD(priv));
- xact = I801_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD(priv));
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, SMBHSTCMD(priv));
- xact = I801_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD(priv));
- outb_p(command, SMBHSTCMD(priv));
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMBHSTDAT0(priv));
- xact = I801_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD(priv));
- outb_p(command, SMBHSTCMD(priv));
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMBHSTDAT0(priv));
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
- }
- xact = I801_WORD_DATA;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD(priv));
- outb_p(command, SMBHSTCMD(priv));
- block = 1;
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- /* NB: page 240 of ICH5 datasheet shows that the R/#W
- * bit should be cleared here, even when reading */
- outb_p((addr & 0x7f) << 1, SMBHSTADD(priv));
- if (read_write == I2C_SMBUS_READ) {
- /* NB: page 240 of ICH5 datasheet also shows
- * that DATA1 is the cmd field when reading */
- outb_p(command, SMBHSTDAT1(priv));
- } else
- outb_p(command, SMBHSTCMD(priv));
- block = 1;
- break;
- default:
- dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
- size);
- return -EOPNOTSUPP;
- }
-
- if (hwpec) /* enable/disable hardware PEC */
- outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
- else
- outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
- SMBAUXCTL(priv));
-
- if (block)
- ret = i801_block_transaction(priv, data, read_write, size,
- hwpec);
- else
- ret = i801_transaction(priv, xact | ENABLE_INT9);
-
- /* Some BIOSes don't like it when PEC is enabled at reboot or resume
- time, so we forcibly disable it after every transaction. Turn off
- E32B for the same reason. */
- if (hwpec || block)
- outb_p(inb_p(SMBAUXCTL(priv)) &
- ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
-
- if (block)
- return ret;
- if (ret)
- return ret;
- if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
- return 0;
-
- switch (xact & 0x7f) {
- case I801_BYTE: /* Result put in SMBHSTDAT0 */
- case I801_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0(priv));
- break;
- case I801_WORD_DATA:
- data->word = inb_p(SMBHSTDAT0(priv)) +
- (inb_p(SMBHSTDAT1(priv)) << 8);
- break;
- }
- return 0;
-}
-
-
-static u32 i801_func(struct i2c_adapter *adapter)
-{
- struct i801_priv *priv = i2c_get_adapdata(adapter);
-
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
- ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
- ((priv->features & FEATURE_I2C_BLOCK_READ) ?
- I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0);
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = i801_access,
- .functionality = i801_func,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, i801_ids);
-
-#if defined CONFIG_X86 && defined CONFIG_DMI
-static unsigned char apanel_addr;
-
-/* Scan the system ROM for the signature "FJKEYINF" */
-static __init const void __iomem *bios_signature(const void __iomem *bios)
-{
- ssize_t offset;
- const unsigned char signature[] = "FJKEYINF";
-
- for (offset = 0; offset < 0x10000; offset += 0x10) {
- if (check_signature(bios + offset, signature,
- sizeof(signature)-1))
- return bios + offset;
- }
- return NULL;
-}
-
-static void __init input_apanel_init(void)
-{
- void __iomem *bios;
- const void __iomem *p;
-
- bios = ioremap(0xF0000, 0x10000); /* Can't fail */
- p = bios_signature(bios);
- if (p) {
- /* just use the first address */
- apanel_addr = readb(p + 8 + 3) >> 1;
- }
- iounmap(bios);
-}
-
-struct dmi_onboard_device_info {
- const char *name;
- u8 type;
- unsigned short i2c_addr;
- const char *i2c_type;
-};
-
-static struct dmi_onboard_device_info __devinitdata dmi_devices[] = {
- { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
- { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
- { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
-};
-
-static void __devinit dmi_check_onboard_device(u8 type, const char *name,
- struct i2c_adapter *adap)
-{
- int i;
- struct i2c_board_info info;
-
- for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
- /* & ~0x80, ignore enabled/disabled bit */
- if ((type & ~0x80) != dmi_devices[i].type)
- continue;
- if (strcasecmp(name, dmi_devices[i].name))
- continue;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = dmi_devices[i].i2c_addr;
- strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
- i2c_new_device(adap, &info);
- break;
- }
-}
-
-/* We use our own function to check for onboard devices instead of
- dmi_find_device() as some buggy BIOS's have the devices we are interested
- in marked as disabled */
-static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
- void *adap)
-{
- int i, count;
-
- if (dm->type != 10)
- return;
-
- count = (dm->length - sizeof(struct dmi_header)) / 2;
- for (i = 0; i < count; i++) {
- const u8 *d = (char *)(dm + 1) + (i * 2);
- const char *name = ((char *) dm) + dm->length;
- u8 type = d[0];
- u8 s = d[1];
-
- if (!s)
- continue;
- s--;
- while (s > 0 && name[0]) {
- name += strlen(name) + 1;
- s--;
- }
- if (name[0] == 0) /* Bogus string reference */
- continue;
-
- dmi_check_onboard_device(type, name, adap);
- }
-}
-
-/* Register optional slaves */
-static void __devinit i801_probe_optional_slaves(struct i801_priv *priv)
-{
- /* Only register slaves on main SMBus channel */
- if (priv->features & FEATURE_IDF)
- return;
-
- if (apanel_addr) {
- struct i2c_board_info info;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = apanel_addr;
- strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
- i2c_new_device(&priv->adapter, &info);
- }
-
- if (dmi_name_in_vendors("FUJITSU"))
- dmi_walk(dmi_check_onboard_devices, &priv->adapter);
-}
-#else
-static void __init input_apanel_init(void) {}
-static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
-#endif /* CONFIG_X86 && CONFIG_DMI */
-
-static int __devinit i801_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- unsigned char temp;
- int err, i;
- struct i801_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- i2c_set_adapdata(&priv->adapter, priv);
- priv->adapter.owner = THIS_MODULE;
- priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- priv->adapter.algo = &smbus_algorithm;
-
- priv->pci_dev = dev;
- switch (dev->device) {
- case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0:
- case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1:
- case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2:
- priv->features |= FEATURE_IDF;
- /* fall through */
- default:
- priv->features |= FEATURE_I2C_BLOCK_READ;
- /* fall through */
- case PCI_DEVICE_ID_INTEL_82801DB_3:
- priv->features |= FEATURE_SMBUS_PEC;
- priv->features |= FEATURE_BLOCK_BUFFER;
- /* fall through */
- case PCI_DEVICE_ID_INTEL_82801CA_3:
- case PCI_DEVICE_ID_INTEL_82801BA_2:
- case PCI_DEVICE_ID_INTEL_82801AB_3:
- case PCI_DEVICE_ID_INTEL_82801AA_3:
- break;
- }
-
- /* Disable features on user request */
- for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
- if (priv->features & disable_features & (1 << i))
- dev_notice(&dev->dev, "%s disabled by user\n",
- i801_feature_names[i]);
- }
- priv->features &= ~disable_features;
-
- err = pci_enable_device(dev);
- if (err) {
- dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
- err);
- goto exit;
- }
-
- /* Determine the address of the SMBus area */
- priv->smba = pci_resource_start(dev, SMBBAR);
- if (!priv->smba) {
- dev_err(&dev->dev, "SMBus base address uninitialized, "
- "upgrade BIOS\n");
- err = -ENODEV;
- goto exit;
- }
-
- err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
- if (err) {
- err = -ENODEV;
- goto exit;
- }
-
- err = pci_request_region(dev, SMBBAR, i801_driver.name);
- if (err) {
- dev_err(&dev->dev, "Failed to request SMBus region "
- "0x%lx-0x%Lx\n", priv->smba,
- (unsigned long long)pci_resource_end(dev, SMBBAR));
- goto exit;
- }
-
- pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
- priv->original_hstcfg = temp;
- temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
- if (!(temp & SMBHSTCFG_HST_EN)) {
- dev_info(&dev->dev, "Enabling SMBus device\n");
- temp |= SMBHSTCFG_HST_EN;
- }
- pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp);
-
- if (temp & SMBHSTCFG_SMB_SMI_EN)
- dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
- else
- dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
-
- /* Clear special mode bits */
- if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
- outb_p(inb_p(SMBAUXCTL(priv)) &
- ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
-
- /* set up the sysfs linkage to our parent device */
- priv->adapter.dev.parent = &dev->dev;
-
- /* Retry up to 3 times on lost arbitration */
- priv->adapter.retries = 3;
-
- snprintf(priv->adapter.name, sizeof(priv->adapter.name),
- "SMBus I801 adapter at %04lx", priv->smba);
- err = i2c_add_adapter(&priv->adapter);
- if (err) {
- dev_err(&dev->dev, "Failed to add SMBus adapter\n");
- goto exit_release;
- }
-
- i801_probe_optional_slaves(priv);
-
- pci_set_drvdata(dev, priv);
- return 0;
-
-exit_release:
- pci_release_region(dev, SMBBAR);
-exit:
- kfree(priv);
- return err;
-}
-
-static void __devexit i801_remove(struct pci_dev *dev)
-{
- struct i801_priv *priv = pci_get_drvdata(dev);
-
- i2c_del_adapter(&priv->adapter);
- pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
- pci_release_region(dev, SMBBAR);
- pci_set_drvdata(dev, NULL);
- kfree(priv);
- /*
- * do not call pci_disable_device(dev) since it can cause hard hangs on
- * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
- */
-}
-
-#ifdef CONFIG_PM
-static int i801_suspend(struct pci_dev *dev, pm_message_t mesg)
-{
- struct i801_priv *priv = pci_get_drvdata(dev);
-
- pci_save_state(dev);
- pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
- pci_set_power_state(dev, pci_choose_state(dev, mesg));
- return 0;
-}
-
-static int i801_resume(struct pci_dev *dev)
-{
- pci_set_power_state(dev, PCI_D0);
- pci_restore_state(dev);
- return pci_enable_device(dev);
-}
-#else
-#define i801_suspend NULL
-#define i801_resume NULL
-#endif
-
-static struct pci_driver i801_driver = {
- .name = "i801_smbus",
- .id_table = i801_ids,
- .probe = i801_probe,
- .remove = __devexit_p(i801_remove),
- .suspend = i801_suspend,
- .resume = i801_resume,
-};
-
-static int __init i2c_i801_init(void)
-{
- if (dmi_name_in_vendors("FUJITSU"))
- input_apanel_init();
- return pci_register_driver(&i801_driver);
-}
-
-static void __exit i2c_i801_exit(void)
-{
- pci_unregister_driver(&i801_driver);
-}
-
-MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, "
- "Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("I801 SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_i801_init);
-module_exit(i2c_i801_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.c
deleted file mode 100644
index 806e225f..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * drivers/i2c/busses/i2c-ibm_iic.c
- *
- * Support for the IIC peripheral on IBM PPC 4xx
- *
- * Copyright (c) 2003, 2004 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Copyright (c) 2008 PIKA Technologies
- * Sean MacLennan <smaclennan@pikatech.com>
- *
- * Based on original work by
- * Ian DaSilva <idasilva@mvista.com>
- * Armin Kuster <akuster@mvista.com>
- * Matt Porter <mporter@mvista.com>
- *
- * Copyright 2000-2003 MontaVista Software Inc.
- *
- * Original driver version was highly leveraged from i2c-elektor.c
- *
- * Copyright 1995-97 Simon G. Vogl
- * 1998-99 Hans Berglund
- *
- * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>
- * and even Frodo Looijaard <frodol@dds.nl>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/of_platform.h>
-#include <linux/of_i2c.h>
-
-#include "i2c-ibm_iic.h"
-
-#define DRIVER_VERSION "2.2"
-
-MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
-static bool iic_force_poll;
-module_param(iic_force_poll, bool, 0);
-MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
-
-static bool iic_force_fast;
-module_param(iic_force_fast, bool, 0);
-MODULE_PARM_DESC(iic_force_fast, "Force fast mode (400 kHz)");
-
-#define DBG_LEVEL 0
-
-#ifdef DBG
-#undef DBG
-#endif
-
-#ifdef DBG2
-#undef DBG2
-#endif
-
-#if DBG_LEVEL > 0
-# define DBG(f,x...) printk(KERN_DEBUG "ibm-iic" f, ##x)
-#else
-# define DBG(f,x...) ((void)0)
-#endif
-#if DBG_LEVEL > 1
-# define DBG2(f,x...) DBG(f, ##x)
-#else
-# define DBG2(f,x...) ((void)0)
-#endif
-#if DBG_LEVEL > 2
-static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header);
- printk(KERN_DEBUG
- " cntl = 0x%02x, mdcntl = 0x%02x\n"
- " sts = 0x%02x, extsts = 0x%02x\n"
- " clkdiv = 0x%02x, xfrcnt = 0x%02x\n"
- " xtcntlss = 0x%02x, directcntl = 0x%02x\n",
- in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts),
- in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt),
- in_8(&iic->xtcntlss), in_8(&iic->directcntl));
-}
-# define DUMP_REGS(h,dev) dump_iic_regs((h),(dev))
-#else
-# define DUMP_REGS(h,dev) ((void)0)
-#endif
-
-/* Bus timings (in ns) for bit-banging */
-static struct i2c_timings {
- unsigned int hd_sta;
- unsigned int su_sto;
- unsigned int low;
- unsigned int high;
- unsigned int buf;
-} timings [] = {
-/* Standard mode (100 KHz) */
-{
- .hd_sta = 4000,
- .su_sto = 4000,
- .low = 4700,
- .high = 4000,
- .buf = 4700,
-},
-/* Fast mode (400 KHz) */
-{
- .hd_sta = 600,
- .su_sto = 600,
- .low = 1300,
- .high = 600,
- .buf = 1300,
-}};
-
-/* Enable/disable interrupt generation */
-static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable)
-{
- out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);
-}
-
-/*
- * Initialize IIC interface.
- */
-static void iic_dev_init(struct ibm_iic_private* dev)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
-
- DBG("%d: init\n", dev->idx);
-
- /* Clear master address */
- out_8(&iic->lmadr, 0);
- out_8(&iic->hmadr, 0);
-
- /* Clear slave address */
- out_8(&iic->lsadr, 0);
- out_8(&iic->hsadr, 0);
-
- /* Clear status & extended status */
- out_8(&iic->sts, STS_SCMP | STS_IRQA);
- out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA
- | EXTSTS_ICT | EXTSTS_XFRA);
-
- /* Set clock divider */
- out_8(&iic->clkdiv, dev->clckdiv);
-
- /* Clear transfer count */
- out_8(&iic->xfrcnt, 0);
-
- /* Clear extended control and status */
- out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC
- | XTCNTLSS_SWS);
-
- /* Clear control register */
- out_8(&iic->cntl, 0);
-
- /* Enable interrupts if possible */
- iic_interrupt_mode(dev, dev->irq >= 0);
-
- /* Set mode control */
- out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS
- | (dev->fast_mode ? MDCNTL_FSM : 0));
-
- DUMP_REGS("iic_init", dev);
-}
-
-/*
- * Reset IIC interface
- */
-static void iic_dev_reset(struct ibm_iic_private* dev)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- int i;
- u8 dc;
-
- DBG("%d: soft reset\n", dev->idx);
- DUMP_REGS("reset", dev);
-
- /* Place chip in the reset state */
- out_8(&iic->xtcntlss, XTCNTLSS_SRST);
-
- /* Check if bus is free */
- dc = in_8(&iic->directcntl);
- if (!DIRCTNL_FREE(dc)){
- DBG("%d: trying to regain bus control\n", dev->idx);
-
- /* Try to set bus free state */
- out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);
-
- /* Wait until we regain bus control */
- for (i = 0; i < 100; ++i){
- dc = in_8(&iic->directcntl);
- if (DIRCTNL_FREE(dc))
- break;
-
- /* Toggle SCL line */
- dc ^= DIRCNTL_SCC;
- out_8(&iic->directcntl, dc);
- udelay(10);
- dc ^= DIRCNTL_SCC;
- out_8(&iic->directcntl, dc);
-
- /* be nice */
- cond_resched();
- }
- }
-
- /* Remove reset */
- out_8(&iic->xtcntlss, 0);
-
- /* Reinitialize interface */
- iic_dev_init(dev);
-}
-
-/*
- * Do 0-length transaction using bit-banging through IIC_DIRECTCNTL register.
- */
-
-/* Wait for SCL and/or SDA to be high */
-static int iic_dc_wait(volatile struct iic_regs __iomem *iic, u8 mask)
-{
- unsigned long x = jiffies + HZ / 28 + 2;
- while ((in_8(&iic->directcntl) & mask) != mask){
- if (unlikely(time_after(jiffies, x)))
- return -1;
- cond_resched();
- }
- return 0;
-}
-
-static int iic_smbus_quick(struct ibm_iic_private* dev, const struct i2c_msg* p)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- const struct i2c_timings* t = &timings[dev->fast_mode ? 1 : 0];
- u8 mask, v, sda;
- int i, res;
-
- /* Only 7-bit addresses are supported */
- if (unlikely(p->flags & I2C_M_TEN)){
- DBG("%d: smbus_quick - 10 bit addresses are not supported\n",
- dev->idx);
- return -EINVAL;
- }
-
- DBG("%d: smbus_quick(0x%02x)\n", dev->idx, p->addr);
-
- /* Reset IIC interface */
- out_8(&iic->xtcntlss, XTCNTLSS_SRST);
-
- /* Wait for bus to become free */
- out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);
- if (unlikely(iic_dc_wait(iic, DIRCNTL_MSDA | DIRCNTL_MSC)))
- goto err;
- ndelay(t->buf);
-
- /* START */
- out_8(&iic->directcntl, DIRCNTL_SCC);
- sda = 0;
- ndelay(t->hd_sta);
-
- /* Send address */
- v = (u8)((p->addr << 1) | ((p->flags & I2C_M_RD) ? 1 : 0));
- for (i = 0, mask = 0x80; i < 8; ++i, mask >>= 1){
- out_8(&iic->directcntl, sda);
- ndelay(t->low / 2);
- sda = (v & mask) ? DIRCNTL_SDAC : 0;
- out_8(&iic->directcntl, sda);
- ndelay(t->low / 2);
-
- out_8(&iic->directcntl, DIRCNTL_SCC | sda);
- if (unlikely(iic_dc_wait(iic, DIRCNTL_MSC)))
- goto err;
- ndelay(t->high);
- }
-
- /* ACK */
- out_8(&iic->directcntl, sda);
- ndelay(t->low / 2);
- out_8(&iic->directcntl, DIRCNTL_SDAC);
- ndelay(t->low / 2);
- out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);
- if (unlikely(iic_dc_wait(iic, DIRCNTL_MSC)))
- goto err;
- res = (in_8(&iic->directcntl) & DIRCNTL_MSDA) ? -EREMOTEIO : 1;
- ndelay(t->high);
-
- /* STOP */
- out_8(&iic->directcntl, 0);
- ndelay(t->low);
- out_8(&iic->directcntl, DIRCNTL_SCC);
- if (unlikely(iic_dc_wait(iic, DIRCNTL_MSC)))
- goto err;
- ndelay(t->su_sto);
- out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);
-
- ndelay(t->buf);
-
- DBG("%d: smbus_quick -> %s\n", dev->idx, res ? "NACK" : "ACK");
-out:
- /* Remove reset */
- out_8(&iic->xtcntlss, 0);
-
- /* Reinitialize interface */
- iic_dev_init(dev);
-
- return res;
-err:
- DBG("%d: smbus_quick - bus is stuck\n", dev->idx);
- res = -EREMOTEIO;
- goto out;
-}
-
-/*
- * IIC interrupt handler
- */
-static irqreturn_t iic_handler(int irq, void *dev_id)
-{
- struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
- volatile struct iic_regs __iomem *iic = dev->vaddr;
-
- DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n",
- dev->idx, in_8(&iic->sts), in_8(&iic->extsts));
-
- /* Acknowledge IRQ and wakeup iic_wait_for_tc */
- out_8(&iic->sts, STS_IRQA | STS_SCMP);
- wake_up_interruptible(&dev->wq);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Get master transfer result and clear errors if any.
- * Returns the number of actually transferred bytes or error (<0)
- */
-static int iic_xfer_result(struct ibm_iic_private* dev)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
-
- if (unlikely(in_8(&iic->sts) & STS_ERR)){
- DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx,
- in_8(&iic->extsts));
-
- /* Clear errors and possible pending IRQs */
- out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD |
- EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
-
- /* Flush master data buffer */
- out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
-
- /* Is bus free?
- * If error happened during combined xfer
- * IIC interface is usually stuck in some strange
- * state, the only way out - soft reset.
- */
- if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
- DBG("%d: bus is stuck, resetting\n", dev->idx);
- iic_dev_reset(dev);
- }
- return -EREMOTEIO;
- }
- else
- return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK;
-}
-
-/*
- * Try to abort active transfer.
- */
-static void iic_abort_xfer(struct ibm_iic_private* dev)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- unsigned long x;
-
- DBG("%d: iic_abort_xfer\n", dev->idx);
-
- out_8(&iic->cntl, CNTL_HMT);
-
- /*
- * Wait for the abort command to complete.
- * It's not worth to be optimized, just poll (timeout >= 1 tick)
- */
- x = jiffies + 2;
- while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
- if (time_after(jiffies, x)){
- DBG("%d: abort timeout, resetting...\n", dev->idx);
- iic_dev_reset(dev);
- return;
- }
- schedule();
- }
-
- /* Just to clear errors */
- iic_xfer_result(dev);
-}
-
-/*
- * Wait for master transfer to complete.
- * It puts current process to sleep until we get interrupt or timeout expires.
- * Returns the number of transferred bytes or error (<0)
- */
-static int iic_wait_for_tc(struct ibm_iic_private* dev){
-
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- int ret = 0;
-
- if (dev->irq >= 0){
- /* Interrupt mode */
- ret = wait_event_interruptible_timeout(dev->wq,
- !(in_8(&iic->sts) & STS_PT), dev->adap.timeout);
-
- if (unlikely(ret < 0))
- DBG("%d: wait interrupted\n", dev->idx);
- else if (unlikely(in_8(&iic->sts) & STS_PT)){
- DBG("%d: wait timeout\n", dev->idx);
- ret = -ETIMEDOUT;
- }
- }
- else {
- /* Polling mode */
- unsigned long x = jiffies + dev->adap.timeout;
-
- while (in_8(&iic->sts) & STS_PT){
- if (unlikely(time_after(jiffies, x))){
- DBG("%d: poll timeout\n", dev->idx);
- ret = -ETIMEDOUT;
- break;
- }
-
- if (unlikely(signal_pending(current))){
- DBG("%d: poll interrupted\n", dev->idx);
- ret = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- }
-
- if (unlikely(ret < 0))
- iic_abort_xfer(dev);
- else
- ret = iic_xfer_result(dev);
-
- DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);
-
- return ret;
-}
-
-/*
- * Low level master transfer routine
- */
-static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,
- int combined_xfer)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- char* buf = pm->buf;
- int i, j, loops, ret = 0;
- int len = pm->len;
-
- u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;
- if (pm->flags & I2C_M_RD)
- cntl |= CNTL_RW;
-
- loops = (len + 3) / 4;
- for (i = 0; i < loops; ++i, len -= 4){
- int count = len > 4 ? 4 : len;
- u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);
-
- if (!(cntl & CNTL_RW))
- for (j = 0; j < count; ++j)
- out_8((void __iomem *)&iic->mdbuf, *buf++);
-
- if (i < loops - 1)
- cmd |= CNTL_CHT;
- else if (combined_xfer)
- cmd |= CNTL_RPST;
-
- DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);
-
- /* Start transfer */
- out_8(&iic->cntl, cmd);
-
- /* Wait for completion */
- ret = iic_wait_for_tc(dev);
-
- if (unlikely(ret < 0))
- break;
- else if (unlikely(ret != count)){
- DBG("%d: xfer_bytes, requested %d, transferred %d\n",
- dev->idx, count, ret);
-
- /* If it's not a last part of xfer, abort it */
- if (combined_xfer || (i < loops - 1))
- iic_abort_xfer(dev);
-
- ret = -EREMOTEIO;
- break;
- }
-
- if (cntl & CNTL_RW)
- for (j = 0; j < count; ++j)
- *buf++ = in_8((void __iomem *)&iic->mdbuf);
- }
-
- return ret > 0 ? 0 : ret;
-}
-
-/*
- * Set target slave address for master transfer
- */
-static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
-{
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- u16 addr = msg->addr;
-
- DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx,
- addr, msg->flags & I2C_M_TEN ? 10 : 7);
-
- if (msg->flags & I2C_M_TEN){
- out_8(&iic->cntl, CNTL_AMD);
- out_8(&iic->lmadr, addr);
- out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06));
- }
- else {
- out_8(&iic->cntl, 0);
- out_8(&iic->lmadr, addr << 1);
- }
-}
-
-static inline int iic_invalid_address(const struct i2c_msg* p)
-{
- return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));
-}
-
-static inline int iic_address_neq(const struct i2c_msg* p1,
- const struct i2c_msg* p2)
-{
- return (p1->addr != p2->addr)
- || ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));
-}
-
-/*
- * Generic master transfer entrypoint.
- * Returns the number of processed messages or error (<0)
- */
-static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));
- volatile struct iic_regs __iomem *iic = dev->vaddr;
- int i, ret = 0;
-
- DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
-
- if (!num)
- return 0;
-
- /* Check the sanity of the passed messages.
- * Uhh, generic i2c layer is more suitable place for such code...
- */
- if (unlikely(iic_invalid_address(&msgs[0]))){
- DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx,
- msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);
- return -EINVAL;
- }
- for (i = 0; i < num; ++i){
- if (unlikely(msgs[i].len <= 0)){
- if (num == 1 && !msgs[0].len){
- /* Special case for I2C_SMBUS_QUICK emulation.
- * IBM IIC doesn't support 0-length transactions
- * so we have to emulate them using bit-banging.
- */
- return iic_smbus_quick(dev, &msgs[0]);
- }
- DBG("%d: invalid len %d in msg[%d]\n", dev->idx,
- msgs[i].len, i);
- return -EINVAL;
- }
- if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){
- DBG("%d: invalid addr in msg[%d]\n", dev->idx, i);
- return -EINVAL;
- }
- }
-
- /* Check bus state */
- if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){
- DBG("%d: iic_xfer, bus is not free\n", dev->idx);
-
- /* Usually it means something serious has happened.
- * We *cannot* have unfinished previous transfer
- * so it doesn't make any sense to try to stop it.
- * Probably we were not able to recover from the
- * previous error.
- * The only *reasonable* thing I can think of here
- * is soft reset. --ebs
- */
- iic_dev_reset(dev);
-
- if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
- DBG("%d: iic_xfer, bus is still not free\n", dev->idx);
- return -EREMOTEIO;
- }
- }
- else {
- /* Flush master data buffer (just in case) */
- out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
- }
-
- /* Load slave address */
- iic_address(dev, &msgs[0]);
-
- /* Do real transfer */
- for (i = 0; i < num && !ret; ++i)
- ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);
-
- return ret < 0 ? ret : num;
-}
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
-}
-
-static const struct i2c_algorithm iic_algo = {
- .master_xfer = iic_xfer,
- .functionality = iic_func
-};
-
-/*
- * Calculates IICx_CLCKDIV value for a specific OPB clock frequency
- */
-static inline u8 iic_clckdiv(unsigned int opb)
-{
- /* Compatibility kludge, should go away after all cards
- * are fixed to fill correct value for opbfreq.
- * Previous driver version used hardcoded divider value 4,
- * it corresponds to OPB frequency from the range (40, 50] MHz
- */
- if (!opb){
- printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq,"
- " fix your board specific setup\n");
- opb = 50000000;
- }
-
- /* Convert to MHz */
- opb /= 1000000;
-
- if (opb < 20 || opb > 150){
- printk(KERN_WARNING "ibm-iic: invalid OPB clock frequency %u MHz\n",
- opb);
- opb = opb < 20 ? 20 : 150;
- }
- return (u8)((opb + 9) / 10 - 1);
-}
-
-static int __devinit iic_request_irq(struct platform_device *ofdev,
- struct ibm_iic_private *dev)
-{
- struct device_node *np = ofdev->dev.of_node;
- int irq;
-
- if (iic_force_poll)
- return 0;
-
- irq = irq_of_parse_and_map(np, 0);
- if (!irq) {
- dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
- return 0;
- }
-
- /* Disable interrupts until we finish initialization, assumes
- * level-sensitive IRQ setup...
- */
- iic_interrupt_mode(dev, 0);
- if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) {
- dev_err(&ofdev->dev, "request_irq %d failed\n", irq);
- /* Fallback to the polling mode */
- return 0;
- }
-
- return irq;
-}
-
-/*
- * Register single IIC interface
- */
-static int __devinit iic_probe(struct platform_device *ofdev)
-{
- struct device_node *np = ofdev->dev.of_node;
- struct ibm_iic_private *dev;
- struct i2c_adapter *adap;
- const u32 *freq;
- int ret;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- dev_err(&ofdev->dev, "failed to allocate device data\n");
- return -ENOMEM;
- }
-
- dev_set_drvdata(&ofdev->dev, dev);
-
- dev->vaddr = of_iomap(np, 0);
- if (dev->vaddr == NULL) {
- dev_err(&ofdev->dev, "failed to iomap device\n");
- ret = -ENXIO;
- goto error_cleanup;
- }
-
- init_waitqueue_head(&dev->wq);
-
- dev->irq = iic_request_irq(ofdev, dev);
- if (!dev->irq)
- dev_warn(&ofdev->dev, "using polling mode\n");
-
- /* Board specific settings */
- if (iic_force_fast || of_get_property(np, "fast-mode", NULL))
- dev->fast_mode = 1;
-
- freq = of_get_property(np, "clock-frequency", NULL);
- if (freq == NULL) {
- freq = of_get_property(np->parent, "clock-frequency", NULL);
- if (freq == NULL) {
- dev_err(&ofdev->dev, "Unable to get bus frequency\n");
- ret = -EINVAL;
- goto error_cleanup;
- }
- }
-
- dev->clckdiv = iic_clckdiv(*freq);
- dev_dbg(&ofdev->dev, "clckdiv = %d\n", dev->clckdiv);
-
- /* Initialize IIC interface */
- iic_dev_init(dev);
-
- /* Register it with i2c layer */
- adap = &dev->adap;
- adap->dev.parent = &ofdev->dev;
- adap->dev.of_node = of_node_get(np);
- strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
- i2c_set_adapdata(adap, dev);
- adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- adap->algo = &iic_algo;
- adap->timeout = HZ;
-
- ret = i2c_add_adapter(adap);
- if (ret < 0) {
- dev_err(&ofdev->dev, "failed to register i2c adapter\n");
- goto error_cleanup;
- }
-
- dev_info(&ofdev->dev, "using %s mode\n",
- dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
-
- /* Now register all the child nodes */
- of_i2c_register_devices(adap);
-
- return 0;
-
-error_cleanup:
- if (dev->irq) {
- iic_interrupt_mode(dev, 0);
- free_irq(dev->irq, dev);
- }
-
- if (dev->vaddr)
- iounmap(dev->vaddr);
-
- dev_set_drvdata(&ofdev->dev, NULL);
- kfree(dev);
- return ret;
-}
-
-/*
- * Cleanup initialized IIC interface
- */
-static int __devexit iic_remove(struct platform_device *ofdev)
-{
- struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
-
- dev_set_drvdata(&ofdev->dev, NULL);
-
- i2c_del_adapter(&dev->adap);
-
- if (dev->irq) {
- iic_interrupt_mode(dev, 0);
- free_irq(dev->irq, dev);
- }
-
- iounmap(dev->vaddr);
- kfree(dev);
-
- return 0;
-}
-
-static const struct of_device_id ibm_iic_match[] = {
- { .compatible = "ibm,iic", },
- {}
-};
-
-static struct platform_driver ibm_iic_driver = {
- .driver = {
- .name = "ibm-iic",
- .owner = THIS_MODULE,
- .of_match_table = ibm_iic_match,
- },
- .probe = iic_probe,
- .remove = __devexit_p(iic_remove),
-};
-
-module_platform_driver(ibm_iic_driver);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.h b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.h
deleted file mode 100644
index fdaa4829..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ibm_iic.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * drivers/i2c/busses/i2c-ibm_iic.h
- *
- * Support for the IIC peripheral on IBM PPC 4xx
- *
- * Copyright (c) 2003 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Ian DaSilva <idasilva@mvista.com>
- * Armin Kuster <akuster@mvista.com>
- * Matt Porter <mporter@mvista.com>
- *
- * Copyright 2000-2003 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-#ifndef __I2C_IBM_IIC_H_
-#define __I2C_IBM_IIC_H_
-
-#include <linux/i2c.h>
-
-struct iic_regs {
- u16 mdbuf;
- u16 sbbuf;
- u8 lmadr;
- u8 hmadr;
- u8 cntl;
- u8 mdcntl;
- u8 sts;
- u8 extsts;
- u8 lsadr;
- u8 hsadr;
- u8 clkdiv;
- u8 intmsk;
- u8 xfrcnt;
- u8 xtcntlss;
- u8 directcntl;
-};
-
-struct ibm_iic_private {
- struct i2c_adapter adap;
- volatile struct iic_regs __iomem *vaddr;
- wait_queue_head_t wq;
- int idx;
- int irq;
- int fast_mode;
- u8 clckdiv;
-};
-
-/* IICx_CNTL register */
-#define CNTL_HMT 0x80
-#define CNTL_AMD 0x40
-#define CNTL_TCT_MASK 0x30
-#define CNTL_TCT_SHIFT 4
-#define CNTL_RPST 0x08
-#define CNTL_CHT 0x04
-#define CNTL_RW 0x02
-#define CNTL_PT 0x01
-
-/* IICx_MDCNTL register */
-#define MDCNTL_FSDB 0x80
-#define MDCNTL_FMDB 0x40
-#define MDCNTL_EGC 0x20
-#define MDCNTL_FSM 0x10
-#define MDCNTL_ESM 0x08
-#define MDCNTL_EINT 0x04
-#define MDCNTL_EUBS 0x02
-#define MDCNTL_HSCL 0x01
-
-/* IICx_STS register */
-#define STS_SSS 0x80
-#define STS_SLPR 0x40
-#define STS_MDBS 0x20
-#define STS_MDBF 0x10
-#define STS_SCMP 0x08
-#define STS_ERR 0x04
-#define STS_IRQA 0x02
-#define STS_PT 0x01
-
-/* IICx_EXTSTS register */
-#define EXTSTS_IRQP 0x80
-#define EXTSTS_BCS_MASK 0x70
-#define EXTSTS_BCS_FREE 0x40
-#define EXTSTS_IRQD 0x08
-#define EXTSTS_LA 0x04
-#define EXTSTS_ICT 0x02
-#define EXTSTS_XFRA 0x01
-
-/* IICx_INTRMSK register */
-#define INTRMSK_EIRC 0x80
-#define INTRMSK_EIRS 0x40
-#define INTRMSK_EIWC 0x20
-#define INTRMSK_EIWS 0x10
-#define INTRMSK_EIHE 0x08
-#define INTRMSK_EIIC 0x04
-#define INTRMSK_EITA 0x02
-#define INTRMSK_EIMTC 0x01
-
-/* IICx_XFRCNT register */
-#define XFRCNT_MTC_MASK 0x07
-
-/* IICx_XTCNTLSS register */
-#define XTCNTLSS_SRC 0x80
-#define XTCNTLSS_SRS 0x40
-#define XTCNTLSS_SWC 0x20
-#define XTCNTLSS_SWS 0x10
-#define XTCNTLSS_SRST 0x01
-
-/* IICx_DIRECTCNTL register */
-#define DIRCNTL_SDAC 0x08
-#define DIRCNTL_SCC 0x04
-#define DIRCNTL_MSDA 0x02
-#define DIRCNTL_MSC 0x01
-
-/* Check if we really control the I2C bus and bus is free */
-#define DIRCTNL_FREE(v) (((v) & 0x0f) == 0x0f)
-
-#endif /* __I2C_IBM_IIC_H_ */
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-imx.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-imx.c
deleted file mode 100644
index dfb84b7e..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-imx.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Copyright (C) 2002 Motorola GSG-China
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- *
- * Author:
- * Darius Augulis, Teltonika Inc.
- *
- * Desc.:
- * Implementation of I2C Adapter/Algorithm Driver
- * for I2C Bus integrated in Freescale i.MX/MXC processors
- *
- * Derived from Motorola GSG China I2C example driver
- *
- * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de
- * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de
- * Copyright (C) 2007 RightHand Technologies, Inc.
- * Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
- *
- */
-
-/** Includes *******************************************************************
-*******************************************************************************/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/sched.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_i2c.h>
-
-#include <mach/irqs.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-
-/** Defines ********************************************************************
-*******************************************************************************/
-
-/* This will be the driver name the kernel reports */
-#define DRIVER_NAME "imx-i2c"
-
-/* Default value */
-#define IMX_I2C_BIT_RATE 100000 /* 100kHz */
-
-/* IMX I2C registers */
-#define IMX_I2C_IADR 0x00 /* i2c slave address */
-#define IMX_I2C_IFDR 0x04 /* i2c frequency divider */
-#define IMX_I2C_I2CR 0x08 /* i2c control */
-#define IMX_I2C_I2SR 0x0C /* i2c status */
-#define IMX_I2C_I2DR 0x10 /* i2c transfer data */
-
-/* Bits of IMX I2C registers */
-#define I2SR_RXAK 0x01
-#define I2SR_IIF 0x02
-#define I2SR_SRW 0x04
-#define I2SR_IAL 0x10
-#define I2SR_IBB 0x20
-#define I2SR_IAAS 0x40
-#define I2SR_ICF 0x80
-#define I2CR_RSTA 0x04
-#define I2CR_TXAK 0x08
-#define I2CR_MTX 0x10
-#define I2CR_MSTA 0x20
-#define I2CR_IIEN 0x40
-#define I2CR_IEN 0x80
-
-/** Variables ******************************************************************
-*******************************************************************************/
-
-/*
- * sorted list of clock divider, register value pairs
- * taken from table 26-5, p.26-9, Freescale i.MX
- * Integrated Portable System Processor Reference Manual
- * Document Number: MC9328MXLRM, Rev. 5.1, 06/2007
- *
- * Duplicated divider values removed from list
- */
-
-static u16 __initdata i2c_clk_div[50][2] = {
- { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 },
- { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 },
- { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, { 52, 0x05 },
- { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2A }, { 72, 0x2B },
- { 80, 0x2C }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A },
- { 112, 0x2E }, { 128, 0x2F }, { 144, 0x0C }, { 160, 0x30 },
- { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 },
- { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, { 448, 0x36 },
- { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x38 },
- { 768, 0x39 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B },
- { 1152, 0x18 }, { 1280, 0x3C }, { 1536, 0x3D }, { 1792, 0x3E },
- { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D },
- { 3072, 0x1E }, { 3840, 0x1F }
-};
-
-struct imx_i2c_struct {
- struct i2c_adapter adapter;
- struct resource *res;
- struct clk *clk;
- void __iomem *base;
- int irq;
- wait_queue_head_t queue;
- unsigned long i2csr;
- unsigned int disable_delay;
- int stopped;
- unsigned int ifdr; /* IMX_I2C_IFDR */
-};
-
-static const struct of_device_id i2c_imx_dt_ids[] = {
- { .compatible = "fsl,imx1-i2c", },
- { /* sentinel */ }
-};
-
-/** Functions for IMX I2C adapter driver ***************************************
-*******************************************************************************/
-
-static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
-{
- unsigned long orig_jiffies = jiffies;
- unsigned int temp;
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
- while (1) {
- temp = readb(i2c_imx->base + IMX_I2C_I2SR);
- if (for_busy && (temp & I2SR_IBB))
- break;
- if (!for_busy && !(temp & I2SR_IBB))
- break;
- if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> I2C bus is busy\n", __func__);
- return -ETIMEDOUT;
- }
- schedule();
- }
-
- return 0;
-}
-
-static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
-{
- wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10);
-
- if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
- dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
- return -ETIMEDOUT;
- }
- dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
- i2c_imx->i2csr = 0;
- return 0;
-}
-
-static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
-{
- if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) {
- dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
- return -EIO; /* No ACK */
- }
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s> ACK received\n", __func__);
- return 0;
-}
-
-static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
-{
- unsigned int temp = 0;
- int result;
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
- clk_prepare_enable(i2c_imx->clk);
- writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
- /* Enable I2C controller */
- writeb(0, i2c_imx->base + IMX_I2C_I2SR);
- writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
-
- /* Wait controller to be stable */
- udelay(50);
-
- /* Start I2C transaction */
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp |= I2CR_MSTA;
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- result = i2c_imx_bus_busy(i2c_imx, 1);
- if (result)
- return result;
- i2c_imx->stopped = 0;
-
- temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- return result;
-}
-
-static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
-{
- unsigned int temp = 0;
-
- if (!i2c_imx->stopped) {
- /* Stop I2C transaction */
- dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp &= ~(I2CR_MSTA | I2CR_MTX);
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- }
- if (cpu_is_mx1()) {
- /*
- * This delay caused by an i.MXL hardware bug.
- * If no (or too short) delay, no "STOP" bit will be generated.
- */
- udelay(i2c_imx->disable_delay);
- }
-
- if (!i2c_imx->stopped) {
- i2c_imx_bus_busy(i2c_imx, 0);
- i2c_imx->stopped = 1;
- }
-
- /* Disable I2C controller */
- writeb(0, i2c_imx->base + IMX_I2C_I2CR);
- clk_disable_unprepare(i2c_imx->clk);
-}
-
-static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
- unsigned int rate)
-{
- unsigned int i2c_clk_rate;
- unsigned int div;
- int i;
-
- /* Divider value calculation */
- i2c_clk_rate = clk_get_rate(i2c_imx->clk);
- div = (i2c_clk_rate + rate - 1) / rate;
- if (div < i2c_clk_div[0][0])
- i = 0;
- else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0])
- i = ARRAY_SIZE(i2c_clk_div) - 1;
- else
- for (i = 0; i2c_clk_div[i][0] < div; i++);
-
- /* Store divider value */
- i2c_imx->ifdr = i2c_clk_div[i][1];
-
- /*
- * There dummy delay is calculated.
- * It should be about one I2C clock period long.
- * This delay is used in I2C bus disable function
- * to fix chip hardware bug.
- */
- i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0]
- + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
-
- /* dev_dbg() can't be used, because adapter is not yet registered */
-#ifdef CONFIG_I2C_DEBUG_BUS
- printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n",
- __func__, i2c_clk_rate, div);
- printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
- __func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
-#endif
-}
-
-static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
-{
- struct imx_i2c_struct *i2c_imx = dev_id;
- unsigned int temp;
-
- temp = readb(i2c_imx->base + IMX_I2C_I2SR);
- if (temp & I2SR_IIF) {
- /* save status register */
- i2c_imx->i2csr = temp;
- temp &= ~I2SR_IIF;
- writeb(temp, i2c_imx->base + IMX_I2C_I2SR);
- wake_up(&i2c_imx->queue);
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
-{
- int i, result;
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n",
- __func__, msgs->addr << 1);
-
- /* write slave address */
- writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
- if (result)
- return result;
- result = i2c_imx_acked(i2c_imx);
- if (result)
- return result;
- dev_dbg(&i2c_imx->adapter.dev, "<%s> write data\n", __func__);
-
- /* write data */
- for (i = 0; i < msgs->len; i++) {
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> write byte: B%d=0x%X\n",
- __func__, i, msgs->buf[i]);
- writeb(msgs->buf[i], i2c_imx->base + IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
- if (result)
- return result;
- result = i2c_imx_acked(i2c_imx);
- if (result)
- return result;
- }
- return 0;
-}
-
-static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
-{
- int i, result;
- unsigned int temp;
-
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> write slave address: addr=0x%x\n",
- __func__, (msgs->addr << 1) | 0x01);
-
- /* write slave address */
- writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
- if (result)
- return result;
- result = i2c_imx_acked(i2c_imx);
- if (result)
- return result;
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);
-
- /* setup bus to read data */
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp &= ~I2CR_MTX;
- if (msgs->len - 1)
- temp &= ~I2CR_TXAK;
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
-
- /* read data */
- for (i = 0; i < msgs->len; i++) {
- result = i2c_imx_trx_complete(i2c_imx);
- if (result)
- return result;
- if (i == (msgs->len - 1)) {
- /* It must generate STOP before read I2DR to prevent
- controller from generating another clock cycle */
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> clear MSTA\n", __func__);
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp &= ~(I2CR_MSTA | I2CR_MTX);
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- i2c_imx_bus_busy(i2c_imx, 0);
- i2c_imx->stopped = 1;
- } else if (i == (msgs->len - 2)) {
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> set TXAK\n", __func__);
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp |= I2CR_TXAK;
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- }
- msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR);
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> read byte: B%d=0x%X\n",
- __func__, i, msgs->buf[i]);
- }
- return 0;
-}
-
-static int i2c_imx_xfer(struct i2c_adapter *adapter,
- struct i2c_msg *msgs, int num)
-{
- unsigned int i, temp;
- int result;
- struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
- /* Start I2C transfer */
- result = i2c_imx_start(i2c_imx);
- if (result)
- goto fail0;
-
- /* read/write data */
- for (i = 0; i < num; i++) {
- if (i) {
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> repeated start\n", __func__);
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- temp |= I2CR_RSTA;
- writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
- result = i2c_imx_bus_busy(i2c_imx, 1);
- if (result)
- goto fail0;
- }
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> transfer message: %d\n", __func__, i);
- /* write/read data */
-#ifdef CONFIG_I2C_DEBUG_BUS
- temp = readb(i2c_imx->base + IMX_I2C_I2CR);
- dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, "
- "MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
- (temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
- (temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
- (temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0));
- temp = readb(i2c_imx->base + IMX_I2C_I2SR);
- dev_dbg(&i2c_imx->adapter.dev,
- "<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
- "IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__,
- (temp & I2SR_ICF ? 1 : 0), (temp & I2SR_IAAS ? 1 : 0),
- (temp & I2SR_IBB ? 1 : 0), (temp & I2SR_IAL ? 1 : 0),
- (temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0),
- (temp & I2SR_RXAK ? 1 : 0));
-#endif
- if (msgs[i].flags & I2C_M_RD)
- result = i2c_imx_read(i2c_imx, &msgs[i]);
- else
- result = i2c_imx_write(i2c_imx, &msgs[i]);
- if (result)
- goto fail0;
- }
-
-fail0:
- /* Stop I2C transfer */
- i2c_imx_stop(i2c_imx);
-
- dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
- (result < 0) ? "error" : "success msg",
- (result < 0) ? result : num);
- return (result < 0) ? result : num;
-}
-
-static u32 i2c_imx_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm i2c_imx_algo = {
- .master_xfer = i2c_imx_xfer,
- .functionality = i2c_imx_func,
-};
-
-static int __init i2c_imx_probe(struct platform_device *pdev)
-{
- struct imx_i2c_struct *i2c_imx;
- struct resource *res;
- struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
- void __iomem *base;
- resource_size_t res_size;
- int irq, bitrate;
- int ret;
-
- dev_dbg(&pdev->dev, "<%s>\n", __func__);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "can't get device resources\n");
- return -ENOENT;
- }
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "can't get irq number\n");
- return -ENOENT;
- }
-
- res_size = resource_size(res);
-
- if (!request_mem_region(res->start, res_size, DRIVER_NAME)) {
- dev_err(&pdev->dev, "request_mem_region failed\n");
- return -EBUSY;
- }
-
- base = ioremap(res->start, res_size);
- if (!base) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -EIO;
- goto fail1;
- }
-
- i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL);
- if (!i2c_imx) {
- dev_err(&pdev->dev, "can't allocate interface\n");
- ret = -ENOMEM;
- goto fail2;
- }
-
- /* Setup i2c_imx driver structure */
- strcpy(i2c_imx->adapter.name, pdev->name);
- i2c_imx->adapter.owner = THIS_MODULE;
- i2c_imx->adapter.algo = &i2c_imx_algo;
- i2c_imx->adapter.dev.parent = &pdev->dev;
- i2c_imx->adapter.nr = pdev->id;
- i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
- i2c_imx->irq = irq;
- i2c_imx->base = base;
- i2c_imx->res = res;
-
- /* Get I2C clock */
- i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
- if (IS_ERR(i2c_imx->clk)) {
- ret = PTR_ERR(i2c_imx->clk);
- dev_err(&pdev->dev, "can't get I2C clock\n");
- goto fail3;
- }
-
- /* Request IRQ */
- ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);
- if (ret) {
- dev_err(&pdev->dev, "can't claim irq %d\n", i2c_imx->irq);
- goto fail4;
- }
-
- /* Init queue */
- init_waitqueue_head(&i2c_imx->queue);
-
- /* Set up adapter data */
- i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
-
- /* Set up clock divider */
- bitrate = IMX_I2C_BIT_RATE;
- ret = of_property_read_u32(pdev->dev.of_node,
- "clock-frequency", &bitrate);
- if (ret < 0 && pdata && pdata->bitrate)
- bitrate = pdata->bitrate;
- i2c_imx_set_clk(i2c_imx, bitrate);
-
- /* Set up chip registers to defaults */
- writeb(0, i2c_imx->base + IMX_I2C_I2CR);
- writeb(0, i2c_imx->base + IMX_I2C_I2SR);
-
- /* Add I2C adapter */
- ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
- if (ret < 0) {
- dev_err(&pdev->dev, "registration failed\n");
- goto fail5;
- }
-
- of_i2c_register_devices(&i2c_imx->adapter);
-
- /* Set up platform driver data */
- platform_set_drvdata(pdev, i2c_imx);
-
- dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", i2c_imx->irq);
- dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",
- i2c_imx->res->start, i2c_imx->res->end);
- dev_dbg(&i2c_imx->adapter.dev, "allocated %d bytes at 0x%x \n",
- res_size, i2c_imx->res->start);
- dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
- i2c_imx->adapter.name);
- dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
-
- return 0; /* Return OK */
-
-fail5:
- free_irq(i2c_imx->irq, i2c_imx);
-fail4:
- clk_put(i2c_imx->clk);
-fail3:
- kfree(i2c_imx);
-fail2:
- iounmap(base);
-fail1:
- release_mem_region(res->start, resource_size(res));
- return ret; /* Return error number */
-}
-
-static int __exit i2c_imx_remove(struct platform_device *pdev)
-{
- struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev);
-
- /* remove adapter */
- dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n");
- i2c_del_adapter(&i2c_imx->adapter);
- platform_set_drvdata(pdev, NULL);
-
- /* free interrupt */
- free_irq(i2c_imx->irq, i2c_imx);
-
- /* setup chip registers to defaults */
- writeb(0, i2c_imx->base + IMX_I2C_IADR);
- writeb(0, i2c_imx->base + IMX_I2C_IFDR);
- writeb(0, i2c_imx->base + IMX_I2C_I2CR);
- writeb(0, i2c_imx->base + IMX_I2C_I2SR);
-
- clk_put(i2c_imx->clk);
-
- iounmap(i2c_imx->base);
- release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
- kfree(i2c_imx);
- return 0;
-}
-
-static struct platform_driver i2c_imx_driver = {
- .remove = __exit_p(i2c_imx_remove),
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- .of_match_table = i2c_imx_dt_ids,
- }
-};
-
-static int __init i2c_adap_imx_init(void)
-{
- return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe);
-}
-subsys_initcall(i2c_adap_imx_init);
-
-static void __exit i2c_adap_imx_exit(void)
-{
- platform_driver_unregister(&i2c_imx_driver);
-}
-module_exit(i2c_adap_imx_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Darius Augulis");
-MODULE_DESCRIPTION("I2C adapter driver for IMX I2C bus");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-intel-mid.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-intel-mid.c
deleted file mode 100644
index 365bad5b..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-intel-mid.c
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*
- * Support for Moorestown/Medfield I2C chip
- *
- * Copyright (c) 2009 Intel Corporation.
- * Copyright (c) 2009 Synopsys. Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License, version
- * 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/pm_runtime.h>
-#include <linux/io.h>
-
-#define DRIVER_NAME "i2c-intel-mid"
-#define VERSION "Version 0.5ac2"
-#define PLATFORM "Moorestown/Medfield"
-
-/* Tables use: 0 Moorestown, 1 Medfield */
-#define NUM_PLATFORMS 2
-enum platform_enum {
- MOORESTOWN = 0,
- MEDFIELD = 1,
-};
-
-enum mid_i2c_status {
- STATUS_IDLE = 0,
- STATUS_READ_START,
- STATUS_READ_IN_PROGRESS,
- STATUS_READ_SUCCESS,
- STATUS_WRITE_START,
- STATUS_WRITE_SUCCESS,
- STATUS_XFER_ABORT,
- STATUS_STANDBY
-};
-
-/**
- * struct intel_mid_i2c_private - per device I²C context
- * @adap: core i2c layer adapter information
- * @dev: device reference for power management
- * @base: register base
- * @speed: speed mode for this port
- * @complete: completion object for transaction wait
- * @abort: reason for last abort
- * @rx_buf: pointer into working receive buffer
- * @rx_buf_len: receive buffer length
- * @status: adapter state machine
- * @msg: the message we are currently processing
- * @platform: the MID device type we are part of
- * @lock: transaction serialization
- *
- * We allocate one of these per device we discover, it holds the core
- * i2c layer objects and the data we need to track privately.
- */
-struct intel_mid_i2c_private {
- struct i2c_adapter adap;
- struct device *dev;
- void __iomem *base;
- int speed;
- struct completion complete;
- int abort;
- u8 *rx_buf;
- int rx_buf_len;
- enum mid_i2c_status status;
- struct i2c_msg *msg;
- enum platform_enum platform;
- struct mutex lock;
-};
-
-#define NUM_SPEEDS 3
-
-#define ACTIVE 0
-#define STANDBY 1
-
-
-/* Control register */
-#define IC_CON 0x00
-#define SLV_DIS (1 << 6) /* Disable slave mode */
-#define RESTART (1 << 5) /* Send a Restart condition */
-#define ADDR_10BIT (1 << 4) /* 10-bit addressing */
-#define STANDARD_MODE (1 << 1) /* standard mode */
-#define FAST_MODE (2 << 1) /* fast mode */
-#define HIGH_MODE (3 << 1) /* high speed mode */
-#define MASTER_EN (1 << 0) /* Master mode */
-
-/* Target address register */
-#define IC_TAR 0x04
-#define IC_TAR_10BIT_ADDR (1 << 12) /* 10-bit addressing */
-#define IC_TAR_SPECIAL (1 << 11) /* Perform special I2C cmd */
-#define IC_TAR_GC_OR_START (1 << 10) /* 0: Gerneral Call Address */
- /* 1: START BYTE */
-/* Slave Address Register */
-#define IC_SAR 0x08 /* Not used in Master mode */
-
-/* High Speed Master Mode Code Address Register */
-#define IC_HS_MADDR 0x0c
-
-/* Rx/Tx Data Buffer and Command Register */
-#define IC_DATA_CMD 0x10
-#define IC_RD (1 << 8) /* 1: Read 0: Write */
-
-/* Standard Speed Clock SCL High Count Register */
-#define IC_SS_SCL_HCNT 0x14
-
-/* Standard Speed Clock SCL Low Count Register */
-#define IC_SS_SCL_LCNT 0x18
-
-/* Fast Speed Clock SCL High Count Register */
-#define IC_FS_SCL_HCNT 0x1c
-
-/* Fast Spedd Clock SCL Low Count Register */
-#define IC_FS_SCL_LCNT 0x20
-
-/* High Speed Clock SCL High Count Register */
-#define IC_HS_SCL_HCNT 0x24
-
-/* High Speed Clock SCL Low Count Register */
-#define IC_HS_SCL_LCNT 0x28
-
-/* Interrupt Status Register */
-#define IC_INTR_STAT 0x2c /* Read only */
-#define R_GEN_CALL (1 << 11)
-#define R_START_DET (1 << 10)
-#define R_STOP_DET (1 << 9)
-#define R_ACTIVITY (1 << 8)
-#define R_RX_DONE (1 << 7)
-#define R_TX_ABRT (1 << 6)
-#define R_RD_REQ (1 << 5)
-#define R_TX_EMPTY (1 << 4)
-#define R_TX_OVER (1 << 3)
-#define R_RX_FULL (1 << 2)
-#define R_RX_OVER (1 << 1)
-#define R_RX_UNDER (1 << 0)
-
-/* Interrupt Mask Register */
-#define IC_INTR_MASK 0x30 /* Read and Write */
-#define M_GEN_CALL (1 << 11)
-#define M_START_DET (1 << 10)
-#define M_STOP_DET (1 << 9)
-#define M_ACTIVITY (1 << 8)
-#define M_RX_DONE (1 << 7)
-#define M_TX_ABRT (1 << 6)
-#define M_RD_REQ (1 << 5)
-#define M_TX_EMPTY (1 << 4)
-#define M_TX_OVER (1 << 3)
-#define M_RX_FULL (1 << 2)
-#define M_RX_OVER (1 << 1)
-#define M_RX_UNDER (1 << 0)
-
-/* Raw Interrupt Status Register */
-#define IC_RAW_INTR_STAT 0x34 /* Read Only */
-#define GEN_CALL (1 << 11) /* General call */
-#define START_DET (1 << 10) /* (RE)START occurred */
-#define STOP_DET (1 << 9) /* STOP occurred */
-#define ACTIVITY (1 << 8) /* Bus busy */
-#define RX_DONE (1 << 7) /* Not used in Master mode */
-#define TX_ABRT (1 << 6) /* Transmit Abort */
-#define RD_REQ (1 << 5) /* Not used in Master mode */
-#define TX_EMPTY (1 << 4) /* TX FIFO <= threshold */
-#define TX_OVER (1 << 3) /* TX FIFO overflow */
-#define RX_FULL (1 << 2) /* RX FIFO >= threshold */
-#define RX_OVER (1 << 1) /* RX FIFO overflow */
-#define RX_UNDER (1 << 0) /* RX FIFO empty */
-
-/* Receive FIFO Threshold Register */
-#define IC_RX_TL 0x38
-
-/* Transmit FIFO Treshold Register */
-#define IC_TX_TL 0x3c
-
-/* Clear Combined and Individual Interrupt Register */
-#define IC_CLR_INTR 0x40
-#define CLR_INTR (1 << 0)
-
-/* Clear RX_UNDER Interrupt Register */
-#define IC_CLR_RX_UNDER 0x44
-#define CLR_RX_UNDER (1 << 0)
-
-/* Clear RX_OVER Interrupt Register */
-#define IC_CLR_RX_OVER 0x48
-#define CLR_RX_OVER (1 << 0)
-
-/* Clear TX_OVER Interrupt Register */
-#define IC_CLR_TX_OVER 0x4c
-#define CLR_TX_OVER (1 << 0)
-
-#define IC_CLR_RD_REQ 0x50
-
-/* Clear TX_ABRT Interrupt Register */
-#define IC_CLR_TX_ABRT 0x54
-#define CLR_TX_ABRT (1 << 0)
-#define IC_CLR_RX_DONE 0x58
-
-/* Clear ACTIVITY Interrupt Register */
-#define IC_CLR_ACTIVITY 0x5c
-#define CLR_ACTIVITY (1 << 0)
-
-/* Clear STOP_DET Interrupt Register */
-#define IC_CLR_STOP_DET 0x60
-#define CLR_STOP_DET (1 << 0)
-
-/* Clear START_DET Interrupt Register */
-#define IC_CLR_START_DET 0x64
-#define CLR_START_DET (1 << 0)
-
-/* Clear GEN_CALL Interrupt Register */
-#define IC_CLR_GEN_CALL 0x68
-#define CLR_GEN_CALL (1 << 0)
-
-/* Enable Register */
-#define IC_ENABLE 0x6c
-#define ENABLE (1 << 0)
-
-/* Status Register */
-#define IC_STATUS 0x70 /* Read Only */
-#define STAT_SLV_ACTIVITY (1 << 6) /* Slave not in idle */
-#define STAT_MST_ACTIVITY (1 << 5) /* Master not in idle */
-#define STAT_RFF (1 << 4) /* RX FIFO Full */
-#define STAT_RFNE (1 << 3) /* RX FIFO Not Empty */
-#define STAT_TFE (1 << 2) /* TX FIFO Empty */
-#define STAT_TFNF (1 << 1) /* TX FIFO Not Full */
-#define STAT_ACTIVITY (1 << 0) /* Activity Status */
-
-/* Transmit FIFO Level Register */
-#define IC_TXFLR 0x74 /* Read Only */
-#define TXFLR (1 << 0) /* TX FIFO level */
-
-/* Receive FIFO Level Register */
-#define IC_RXFLR 0x78 /* Read Only */
-#define RXFLR (1 << 0) /* RX FIFO level */
-
-/* Transmit Abort Source Register */
-#define IC_TX_ABRT_SOURCE 0x80
-#define ABRT_SLVRD_INTX (1 << 15)
-#define ABRT_SLV_ARBLOST (1 << 14)
-#define ABRT_SLVFLUSH_TXFIFO (1 << 13)
-#define ARB_LOST (1 << 12)
-#define ABRT_MASTER_DIS (1 << 11)
-#define ABRT_10B_RD_NORSTRT (1 << 10)
-#define ABRT_SBYTE_NORSTRT (1 << 9)
-#define ABRT_HS_NORSTRT (1 << 8)
-#define ABRT_SBYTE_ACKDET (1 << 7)
-#define ABRT_HS_ACKDET (1 << 6)
-#define ABRT_GCALL_READ (1 << 5)
-#define ABRT_GCALL_NOACK (1 << 4)
-#define ABRT_TXDATA_NOACK (1 << 3)
-#define ABRT_10ADDR2_NOACK (1 << 2)
-#define ABRT_10ADDR1_NOACK (1 << 1)
-#define ABRT_7B_ADDR_NOACK (1 << 0)
-
-/* Enable Status Register */
-#define IC_ENABLE_STATUS 0x9c
-#define IC_EN (1 << 0) /* I2C in an enabled state */
-
-/* Component Parameter Register 1*/
-#define IC_COMP_PARAM_1 0xf4
-#define APB_DATA_WIDTH (0x3 << 0)
-
-/* added by xiaolin --begin */
-#define SS_MIN_SCL_HIGH 4000
-#define SS_MIN_SCL_LOW 4700
-#define FS_MIN_SCL_HIGH 600
-#define FS_MIN_SCL_LOW 1300
-#define HS_MIN_SCL_HIGH_100PF 60
-#define HS_MIN_SCL_LOW_100PF 120
-
-#define STANDARD 0
-#define FAST 1
-#define HIGH 2
-
-#define NUM_SPEEDS 3
-
-static int speed_mode[6] = {
- FAST,
- FAST,
- FAST,
- STANDARD,
- FAST,
- FAST
-};
-
-static int ctl_num = 6;
-module_param_array(speed_mode, int, &ctl_num, S_IRUGO);
-MODULE_PARM_DESC(speed_mode, "Set the speed of the i2c interface (0-2)");
-
-/**
- * intel_mid_i2c_disable - Disable I2C controller
- * @adap: struct pointer to i2c_adapter
- *
- * Return Value:
- * 0 success
- * -EBUSY if device is busy
- * -ETIMEDOUT if i2c cannot be disabled within the given time
- *
- * I2C bus state should be checked prior to disabling the hardware. If bus is
- * not in idle state, an errno is returned. Write "0" to IC_ENABLE to disable
- * I2C controller.
- */
-static int intel_mid_i2c_disable(struct i2c_adapter *adap)
-{
- struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
- int err = 0;
- int count = 0;
- int ret1, ret2;
- static const u16 delay[NUM_SPEEDS] = {100, 25, 3};
-
- /* Set IC_ENABLE to 0 */
- writel(0, i2c->base + IC_ENABLE);
-
- /* Check if device is busy */
- dev_dbg(&adap->dev, "mrst i2c disable\n");
- while ((ret1 = readl(i2c->base + IC_ENABLE_STATUS) & 0x1)
- || (ret2 = readl(i2c->base + IC_STATUS) & 0x1)) {
- udelay(delay[i2c->speed]);
- writel(0, i2c->base + IC_ENABLE);
- dev_dbg(&adap->dev, "i2c is busy, count is %d speed %d\n",
- count, i2c->speed);
- if (count++ > 10) {
- err = -ETIMEDOUT;
- break;
- }
- }
-
- /* Clear all interrupts */
- readl(i2c->base + IC_CLR_INTR);
- readl(i2c->base + IC_CLR_STOP_DET);
- readl(i2c->base + IC_CLR_START_DET);
- readl(i2c->base + IC_CLR_ACTIVITY);
- readl(i2c->base + IC_CLR_TX_ABRT);
- readl(i2c->base + IC_CLR_RX_OVER);
- readl(i2c->base + IC_CLR_RX_UNDER);
- readl(i2c->base + IC_CLR_TX_OVER);
- readl(i2c->base + IC_CLR_RX_DONE);
- readl(i2c->base + IC_CLR_GEN_CALL);
-
- /* Disable all interupts */
- writel(0x0000, i2c->base + IC_INTR_MASK);
-
- return err;
-}
-
-/**
- * intel_mid_i2c_hwinit - Initialize the I2C hardware registers
- * @dev: pci device struct pointer
- *
- * This function will be called in intel_mid_i2c_probe() before device
- * registration.
- *
- * Return Values:
- * 0 success
- * -EBUSY i2c cannot be disabled
- * -ETIMEDOUT i2c cannot be disabled
- * -EFAULT If APB data width is not 32-bit wide
- *
- * I2C should be disabled prior to other register operation. If failed, an
- * errno is returned. Mask and Clear all interrpts, this should be done at
- * first. Set common registers which will not be modified during normal
- * transfers, including: control register, FIFO threshold and clock freq.
- * Check APB data width at last.
- */
-static int intel_mid_i2c_hwinit(struct intel_mid_i2c_private *i2c)
-{
- int err;
-
- static const u16 hcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
- { 0x75, 0x15, 0x07 },
- { 0x04c, 0x10, 0x06 }
- };
- static const u16 lcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
- { 0x7C, 0x21, 0x0E },
- { 0x053, 0x19, 0x0F }
- };
-
- /* Disable i2c first */
- err = intel_mid_i2c_disable(&i2c->adap);
- if (err)
- return err;
-
- /*
- * Setup clock frequency and speed mode
- * Enable restart condition,
- * enable master FSM, disable slave FSM,
- * use target address when initiating transfer
- */
-
- writel((i2c->speed + 1) << 1 | SLV_DIS | RESTART | MASTER_EN,
- i2c->base + IC_CON);
- writel(hcnt[i2c->platform][i2c->speed],
- i2c->base + (IC_SS_SCL_HCNT + (i2c->speed << 3)));
- writel(lcnt[i2c->platform][i2c->speed],
- i2c->base + (IC_SS_SCL_LCNT + (i2c->speed << 3)));
-
- /* Set tranmit & receive FIFO threshold to zero */
- writel(0x0, i2c->base + IC_RX_TL);
- writel(0x0, i2c->base + IC_TX_TL);
-
- return 0;
-}
-
-/**
- * intel_mid_i2c_func - Return the supported three I2C operations.
- * @adapter: i2c_adapter struct pointer
- */
-static u32 intel_mid_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
-}
-
-/**
- * intel_mid_i2c_address_neq - To check if the addresses for different i2c messages
- * are equal.
- * @p1: first i2c_msg
- * @p2: second i2c_msg
- *
- * Return Values:
- * 0 if addresses are equal
- * 1 if not equal
- *
- * Within a single transfer, the I2C client may need to send its address more
- * than once. So a check if the addresses match is needed.
- */
-static inline bool intel_mid_i2c_address_neq(const struct i2c_msg *p1,
- const struct i2c_msg *p2)
-{
- if (p1->addr != p2->addr)
- return 1;
- if ((p1->flags ^ p2->flags) & I2C_M_TEN)
- return 1;
- return 0;
-}
-
-/**
- * intel_mid_i2c_abort - To handle transfer abortions and print error messages.
- * @adap: i2c_adapter struct pointer
- *
- * By reading register IC_TX_ABRT_SOURCE, various transfer errors can be
- * distingushed. At present, no circumstances have been found out that
- * multiple errors would be occurred simutaneously, so we simply use the
- * register value directly.
- *
- * At last the error bits are cleared. (Note clear ABRT_SBYTE_NORSTRT bit need
- * a few extra steps)
- */
-static void intel_mid_i2c_abort(struct intel_mid_i2c_private *i2c)
-{
- /* Read about source register */
- int abort = i2c->abort;
- struct i2c_adapter *adap = &i2c->adap;
-
- /* Single transfer error check:
- * According to databook, TX/RX FIFOs would be flushed when
- * the abort interrupt occurred.
- */
- if (abort & ABRT_MASTER_DIS)
- dev_err(&adap->dev,
- "initiate master operation with master mode disabled.\n");
- if (abort & ABRT_10B_RD_NORSTRT)
- dev_err(&adap->dev,
- "RESTART disabled and master sent READ cmd in 10-bit addressing.\n");
-
- if (abort & ABRT_SBYTE_NORSTRT) {
- dev_err(&adap->dev,
- "RESTART disabled and user is trying to send START byte.\n");
- writel(~ABRT_SBYTE_NORSTRT, i2c->base + IC_TX_ABRT_SOURCE);
- writel(RESTART, i2c->base + IC_CON);
- writel(~IC_TAR_SPECIAL, i2c->base + IC_TAR);
- }
-
- if (abort & ABRT_SBYTE_ACKDET)
- dev_err(&adap->dev,
- "START byte was not acknowledged.\n");
- if (abort & ABRT_TXDATA_NOACK)
- dev_dbg(&adap->dev,
- "No acknowledgement received from slave.\n");
- if (abort & ABRT_10ADDR2_NOACK)
- dev_dbg(&adap->dev,
- "The 2nd address byte of the 10-bit address was not acknowledged.\n");
- if (abort & ABRT_10ADDR1_NOACK)
- dev_dbg(&adap->dev,
- "The 1st address byte of 10-bit address was not acknowledged.\n");
- if (abort & ABRT_7B_ADDR_NOACK)
- dev_dbg(&adap->dev,
- "I2C slave device not acknowledged.\n");
-
- /* Clear TX_ABRT bit */
- readl(i2c->base + IC_CLR_TX_ABRT);
- i2c->status = STATUS_XFER_ABORT;
-}
-
-/**
- * xfer_read - Internal function to implement master read transfer.
- * @adap: i2c_adapter struct pointer
- * @buf: buffer in i2c_msg
- * @length: number of bytes to be read
- *
- * Return Values:
- * 0 if the read transfer succeeds
- * -ETIMEDOUT if cannot read the "raw" interrupt register
- * -EINVAL if a transfer abort occurred
- *
- * For every byte, a "READ" command will be loaded into IC_DATA_CMD prior to
- * data transfer. The actual "read" operation will be performed if an RX_FULL
- * interrupt occurred.
- *
- * Note there may be two interrupt signals captured, one should read
- * IC_RAW_INTR_STAT to separate between errors and actual data.
- */
-static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
- struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
- int i = length;
- int err;
-
- if (length >= 256) {
- dev_err(&adap->dev,
- "I2C FIFO cannot support larger than 256 bytes\n");
- return -EMSGSIZE;
- }
-
- INIT_COMPLETION(i2c->complete);
-
- readl(i2c->base + IC_CLR_INTR);
- writel(0x0044, i2c->base + IC_INTR_MASK);
-
- i2c->status = STATUS_READ_START;
-
- while (i--)
- writel(IC_RD, i2c->base + IC_DATA_CMD);
-
- i2c->status = STATUS_READ_START;
- err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
- if (!err) {
- dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
- intel_mid_i2c_hwinit(i2c);
- return -ETIMEDOUT;
- }
- if (i2c->status == STATUS_READ_SUCCESS)
- return 0;
- else
- return -EIO;
-}
-
-/**
- * xfer_write - Internal function to implement master write transfer.
- * @adap: i2c_adapter struct pointer
- * @buf: buffer in i2c_msg
- * @length: number of bytes to be read
- *
- * Return Values:
- * 0 if the read transfer succeeds
- * -ETIMEDOUT if we cannot read the "raw" interrupt register
- * -EINVAL if a transfer abort occurred
- *
- * For every byte, a "WRITE" command will be loaded into IC_DATA_CMD prior to
- * data transfer. The actual "write" operation will be performed when the
- * RX_FULL interrupt signal occurs.
- *
- * Note there may be two interrupt signals captured, one should read
- * IC_RAW_INTR_STAT to separate between errors and actual data.
- */
-static int xfer_write(struct i2c_adapter *adap,
- unsigned char *buf, int length)
-{
- struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
- int i, err;
-
- if (length >= 256) {
- dev_err(&adap->dev,
- "I2C FIFO cannot support larger than 256 bytes\n");
- return -EMSGSIZE;
- }
-
- INIT_COMPLETION(i2c->complete);
-
- readl(i2c->base + IC_CLR_INTR);
- writel(0x0050, i2c->base + IC_INTR_MASK);
-
- i2c->status = STATUS_WRITE_START;
- for (i = 0; i < length; i++)
- writel((u16)(*(buf + i)), i2c->base + IC_DATA_CMD);
-
- i2c->status = STATUS_WRITE_START;
- err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
- if (!err) {
- dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
- intel_mid_i2c_hwinit(i2c);
- return -ETIMEDOUT;
- } else {
- if (i2c->status == STATUS_WRITE_SUCCESS)
- return 0;
- else
- return -EIO;
- }
-}
-
-static int intel_mid_i2c_setup(struct i2c_adapter *adap, struct i2c_msg *pmsg)
-{
- struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
- int err;
- u32 reg;
- u32 bit_mask;
- u32 mode;
-
- /* Disable device first */
- err = intel_mid_i2c_disable(adap);
- if (err) {
- dev_err(&adap->dev,
- "Cannot disable i2c controller, timeout\n");
- return err;
- }
-
- mode = (1 + i2c->speed) << 1;
- /* set the speed mode */
- reg = readl(i2c->base + IC_CON);
- if ((reg & 0x06) != mode) {
- dev_dbg(&adap->dev, "set mode %d\n", i2c->speed);
- writel((reg & ~0x6) | mode, i2c->base + IC_CON);
- }
-
- reg = readl(i2c->base + IC_CON);
- /* use 7-bit addressing */
- if (pmsg->flags & I2C_M_TEN) {
- if ((reg & ADDR_10BIT) != ADDR_10BIT) {
- dev_dbg(&adap->dev, "set i2c 10 bit address mode\n");
- writel(reg | ADDR_10BIT, i2c->base + IC_CON);
- }
- } else {
- if ((reg & ADDR_10BIT) != 0x0) {
- dev_dbg(&adap->dev, "set i2c 7 bit address mode\n");
- writel(reg & ~ADDR_10BIT, i2c->base + IC_CON);
- }
- }
- /* enable restart conditions */
- reg = readl(i2c->base + IC_CON);
- if ((reg & RESTART) != RESTART) {
- dev_dbg(&adap->dev, "enable restart conditions\n");
- writel(reg | RESTART, i2c->base + IC_CON);
- }
-
- /* enable master FSM */
- reg = readl(i2c->base + IC_CON);
- dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
- writel(reg | MASTER_EN, i2c->base + IC_CON);
- if ((reg & SLV_DIS) != SLV_DIS) {
- dev_dbg(&adap->dev, "enable master FSM\n");
- writel(reg | SLV_DIS, i2c->base + IC_CON);
- dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
- }
-
- /* use target address when initiating transfer */
- reg = readl(i2c->base + IC_TAR);
- bit_mask = IC_TAR_SPECIAL | IC_TAR_GC_OR_START;
-
- if ((reg & bit_mask) != 0x0) {
- dev_dbg(&adap->dev,
- "WR: use target address when intiating transfer, i2c_tx_target\n");
- writel(reg & ~bit_mask, i2c->base + IC_TAR);
- }
-
- /* set target address to the I2C slave address */
- dev_dbg(&adap->dev,
- "set target address to the I2C slave address, addr is %x\n",
- pmsg->addr);
- writel(pmsg->addr | (pmsg->flags & I2C_M_TEN ? IC_TAR_10BIT_ADDR : 0),
- i2c->base + IC_TAR);
-
- /* Enable I2C controller */
- writel(ENABLE, i2c->base + IC_ENABLE);
-
- return 0;
-}
-
-/**
- * intel_mid_i2c_xfer - Main master transfer routine.
- * @adap: i2c_adapter struct pointer
- * @pmsg: i2c_msg struct pointer
- * @num: number of i2c_msg
- *
- * Return Values:
- * + number of messages transferred
- * -ETIMEDOUT If cannot disable I2C controller or read IC_STATUS
- * -EINVAL If the address in i2c_msg is invalid
- *
- * This function will be registered in i2c-core and exposed to external
- * I2C clients.
- * 1. Disable I2C controller
- * 2. Unmask three interrupts: RX_FULL, TX_EMPTY, TX_ABRT
- * 3. Check if address in i2c_msg is valid
- * 4. Enable I2C controller
- * 5. Perform real transfer (call xfer_read or xfer_write)
- * 6. Wait until the current transfer is finished (check bus state)
- * 7. Mask and clear all interrupts
- */
-static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
- struct i2c_msg *pmsg,
- int num)
-{
- struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
- int i, err = 0;
-
- /* if number of messages equal 0*/
- if (num == 0)
- return 0;
-
- pm_runtime_get(i2c->dev);
-
- mutex_lock(&i2c->lock);
- dev_dbg(&adap->dev, "intel_mid_i2c_xfer, process %d msg(s)\n", num);
- dev_dbg(&adap->dev, "slave address is %x\n", pmsg->addr);
-
-
- if (i2c->status != STATUS_IDLE) {
- dev_err(&adap->dev, "Adapter %d in transfer/standby\n",
- adap->nr);
- mutex_unlock(&i2c->lock);
- pm_runtime_put(i2c->dev);
- return -1;
- }
-
-
- for (i = 1; i < num; i++) {
- /* Message address equal? */
- if (unlikely(intel_mid_i2c_address_neq(&pmsg[0], &pmsg[i]))) {
- dev_err(&adap->dev, "Invalid address in msg[%d]\n", i);
- mutex_unlock(&i2c->lock);
- pm_runtime_put(i2c->dev);
- return -EINVAL;
- }
- }
-
- if (intel_mid_i2c_setup(adap, pmsg)) {
- mutex_unlock(&i2c->lock);
- pm_runtime_put(i2c->dev);
- return -EINVAL;
- }
-
- for (i = 0; i < num; i++) {
- i2c->msg = pmsg;
- i2c->status = STATUS_IDLE;
- /* Read or Write */
- if (pmsg->flags & I2C_M_RD) {
- dev_dbg(&adap->dev, "I2C_M_RD\n");
- err = xfer_read(adap, pmsg->buf, pmsg->len);
- } else {
- dev_dbg(&adap->dev, "I2C_M_WR\n");
- err = xfer_write(adap, pmsg->buf, pmsg->len);
- }
- if (err < 0)
- break;
- dev_dbg(&adap->dev, "msg[%d] transfer complete\n", i);
- pmsg++; /* next message */
- }
-
- /* Mask interrupts */
- writel(0x0000, i2c->base + IC_INTR_MASK);
- /* Clear all interrupts */
- readl(i2c->base + IC_CLR_INTR);
-
- i2c->status = STATUS_IDLE;
- mutex_unlock(&i2c->lock);
- pm_runtime_put(i2c->dev);
-
- return err;
-}
-
-static int intel_mid_i2c_runtime_suspend(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct intel_mid_i2c_private *i2c = pci_get_drvdata(pdev);
- struct i2c_adapter *adap = to_i2c_adapter(dev);
- int err;
-
- if (i2c->status != STATUS_IDLE)
- return -1;
-
- intel_mid_i2c_disable(adap);
-
- err = pci_save_state(pdev);
- if (err) {
- dev_err(dev, "pci_save_state failed\n");
- return err;
- }
-
- err = pci_set_power_state(pdev, PCI_D3hot);
- if (err) {
- dev_err(dev, "pci_set_power_state failed\n");
- return err;
- }
- i2c->status = STATUS_STANDBY;
-
- return 0;
-}
-
-static int intel_mid_i2c_runtime_resume(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct intel_mid_i2c_private *i2c = pci_get_drvdata(pdev);
- int err;
-
- if (i2c->status != STATUS_STANDBY)
- return 0;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(dev, "pci_enable_device failed\n");
- return err;
- }
-
- i2c->status = STATUS_IDLE;
-
- intel_mid_i2c_hwinit(i2c);
- return err;
-}
-
-static void i2c_isr_read(struct intel_mid_i2c_private *i2c)
-{
- struct i2c_msg *msg = i2c->msg;
- int rx_num;
- u32 len;
- u8 *buf;
-
- if (!(msg->flags & I2C_M_RD))
- return;
-
- if (i2c->status != STATUS_READ_IN_PROGRESS) {
- len = msg->len;
- buf = msg->buf;
- } else {
- len = i2c->rx_buf_len;
- buf = i2c->rx_buf;
- }
-
- rx_num = readl(i2c->base + IC_RXFLR);
-
- for (; len > 0 && rx_num > 0; len--, rx_num--)
- *buf++ = readl(i2c->base + IC_DATA_CMD);
-
- if (len > 0) {
- i2c->status = STATUS_READ_IN_PROGRESS;
- i2c->rx_buf_len = len;
- i2c->rx_buf = buf;
- } else
- i2c->status = STATUS_READ_SUCCESS;
-
- return;
-}
-
-static irqreturn_t intel_mid_i2c_isr(int this_irq, void *dev)
-{
- struct intel_mid_i2c_private *i2c = dev;
- u32 stat = readl(i2c->base + IC_INTR_STAT);
-
- if (!stat)
- return IRQ_NONE;
-
- dev_dbg(&i2c->adap.dev, "%s, stat = 0x%x\n", __func__, stat);
- stat &= 0x54;
-
- if (i2c->status != STATUS_WRITE_START &&
- i2c->status != STATUS_READ_START &&
- i2c->status != STATUS_READ_IN_PROGRESS)
- goto err;
-
- if (stat & TX_ABRT)
- i2c->abort = readl(i2c->base + IC_TX_ABRT_SOURCE);
-
- readl(i2c->base + IC_CLR_INTR);
-
- if (stat & TX_ABRT) {
- intel_mid_i2c_abort(i2c);
- goto exit;
- }
-
- if (stat & RX_FULL) {
- i2c_isr_read(i2c);
- goto exit;
- }
-
- if (stat & TX_EMPTY) {
- if (readl(i2c->base + IC_STATUS) & 0x4)
- i2c->status = STATUS_WRITE_SUCCESS;
- }
-
-exit:
- if (i2c->status == STATUS_READ_SUCCESS ||
- i2c->status == STATUS_WRITE_SUCCESS ||
- i2c->status == STATUS_XFER_ABORT) {
- /* Clear all interrupts */
- readl(i2c->base + IC_CLR_INTR);
- /* Mask interrupts */
- writel(0, i2c->base + IC_INTR_MASK);
- complete(&i2c->complete);
- }
-err:
- return IRQ_HANDLED;
-}
-
-static struct i2c_algorithm intel_mid_i2c_algorithm = {
- .master_xfer = intel_mid_i2c_xfer,
- .functionality = intel_mid_i2c_func,
-};
-
-
-static const struct dev_pm_ops intel_mid_i2c_pm_ops = {
- .runtime_suspend = intel_mid_i2c_runtime_suspend,
- .runtime_resume = intel_mid_i2c_runtime_resume,
-};
-
-/**
- * intel_mid_i2c_probe - I2C controller initialization routine
- * @dev: pci device
- * @id: device id
- *
- * Return Values:
- * 0 success
- * -ENODEV If cannot allocate pci resource
- * -ENOMEM If the register base remapping failed, or
- * if kzalloc failed
- *
- * Initialization steps:
- * 1. Request for PCI resource
- * 2. Remap the start address of PCI resource to register base
- * 3. Request for device memory region
- * 4. Fill in the struct members of intel_mid_i2c_private
- * 5. Call intel_mid_i2c_hwinit() for hardware initialization
- * 6. Register I2C adapter in i2c-core
- */
-static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- struct intel_mid_i2c_private *mrst;
- unsigned long start, len;
- int err, busnum;
- void __iomem *base = NULL;
-
- dev_dbg(&dev->dev, "Get into probe function for I2C\n");
- err = pci_enable_device(dev);
- if (err) {
- dev_err(&dev->dev, "Failed to enable I2C PCI device (%d)\n",
- err);
- goto exit;
- }
-
- /* Determine the address of the I2C area */
- start = pci_resource_start(dev, 0);
- len = pci_resource_len(dev, 0);
- if (!start || len == 0) {
- dev_err(&dev->dev, "base address not set\n");
- err = -ENODEV;
- goto exit;
- }
- dev_dbg(&dev->dev, "%s i2c resource start 0x%lx, len=%ld\n",
- PLATFORM, start, len);
-
- err = pci_request_region(dev, 0, DRIVER_NAME);
- if (err) {
- dev_err(&dev->dev, "failed to request I2C region "
- "0x%lx-0x%lx\n", start,
- (unsigned long)pci_resource_end(dev, 0));
- goto exit;
- }
-
- base = ioremap_nocache(start, len);
- if (!base) {
- dev_err(&dev->dev, "I/O memory remapping failed\n");
- err = -ENOMEM;
- goto fail0;
- }
-
- /* Allocate the per-device data structure, intel_mid_i2c_private */
- mrst = kzalloc(sizeof(struct intel_mid_i2c_private), GFP_KERNEL);
- if (mrst == NULL) {
- dev_err(&dev->dev, "can't allocate interface\n");
- err = -ENOMEM;
- goto fail1;
- }
-
- /* Initialize struct members */
- snprintf(mrst->adap.name, sizeof(mrst->adap.name),
- "Intel MID I2C at %lx", start);
- mrst->adap.owner = THIS_MODULE;
- mrst->adap.algo = &intel_mid_i2c_algorithm;
- mrst->adap.dev.parent = &dev->dev;
- mrst->dev = &dev->dev;
- mrst->base = base;
- mrst->speed = STANDARD;
- mrst->abort = 0;
- mrst->rx_buf_len = 0;
- mrst->status = STATUS_IDLE;
-
- pci_set_drvdata(dev, mrst);
- i2c_set_adapdata(&mrst->adap, mrst);
-
- mrst->adap.nr = busnum = id->driver_data;
- if (dev->device <= 0x0804)
- mrst->platform = MOORESTOWN;
- else
- mrst->platform = MEDFIELD;
-
- dev_dbg(&dev->dev, "I2C%d\n", busnum);
-
- if (ctl_num > busnum) {
- if (speed_mode[busnum] < 0 || speed_mode[busnum] >= NUM_SPEEDS)
- dev_warn(&dev->dev, "invalid speed %d ignored.\n",
- speed_mode[busnum]);
- else
- mrst->speed = speed_mode[busnum];
- }
-
- /* Initialize i2c controller */
- err = intel_mid_i2c_hwinit(mrst);
- if (err < 0) {
- dev_err(&dev->dev, "I2C interface initialization failed\n");
- goto fail2;
- }
-
- mutex_init(&mrst->lock);
- init_completion(&mrst->complete);
-
- /* Clear all interrupts */
- readl(mrst->base + IC_CLR_INTR);
- writel(0x0000, mrst->base + IC_INTR_MASK);
-
- err = request_irq(dev->irq, intel_mid_i2c_isr, IRQF_SHARED,
- mrst->adap.name, mrst);
- if (err) {
- dev_err(&dev->dev, "Failed to request IRQ for I2C controller: "
- "%s", mrst->adap.name);
- goto fail2;
- }
-
- /* Adapter registration */
- err = i2c_add_numbered_adapter(&mrst->adap);
- if (err) {
- dev_err(&dev->dev, "Adapter %s registration failed\n",
- mrst->adap.name);
- goto fail3;
- }
-
- dev_dbg(&dev->dev, "%s I2C bus %d driver bind success.\n",
- (mrst->platform == MOORESTOWN) ? "Moorestown" : "Medfield",
- busnum);
-
- pm_runtime_enable(&dev->dev);
- return 0;
-
-fail3:
- free_irq(dev->irq, mrst);
-fail2:
- pci_set_drvdata(dev, NULL);
- kfree(mrst);
-fail1:
- iounmap(base);
-fail0:
- pci_release_region(dev, 0);
-exit:
- return err;
-}
-
-static void __devexit intel_mid_i2c_remove(struct pci_dev *dev)
-{
- struct intel_mid_i2c_private *mrst = pci_get_drvdata(dev);
- intel_mid_i2c_disable(&mrst->adap);
- if (i2c_del_adapter(&mrst->adap))
- dev_err(&dev->dev, "Failed to delete i2c adapter");
-
- free_irq(dev->irq, mrst);
- pci_set_drvdata(dev, NULL);
- iounmap(mrst->base);
- kfree(mrst);
- pci_release_region(dev, 0);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(intel_mid_i2c_ids) = {
- /* Moorestown */
- { PCI_VDEVICE(INTEL, 0x0802), 0 },
- { PCI_VDEVICE(INTEL, 0x0803), 1 },
- { PCI_VDEVICE(INTEL, 0x0804), 2 },
- /* Medfield */
- { PCI_VDEVICE(INTEL, 0x0817), 3,},
- { PCI_VDEVICE(INTEL, 0x0818), 4 },
- { PCI_VDEVICE(INTEL, 0x0819), 5 },
- { PCI_VDEVICE(INTEL, 0x082C), 0 },
- { PCI_VDEVICE(INTEL, 0x082D), 1 },
- { PCI_VDEVICE(INTEL, 0x082E), 2 },
- { 0,}
-};
-MODULE_DEVICE_TABLE(pci, intel_mid_i2c_ids);
-
-static struct pci_driver intel_mid_i2c_driver = {
- .name = DRIVER_NAME,
- .id_table = intel_mid_i2c_ids,
- .probe = intel_mid_i2c_probe,
- .remove = __devexit_p(intel_mid_i2c_remove),
-};
-
-static int __init intel_mid_i2c_init(void)
-{
- return pci_register_driver(&intel_mid_i2c_driver);
-}
-
-static void __exit intel_mid_i2c_exit(void)
-{
- pci_unregister_driver(&intel_mid_i2c_driver);
-}
-
-module_init(intel_mid_i2c_init);
-module_exit(intel_mid_i2c_exit);
-
-MODULE_AUTHOR("Ba Zheng <zheng.ba@intel.com>");
-MODULE_DESCRIPTION("I2C driver for Moorestown Platform");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VERSION);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.c
deleted file mode 100644
index 93f147a9..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
- * <Peter dot Milne at D hyphen TACQ dot com>
- *
- * With acknowledgements to i2c-algo-ibm_ocp.c by
- * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
- *
- * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
- *
- * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
- *
- * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
- * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
- *
- * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005:
- *
- * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs
- * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference
- * - Make it work with IXP46x chips
- * - Cleanup function names, coding style, etc
- *
- * - writing to slave address causes latchup on iop331.
- * fix: driver refuses to address self.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-
-#include "i2c-iop3xx.h"
-
-/* global unit counter */
-static int i2c_id;
-
-static inline unsigned char
-iic_cook_addr(struct i2c_msg *msg)
-{
- unsigned char addr;
-
- addr = (msg->addr << 1);
-
- if (msg->flags & I2C_M_RD)
- addr |= 1;
-
- return addr;
-}
-
-static void
-iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
- /* Follows devman 9.3 */
- __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET);
- __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET);
- __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
-}
-
-static void
-iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
- u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
-
- /*
- * Every time unit enable is asserted, GPOD needs to be cleared
- * on IOP3XX to avoid data corruption on the bus.
- */
-#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
- if (iop3xx_adap->id == 0) {
- gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW);
- gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW);
- } else {
- gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW);
- gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW);
- }
-#endif
- /* NB SR bits not same position as CR IE bits :-( */
- iop3xx_adap->SR_enabled =
- IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
- IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
-
- cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
- IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE;
-
- __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
-}
-
-static void
-iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
- unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
-
- cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE |
- IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN);
-
- __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
-}
-
-/*
- * NB: the handler has to clear the source of the interrupt!
- * Then it passes the SR flags of interest to BH via adap data
- */
-static irqreturn_t
-iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
-{
- struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
- u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
-
- if ((sr &= iop3xx_adap->SR_enabled)) {
- __raw_writel(sr, iop3xx_adap->ioaddr + SR_OFFSET);
- iop3xx_adap->SR_received |= sr;
- wake_up_interruptible(&iop3xx_adap->waitq);
- }
- return IRQ_HANDLED;
-}
-
-/* check all error conditions, clear them , report most important */
-static int
-iop3xx_i2c_error(u32 sr)
-{
- int rc = 0;
-
- if ((sr & IOP3XX_ISR_BERRD)) {
- if ( !rc ) rc = -I2C_ERR_BERR;
- }
- if ((sr & IOP3XX_ISR_ALD)) {
- if ( !rc ) rc = -I2C_ERR_ALD;
- }
- return rc;
-}
-
-static inline u32
-iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
- unsigned long flags;
- u32 sr;
-
- spin_lock_irqsave(&iop3xx_adap->lock, flags);
- sr = iop3xx_adap->SR_received;
- iop3xx_adap->SR_received = 0;
- spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
-
- return sr;
-}
-
-/*
- * sleep until interrupted, then recover and analyse the SR
- * saved by handler
- */
-typedef int (* compare_func)(unsigned test, unsigned mask);
-/* returns 1 on correct comparison */
-
-static int
-iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
- unsigned flags, unsigned* status,
- compare_func compare)
-{
- unsigned sr = 0;
- int interrupted;
- int done;
- int rc = 0;
-
- do {
- interrupted = wait_event_interruptible_timeout (
- iop3xx_adap->waitq,
- (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
- 1 * HZ;
- );
- if ((rc = iop3xx_i2c_error(sr)) < 0) {
- *status = sr;
- return rc;
- } else if (!interrupted) {
- *status = sr;
- return -ETIMEDOUT;
- }
- } while(!done);
-
- *status = sr;
-
- return 0;
-}
-
-/*
- * Concrete compare_funcs
- */
-static int
-all_bits_clear(unsigned test, unsigned mask)
-{
- return (test & mask) == 0;
-}
-
-static int
-any_bits_set(unsigned test, unsigned mask)
-{
- return (test & mask) != 0;
-}
-
-static int
-iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
- return iop3xx_i2c_wait_event(
- iop3xx_adap,
- IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
- status, any_bits_set);
-}
-
-static int
-iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
- return iop3xx_i2c_wait_event(
- iop3xx_adap,
- IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
- status, any_bits_set);
-}
-
-static int
-iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
- return iop3xx_i2c_wait_event(
- iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear);
-}
-
-static int
-iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
- struct i2c_msg* msg)
-{
- unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
- int status;
- int rc;
-
- /* avoid writing to my slave address (hangs on 80331),
- * forbidden in Intel developer manual
- */
- if (msg->addr == MYSAR) {
- return -EBUSY;
- }
-
- __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
-
- cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
- cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE;
-
- __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
- rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
-
- return rc;
-}
-
-static int
-iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
- int stop)
-{
- unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
- int status;
- int rc = 0;
-
- __raw_writel(byte, iop3xx_adap->ioaddr + DBR_OFFSET);
- cr &= ~IOP3XX_ICR_MSTART;
- if (stop) {
- cr |= IOP3XX_ICR_MSTOP;
- } else {
- cr &= ~IOP3XX_ICR_MSTOP;
- }
- cr |= IOP3XX_ICR_TBYTE;
- __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
- rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
-
- return rc;
-}
-
-static int
-iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
- int stop)
-{
- unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
- int status;
- int rc = 0;
-
- cr &= ~IOP3XX_ICR_MSTART;
-
- if (stop) {
- cr |= IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK;
- } else {
- cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
- }
- cr |= IOP3XX_ICR_TBYTE;
- __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
-
- rc = iop3xx_i2c_wait_rx_done(iop3xx_adap, &status);
-
- *byte = __raw_readl(iop3xx_adap->ioaddr + DBR_OFFSET);
-
- return rc;
-}
-
-static int
-iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count)
-{
- struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
- int ii;
- int rc = 0;
-
- for (ii = 0; rc == 0 && ii != count; ++ii)
- rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1);
- return rc;
-}
-
-static int
-iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
-{
- struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
- int ii;
- int rc = 0;
-
- for (ii = 0; rc == 0 && ii != count; ++ii)
- rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
-
- return rc;
-}
-
-/*
- * Description: This function implements combined transactions. Combined
- * transactions consist of combinations of reading and writing blocks of data.
- * FROM THE SAME ADDRESS
- * Each transfer (i.e. a read or a write) is separated by a repeated start
- * condition.
- */
-static int
-iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
-{
- struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
- int rc;
-
- rc = iop3xx_i2c_send_target_addr(iop3xx_adap, pmsg);
- if (rc < 0) {
- return rc;
- }
-
- if ((pmsg->flags&I2C_M_RD)) {
- return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
- } else {
- return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
- }
-}
-
-/*
- * master_xfer() - main read/write entry
- */
-static int
-iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
- int im = 0;
- int ret = 0;
- int status;
-
- iop3xx_i2c_wait_idle(iop3xx_adap, &status);
- iop3xx_i2c_reset(iop3xx_adap);
- iop3xx_i2c_enable(iop3xx_adap);
-
- for (im = 0; ret == 0 && im != num; im++) {
- ret = iop3xx_i2c_handle_msg(i2c_adap, &msgs[im]);
- }
-
- iop3xx_i2c_transaction_cleanup(iop3xx_adap);
-
- if(ret)
- return ret;
-
- return im;
-}
-
-static u32
-iop3xx_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm iop3xx_i2c_algo = {
- .master_xfer = iop3xx_i2c_master_xfer,
- .functionality = iop3xx_i2c_func,
-};
-
-static int
-iop3xx_i2c_remove(struct platform_device *pdev)
-{
- struct i2c_adapter *padapter = platform_get_drvdata(pdev);
- struct i2c_algo_iop3xx_data *adapter_data =
- (struct i2c_algo_iop3xx_data *)padapter->algo_data;
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET);
-
- /*
- * Disable the actual HW unit
- */
- cr &= ~(IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
- IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE);
- __raw_writel(cr, adapter_data->ioaddr + CR_OFFSET);
-
- iounmap(adapter_data->ioaddr);
- release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
- kfree(adapter_data);
- kfree(padapter);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static int
-iop3xx_i2c_probe(struct platform_device *pdev)
-{
- struct resource *res;
- int ret, irq;
- struct i2c_adapter *new_adapter;
- struct i2c_algo_iop3xx_data *adapter_data;
-
- new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
- if (!new_adapter) {
- ret = -ENOMEM;
- goto out;
- }
-
- adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
- if (!adapter_data) {
- ret = -ENOMEM;
- goto free_adapter;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto free_both;
- }
-
- if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) {
- ret = -EBUSY;
- goto free_both;
- }
-
- /* set the adapter enumeration # */
- adapter_data->id = i2c_id++;
-
- adapter_data->ioaddr = ioremap(res->start, IOP3XX_I2C_IO_SIZE);
- if (!adapter_data->ioaddr) {
- ret = -ENOMEM;
- goto release_region;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = -ENXIO;
- goto unmap;
- }
- ret = request_irq(irq, iop3xx_i2c_irq_handler, 0,
- pdev->name, adapter_data);
-
- if (ret) {
- ret = -EIO;
- goto unmap;
- }
-
- memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
- new_adapter->owner = THIS_MODULE;
- new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- new_adapter->dev.parent = &pdev->dev;
- new_adapter->nr = pdev->id;
-
- /*
- * Default values...should these come in from board code?
- */
- new_adapter->timeout = HZ;
- new_adapter->algo = &iop3xx_i2c_algo;
-
- init_waitqueue_head(&adapter_data->waitq);
- spin_lock_init(&adapter_data->lock);
-
- iop3xx_i2c_reset(adapter_data);
- iop3xx_i2c_enable(adapter_data);
-
- platform_set_drvdata(pdev, new_adapter);
- new_adapter->algo_data = adapter_data;
-
- i2c_add_numbered_adapter(new_adapter);
-
- return 0;
-
-unmap:
- iounmap(adapter_data->ioaddr);
-
-release_region:
- release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
-
-free_both:
- kfree(adapter_data);
-
-free_adapter:
- kfree(new_adapter);
-
-out:
- return ret;
-}
-
-
-static struct platform_driver iop3xx_i2c_driver = {
- .probe = iop3xx_i2c_probe,
- .remove = iop3xx_i2c_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "IOP3xx-I2C",
- },
-};
-
-module_platform_driver(iop3xx_i2c_driver);
-
-MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
-MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:IOP3xx-I2C");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.h b/ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.h
deleted file mode 100644
index 097e2709..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-iop3xx.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-iop3xx.h algorithm driver definitions private to i2c-iop3xx.c */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
- * <Peter dot Milne at D hyphen TACQ dot com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, version 2.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* ------------------------------------------------------------------------- */
-
-
-#ifndef I2C_IOP3XX_H
-#define I2C_IOP3XX_H 1
-
-/*
- * iop321 hardware bit definitions
- */
-#define IOP3XX_ICR_FAST_MODE 0x8000 /* 1=400kBps, 0=100kBps */
-#define IOP3XX_ICR_UNIT_RESET 0x4000 /* 1=RESET */
-#define IOP3XX_ICR_SAD_IE 0x2000 /* 1=Slave Detect Interrupt Enable */
-#define IOP3XX_ICR_ALD_IE 0x1000 /* 1=Arb Loss Detect Interrupt Enable */
-#define IOP3XX_ICR_SSD_IE 0x0800 /* 1=Slave STOP Detect Interrupt Enable */
-#define IOP3XX_ICR_BERR_IE 0x0400 /* 1=Bus Error Interrupt Enable */
-#define IOP3XX_ICR_RXFULL_IE 0x0200 /* 1=Receive Full Interrupt Enable */
-#define IOP3XX_ICR_TXEMPTY_IE 0x0100 /* 1=Transmit Empty Interrupt Enable */
-#define IOP3XX_ICR_GCD 0x0080 /* 1=General Call Disable */
-/*
- * IOP3XX_ICR_GCD: 1 disables response as slave. "This bit must be set
- * when sending a master mode general call message from the I2C unit"
- */
-#define IOP3XX_ICR_UE 0x0040 /* 1=Unit Enable */
-/*
- * "NOTE: To avoid I2C bus integrity problems,
- * the user needs to ensure that the GPIO Output Data Register -
- * GPOD bits associated with an I2C port are cleared prior to setting
- * the enable bit for that I2C serial port.
- * The user prepares to enable I2C port 0 and
- * I2C port 1 by clearing GPOD bits 7:6 and GPOD bits 5:4, respectively.
- */
-#define IOP3XX_ICR_SCLEN 0x0020 /* 1=SCL enable for master mode */
-#define IOP3XX_ICR_MABORT 0x0010 /* 1=Send a STOP with no data
- * NB TBYTE must be clear */
-#define IOP3XX_ICR_TBYTE 0x0008 /* 1=Send/Receive a byte. i2c clears */
-#define IOP3XX_ICR_NACK 0x0004 /* 1=reply with NACK */
-#define IOP3XX_ICR_MSTOP 0x0002 /* 1=send a STOP after next data byte */
-#define IOP3XX_ICR_MSTART 0x0001 /* 1=initiate a START */
-
-
-#define IOP3XX_ISR_BERRD 0x0400 /* 1=BUS ERROR Detected */
-#define IOP3XX_ISR_SAD 0x0200 /* 1=Slave ADdress Detected */
-#define IOP3XX_ISR_GCAD 0x0100 /* 1=General Call Address Detected */
-#define IOP3XX_ISR_RXFULL 0x0080 /* 1=Receive Full */
-#define IOP3XX_ISR_TXEMPTY 0x0040 /* 1=Transmit Empty */
-#define IOP3XX_ISR_ALD 0x0020 /* 1=Arbitration Loss Detected */
-#define IOP3XX_ISR_SSD 0x0010 /* 1=Slave STOP Detected */
-#define IOP3XX_ISR_BBUSY 0x0008 /* 1=Bus BUSY */
-#define IOP3XX_ISR_UNITBUSY 0x0004 /* 1=Unit Busy */
-#define IOP3XX_ISR_NACK 0x0002 /* 1=Unit Rx or Tx a NACK */
-#define IOP3XX_ISR_RXREAD 0x0001 /* 1=READ 0=WRITE (R/W bit of slave addr */
-
-#define IOP3XX_ISR_CLEARBITS 0x07f0
-
-#define IOP3XX_ISAR_SAMASK 0x007f
-
-#define IOP3XX_IDBR_MASK 0x00ff
-
-#define IOP3XX_IBMR_SCL 0x0002
-#define IOP3XX_IBMR_SDA 0x0001
-
-#define IOP3XX_GPOD_I2C0 0x00c0 /* clear these bits to enable ch0 */
-#define IOP3XX_GPOD_I2C1 0x0030 /* clear these bits to enable ch1 */
-
-#define MYSAR 0 /* default slave address */
-
-#define I2C_ERR 321
-#define I2C_ERR_BERR (I2C_ERR+0)
-#define I2C_ERR_ALD (I2C_ERR+1)
-
-
-#define CR_OFFSET 0
-#define SR_OFFSET 0x4
-#define SAR_OFFSET 0x8
-#define DBR_OFFSET 0xc
-#define CCR_OFFSET 0x10
-#define BMR_OFFSET 0x14
-
-#define IOP3XX_I2C_IO_SIZE 0x18
-
-struct i2c_algo_iop3xx_data {
- void __iomem *ioaddr;
- wait_queue_head_t waitq;
- spinlock_t lock;
- u32 SR_enabled, SR_received;
- int id;
-};
-
-#endif /* I2C_IOP3XX_H */
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-isch.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-isch.c
deleted file mode 100644
index f90a6057..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-isch.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- i2c-isch.c - Linux kernel driver for Intel SCH chipset SMBus
- - Based on i2c-piix4.c
- Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
- - Intel SCH support
- Copyright (c) 2007 - 2008 Jacob Jun Pan <jacob.jun.pan@intel.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- Supports:
- Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L)
- Note: we assume there can only be one device, with one SMBus interface.
-*/
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/acpi.h>
-
-/* SCH SMBus address offsets */
-#define SMBHSTCNT (0 + sch_smba)
-#define SMBHSTSTS (1 + sch_smba)
-#define SMBHSTADD (4 + sch_smba) /* TSA */
-#define SMBHSTCMD (5 + sch_smba)
-#define SMBHSTDAT0 (6 + sch_smba)
-#define SMBHSTDAT1 (7 + sch_smba)
-#define SMBBLKDAT (0x20 + sch_smba)
-
-/* Other settings */
-#define MAX_RETRIES 5000
-
-/* I2C constants */
-#define SCH_QUICK 0x00
-#define SCH_BYTE 0x01
-#define SCH_BYTE_DATA 0x02
-#define SCH_WORD_DATA 0x03
-#define SCH_BLOCK_DATA 0x05
-
-static unsigned short sch_smba;
-static struct i2c_adapter sch_adapter;
-
-/*
- * Start the i2c transaction -- the i2c_access will prepare the transaction
- * and this function will execute it.
- * return 0 for success and others for failure.
- */
-static int sch_transaction(void)
-{
- int temp;
- int result = 0;
- int retries = 0;
-
- dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
- inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0),
- inb(SMBHSTDAT1));
-
- /* Make sure the SMBus host is ready to start transmitting */
- temp = inb(SMBHSTSTS) & 0x0f;
- if (temp) {
- /* Can not be busy since we checked it in sch_access */
- if (temp & 0x01) {
- dev_dbg(&sch_adapter.dev, "Completion (%02x). "
- "Clear...\n", temp);
- }
- if (temp & 0x06) {
- dev_dbg(&sch_adapter.dev, "SMBus error (%02x). "
- "Resetting...\n", temp);
- }
- outb(temp, SMBHSTSTS);
- temp = inb(SMBHSTSTS) & 0x0f;
- if (temp) {
- dev_err(&sch_adapter.dev,
- "SMBus is not ready: (%02x)\n", temp);
- return -EAGAIN;
- }
- }
-
- /* start the transaction by setting bit 4 */
- outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT);
-
- do {
- usleep_range(100, 200);
- temp = inb(SMBHSTSTS) & 0x0f;
- } while ((temp & 0x08) && (retries++ < MAX_RETRIES));
-
- /* If the SMBus is still busy, we give up */
- if (retries > MAX_RETRIES) {
- dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
- result = -ETIMEDOUT;
- }
- if (temp & 0x04) {
- result = -EIO;
- dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
- "locked until next hard reset. (sorry!)\n");
- /* Clock stops and slave is stuck in mid-transmission */
- } else if (temp & 0x02) {
- result = -EIO;
- dev_err(&sch_adapter.dev, "Error: no response!\n");
- } else if (temp & 0x01) {
- dev_dbg(&sch_adapter.dev, "Post complete!\n");
- outb(temp, SMBHSTSTS);
- temp = inb(SMBHSTSTS) & 0x07;
- if (temp & 0x06) {
- /* Completion clear failed */
- dev_dbg(&sch_adapter.dev, "Failed reset at end of "
- "transaction (%02x), Bus error!\n", temp);
- }
- } else {
- result = -ENXIO;
- dev_dbg(&sch_adapter.dev, "No such address.\n");
- }
- dev_dbg(&sch_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
- inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0),
- inb(SMBHSTDAT1));
- return result;
-}
-
-/*
- * This is the main access entry for i2c-sch access
- * adap is i2c_adapter pointer, addr is the i2c device bus address, read_write
- * (0 for read and 1 for write), size is i2c transaction type and data is the
- * union of transaction for data to be transferred or data read from bus.
- * return 0 for success and others for failure.
- */
-static s32 sch_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data *data)
-{
- int i, len, temp, rc;
-
- /* Make sure the SMBus host is not busy */
- temp = inb(SMBHSTSTS) & 0x0f;
- if (temp & 0x08) {
- dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp);
- return -EAGAIN;
- }
- dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size,
- (read_write)?"READ":"WRITE");
- switch (size) {
- case I2C_SMBUS_QUICK:
- outb((addr << 1) | read_write, SMBHSTADD);
- size = SCH_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- outb((addr << 1) | read_write, SMBHSTADD);
- if (read_write == I2C_SMBUS_WRITE)
- outb(command, SMBHSTCMD);
- size = SCH_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- outb((addr << 1) | read_write, SMBHSTADD);
- outb(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE)
- outb(data->byte, SMBHSTDAT0);
- size = SCH_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- outb((addr << 1) | read_write, SMBHSTADD);
- outb(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- outb(data->word & 0xff, SMBHSTDAT0);
- outb((data->word & 0xff00) >> 8, SMBHSTDAT1);
- }
- size = SCH_WORD_DATA;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- outb((addr << 1) | read_write, SMBHSTADD);
- outb(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
- return -EINVAL;
- outb(len, SMBHSTDAT0);
- for (i = 1; i <= len; i++)
- outb(data->block[i], SMBBLKDAT+i-1);
- }
- size = SCH_BLOCK_DATA;
- break;
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
- dev_dbg(&sch_adapter.dev, "write size %d to 0x%04x\n", size, SMBHSTCNT);
- outb((inb(SMBHSTCNT) & 0xb0) | (size & 0x7), SMBHSTCNT);
-
- rc = sch_transaction();
- if (rc) /* Error in transaction */
- return rc;
-
- if ((read_write == I2C_SMBUS_WRITE) || (size == SCH_QUICK))
- return 0;
-
- switch (size) {
- case SCH_BYTE:
- case SCH_BYTE_DATA:
- data->byte = inb(SMBHSTDAT0);
- break;
- case SCH_WORD_DATA:
- data->word = inb(SMBHSTDAT0) + (inb(SMBHSTDAT1) << 8);
- break;
- case SCH_BLOCK_DATA:
- data->block[0] = inb(SMBHSTDAT0);
- if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
- return -EPROTO;
- for (i = 1; i <= data->block[0]; i++)
- data->block[i] = inb(SMBBLKDAT+i-1);
- break;
- }
- return 0;
-}
-
-static u32 sch_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = sch_access,
- .functionality = sch_func,
-};
-
-static struct i2c_adapter sch_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static int __devinit smbus_sch_probe(struct platform_device *dev)
-{
- struct resource *res;
- int retval;
-
- res = platform_get_resource(dev, IORESOURCE_IO, 0);
- if (!res)
- return -EBUSY;
-
- if (!request_region(res->start, resource_size(res), dev->name)) {
- dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
- sch_smba);
- return -EBUSY;
- }
-
- sch_smba = res->start;
-
- dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba);
-
- /* set up the sysfs linkage to our parent device */
- sch_adapter.dev.parent = &dev->dev;
-
- snprintf(sch_adapter.name, sizeof(sch_adapter.name),
- "SMBus SCH adapter at %04x", sch_smba);
-
- retval = i2c_add_adapter(&sch_adapter);
- if (retval) {
- dev_err(&dev->dev, "Couldn't register adapter!\n");
- release_region(res->start, resource_size(res));
- sch_smba = 0;
- }
-
- return retval;
-}
-
-static int __devexit smbus_sch_remove(struct platform_device *pdev)
-{
- struct resource *res;
- if (sch_smba) {
- i2c_del_adapter(&sch_adapter);
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- release_region(res->start, resource_size(res));
- sch_smba = 0;
- }
-
- return 0;
-}
-
-static struct platform_driver smbus_sch_driver = {
- .driver = {
- .name = "isch_smbus",
- .owner = THIS_MODULE,
- },
- .probe = smbus_sch_probe,
- .remove = __devexit_p(smbus_sch_remove),
-};
-
-module_platform_driver(smbus_sch_driver);
-
-MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
-MODULE_DESCRIPTION("Intel SCH SMBus driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:isch_smbus");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ixp2000.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ixp2000.c
deleted file mode 100644
index 5d263f90..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ixp2000.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * drivers/i2c/busses/i2c-ixp2000.c
- *
- * I2C adapter for IXP2000 systems using GPIOs for I2C bus
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- * Based on IXDP2400 code by: Naeem M. Afzal <naeem.m.afzal@intel.com>
- * Made generic by: Jeff Daly <jeffrey.daly@intel.com>
- *
- * Copyright (c) 2003-2004 MontaVista Software Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
- * From Jeff Daly:
- *
- * I2C adapter driver for Intel IXDP2xxx platforms. This should work for any
- * IXP2000 platform if it uses the HW GPIO in the same manner. Basically,
- * SDA and SCL GPIOs have external pullups. Setting the respective GPIO to
- * an input will make the signal a '1' via the pullup. Setting them to
- * outputs will pull them down.
- *
- * The GPIOs are open drain signals and are used as configuration strap inputs
- * during power-up so there's generally a buffer on the board that needs to be
- * 'enabled' to drive the GPIOs.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/slab.h>
-
-#include <mach/hardware.h> /* Pick up IXP2000-specific bits */
-#include <mach/gpio-ixp2000.h>
-
-static inline int ixp2000_scl_pin(void *data)
-{
- return ((struct ixp2000_i2c_pins*)data)->scl_pin;
-}
-
-static inline int ixp2000_sda_pin(void *data)
-{
- return ((struct ixp2000_i2c_pins*)data)->sda_pin;
-}
-
-
-static void ixp2000_bit_setscl(void *data, int val)
-{
- int i = 5000;
-
- if (val) {
- gpio_line_config(ixp2000_scl_pin(data), GPIO_IN);
- while(!gpio_line_get(ixp2000_scl_pin(data)) && i--);
- } else {
- gpio_line_config(ixp2000_scl_pin(data), GPIO_OUT);
- }
-}
-
-static void ixp2000_bit_setsda(void *data, int val)
-{
- if (val) {
- gpio_line_config(ixp2000_sda_pin(data), GPIO_IN);
- } else {
- gpio_line_config(ixp2000_sda_pin(data), GPIO_OUT);
- }
-}
-
-static int ixp2000_bit_getscl(void *data)
-{
- return gpio_line_get(ixp2000_scl_pin(data));
-}
-
-static int ixp2000_bit_getsda(void *data)
-{
- return gpio_line_get(ixp2000_sda_pin(data));
-}
-
-struct ixp2000_i2c_data {
- struct ixp2000_i2c_pins *gpio_pins;
- struct i2c_adapter adapter;
- struct i2c_algo_bit_data algo_data;
-};
-
-static int ixp2000_i2c_remove(struct platform_device *plat_dev)
-{
- struct ixp2000_i2c_data *drv_data = platform_get_drvdata(plat_dev);
-
- platform_set_drvdata(plat_dev, NULL);
-
- i2c_del_adapter(&drv_data->adapter);
-
- kfree(drv_data);
-
- return 0;
-}
-
-static int ixp2000_i2c_probe(struct platform_device *plat_dev)
-{
- int err;
- struct ixp2000_i2c_pins *gpio = plat_dev->dev.platform_data;
- struct ixp2000_i2c_data *drv_data =
- kzalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL);
-
- if (!drv_data)
- return -ENOMEM;
- drv_data->gpio_pins = gpio;
-
- drv_data->algo_data.data = gpio;
- drv_data->algo_data.setsda = ixp2000_bit_setsda;
- drv_data->algo_data.setscl = ixp2000_bit_setscl;
- drv_data->algo_data.getsda = ixp2000_bit_getsda;
- drv_data->algo_data.getscl = ixp2000_bit_getscl;
- drv_data->algo_data.udelay = 6;
- drv_data->algo_data.timeout = HZ;
-
- strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
- sizeof(drv_data->adapter.name));
- drv_data->adapter.algo_data = &drv_data->algo_data,
-
- drv_data->adapter.dev.parent = &plat_dev->dev;
-
- gpio_line_config(gpio->sda_pin, GPIO_IN);
- gpio_line_config(gpio->scl_pin, GPIO_IN);
- gpio_line_set(gpio->scl_pin, 0);
- gpio_line_set(gpio->sda_pin, 0);
-
- if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
- dev_err(&plat_dev->dev, "Could not install, error %d\n", err);
- kfree(drv_data);
- return err;
- }
-
- platform_set_drvdata(plat_dev, drv_data);
-
- return 0;
-}
-
-static struct platform_driver ixp2000_i2c_driver = {
- .probe = ixp2000_i2c_probe,
- .remove = ixp2000_i2c_remove,
- .driver = {
- .name = "IXP2000-I2C",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(ixp2000_i2c_driver);
-
-MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>");
-MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:IXP2000-I2C");
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-mpc.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-mpc.c
deleted file mode 100644
index 206caacd..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-mpc.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * (C) Copyright 2003-2004
- * Humboldt Solutions Ltd, adrian@humboldt.co.uk.
-
- * This is a combined i2c adapter and algorithm driver for the
- * MPC107/Tsi107 PowerPC northbridge and processors that include
- * the same I2C unit (8240, 8245, 85xx).
- *
- * Release 0.8
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/of_platform.h>
-#include <linux/of_i2c.h>
-#include <linux/slab.h>
-
-#include <linux/io.h>
-#include <linux/fsl_devices.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <asm/mpc52xx.h>
-#include <sysdev/fsl_soc.h>
-
-#define DRV_NAME "mpc-i2c"
-
-#define MPC_I2C_CLOCK_LEGACY 0
-#define MPC_I2C_CLOCK_PRESERVE (~0U)
-
-#define MPC_I2C_FDR 0x04
-#define MPC_I2C_CR 0x08
-#define MPC_I2C_SR 0x0c
-#define MPC_I2C_DR 0x10
-#define MPC_I2C_DFSRR 0x14
-
-#define CCR_MEN 0x80
-#define CCR_MIEN 0x40
-#define CCR_MSTA 0x20
-#define CCR_MTX 0x10
-#define CCR_TXAK 0x08
-#define CCR_RSTA 0x04
-
-#define CSR_MCF 0x80
-#define CSR_MAAS 0x40
-#define CSR_MBB 0x20
-#define CSR_MAL 0x10
-#define CSR_SRW 0x04
-#define CSR_MIF 0x02
-#define CSR_RXAK 0x01
-
-struct mpc_i2c {
- struct device *dev;
- void __iomem *base;
- u32 interrupt;
- wait_queue_head_t queue;
- struct i2c_adapter adap;
- int irq;
- u32 real_clk;
-};
-
-struct mpc_i2c_divider {
- u16 divider;
- u16 fdr; /* including dfsrr */
-};
-
-struct mpc_i2c_data {
- void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
- u32 clock, u32 prescaler);
- u32 prescaler;
-};
-
-static inline void writeccr(struct mpc_i2c *i2c, u32 x)
-{
- writeb(x, i2c->base + MPC_I2C_CR);
-}
-
-static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
-{
- struct mpc_i2c *i2c = dev_id;
- if (readb(i2c->base + MPC_I2C_SR) & CSR_MIF) {
- /* Read again to allow register to stabilise */
- i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
- writeb(0, i2c->base + MPC_I2C_SR);
- wake_up(&i2c->queue);
- }
- return IRQ_HANDLED;
-}
-
-/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
- * the bus, because it wants to send ACK.
- * Following sequence of enabling/disabling and sending start/stop generates
- * the 9 pulses, so it's all OK.
- */
-static void mpc_i2c_fixup(struct mpc_i2c *i2c)
-{
- int k;
- u32 delay_val = 1000000 / i2c->real_clk + 1;
-
- if (delay_val < 2)
- delay_val = 2;
-
- for (k = 9; k; k--) {
- writeccr(i2c, 0);
- writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
- udelay(delay_val);
- writeccr(i2c, CCR_MEN);
- udelay(delay_val << 1);
- }
-}
-
-static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
-{
- unsigned long orig_jiffies = jiffies;
- u32 x;
- int result = 0;
-
- if (!i2c->irq) {
- while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
- schedule();
- if (time_after(jiffies, orig_jiffies + timeout)) {
- dev_dbg(i2c->dev, "timeout\n");
- writeccr(i2c, 0);
- result = -EIO;
- break;
- }
- }
- x = readb(i2c->base + MPC_I2C_SR);
- writeb(0, i2c->base + MPC_I2C_SR);
- } else {
- /* Interrupt mode */
- result = wait_event_timeout(i2c->queue,
- (i2c->interrupt & CSR_MIF), timeout);
-
- if (unlikely(!(i2c->interrupt & CSR_MIF))) {
- dev_dbg(i2c->dev, "wait timeout\n");
- writeccr(i2c, 0);
- result = -ETIMEDOUT;
- }
-
- x = i2c->interrupt;
- i2c->interrupt = 0;
- }
-
- if (result < 0)
- return result;
-
- if (!(x & CSR_MCF)) {
- dev_dbg(i2c->dev, "unfinished\n");
- return -EIO;
- }
-
- if (x & CSR_MAL) {
- dev_dbg(i2c->dev, "MAL\n");
- return -EIO;
- }
-
- if (writing && (x & CSR_RXAK)) {
- dev_dbg(i2c->dev, "No RXAK\n");
- /* generate stop */
- writeccr(i2c, CCR_MEN);
- return -EIO;
- }
- return 0;
-}
-
-#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
-static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
- {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
- {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
- {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
- {52, 0x63}, {56, 0x29}, {60, 0x41}, {64, 0x2a},
- {68, 0x07}, {72, 0x2b}, {80, 0x2c}, {88, 0x09},
- {96, 0x2d}, {104, 0x0a}, {112, 0x2e}, {120, 0x81},
- {128, 0x2f}, {136, 0x47}, {144, 0x0c}, {160, 0x30},
- {176, 0x49}, {192, 0x31}, {208, 0x4a}, {224, 0x32},
- {240, 0x0f}, {256, 0x33}, {272, 0x87}, {288, 0x10},
- {320, 0x34}, {352, 0x89}, {384, 0x35}, {416, 0x8a},
- {448, 0x36}, {480, 0x13}, {512, 0x37}, {576, 0x14},
- {640, 0x38}, {768, 0x39}, {896, 0x3a}, {960, 0x17},
- {1024, 0x3b}, {1152, 0x18}, {1280, 0x3c}, {1536, 0x3d},
- {1792, 0x3e}, {1920, 0x1b}, {2048, 0x3f}, {2304, 0x1c},
- {2560, 0x1d}, {3072, 0x1e}, {3584, 0x7e}, {3840, 0x1f},
- {4096, 0x7f}, {4608, 0x5c}, {5120, 0x5d}, {6144, 0x5e},
- {7168, 0xbe}, {7680, 0x5f}, {8192, 0xbf}, {9216, 0x9c},
- {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
-};
-
-static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
- int prescaler, u32 *real_clk)
-{
- const struct mpc_i2c_divider *div = NULL;
- unsigned int pvr = mfspr(SPRN_PVR);
- u32 divider;
- int i;
-
- if (clock == MPC_I2C_CLOCK_LEGACY) {
- /* see below - default fdr = 0x3f -> div = 2048 */
- *real_clk = mpc5xxx_get_bus_frequency(node) / 2048;
- return -EINVAL;
- }
-
- /* Determine divider value */
- divider = mpc5xxx_get_bus_frequency(node) / clock;
-
- /*
- * We want to choose an FDR/DFSR that generates an I2C bus speed that
- * is equal to or lower than the requested speed.
- */
- for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_52xx); i++) {
- div = &mpc_i2c_dividers_52xx[i];
- /* Old MPC5200 rev A CPUs do not support the high bits */
- if (div->fdr & 0xc0 && pvr == 0x80822011)
- continue;
- if (div->divider >= divider)
- break;
- }
-
- *real_clk = mpc5xxx_get_bus_frequency(node) / div->divider;
- return (int)div->fdr;
-}
-
-static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
-{
- int ret, fdr;
-
- if (clock == MPC_I2C_CLOCK_PRESERVE) {
- dev_dbg(i2c->dev, "using fdr %d\n",
- readb(i2c->base + MPC_I2C_FDR));
- return;
- }
-
- ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, &i2c->real_clk);
- fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
-
- writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
-
- if (ret >= 0)
- dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk,
- fdr);
-}
-#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
-static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
-{
-}
-#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
-
-#ifdef CONFIG_PPC_MPC512x
-static void __devinit mpc_i2c_setup_512x(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
-{
- struct device_node *node_ctrl;
- void __iomem *ctrl;
- const u32 *pval;
- u32 idx;
-
- /* Enable I2C interrupts for mpc5121 */
- node_ctrl = of_find_compatible_node(NULL, NULL,
- "fsl,mpc5121-i2c-ctrl");
- if (node_ctrl) {
- ctrl = of_iomap(node_ctrl, 0);
- if (ctrl) {
- /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
- pval = of_get_property(node, "reg", NULL);
- idx = (*pval & 0xff) / 0x20;
- setbits32(ctrl, 1 << (24 + idx * 2));
- iounmap(ctrl);
- }
- of_node_put(node_ctrl);
- }
-
- /* The clock setup for the 52xx works also fine for the 512x */
- mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
-}
-#else /* CONFIG_PPC_MPC512x */
-static void __devinit mpc_i2c_setup_512x(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
-{
-}
-#endif /* CONFIG_PPC_MPC512x */
-
-#ifdef CONFIG_FSL_SOC
-static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = {
- {160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
- {288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
- {416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
- {544, 0x0b03}, {576, 0x0104}, {608, 0x1603}, {640, 0x0105},
- {672, 0x2003}, {704, 0x0b05}, {736, 0x2b03}, {768, 0x0106},
- {800, 0x3603}, {832, 0x0b06}, {896, 0x012a}, {960, 0x0107},
- {1024, 0x012b}, {1088, 0x1607}, {1152, 0x0108}, {1216, 0x2b07},
- {1280, 0x0109}, {1408, 0x1609}, {1536, 0x010a}, {1664, 0x160a},
- {1792, 0x012e}, {1920, 0x010b}, {2048, 0x012f}, {2176, 0x2b0b},
- {2304, 0x010c}, {2560, 0x010d}, {2816, 0x2b0d}, {3072, 0x010e},
- {3328, 0x2b0e}, {3584, 0x0132}, {3840, 0x010f}, {4096, 0x0133},
- {4608, 0x0110}, {5120, 0x0111}, {6144, 0x0112}, {7168, 0x0136},
- {7680, 0x0113}, {8192, 0x0137}, {9216, 0x0114}, {10240, 0x0115},
- {12288, 0x0116}, {14336, 0x013a}, {15360, 0x0117}, {16384, 0x013b},
- {18432, 0x0118}, {20480, 0x0119}, {24576, 0x011a}, {28672, 0x013e},
- {30720, 0x011b}, {32768, 0x013f}, {36864, 0x011c}, {40960, 0x011d},
- {49152, 0x011e}, {61440, 0x011f}
-};
-
-static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
-{
- struct device_node *node = NULL;
- u32 __iomem *reg;
- u32 val = 0;
-
- node = of_find_node_by_name(NULL, "global-utilities");
- if (node) {
- const u32 *prop = of_get_property(node, "reg", NULL);
- if (prop) {
- /*
- * Map and check POR Device Status Register 2
- * (PORDEVSR2) at 0xE0014
- */
- reg = ioremap(get_immrbase() + *prop + 0x14, 0x4);
- if (!reg)
- printk(KERN_ERR
- "Error: couldn't map PORDEVSR2\n");
- else
- val = in_be32(reg) & 0x00000080; /* sec-cfg */
- iounmap(reg);
- }
- }
- if (node)
- of_node_put(node);
-
- return val;
-}
-
-static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
- u32 prescaler, u32 *real_clk)
-{
- const struct mpc_i2c_divider *div = NULL;
- u32 divider;
- int i;
-
- if (clock == MPC_I2C_CLOCK_LEGACY) {
- /* see below - default fdr = 0x1031 -> div = 16 * 3072 */
- *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
- return -EINVAL;
- }
-
- /* Determine proper divider value */
- if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
- prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
- if (!prescaler)
- prescaler = 1;
-
- divider = fsl_get_sys_freq() / clock / prescaler;
-
- pr_debug("I2C: src_clock=%d clock=%d divider=%d\n",
- fsl_get_sys_freq(), clock, divider);
-
- /*
- * We want to choose an FDR/DFSR that generates an I2C bus speed that
- * is equal to or lower than the requested speed.
- */
- for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_8xxx); i++) {
- div = &mpc_i2c_dividers_8xxx[i];
- if (div->divider >= divider)
- break;
- }
-
- *real_clk = fsl_get_sys_freq() / prescaler / div->divider;
- return div ? (int)div->fdr : -EINVAL;
-}
-
-static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
-{
- int ret, fdr;
-
- if (clock == MPC_I2C_CLOCK_PRESERVE) {
- dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
- readb(i2c->base + MPC_I2C_DFSRR),
- readb(i2c->base + MPC_I2C_FDR));
- return;
- }
-
- ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, &i2c->real_clk);
- fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
-
- writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
- writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR);
-
- if (ret >= 0)
- dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
- i2c->real_clk, fdr >> 8, fdr & 0xff);
-}
-
-#else /* !CONFIG_FSL_SOC */
-static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
-{
-}
-#endif /* CONFIG_FSL_SOC */
-
-static void mpc_i2c_start(struct mpc_i2c *i2c)
-{
- /* Clear arbitration */
- writeb(0, i2c->base + MPC_I2C_SR);
- /* Start with MEN */
- writeccr(i2c, CCR_MEN);
-}
-
-static void mpc_i2c_stop(struct mpc_i2c *i2c)
-{
- writeccr(i2c, CCR_MEN);
-}
-
-static int mpc_write(struct mpc_i2c *i2c, int target,
- const u8 *data, int length, int restart)
-{
- int i, result;
- unsigned timeout = i2c->adap.timeout;
- u32 flags = restart ? CCR_RSTA : 0;
-
- /* Start as master */
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
- /* Write target byte */
- writeb((target << 1), i2c->base + MPC_I2C_DR);
-
- result = i2c_wait(i2c, timeout, 1);
- if (result < 0)
- return result;
-
- for (i = 0; i < length; i++) {
- /* Write data byte */
- writeb(data[i], i2c->base + MPC_I2C_DR);
-
- result = i2c_wait(i2c, timeout, 1);
- if (result < 0)
- return result;
- }
-
- return 0;
-}
-
-static int mpc_read(struct mpc_i2c *i2c, int target,
- u8 *data, int length, int restart, bool recv_len)
-{
- unsigned timeout = i2c->adap.timeout;
- int i, result;
- u32 flags = restart ? CCR_RSTA : 0;
-
- /* Switch to read - restart */
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
- /* Write target address byte - this time with the read flag set */
- writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
-
- result = i2c_wait(i2c, timeout, 1);
- if (result < 0)
- return result;
-
- if (length) {
- if (length == 1 && !recv_len)
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);
- else
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA);
- /* Dummy read */
- readb(i2c->base + MPC_I2C_DR);
- }
-
- for (i = 0; i < length; i++) {
- u8 byte;
-
- result = i2c_wait(i2c, timeout, 0);
- if (result < 0)
- return result;
-
- /*
- * For block reads, we have to know the total length (1st byte)
- * before we can determine if we are done.
- */
- if (i || !recv_len) {
- /* Generate txack on next to last byte */
- if (i == length - 2)
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA
- | CCR_TXAK);
- /* Do not generate stop on last byte */
- if (i == length - 1)
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA
- | CCR_MTX);
- }
-
- byte = readb(i2c->base + MPC_I2C_DR);
-
- /*
- * Adjust length if first received byte is length.
- * The length is 1 length byte plus actually data length
- */
- if (i == 0 && recv_len) {
- if (byte == 0 || byte > I2C_SMBUS_BLOCK_MAX)
- return -EPROTO;
- length += byte;
- /*
- * For block reads, generate txack here if data length
- * is 1 byte (total length is 2 bytes).
- */
- if (length == 2)
- writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA
- | CCR_TXAK);
- }
- data[i] = byte;
- }
-
- return length;
-}
-
-static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct i2c_msg *pmsg;
- int i;
- int ret = 0;
- unsigned long orig_jiffies = jiffies;
- struct mpc_i2c *i2c = i2c_get_adapdata(adap);
-
- mpc_i2c_start(i2c);
-
- /* Allow bus up to 1s to become not busy */
- while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
- if (signal_pending(current)) {
- dev_dbg(i2c->dev, "Interrupted\n");
- writeccr(i2c, 0);
- return -EINTR;
- }
- if (time_after(jiffies, orig_jiffies + HZ)) {
- u8 status = readb(i2c->base + MPC_I2C_SR);
-
- dev_dbg(i2c->dev, "timeout\n");
- if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
- writeb(status & ~CSR_MAL,
- i2c->base + MPC_I2C_SR);
- mpc_i2c_fixup(i2c);
- }
- return -EIO;
- }
- schedule();
- }
-
- for (i = 0; ret >= 0 && i < num; i++) {
- pmsg = &msgs[i];
- dev_dbg(i2c->dev,
- "Doing %s %d bytes to 0x%02x - %d of %d messages\n",
- pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);
- if (pmsg->flags & I2C_M_RD) {
- bool recv_len = pmsg->flags & I2C_M_RECV_LEN;
-
- ret = mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i,
- recv_len);
- if (recv_len && ret > 0)
- pmsg->len = ret;
- } else {
- ret =
- mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
- }
- }
- mpc_i2c_stop(i2c);
- return (ret < 0) ? ret : num;
-}
-
-static u32 mpc_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
- | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
-}
-
-static const struct i2c_algorithm mpc_algo = {
- .master_xfer = mpc_xfer,
- .functionality = mpc_functionality,
-};
-
-static struct i2c_adapter mpc_ops = {
- .owner = THIS_MODULE,
- .name = "MPC adapter",
- .algo = &mpc_algo,
- .timeout = HZ,
-};
-
-static const struct of_device_id mpc_i2c_of_match[];
-static int __devinit fsl_i2c_probe(struct platform_device *op)
-{
- const struct of_device_id *match;
- struct mpc_i2c *i2c;
- const u32 *prop;
- u32 clock = MPC_I2C_CLOCK_LEGACY;
- int result = 0;
- int plen;
-
- match = of_match_device(mpc_i2c_of_match, &op->dev);
- if (!match)
- return -EINVAL;
-
- i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
- if (!i2c)
- return -ENOMEM;
-
- i2c->dev = &op->dev; /* for debug and error output */
-
- init_waitqueue_head(&i2c->queue);
-
- i2c->base = of_iomap(op->dev.of_node, 0);
- if (!i2c->base) {
- dev_err(i2c->dev, "failed to map controller\n");
- result = -ENOMEM;
- goto fail_map;
- }
-
- i2c->irq = irq_of_parse_and_map(op->dev.of_node, 0);
- if (i2c->irq) { /* no i2c->irq implies polling */
- result = request_irq(i2c->irq, mpc_i2c_isr,
- IRQF_SHARED, "i2c-mpc", i2c);
- if (result < 0) {
- dev_err(i2c->dev, "failed to attach interrupt\n");
- goto fail_request;
- }
- }
-
- if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) {
- clock = MPC_I2C_CLOCK_PRESERVE;
- } else {
- prop = of_get_property(op->dev.of_node, "clock-frequency",
- &plen);
- if (prop && plen == sizeof(u32))
- clock = *prop;
- }
-
- if (match->data) {
- struct mpc_i2c_data *data = match->data;
- data->setup(op->dev.of_node, i2c, clock, data->prescaler);
- } else {
- /* Backwards compatibility */
- if (of_get_property(op->dev.of_node, "dfsrr", NULL))
- mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0);
- }
-
- prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen);
- if (prop && plen == sizeof(u32)) {
- mpc_ops.timeout = *prop * HZ / 1000000;
- if (mpc_ops.timeout < 5)
- mpc_ops.timeout = 5;
- }
- dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
-
- dev_set_drvdata(&op->dev, i2c);
-
- i2c->adap = mpc_ops;
- i2c_set_adapdata(&i2c->adap, i2c);
- i2c->adap.dev.parent = &op->dev;
- i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
-
- result = i2c_add_adapter(&i2c->adap);
- if (result < 0) {
- dev_err(i2c->dev, "failed to add adapter\n");
- goto fail_add;
- }
- of_i2c_register_devices(&i2c->adap);
-
- return result;
-
- fail_add:
- dev_set_drvdata(&op->dev, NULL);
- free_irq(i2c->irq, i2c);
- fail_request:
- irq_dispose_mapping(i2c->irq);
- iounmap(i2c->base);
- fail_map:
- kfree(i2c);
- return result;
-};
-
-static int __devexit fsl_i2c_remove(struct platform_device *op)
-{
- struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
-
- i2c_del_adapter(&i2c->adap);
- dev_set_drvdata(&op->dev, NULL);
-
- if (i2c->irq)
- free_irq(i2c->irq, i2c);
-
- irq_dispose_mapping(i2c->irq);
- iounmap(i2c->base);
- kfree(i2c);
- return 0;
-};
-
-static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
- .setup = mpc_i2c_setup_512x,
-};
-
-static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
- .setup = mpc_i2c_setup_52xx,
-};
-
-static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = {
- .setup = mpc_i2c_setup_8xxx,
-};
-
-static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = {
- .setup = mpc_i2c_setup_8xxx,
- .prescaler = 2,
-};
-
-static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = {
- .setup = mpc_i2c_setup_8xxx,
- .prescaler = 3,
-};
-
-static const struct of_device_id mpc_i2c_of_match[] = {
- {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
- {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
- {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
- {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
- {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
- {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
- {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
- /* Backward compatibility */
- {.compatible = "fsl-i2c", },
- {},
-};
-MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
-
-/* Structure for a device driver */
-static struct platform_driver mpc_i2c_driver = {
- .probe = fsl_i2c_probe,
- .remove = __devexit_p(fsl_i2c_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = DRV_NAME,
- .of_match_table = mpc_i2c_of_match,
- },
-};
-
-module_platform_driver(mpc_i2c_driver);
-
-MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
-MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
- "MPC824x/83xx/85xx/86xx/512x/52xx processors");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-mv64xxx.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-mv64xxx.c
deleted file mode 100644
index 4f44a330..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-mv64xxx.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * Driver for the i2c controller on the Marvell line of host bridges
- * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, and Orion SoC family).
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2005 (c) MontaVista, Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/mv643xx_i2c.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-/* Register defines */
-#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00
-#define MV64XXX_I2C_REG_DATA 0x04
-#define MV64XXX_I2C_REG_CONTROL 0x08
-#define MV64XXX_I2C_REG_STATUS 0x0c
-#define MV64XXX_I2C_REG_BAUD 0x0c
-#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10
-#define MV64XXX_I2C_REG_SOFT_RESET 0x1c
-
-#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004
-#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008
-#define MV64XXX_I2C_REG_CONTROL_STOP 0x00000010
-#define MV64XXX_I2C_REG_CONTROL_START 0x00000020
-#define MV64XXX_I2C_REG_CONTROL_TWSIEN 0x00000040
-#define MV64XXX_I2C_REG_CONTROL_INTEN 0x00000080
-
-/* Ctlr status values */
-#define MV64XXX_I2C_STATUS_BUS_ERR 0x00
-#define MV64XXX_I2C_STATUS_MAST_START 0x08
-#define MV64XXX_I2C_STATUS_MAST_REPEAT_START 0x10
-#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
-#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
-#define MV64XXX_I2C_STATUS_MAST_WR_ACK 0x28
-#define MV64XXX_I2C_STATUS_MAST_WR_NO_ACK 0x30
-#define MV64XXX_I2C_STATUS_MAST_LOST_ARB 0x38
-#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
-#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
-#define MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK 0x50
-#define MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
-#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
-#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
-#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
-#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
-#define MV64XXX_I2C_STATUS_NO_STATUS 0xf8
-
-/* Driver states */
-enum {
- MV64XXX_I2C_STATE_INVALID,
- MV64XXX_I2C_STATE_IDLE,
- MV64XXX_I2C_STATE_WAITING_FOR_START_COND,
- MV64XXX_I2C_STATE_WAITING_FOR_RESTART,
- MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
- MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
-};
-
-/* Driver actions */
-enum {
- MV64XXX_I2C_ACTION_INVALID,
- MV64XXX_I2C_ACTION_CONTINUE,
- MV64XXX_I2C_ACTION_SEND_START,
- MV64XXX_I2C_ACTION_SEND_RESTART,
- MV64XXX_I2C_ACTION_SEND_ADDR_1,
- MV64XXX_I2C_ACTION_SEND_ADDR_2,
- MV64XXX_I2C_ACTION_SEND_DATA,
- MV64XXX_I2C_ACTION_RCV_DATA,
- MV64XXX_I2C_ACTION_RCV_DATA_STOP,
- MV64XXX_I2C_ACTION_SEND_STOP,
-};
-
-struct mv64xxx_i2c_data {
- int irq;
- u32 state;
- u32 action;
- u32 aborting;
- u32 cntl_bits;
- void __iomem *reg_base;
- u32 reg_base_p;
- u32 reg_size;
- u32 addr1;
- u32 addr2;
- u32 bytes_left;
- u32 byte_posn;
- u32 send_stop;
- u32 block;
- int rc;
- u32 freq_m;
- u32 freq_n;
- wait_queue_head_t waitq;
- spinlock_t lock;
- struct i2c_msg *msg;
- struct i2c_adapter adapter;
-};
-
-/*
- *****************************************************************************
- *
- * Finite State Machine & Interrupt Routines
- *
- *****************************************************************************
- */
-
-/* Reset hardware and initialize FSM */
-static void
-mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
-{
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
- writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
- drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
- writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
-}
-
-static void
-mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
-{
- /*
- * If state is idle, then this is likely the remnants of an old
- * operation that driver has given up on or the user has killed.
- * If so, issue the stop condition and go to idle.
- */
- if (drv_data->state == MV64XXX_I2C_STATE_IDLE) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- return;
- }
-
- /* The status from the ctlr [mostly] tells us what to do next */
- switch (status) {
- /* Start condition interrupt */
- case MV64XXX_I2C_STATUS_MAST_START: /* 0x08 */
- case MV64XXX_I2C_STATUS_MAST_REPEAT_START: /* 0x10 */
- drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
- drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
- break;
-
- /* Performing a write */
- case MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK: /* 0x18 */
- if (drv_data->msg->flags & I2C_M_TEN) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_2;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
- break;
- }
- /* FALLTHRU */
- case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
- case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
- if ((drv_data->bytes_left == 0)
- || (drv_data->aborting
- && (drv_data->byte_posn != 0))) {
- if (drv_data->send_stop) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
- } else {
- drv_data->action =
- MV64XXX_I2C_ACTION_SEND_RESTART;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_RESTART;
- }
- } else {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
- drv_data->bytes_left--;
- }
- break;
-
- /* Performing a read */
- case MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK: /* 40 */
- if (drv_data->msg->flags & I2C_M_TEN) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_2;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
- break;
- }
- /* FALLTHRU */
- case MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */
- if (drv_data->bytes_left == 0) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
- break;
- }
- /* FALLTHRU */
- case MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */
- if (status != MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK)
- drv_data->action = MV64XXX_I2C_ACTION_CONTINUE;
- else {
- drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA;
- drv_data->bytes_left--;
- }
- drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
-
- if ((drv_data->bytes_left == 1) || drv_data->aborting)
- drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
- break;
-
- case MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK: /* 0x58 */
- drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
- break;
-
- case MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK: /* 0x20 */
- case MV64XXX_I2C_STATUS_MAST_WR_NO_ACK: /* 30 */
- case MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK: /* 48 */
- /* Doesn't seem to be a device at other end */
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
- drv_data->rc = -ENODEV;
- break;
-
- default:
- dev_err(&drv_data->adapter.dev,
- "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, "
- "status: 0x%x, addr: 0x%x, flags: 0x%x\n",
- drv_data->state, status, drv_data->msg->addr,
- drv_data->msg->flags);
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- mv64xxx_i2c_hw_init(drv_data);
- drv_data->rc = -EIO;
- }
-}
-
-static void
-mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
-{
- switch(drv_data->action) {
- case MV64XXX_I2C_ACTION_SEND_RESTART:
- drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
- drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
- writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- drv_data->block = 0;
- wake_up_interruptible(&drv_data->waitq);
- break;
-
- case MV64XXX_I2C_ACTION_CONTINUE:
- writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- break;
-
- case MV64XXX_I2C_ACTION_SEND_START:
- writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- break;
-
- case MV64XXX_I2C_ACTION_SEND_ADDR_1:
- writel(drv_data->addr1,
- drv_data->reg_base + MV64XXX_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- break;
-
- case MV64XXX_I2C_ACTION_SEND_ADDR_2:
- writel(drv_data->addr2,
- drv_data->reg_base + MV64XXX_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- break;
-
- case MV64XXX_I2C_ACTION_SEND_DATA:
- writel(drv_data->msg->buf[drv_data->byte_posn++],
- drv_data->reg_base + MV64XXX_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- break;
-
- case MV64XXX_I2C_ACTION_RCV_DATA:
- drv_data->msg->buf[drv_data->byte_posn++] =
- readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- break;
-
- case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
- drv_data->msg->buf[drv_data->byte_posn++] =
- readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
- drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
- writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- drv_data->block = 0;
- wake_up_interruptible(&drv_data->waitq);
- break;
-
- case MV64XXX_I2C_ACTION_INVALID:
- default:
- dev_err(&drv_data->adapter.dev,
- "mv64xxx_i2c_do_action: Invalid action: %d\n",
- drv_data->action);
- drv_data->rc = -EIO;
- /* FALLTHRU */
- case MV64XXX_I2C_ACTION_SEND_STOP:
- drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
- writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- drv_data->block = 0;
- wake_up_interruptible(&drv_data->waitq);
- break;
- }
-}
-
-static irqreturn_t
-mv64xxx_i2c_intr(int irq, void *dev_id)
-{
- struct mv64xxx_i2c_data *drv_data = dev_id;
- unsigned long flags;
- u32 status;
- irqreturn_t rc = IRQ_NONE;
-
- spin_lock_irqsave(&drv_data->lock, flags);
- while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) &
- MV64XXX_I2C_REG_CONTROL_IFLG) {
- status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS);
- mv64xxx_i2c_fsm(drv_data, status);
- mv64xxx_i2c_do_action(drv_data);
- rc = IRQ_HANDLED;
- }
- spin_unlock_irqrestore(&drv_data->lock, flags);
-
- return rc;
-}
-
-/*
- *****************************************************************************
- *
- * I2C Msg Execution Routines
- *
- *****************************************************************************
- */
-static void
-mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
- struct i2c_msg *msg)
-{
- u32 dir = 0;
-
- drv_data->msg = msg;
- drv_data->byte_posn = 0;
- drv_data->bytes_left = msg->len;
- drv_data->aborting = 0;
- drv_data->rc = 0;
- drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
- MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
-
- if (msg->flags & I2C_M_RD)
- dir = 1;
-
- if (msg->flags & I2C_M_TEN) {
- drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
- drv_data->addr2 = (u32)msg->addr & 0xff;
- } else {
- drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
- drv_data->addr2 = 0;
- }
-}
-
-static void
-mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
-{
- long time_left;
- unsigned long flags;
- char abort = 0;
-
- time_left = wait_event_interruptible_timeout(drv_data->waitq,
- !drv_data->block, drv_data->adapter.timeout);
-
- spin_lock_irqsave(&drv_data->lock, flags);
- if (!time_left) { /* Timed out */
- drv_data->rc = -ETIMEDOUT;
- abort = 1;
- } else if (time_left < 0) { /* Interrupted/Error */
- drv_data->rc = time_left; /* errno value */
- abort = 1;
- }
-
- if (abort && drv_data->block) {
- drv_data->aborting = 1;
- spin_unlock_irqrestore(&drv_data->lock, flags);
-
- time_left = wait_event_timeout(drv_data->waitq,
- !drv_data->block, drv_data->adapter.timeout);
-
- if ((time_left <= 0) && drv_data->block) {
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
- dev_err(&drv_data->adapter.dev,
- "mv64xxx: I2C bus locked, block: %d, "
- "time_left: %d\n", drv_data->block,
- (int)time_left);
- mv64xxx_i2c_hw_init(drv_data);
- }
- } else
- spin_unlock_irqrestore(&drv_data->lock, flags);
-}
-
-static int
-mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
- int is_first, int is_last)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&drv_data->lock, flags);
- mv64xxx_i2c_prepare_for_io(drv_data, msg);
-
- if (unlikely(msg->flags & I2C_M_NOSTART)) { /* Skip start/addr phases */
- if (drv_data->msg->flags & I2C_M_RD) {
- /* No action to do, wait for slave to send a byte */
- drv_data->action = MV64XXX_I2C_ACTION_CONTINUE;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
- } else {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
- drv_data->bytes_left--;
- }
- } else {
- if (is_first) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
- } else {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
- drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
- }
- }
-
- drv_data->send_stop = is_last;
- drv_data->block = 1;
- mv64xxx_i2c_do_action(drv_data);
- spin_unlock_irqrestore(&drv_data->lock, flags);
-
- mv64xxx_i2c_wait_for_completion(drv_data);
- return drv_data->rc;
-}
-
-/*
- *****************************************************************************
- *
- * I2C Core Support Routines (Interface to higher level I2C code)
- *
- *****************************************************************************
- */
-static u32
-mv64xxx_i2c_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
-}
-
-static int
-mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-{
- struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
- int i, rc;
-
- for (i = 0; i < num; i++) {
- rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i],
- i == 0, i + 1 == num);
- if (rc < 0)
- return rc;
- }
-
- return num;
-}
-
-static const struct i2c_algorithm mv64xxx_i2c_algo = {
- .master_xfer = mv64xxx_i2c_xfer,
- .functionality = mv64xxx_i2c_functionality,
-};
-
-/*
- *****************************************************************************
- *
- * Driver Interface & Early Init Routines
- *
- *****************************************************************************
- */
-static int __devinit
-mv64xxx_i2c_map_regs(struct platform_device *pd,
- struct mv64xxx_i2c_data *drv_data)
-{
- int size;
- struct resource *r = platform_get_resource(pd, IORESOURCE_MEM, 0);
-
- if (!r)
- return -ENODEV;
-
- size = resource_size(r);
-
- if (!request_mem_region(r->start, size, drv_data->adapter.name))
- return -EBUSY;
-
- drv_data->reg_base = ioremap(r->start, size);
- drv_data->reg_base_p = r->start;
- drv_data->reg_size = size;
-
- return 0;
-}
-
-static void
-mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
-{
- if (drv_data->reg_base) {
- iounmap(drv_data->reg_base);
- release_mem_region(drv_data->reg_base_p, drv_data->reg_size);
- }
-
- drv_data->reg_base = NULL;
- drv_data->reg_base_p = 0;
-}
-
-static int __devinit
-mv64xxx_i2c_probe(struct platform_device *pd)
-{
- struct mv64xxx_i2c_data *drv_data;
- struct mv64xxx_i2c_pdata *pdata = pd->dev.platform_data;
- int rc;
-
- if ((pd->id != 0) || !pdata)
- return -ENODEV;
-
- drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
- if (!drv_data)
- return -ENOMEM;
-
- if (mv64xxx_i2c_map_regs(pd, drv_data)) {
- rc = -ENODEV;
- goto exit_kfree;
- }
-
- strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
- sizeof(drv_data->adapter.name));
-
- init_waitqueue_head(&drv_data->waitq);
- spin_lock_init(&drv_data->lock);
-
- drv_data->freq_m = pdata->freq_m;
- drv_data->freq_n = pdata->freq_n;
- drv_data->irq = platform_get_irq(pd, 0);
- if (drv_data->irq < 0) {
- rc = -ENXIO;
- goto exit_unmap_regs;
- }
- drv_data->adapter.dev.parent = &pd->dev;
- drv_data->adapter.algo = &mv64xxx_i2c_algo;
- drv_data->adapter.owner = THIS_MODULE;
- drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
- drv_data->adapter.nr = pd->id;
- platform_set_drvdata(pd, drv_data);
- i2c_set_adapdata(&drv_data->adapter, drv_data);
-
- mv64xxx_i2c_hw_init(drv_data);
-
- if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
- MV64XXX_I2C_CTLR_NAME, drv_data)) {
- dev_err(&drv_data->adapter.dev,
- "mv64xxx: Can't register intr handler irq: %d\n",
- drv_data->irq);
- rc = -EINVAL;
- goto exit_unmap_regs;
- } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
- dev_err(&drv_data->adapter.dev,
- "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
- goto exit_free_irq;
- }
-
- return 0;
-
- exit_free_irq:
- free_irq(drv_data->irq, drv_data);
- exit_unmap_regs:
- mv64xxx_i2c_unmap_regs(drv_data);
- exit_kfree:
- kfree(drv_data);
- return rc;
-}
-
-static int __devexit
-mv64xxx_i2c_remove(struct platform_device *dev)
-{
- struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(dev);
- int rc;
-
- rc = i2c_del_adapter(&drv_data->adapter);
- free_irq(drv_data->irq, drv_data);
- mv64xxx_i2c_unmap_regs(drv_data);
- kfree(drv_data);
-
- return rc;
-}
-
-static struct platform_driver mv64xxx_i2c_driver = {
- .probe = mv64xxx_i2c_probe,
- .remove = __devexit_p(mv64xxx_i2c_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = MV64XXX_I2C_CTLR_NAME,
- },
-};
-
-module_platform_driver(mv64xxx_i2c_driver);
-
-MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
-MODULE_DESCRIPTION("Marvell mv64xxx host bridge i2c ctlr driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-mxs.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-mxs.c
deleted file mode 100644
index 76b8af44..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-mxs.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Freescale MXS I2C bus driver
- *
- * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.
- *
- * based on a (non-working) driver which was:
- *
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * TODO: add dma-support if platform-support for it is available
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/completion.h>
-#include <linux/platform_device.h>
-#include <linux/jiffies.h>
-#include <linux/io.h>
-
-#include <mach/common.h>
-
-#define DRIVER_NAME "mxs-i2c"
-
-#define MXS_I2C_CTRL0 (0x00)
-#define MXS_I2C_CTRL0_SET (0x04)
-
-#define MXS_I2C_CTRL0_SFTRST 0x80000000
-#define MXS_I2C_CTRL0_SEND_NAK_ON_LAST 0x02000000
-#define MXS_I2C_CTRL0_RETAIN_CLOCK 0x00200000
-#define MXS_I2C_CTRL0_POST_SEND_STOP 0x00100000
-#define MXS_I2C_CTRL0_PRE_SEND_START 0x00080000
-#define MXS_I2C_CTRL0_MASTER_MODE 0x00020000
-#define MXS_I2C_CTRL0_DIRECTION 0x00010000
-#define MXS_I2C_CTRL0_XFER_COUNT(v) ((v) & 0x0000FFFF)
-
-#define MXS_I2C_CTRL1 (0x40)
-#define MXS_I2C_CTRL1_SET (0x44)
-#define MXS_I2C_CTRL1_CLR (0x48)
-
-#define MXS_I2C_CTRL1_BUS_FREE_IRQ 0x80
-#define MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ 0x40
-#define MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ 0x20
-#define MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ 0x10
-#define MXS_I2C_CTRL1_EARLY_TERM_IRQ 0x08
-#define MXS_I2C_CTRL1_MASTER_LOSS_IRQ 0x04
-#define MXS_I2C_CTRL1_SLAVE_STOP_IRQ 0x02
-#define MXS_I2C_CTRL1_SLAVE_IRQ 0x01
-
-#define MXS_I2C_IRQ_MASK (MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ | \
- MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ | \
- MXS_I2C_CTRL1_EARLY_TERM_IRQ | \
- MXS_I2C_CTRL1_MASTER_LOSS_IRQ | \
- MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \
- MXS_I2C_CTRL1_SLAVE_IRQ)
-
-#define MXS_I2C_QUEUECTRL (0x60)
-#define MXS_I2C_QUEUECTRL_SET (0x64)
-#define MXS_I2C_QUEUECTRL_CLR (0x68)
-
-#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20
-#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04
-
-#define MXS_I2C_QUEUESTAT (0x70)
-#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000
-#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F
-
-#define MXS_I2C_QUEUECMD (0x80)
-
-#define MXS_I2C_QUEUEDATA (0x90)
-
-#define MXS_I2C_DATA (0xa0)
-
-
-#define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \
- MXS_I2C_CTRL0_PRE_SEND_START | \
- MXS_I2C_CTRL0_MASTER_MODE | \
- MXS_I2C_CTRL0_DIRECTION | \
- MXS_I2C_CTRL0_XFER_COUNT(1))
-
-#define MXS_CMD_I2C_WRITE (MXS_I2C_CTRL0_PRE_SEND_START | \
- MXS_I2C_CTRL0_MASTER_MODE | \
- MXS_I2C_CTRL0_DIRECTION)
-
-#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
- MXS_I2C_CTRL0_MASTER_MODE)
-
-/**
- * struct mxs_i2c_dev - per device, private MXS-I2C data
- *
- * @dev: driver model device node
- * @regs: IO registers pointer
- * @cmd_complete: completion object for transaction wait
- * @cmd_err: error code for last transaction
- * @adapter: i2c subsystem adapter node
- */
-struct mxs_i2c_dev {
- struct device *dev;
- void __iomem *regs;
- struct completion cmd_complete;
- u32 cmd_err;
- struct i2c_adapter adapter;
-};
-
-/*
- * TODO: check if calls to here are really needed. If not, we could get rid of
- * mxs_reset_block and the mach-dependency. Needs an I2C analyzer, probably.
- */
-static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
-{
- mxs_reset_block(i2c->regs);
- writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
- writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
- i2c->regs + MXS_I2C_QUEUECTRL_SET);
-}
-
-static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len,
- int flags)
-{
- u32 data;
-
- writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD);
-
- data = (addr << 1) | I2C_SMBUS_READ;
- writel(data, i2c->regs + MXS_I2C_DATA);
-
- data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags;
- writel(data, i2c->regs + MXS_I2C_QUEUECMD);
-}
-
-static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c,
- u8 addr, u8 *buf, int len, int flags)
-{
- u32 data;
- int i, shifts_left;
-
- data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags;
- writel(data, i2c->regs + MXS_I2C_QUEUECMD);
-
- /*
- * We have to copy the slave address (u8) and buffer (arbitrary number
- * of u8) into the data register (u32). To achieve that, the u8 are put
- * into the MSBs of 'data' which is then shifted for the next u8. When
- * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32
- * looks like this:
- *
- * 3 2 1 0
- * 10987654|32109876|54321098|76543210
- * --------+--------+--------+--------
- * buffer+2|buffer+1|buffer+0|slave_addr
- */
-
- data = ((addr << 1) | I2C_SMBUS_WRITE) << 24;
-
- for (i = 0; i < len; i++) {
- data >>= 8;
- data |= buf[i] << 24;
- if ((i & 3) == 2)
- writel(data, i2c->regs + MXS_I2C_DATA);
- }
-
- /* Write out the remaining bytes if any */
- shifts_left = 24 - (i & 3) * 8;
- if (shifts_left)
- writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA);
-}
-
-/*
- * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the
- * rd_threshold to 1). Couldn't get this to work, though.
- */
-static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c)
-{
- unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-
- while (readl(i2c->regs + MXS_I2C_QUEUESTAT)
- & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) {
- if (time_after(jiffies, timeout))
- return -ETIMEDOUT;
- cond_resched();
- }
-
- return 0;
-}
-
-static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len)
-{
- u32 data;
- int i;
-
- for (i = 0; i < len; i++) {
- if ((i & 3) == 0) {
- if (mxs_i2c_wait_for_data(i2c))
- return -ETIMEDOUT;
- data = readl(i2c->regs + MXS_I2C_QUEUEDATA);
- }
- buf[i] = data & 0xff;
- data >>= 8;
- }
-
- return 0;
-}
-
-/*
- * Low level master read/write transaction.
- */
-static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
- int stop)
-{
- struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
- int ret;
- int flags;
-
- dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
- msg->addr, msg->len, msg->flags, stop);
-
- if (msg->len == 0)
- return -EINVAL;
-
- init_completion(&i2c->cmd_complete);
- i2c->cmd_err = 0;
-
- flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
-
- if (msg->flags & I2C_M_RD)
- mxs_i2c_pioq_setup_read(i2c, msg->addr, msg->len, flags);
- else
- mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, msg->len,
- flags);
-
- writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
- i2c->regs + MXS_I2C_QUEUECTRL_SET);
-
- ret = wait_for_completion_timeout(&i2c->cmd_complete,
- msecs_to_jiffies(1000));
- if (ret == 0)
- goto timeout;
-
- if ((!i2c->cmd_err) && (msg->flags & I2C_M_RD)) {
- ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len);
- if (ret)
- goto timeout;
- }
-
- if (i2c->cmd_err == -ENXIO)
- mxs_i2c_reset(i2c);
- else
- writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
- i2c->regs + MXS_I2C_QUEUECTRL_CLR);
-
- dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
-
- return i2c->cmd_err;
-
-timeout:
- dev_dbg(i2c->dev, "Timeout!\n");
- mxs_i2c_reset(i2c);
- return -ETIMEDOUT;
-}
-
-static int mxs_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
- int num)
-{
- int i;
- int err;
-
- for (i = 0; i < num; i++) {
- err = mxs_i2c_xfer_msg(adap, &msgs[i], i == (num - 1));
- if (err)
- return err;
- }
-
- return num;
-}
-
-static u32 mxs_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
-}
-
-static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
-{
- struct mxs_i2c_dev *i2c = dev_id;
- u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK;
- bool is_last_cmd;
-
- if (!stat)
- return IRQ_NONE;
-
- if (stat & MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ)
- i2c->cmd_err = -ENXIO;
- else if (stat & (MXS_I2C_CTRL1_EARLY_TERM_IRQ |
- MXS_I2C_CTRL1_MASTER_LOSS_IRQ |
- MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))
- /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
- i2c->cmd_err = -EIO;
-
- is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
- MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
-
- if (is_last_cmd || i2c->cmd_err)
- complete(&i2c->cmd_complete);
-
- writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
-
- return IRQ_HANDLED;
-}
-
-static const struct i2c_algorithm mxs_i2c_algo = {
- .master_xfer = mxs_i2c_xfer,
- .functionality = mxs_i2c_func,
-};
-
-static int __devinit mxs_i2c_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mxs_i2c_dev *i2c;
- struct i2c_adapter *adap;
- struct resource *res;
- resource_size_t res_size;
- int err, irq;
-
- i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
- if (!i2c)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENOENT;
-
- res_size = resource_size(res);
- if (!devm_request_mem_region(dev, res->start, res_size, res->name))
- return -EBUSY;
-
- i2c->regs = devm_ioremap_nocache(dev, res->start, res_size);
- if (!i2c->regs)
- return -EBUSY;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c);
- if (err)
- return err;
-
- i2c->dev = dev;
- platform_set_drvdata(pdev, i2c);
-
- /* Do reset to enforce correct startup after pinmuxing */
- mxs_i2c_reset(i2c);
-
- adap = &i2c->adapter;
- strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
- adap->owner = THIS_MODULE;
- adap->algo = &mxs_i2c_algo;
- adap->dev.parent = dev;
- adap->nr = pdev->id;
- i2c_set_adapdata(adap, i2c);
- err = i2c_add_numbered_adapter(adap);
- if (err) {
- dev_err(dev, "Failed to add adapter (%d)\n", err);
- writel(MXS_I2C_CTRL0_SFTRST,
- i2c->regs + MXS_I2C_CTRL0_SET);
- return err;
- }
-
- return 0;
-}
-
-static int __devexit mxs_i2c_remove(struct platform_device *pdev)
-{
- struct mxs_i2c_dev *i2c = platform_get_drvdata(pdev);
- int ret;
-
- ret = i2c_del_adapter(&i2c->adapter);
- if (ret)
- return -EBUSY;
-
- writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver mxs_i2c_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- },
- .remove = __devexit_p(mxs_i2c_remove),
-};
-
-static int __init mxs_i2c_init(void)
-{
- return platform_driver_probe(&mxs_i2c_driver, mxs_i2c_probe);
-}
-subsys_initcall(mxs_i2c_init);
-
-static void __exit mxs_i2c_exit(void)
-{
- platform_driver_unregister(&mxs_i2c_driver);
-}
-module_exit(mxs_i2c_exit);
-
-MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("MXS I2C Bus Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2-s4985.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2-s4985.c
deleted file mode 100644
index 29015eb9..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2-s4985.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * i2c-nforce2-s4985.c - i2c-nforce2 extras for the Tyan S4985 motherboard
- *
- * Copyright (C) 2008 Jean Delvare <khali@linux-fr.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * We select the channels by sending commands to the Philips
- * PCA9556 chip at I2C address 0x18. The main adapter is used for
- * the non-multiplexed part of the bus, and 4 virtual adapters
- * are defined for the multiplexed addresses: 0x50-0x53 (memory
- * module EEPROM) located on channels 1-4. We define one virtual
- * adapter per CPU, which corresponds to one multiplexed channel:
- * CPU0: virtual adapter 1, channel 1
- * CPU1: virtual adapter 2, channel 2
- * CPU2: virtual adapter 3, channel 3
- * CPU3: virtual adapter 4, channel 4
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-extern struct i2c_adapter *nforce2_smbus;
-
-static struct i2c_adapter *s4985_adapter;
-static struct i2c_algorithm *s4985_algo;
-
-/* Wrapper access functions for multiplexed SMBus */
-static DEFINE_MUTEX(nforce2_lock);
-
-static s32 nforce2_access_virt0(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data)
-{
- int error;
-
- /* We exclude the multiplexed addresses */
- if ((addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
- || addr == 0x18)
- return -ENXIO;
-
- mutex_lock(&nforce2_lock);
- error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
- command, size, data);
- mutex_unlock(&nforce2_lock);
-
- return error;
-}
-
-/* We remember the last used channels combination so as to only switch
- channels when it is really needed. This greatly reduces the SMBus
- overhead, but also assumes that nobody will be writing to the PCA9556
- in our back. */
-static u8 last_channels;
-
-static inline s32 nforce2_access_channel(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data,
- u8 channels)
-{
- int error;
-
- /* We exclude the non-multiplexed addresses */
- if ((addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
- return -ENXIO;
-
- mutex_lock(&nforce2_lock);
- if (last_channels != channels) {
- union i2c_smbus_data mplxdata;
- mplxdata.byte = channels;
-
- error = nforce2_smbus->algo->smbus_xfer(adap, 0x18, 0,
- I2C_SMBUS_WRITE, 0x01,
- I2C_SMBUS_BYTE_DATA,
- &mplxdata);
- if (error)
- goto UNLOCK;
- last_channels = channels;
- }
- error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
- command, size, data);
-
-UNLOCK:
- mutex_unlock(&nforce2_lock);
- return error;
-}
-
-static s32 nforce2_access_virt1(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data)
-{
- /* CPU0: channel 1 enabled */
- return nforce2_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x02);
-}
-
-static s32 nforce2_access_virt2(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data)
-{
- /* CPU1: channel 2 enabled */
- return nforce2_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x04);
-}
-
-static s32 nforce2_access_virt3(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data)
-{
- /* CPU2: channel 3 enabled */
- return nforce2_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x08);
-}
-
-static s32 nforce2_access_virt4(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size,
- union i2c_smbus_data *data)
-{
- /* CPU3: channel 4 enabled */
- return nforce2_access_channel(adap, addr, flags, read_write, command,
- size, data, 0x10);
-}
-
-static int __init nforce2_s4985_init(void)
-{
- int i, error;
- union i2c_smbus_data ioconfig;
-
- if (!nforce2_smbus)
- return -ENODEV;
-
- /* Configure the PCA9556 multiplexer */
- ioconfig.byte = 0x00; /* All I/O to output mode */
- error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
- I2C_SMBUS_BYTE_DATA, &ioconfig);
- if (error) {
- dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
- error = -EIO;
- goto ERROR0;
- }
-
- /* Unregister physical bus */
- error = i2c_del_adapter(nforce2_smbus);
- if (error) {
- dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n");
- goto ERROR0;
- }
-
- printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n");
- /* Define the 5 virtual adapters and algorithms structures */
- s4985_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL);
- if (!s4985_adapter) {
- error = -ENOMEM;
- goto ERROR1;
- }
- s4985_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL);
- if (!s4985_algo) {
- error = -ENOMEM;
- goto ERROR2;
- }
-
- /* Fill in the new structures */
- s4985_algo[0] = *(nforce2_smbus->algo);
- s4985_algo[0].smbus_xfer = nforce2_access_virt0;
- s4985_adapter[0] = *nforce2_smbus;
- s4985_adapter[0].algo = s4985_algo;
- s4985_adapter[0].dev.parent = nforce2_smbus->dev.parent;
- for (i = 1; i < 5; i++) {
- s4985_algo[i] = *(nforce2_smbus->algo);
- s4985_adapter[i] = *nforce2_smbus;
- snprintf(s4985_adapter[i].name, sizeof(s4985_adapter[i].name),
- "SMBus nForce2 adapter (CPU%d)", i - 1);
- s4985_adapter[i].algo = s4985_algo + i;
- s4985_adapter[i].dev.parent = nforce2_smbus->dev.parent;
- }
- s4985_algo[1].smbus_xfer = nforce2_access_virt1;
- s4985_algo[2].smbus_xfer = nforce2_access_virt2;
- s4985_algo[3].smbus_xfer = nforce2_access_virt3;
- s4985_algo[4].smbus_xfer = nforce2_access_virt4;
-
- /* Register virtual adapters */
- for (i = 0; i < 5; i++) {
- error = i2c_add_adapter(s4985_adapter + i);
- if (error) {
- printk(KERN_ERR "i2c-nforce2-s4985: "
- "Virtual adapter %d registration "
- "failed, module not inserted\n", i);
- for (i--; i >= 0; i--)
- i2c_del_adapter(s4985_adapter + i);
- goto ERROR3;
- }
- }
-
- return 0;
-
-ERROR3:
- kfree(s4985_algo);
- s4985_algo = NULL;
-ERROR2:
- kfree(s4985_adapter);
- s4985_adapter = NULL;
-ERROR1:
- /* Restore physical bus */
- i2c_add_adapter(nforce2_smbus);
-ERROR0:
- return error;
-}
-
-static void __exit nforce2_s4985_exit(void)
-{
- if (s4985_adapter) {
- int i;
-
- for (i = 0; i < 5; i++)
- i2c_del_adapter(s4985_adapter+i);
- kfree(s4985_adapter);
- s4985_adapter = NULL;
- }
- kfree(s4985_algo);
- s4985_algo = NULL;
-
- /* Restore physical bus */
- if (i2c_add_adapter(nforce2_smbus))
- printk(KERN_ERR "i2c-nforce2-s4985: "
- "Physical bus restoration failed\n");
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("S4985 SMBus multiplexing");
-MODULE_LICENSE("GPL");
-
-module_init(nforce2_s4985_init);
-module_exit(nforce2_s4985_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2.c
deleted file mode 100644
index 43a96a12..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nforce2.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- SMBus driver for nVidia nForce2 MCP
-
- Added nForce3 Pro 150 Thomas Leibold <thomas@plx.com>,
- Ported to 2.5 Patrick Dreker <patrick@dreker.de>,
- Copyright (c) 2003 Hans-Frieder Vogt <hfvogt@arcor.de>,
- Based on
- SMBus 2.0 driver for AMD-8111 IO-Hub
- Copyright (c) 2002 Vojtech Pavlik
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- SUPPORTED DEVICES PCI ID
- nForce2 MCP 0064
- nForce2 Ultra 400 MCP 0084
- nForce3 Pro150 MCP 00D4
- nForce3 250Gb MCP 00E4
- nForce4 MCP 0052
- nForce4 MCP-04 0034
- nForce MCP51 0264
- nForce MCP55 0368
- nForce MCP61 03EB
- nForce MCP65 0446
- nForce MCP67 0542
- nForce MCP73 07D8
- nForce MCP78S 0752
- nForce MCP79 0AA2
-
- This driver supports the 2 SMBuses that are included in the MCP of the
- nForce2/3/4/5xx chipsets.
-*/
-
-/* Note: we assume there can only be one nForce2, with two SMBus interfaces */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/dmi.h>
-#include <linux/acpi.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
-MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
-
-
-struct nforce2_smbus {
- struct i2c_adapter adapter;
- int base;
- int size;
- int blockops;
- int can_abort;
-};
-
-
-/*
- * nVidia nForce2 SMBus control register definitions
- * (Newer incarnations use standard BARs 4 and 5 instead)
- */
-#define NFORCE_PCI_SMB1 0x50
-#define NFORCE_PCI_SMB2 0x54
-
-
-/*
- * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
- */
-#define NVIDIA_SMB_PRTCL (smbus->base + 0x00) /* protocol, PEC */
-#define NVIDIA_SMB_STS (smbus->base + 0x01) /* status */
-#define NVIDIA_SMB_ADDR (smbus->base + 0x02) /* address */
-#define NVIDIA_SMB_CMD (smbus->base + 0x03) /* command */
-#define NVIDIA_SMB_DATA (smbus->base + 0x04) /* 32 data registers */
-#define NVIDIA_SMB_BCNT (smbus->base + 0x24) /* number of data
- bytes */
-#define NVIDIA_SMB_STATUS_ABRT (smbus->base + 0x3c) /* register used to
- check the status of
- the abort command */
-#define NVIDIA_SMB_CTRL (smbus->base + 0x3e) /* control register */
-
-#define NVIDIA_SMB_STATUS_ABRT_STS 0x01 /* Bit to notify that
- abort succeeded */
-#define NVIDIA_SMB_CTRL_ABORT 0x20
-#define NVIDIA_SMB_STS_DONE 0x80
-#define NVIDIA_SMB_STS_ALRM 0x40
-#define NVIDIA_SMB_STS_RES 0x20
-#define NVIDIA_SMB_STS_STATUS 0x1f
-
-#define NVIDIA_SMB_PRTCL_WRITE 0x00
-#define NVIDIA_SMB_PRTCL_READ 0x01
-#define NVIDIA_SMB_PRTCL_QUICK 0x02
-#define NVIDIA_SMB_PRTCL_BYTE 0x04
-#define NVIDIA_SMB_PRTCL_BYTE_DATA 0x06
-#define NVIDIA_SMB_PRTCL_WORD_DATA 0x08
-#define NVIDIA_SMB_PRTCL_BLOCK_DATA 0x0a
-#define NVIDIA_SMB_PRTCL_PEC 0x80
-
-/* Misc definitions */
-#define MAX_TIMEOUT 100
-
-/* We disable the second SMBus channel on these boards */
-static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = {
- {
- .ident = "DFI Lanparty NF4 Expert",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "DFI Corp,LTD"),
- DMI_MATCH(DMI_BOARD_NAME, "LP UT NF4 Expert"),
- },
- },
- { }
-};
-
-static struct pci_driver nforce2_driver;
-
-/* For multiplexing support, we need a global reference to the 1st
- SMBus channel */
-#if defined CONFIG_I2C_NFORCE2_S4985 || defined CONFIG_I2C_NFORCE2_S4985_MODULE
-struct i2c_adapter *nforce2_smbus;
-EXPORT_SYMBOL_GPL(nforce2_smbus);
-
-static void nforce2_set_reference(struct i2c_adapter *adap)
-{
- nforce2_smbus = adap;
-}
-#else
-static inline void nforce2_set_reference(struct i2c_adapter *adap) { }
-#endif
-
-static void nforce2_abort(struct i2c_adapter *adap)
-{
- struct nforce2_smbus *smbus = adap->algo_data;
- int timeout = 0;
- unsigned char temp;
-
- dev_dbg(&adap->dev, "Aborting current transaction\n");
-
- outb_p(NVIDIA_SMB_CTRL_ABORT, NVIDIA_SMB_CTRL);
- do {
- msleep(1);
- temp = inb_p(NVIDIA_SMB_STATUS_ABRT);
- } while (!(temp & NVIDIA_SMB_STATUS_ABRT_STS) &&
- (timeout++ < MAX_TIMEOUT));
- if (!(temp & NVIDIA_SMB_STATUS_ABRT_STS))
- dev_err(&adap->dev, "Can't reset the smbus\n");
- outb_p(NVIDIA_SMB_STATUS_ABRT_STS, NVIDIA_SMB_STATUS_ABRT);
-}
-
-static int nforce2_check_status(struct i2c_adapter *adap)
-{
- struct nforce2_smbus *smbus = adap->algo_data;
- int timeout = 0;
- unsigned char temp;
-
- do {
- msleep(1);
- temp = inb_p(NVIDIA_SMB_STS);
- } while ((!temp) && (timeout++ < MAX_TIMEOUT));
-
- if (timeout > MAX_TIMEOUT) {
- dev_dbg(&adap->dev, "SMBus Timeout!\n");
- if (smbus->can_abort)
- nforce2_abort(adap);
- return -ETIMEDOUT;
- }
- if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
- dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp);
- return -EIO;
- }
- return 0;
-}
-
-/* Return negative errno on error */
-static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data * data)
-{
- struct nforce2_smbus *smbus = adap->algo_data;
- unsigned char protocol, pec;
- u8 len;
- int i, status;
-
- protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
- NVIDIA_SMB_PRTCL_WRITE;
- pec = (flags & I2C_CLIENT_PEC) ? NVIDIA_SMB_PRTCL_PEC : 0;
-
- switch (size) {
-
- case I2C_SMBUS_QUICK:
- protocol |= NVIDIA_SMB_PRTCL_QUICK;
- read_write = I2C_SMBUS_WRITE;
- break;
-
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, NVIDIA_SMB_CMD);
- protocol |= NVIDIA_SMB_PRTCL_BYTE;
- break;
-
- case I2C_SMBUS_BYTE_DATA:
- outb_p(command, NVIDIA_SMB_CMD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, NVIDIA_SMB_DATA);
- protocol |= NVIDIA_SMB_PRTCL_BYTE_DATA;
- break;
-
- case I2C_SMBUS_WORD_DATA:
- outb_p(command, NVIDIA_SMB_CMD);
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word, NVIDIA_SMB_DATA);
- outb_p(data->word >> 8, NVIDIA_SMB_DATA+1);
- }
- protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
- break;
-
- case I2C_SMBUS_BLOCK_DATA:
- outb_p(command, NVIDIA_SMB_CMD);
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
- dev_err(&adap->dev,
- "Transaction failed "
- "(requested block size: %d)\n",
- len);
- return -EINVAL;
- }
- outb_p(len, NVIDIA_SMB_BCNT);
- for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
- outb_p(data->block[i + 1],
- NVIDIA_SMB_DATA+i);
- }
- protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
- break;
-
- default:
- dev_err(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
- outb_p(protocol, NVIDIA_SMB_PRTCL);
-
- status = nforce2_check_status(adap);
- if (status)
- return status;
-
- if (read_write == I2C_SMBUS_WRITE)
- return 0;
-
- switch (size) {
-
- case I2C_SMBUS_BYTE:
- case I2C_SMBUS_BYTE_DATA:
- data->byte = inb_p(NVIDIA_SMB_DATA);
- break;
-
- case I2C_SMBUS_WORD_DATA:
- data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
- break;
-
- case I2C_SMBUS_BLOCK_DATA:
- len = inb_p(NVIDIA_SMB_BCNT);
- if ((len <= 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
- dev_err(&adap->dev, "Transaction failed "
- "(received block size: 0x%02x)\n",
- len);
- return -EPROTO;
- }
- for (i = 0; i < len; i++)
- data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
- data->block[0] = len;
- break;
- }
-
- return 0;
-}
-
-
-static u32 nforce2_func(struct i2c_adapter *adapter)
-{
- /* other functionality might be possible, but is not tested */
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_PEC |
- (((struct nforce2_smbus*)adapter->algo_data)->blockops ?
- I2C_FUNC_SMBUS_BLOCK_DATA : 0);
-}
-
-static struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = nforce2_access,
- .functionality = nforce2_func,
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE (pci, nforce2_ids);
-
-
-static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
- int alt_reg, struct nforce2_smbus *smbus, const char *name)
-{
- int error;
-
- smbus->base = pci_resource_start(dev, bar);
- if (smbus->base) {
- smbus->size = pci_resource_len(dev, bar);
- } else {
- /* Older incarnations of the device used non-standard BARs */
- u16 iobase;
-
- if (pci_read_config_word(dev, alt_reg, &iobase)
- != PCIBIOS_SUCCESSFUL) {
- dev_err(&dev->dev, "Error reading PCI config for %s\n",
- name);
- return -EIO;
- }
-
- smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
- smbus->size = 64;
- }
-
- error = acpi_check_region(smbus->base, smbus->size,
- nforce2_driver.name);
- if (error)
- return error;
-
- if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
- dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
- smbus->base, smbus->base+smbus->size-1, name);
- return -EBUSY;
- }
- smbus->adapter.owner = THIS_MODULE;
- smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- smbus->adapter.algo = &smbus_algorithm;
- smbus->adapter.algo_data = smbus;
- smbus->adapter.dev.parent = &dev->dev;
- snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
- "SMBus nForce2 adapter at %04x", smbus->base);
-
- error = i2c_add_adapter(&smbus->adapter);
- if (error) {
- dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
- release_region(smbus->base, smbus->size);
- return error;
- }
- dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base);
- return 0;
-}
-
-
-static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- struct nforce2_smbus *smbuses;
- int res1, res2;
-
- /* we support 2 SMBus adapters */
- if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
- return -ENOMEM;
- pci_set_drvdata(dev, smbuses);
-
- switch(dev->device) {
- case PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS:
- case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
- case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
- smbuses[0].blockops = 1;
- smbuses[1].blockops = 1;
- smbuses[0].can_abort = 1;
- smbuses[1].can_abort = 1;
- }
-
- /* SMBus adapter 1 */
- res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
- if (res1 < 0)
- smbuses[0].base = 0; /* to have a check value */
-
- /* SMBus adapter 2 */
- if (dmi_check_system(nforce2_dmi_blacklist2)) {
- dev_err(&dev->dev, "Disabling SMB2 for safety reasons.\n");
- res2 = -EPERM;
- smbuses[1].base = 0;
- } else {
- res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1],
- "SMB2");
- if (res2 < 0)
- smbuses[1].base = 0; /* to have a check value */
- }
-
- if ((res1 < 0) && (res2 < 0)) {
- /* we did not find even one of the SMBuses, so we give up */
- kfree(smbuses);
- return -ENODEV;
- }
-
- nforce2_set_reference(&smbuses[0].adapter);
- return 0;
-}
-
-
-static void __devexit nforce2_remove(struct pci_dev *dev)
-{
- struct nforce2_smbus *smbuses = pci_get_drvdata(dev);
-
- nforce2_set_reference(NULL);
- if (smbuses[0].base) {
- i2c_del_adapter(&smbuses[0].adapter);
- release_region(smbuses[0].base, smbuses[0].size);
- }
- if (smbuses[1].base) {
- i2c_del_adapter(&smbuses[1].adapter);
- release_region(smbuses[1].base, smbuses[1].size);
- }
- kfree(smbuses);
-}
-
-static struct pci_driver nforce2_driver = {
- .name = "nForce2_smbus",
- .id_table = nforce2_ids,
- .probe = nforce2_probe,
- .remove = __devexit_p(nforce2_remove),
-};
-
-static int __init nforce2_init(void)
-{
- return pci_register_driver(&nforce2_driver);
-}
-
-static void __exit nforce2_exit(void)
-{
- pci_unregister_driver(&nforce2_driver);
-}
-
-module_init(nforce2_init);
-module_exit(nforce2_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nomadik.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-nomadik.c
deleted file mode 100644
index 5267ab93..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nomadik.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- * Copyright (C) 2009 ST-Ericsson SA
- * Copyright (C) 2009 STMicroelectronics
- *
- * I2C master mode controller driver, used in Nomadik 8815
- * and Ux500 platforms.
- *
- * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
- * Author: Sachin Verma <sachin.verma@st.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/regulator/consumer.h>
-#include <linux/pm_runtime.h>
-
-#include <plat/i2c.h>
-
-#define DRIVER_NAME "nmk-i2c"
-
-/* I2C Controller register offsets */
-#define I2C_CR (0x000)
-#define I2C_SCR (0x004)
-#define I2C_HSMCR (0x008)
-#define I2C_MCR (0x00C)
-#define I2C_TFR (0x010)
-#define I2C_SR (0x014)
-#define I2C_RFR (0x018)
-#define I2C_TFTR (0x01C)
-#define I2C_RFTR (0x020)
-#define I2C_DMAR (0x024)
-#define I2C_BRCR (0x028)
-#define I2C_IMSCR (0x02C)
-#define I2C_RISR (0x030)
-#define I2C_MISR (0x034)
-#define I2C_ICR (0x038)
-
-/* Control registers */
-#define I2C_CR_PE (0x1 << 0) /* Peripheral Enable */
-#define I2C_CR_OM (0x3 << 1) /* Operating mode */
-#define I2C_CR_SAM (0x1 << 3) /* Slave addressing mode */
-#define I2C_CR_SM (0x3 << 4) /* Speed mode */
-#define I2C_CR_SGCM (0x1 << 6) /* Slave general call mode */
-#define I2C_CR_FTX (0x1 << 7) /* Flush Transmit */
-#define I2C_CR_FRX (0x1 << 8) /* Flush Receive */
-#define I2C_CR_DMA_TX_EN (0x1 << 9) /* DMA Tx enable */
-#define I2C_CR_DMA_RX_EN (0x1 << 10) /* DMA Rx Enable */
-#define I2C_CR_DMA_SLE (0x1 << 11) /* DMA sync. logic enable */
-#define I2C_CR_LM (0x1 << 12) /* Loopback mode */
-#define I2C_CR_FON (0x3 << 13) /* Filtering on */
-#define I2C_CR_FS (0x3 << 15) /* Force stop enable */
-
-/* Master controller (MCR) register */
-#define I2C_MCR_OP (0x1 << 0) /* Operation */
-#define I2C_MCR_A7 (0x7f << 1) /* 7-bit address */
-#define I2C_MCR_EA10 (0x7 << 8) /* 10-bit Extended address */
-#define I2C_MCR_SB (0x1 << 11) /* Extended address */
-#define I2C_MCR_AM (0x3 << 12) /* Address type */
-#define I2C_MCR_STOP (0x1 << 14) /* Stop condition */
-#define I2C_MCR_LENGTH (0x7ff << 15) /* Transaction length */
-
-/* Status register (SR) */
-#define I2C_SR_OP (0x3 << 0) /* Operation */
-#define I2C_SR_STATUS (0x3 << 2) /* controller status */
-#define I2C_SR_CAUSE (0x7 << 4) /* Abort cause */
-#define I2C_SR_TYPE (0x3 << 7) /* Receive type */
-#define I2C_SR_LENGTH (0x7ff << 9) /* Transfer length */
-
-/* Interrupt mask set/clear (IMSCR) bits */
-#define I2C_IT_TXFE (0x1 << 0)
-#define I2C_IT_TXFNE (0x1 << 1)
-#define I2C_IT_TXFF (0x1 << 2)
-#define I2C_IT_TXFOVR (0x1 << 3)
-#define I2C_IT_RXFE (0x1 << 4)
-#define I2C_IT_RXFNF (0x1 << 5)
-#define I2C_IT_RXFF (0x1 << 6)
-#define I2C_IT_RFSR (0x1 << 16)
-#define I2C_IT_RFSE (0x1 << 17)
-#define I2C_IT_WTSR (0x1 << 18)
-#define I2C_IT_MTD (0x1 << 19)
-#define I2C_IT_STD (0x1 << 20)
-#define I2C_IT_MAL (0x1 << 24)
-#define I2C_IT_BERR (0x1 << 25)
-#define I2C_IT_MTDWS (0x1 << 28)
-
-#define GEN_MASK(val, mask, sb) (((val) << (sb)) & (mask))
-
-/* some bits in ICR are reserved */
-#define I2C_CLEAR_ALL_INTS 0x131f007f
-
-/* first three msb bits are reserved */
-#define IRQ_MASK(mask) (mask & 0x1fffffff)
-
-/* maximum threshold value */
-#define MAX_I2C_FIFO_THRESHOLD 15
-
-enum i2c_status {
- I2C_NOP,
- I2C_ON_GOING,
- I2C_OK,
- I2C_ABORT
-};
-
-/* operation */
-enum i2c_operation {
- I2C_NO_OPERATION = 0xff,
- I2C_WRITE = 0x00,
- I2C_READ = 0x01
-};
-
-/**
- * struct i2c_nmk_client - client specific data
- * @slave_adr: 7-bit slave address
- * @count: no. bytes to be transferred
- * @buffer: client data buffer
- * @xfer_bytes: bytes transferred till now
- * @operation: current I2C operation
- */
-struct i2c_nmk_client {
- unsigned short slave_adr;
- unsigned long count;
- unsigned char *buffer;
- unsigned long xfer_bytes;
- enum i2c_operation operation;
-};
-
-/**
- * struct nmk_i2c_dev - private data structure of the controller.
- * @pdev: parent platform device.
- * @adap: corresponding I2C adapter.
- * @irq: interrupt line for the controller.
- * @virtbase: virtual io memory area.
- * @clk: hardware i2c block clock.
- * @cfg: machine provided controller configuration.
- * @cli: holder of client specific data.
- * @stop: stop condition.
- * @xfer_complete: acknowledge completion for a I2C message.
- * @result: controller propogated result.
- * @regulator: pointer to i2c regulator.
- * @busy: Busy doing transfer.
- */
-struct nmk_i2c_dev {
- struct platform_device *pdev;
- struct i2c_adapter adap;
- int irq;
- void __iomem *virtbase;
- struct clk *clk;
- struct nmk_i2c_controller cfg;
- struct i2c_nmk_client cli;
- int stop;
- struct completion xfer_complete;
- int result;
- struct regulator *regulator;
- bool busy;
-};
-
-/* controller's abort causes */
-static const char *abort_causes[] = {
- "no ack received after address transmission",
- "no ack received during data phase",
- "ack received after xmission of master code",
- "master lost arbitration",
- "slave restarts",
- "slave reset",
- "overflow, maxsize is 2047 bytes",
-};
-
-static inline void i2c_set_bit(void __iomem *reg, u32 mask)
-{
- writel(readl(reg) | mask, reg);
-}
-
-static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
-{
- writel(readl(reg) & ~mask, reg);
-}
-
-/**
- * flush_i2c_fifo() - This function flushes the I2C FIFO
- * @dev: private data of I2C Driver
- *
- * This function flushes the I2C Tx and Rx FIFOs. It returns
- * 0 on successful flushing of FIFO
- */
-static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
-{
-#define LOOP_ATTEMPTS 10
- int i;
- unsigned long timeout;
-
- /*
- * flush the transmit and receive FIFO. The flushing
- * operation takes several cycles before to be completed.
- * On the completion, the I2C internal logic clears these
- * bits, until then no one must access Tx, Rx FIFO and
- * should poll on these bits waiting for the completion.
- */
- writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
-
- for (i = 0; i < LOOP_ATTEMPTS; i++) {
- timeout = jiffies + dev->adap.timeout;
-
- while (!time_after(jiffies, timeout)) {
- if ((readl(dev->virtbase + I2C_CR) &
- (I2C_CR_FTX | I2C_CR_FRX)) == 0)
- return 0;
- }
- }
-
- dev_err(&dev->pdev->dev,
- "flushing operation timed out giving up after %d attempts",
- LOOP_ATTEMPTS);
-
- return -ETIMEDOUT;
-}
-
-/**
- * disable_all_interrupts() - Disable all interrupts of this I2c Bus
- * @dev: private data of I2C Driver
- */
-static void disable_all_interrupts(struct nmk_i2c_dev *dev)
-{
- u32 mask = IRQ_MASK(0);
- writel(mask, dev->virtbase + I2C_IMSCR);
-}
-
-/**
- * clear_all_interrupts() - Clear all interrupts of I2C Controller
- * @dev: private data of I2C Driver
- */
-static void clear_all_interrupts(struct nmk_i2c_dev *dev)
-{
- u32 mask;
- mask = IRQ_MASK(I2C_CLEAR_ALL_INTS);
- writel(mask, dev->virtbase + I2C_ICR);
-}
-
-/**
- * init_hw() - initialize the I2C hardware
- * @dev: private data of I2C Driver
- */
-static int init_hw(struct nmk_i2c_dev *dev)
-{
- int stat;
-
- stat = flush_i2c_fifo(dev);
- if (stat)
- goto exit;
-
- /* disable the controller */
- i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
-
- disable_all_interrupts(dev);
-
- clear_all_interrupts(dev);
-
- dev->cli.operation = I2C_NO_OPERATION;
-
-exit:
- return stat;
-}
-
-/* enable peripheral, master mode operation */
-#define DEFAULT_I2C_REG_CR ((1 << 1) | I2C_CR_PE)
-
-/**
- * load_i2c_mcr_reg() - load the MCR register
- * @dev: private data of controller
- */
-static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev)
-{
- u32 mcr = 0;
-
- /* 7-bit address transaction */
- mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
- mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1);
-
- /* start byte procedure not applied */
- mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
-
- /* check the operation, master read/write? */
- if (dev->cli.operation == I2C_WRITE)
- mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
- else
- mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
-
- /* stop or repeated start? */
- if (dev->stop)
- mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
- else
- mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
-
- mcr |= GEN_MASK(dev->cli.count, I2C_MCR_LENGTH, 15);
-
- return mcr;
-}
-
-/**
- * setup_i2c_controller() - setup the controller
- * @dev: private data of controller
- */
-static void setup_i2c_controller(struct nmk_i2c_dev *dev)
-{
- u32 brcr1, brcr2;
- u32 i2c_clk, div;
-
- writel(0x0, dev->virtbase + I2C_CR);
- writel(0x0, dev->virtbase + I2C_HSMCR);
- writel(0x0, dev->virtbase + I2C_TFTR);
- writel(0x0, dev->virtbase + I2C_RFTR);
- writel(0x0, dev->virtbase + I2C_DMAR);
-
- /*
- * set the slsu:
- *
- * slsu defines the data setup time after SCL clock
- * stretching in terms of i2c clk cycles. The
- * needed setup time for the three modes are 250ns,
- * 100ns, 10ns respectively thus leading to the values
- * of 14, 6, 2 for a 48 MHz i2c clk.
- */
- writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR);
-
- i2c_clk = clk_get_rate(dev->clk);
-
- /* fallback to std. mode if machine has not provided it */
- if (dev->cfg.clk_freq == 0)
- dev->cfg.clk_freq = 100000;
-
- /*
- * The spec says, in case of std. mode the divider is
- * 2 whereas it is 3 for fast and fastplus mode of
- * operation. TODO - high speed support.
- */
- div = (dev->cfg.clk_freq > 100000) ? 3 : 2;
-
- /*
- * generate the mask for baud rate counters. The controller
- * has two baud rate counters. One is used for High speed
- * operation, and the other is for std, fast mode, fast mode
- * plus operation. Currently we do not supprt high speed mode
- * so set brcr1 to 0.
- */
- brcr1 = 0 << 16;
- brcr2 = (i2c_clk/(dev->cfg.clk_freq * div)) & 0xffff;
-
- /* set the baud rate counter register */
- writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
-
- /*
- * set the speed mode. Currently we support
- * only standard and fast mode of operation
- * TODO - support for fast mode plus (up to 1Mb/s)
- * and high speed (up to 3.4 Mb/s)
- */
- if (dev->cfg.sm > I2C_FREQ_MODE_FAST) {
- dev_err(&dev->pdev->dev,
- "do not support this mode defaulting to std. mode\n");
- brcr2 = i2c_clk/(100000 * 2) & 0xffff;
- writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
- writel(I2C_FREQ_MODE_STANDARD << 4,
- dev->virtbase + I2C_CR);
- }
- writel(dev->cfg.sm << 4, dev->virtbase + I2C_CR);
-
- /* set the Tx and Rx FIFO threshold */
- writel(dev->cfg.tft, dev->virtbase + I2C_TFTR);
- writel(dev->cfg.rft, dev->virtbase + I2C_RFTR);
-}
-
-/**
- * read_i2c() - Read from I2C client device
- * @dev: private data of I2C Driver
- *
- * This function reads from i2c client device when controller is in
- * master mode. There is a completion timeout. If there is no transfer
- * before timeout error is returned.
- */
-static int read_i2c(struct nmk_i2c_dev *dev)
-{
- u32 status = 0;
- u32 mcr;
- u32 irq_mask = 0;
- int timeout;
-
- mcr = load_i2c_mcr_reg(dev);
- writel(mcr, dev->virtbase + I2C_MCR);
-
- /* load the current CR value */
- writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
- dev->virtbase + I2C_CR);
-
- /* enable the controller */
- i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
-
- init_completion(&dev->xfer_complete);
-
- /* enable interrupts by setting the mask */
- irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
- I2C_IT_MAL | I2C_IT_BERR);
-
- if (dev->stop)
- irq_mask |= I2C_IT_MTD;
- else
- irq_mask |= I2C_IT_MTDWS;
-
- irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
-
- writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
- dev->virtbase + I2C_IMSCR);
-
- timeout = wait_for_completion_timeout(
- &dev->xfer_complete, dev->adap.timeout);
-
- if (timeout < 0) {
- dev_err(&dev->pdev->dev,
- "wait_for_completion_timeout "
- "returned %d waiting for event\n", timeout);
- status = timeout;
- }
-
- if (timeout == 0) {
- /* Controller timed out */
- dev_err(&dev->pdev->dev, "read from slave 0x%x timed out\n",
- dev->cli.slave_adr);
- status = -ETIMEDOUT;
- }
- return status;
-}
-
-static void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes)
-{
- int count;
-
- for (count = (no_bytes - 2);
- (count > 0) &&
- (dev->cli.count != 0);
- count--) {
- /* write to the Tx FIFO */
- writeb(*dev->cli.buffer,
- dev->virtbase + I2C_TFR);
- dev->cli.buffer++;
- dev->cli.count--;
- dev->cli.xfer_bytes++;
- }
-
-}
-
-/**
- * write_i2c() - Write data to I2C client.
- * @dev: private data of I2C Driver
- *
- * This function writes data to I2C client
- */
-static int write_i2c(struct nmk_i2c_dev *dev)
-{
- u32 status = 0;
- u32 mcr;
- u32 irq_mask = 0;
- int timeout;
-
- mcr = load_i2c_mcr_reg(dev);
-
- writel(mcr, dev->virtbase + I2C_MCR);
-
- /* load the current CR value */
- writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
- dev->virtbase + I2C_CR);
-
- /* enable the controller */
- i2c_set_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
-
- init_completion(&dev->xfer_complete);
-
- /* enable interrupts by settings the masks */
- irq_mask = (I2C_IT_TXFOVR | I2C_IT_MAL | I2C_IT_BERR);
-
- /* Fill the TX FIFO with transmit data */
- fill_tx_fifo(dev, MAX_I2C_FIFO_THRESHOLD);
-
- if (dev->cli.count != 0)
- irq_mask |= I2C_IT_TXFNE;
-
- /*
- * check if we want to transfer a single or multiple bytes, if so
- * set the MTDWS bit (Master Transaction Done Without Stop)
- * to start repeated start operation
- */
- if (dev->stop)
- irq_mask |= I2C_IT_MTD;
- else
- irq_mask |= I2C_IT_MTDWS;
-
- irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
-
- writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
- dev->virtbase + I2C_IMSCR);
-
- timeout = wait_for_completion_timeout(
- &dev->xfer_complete, dev->adap.timeout);
-
- if (timeout < 0) {
- dev_err(&dev->pdev->dev,
- "wait_for_completion_timeout "
- "returned %d waiting for event\n", timeout);
- status = timeout;
- }
-
- if (timeout == 0) {
- /* Controller timed out */
- dev_err(&dev->pdev->dev, "write to slave 0x%x timed out\n",
- dev->cli.slave_adr);
- status = -ETIMEDOUT;
- }
-
- return status;
-}
-
-/**
- * nmk_i2c_xfer_one() - transmit a single I2C message
- * @dev: device with a message encoded into it
- * @flags: message flags
- */
-static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
-{
- int status;
-
- if (flags & I2C_M_RD) {
- /* read operation */
- dev->cli.operation = I2C_READ;
- status = read_i2c(dev);
- } else {
- /* write operation */
- dev->cli.operation = I2C_WRITE;
- status = write_i2c(dev);
- }
-
- if (status || (dev->result)) {
- u32 i2c_sr;
- u32 cause;
-
- i2c_sr = readl(dev->virtbase + I2C_SR);
- /*
- * Check if the controller I2C operation status
- * is set to ABORT(11b).
- */
- if (((i2c_sr >> 2) & 0x3) == 0x3) {
- /* get the abort cause */
- cause = (i2c_sr >> 4) & 0x7;
- dev_err(&dev->pdev->dev, "%s\n",
- cause >= ARRAY_SIZE(abort_causes) ?
- "unknown reason" :
- abort_causes[cause]);
- }
-
- (void) init_hw(dev);
-
- status = status ? status : dev->result;
- }
-
- return status;
-}
-
-/**
- * nmk_i2c_xfer() - I2C transfer function used by kernel framework
- * @i2c_adap: Adapter pointer to the controller
- * @msgs: Pointer to data to be written.
- * @num_msgs: Number of messages to be executed
- *
- * This is the function called by the generic kernel i2c_transfer()
- * or i2c_smbus...() API calls. Note that this code is protected by the
- * semaphore set in the kernel i2c_transfer() function.
- *
- * NOTE:
- * READ TRANSFER : We impose a restriction of the first message to be the
- * index message for any read transaction.
- * - a no index is coded as '0',
- * - 2byte big endian index is coded as '3'
- * !!! msg[0].buf holds the actual index.
- * This is compatible with generic messages of smbus emulator
- * that send a one byte index.
- * eg. a I2C transation to read 2 bytes from index 0
- * idx = 0;
- * msg[0].addr = client->addr;
- * msg[0].flags = 0x0;
- * msg[0].len = 1;
- * msg[0].buf = &idx;
- *
- * msg[1].addr = client->addr;
- * msg[1].flags = I2C_M_RD;
- * msg[1].len = 2;
- * msg[1].buf = rd_buff
- * i2c_transfer(adap, msg, 2);
- *
- * WRITE TRANSFER : The I2C standard interface interprets all data as payload.
- * If you want to emulate an SMBUS write transaction put the
- * index as first byte(or first and second) in the payload.
- * eg. a I2C transation to write 2 bytes from index 1
- * wr_buff[0] = 0x1;
- * wr_buff[1] = 0x23;
- * wr_buff[2] = 0x46;
- * msg[0].flags = 0x0;
- * msg[0].len = 3;
- * msg[0].buf = wr_buff;
- * i2c_transfer(adap, msg, 1);
- *
- * To read or write a block of data (multiple bytes) using SMBUS emulation
- * please use the i2c_smbus_read_i2c_block_data()
- * or i2c_smbus_write_i2c_block_data() API
- */
-static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg msgs[], int num_msgs)
-{
- int status;
- int i;
- struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
- int j;
-
- dev->busy = true;
-
- if (dev->regulator)
- regulator_enable(dev->regulator);
- pm_runtime_get_sync(&dev->pdev->dev);
-
- clk_enable(dev->clk);
-
- status = init_hw(dev);
- if (status)
- goto out;
-
- /* Attempt three times to send the message queue */
- for (j = 0; j < 3; j++) {
- /* setup the i2c controller */
- setup_i2c_controller(dev);
-
- for (i = 0; i < num_msgs; i++) {
- if (unlikely(msgs[i].flags & I2C_M_TEN)) {
- dev_err(&dev->pdev->dev,
- "10 bit addressing not supported\n");
-
- status = -EINVAL;
- goto out;
- }
- dev->cli.slave_adr = msgs[i].addr;
- dev->cli.buffer = msgs[i].buf;
- dev->cli.count = msgs[i].len;
- dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
- dev->result = 0;
-
- status = nmk_i2c_xfer_one(dev, msgs[i].flags);
- if (status != 0)
- break;
- }
- if (status == 0)
- break;
- }
-
-out:
- clk_disable(dev->clk);
- pm_runtime_put_sync(&dev->pdev->dev);
- if (dev->regulator)
- regulator_disable(dev->regulator);
-
- dev->busy = false;
-
- /* return the no. messages processed */
- if (status)
- return status;
- else
- return num_msgs;
-}
-
-/**
- * disable_interrupts() - disable the interrupts
- * @dev: private data of controller
- * @irq: interrupt number
- */
-static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
-{
- irq = IRQ_MASK(irq);
- writel(readl(dev->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
- dev->virtbase + I2C_IMSCR);
- return 0;
-}
-
-/**
- * i2c_irq_handler() - interrupt routine
- * @irq: interrupt number
- * @arg: data passed to the handler
- *
- * This is the interrupt handler for the i2c driver. Currently
- * it handles the major interrupts like Rx & Tx FIFO management
- * interrupts, master transaction interrupts, arbitration and
- * bus error interrupts. The rest of the interrupts are treated as
- * unhandled.
- */
-static irqreturn_t i2c_irq_handler(int irq, void *arg)
-{
- struct nmk_i2c_dev *dev = arg;
- u32 tft, rft;
- u32 count;
- u32 misr;
- u32 src = 0;
-
- /* load Tx FIFO and Rx FIFO threshold values */
- tft = readl(dev->virtbase + I2C_TFTR);
- rft = readl(dev->virtbase + I2C_RFTR);
-
- /* read interrupt status register */
- misr = readl(dev->virtbase + I2C_MISR);
-
- src = __ffs(misr);
- switch ((1 << src)) {
-
- /* Transmit FIFO nearly empty interrupt */
- case I2C_IT_TXFNE:
- {
- if (dev->cli.operation == I2C_READ) {
- /*
- * in read operation why do we care for writing?
- * so disable the Transmit FIFO interrupt
- */
- disable_interrupts(dev, I2C_IT_TXFNE);
- } else {
- fill_tx_fifo(dev, (MAX_I2C_FIFO_THRESHOLD - tft));
- /*
- * if done, close the transfer by disabling the
- * corresponding TXFNE interrupt
- */
- if (dev->cli.count == 0)
- disable_interrupts(dev, I2C_IT_TXFNE);
- }
- }
- break;
-
- /*
- * Rx FIFO nearly full interrupt.
- * This is set when the numer of entries in Rx FIFO is
- * greater or equal than the threshold value programmed
- * in RFT
- */
- case I2C_IT_RXFNF:
- for (count = rft; count > 0; count--) {
- /* Read the Rx FIFO */
- *dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
- dev->cli.buffer++;
- }
- dev->cli.count -= rft;
- dev->cli.xfer_bytes += rft;
- break;
-
- /* Rx FIFO full */
- case I2C_IT_RXFF:
- for (count = MAX_I2C_FIFO_THRESHOLD; count > 0; count--) {
- *dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
- dev->cli.buffer++;
- }
- dev->cli.count -= MAX_I2C_FIFO_THRESHOLD;
- dev->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD;
- break;
-
- /* Master Transaction Done with/without stop */
- case I2C_IT_MTD:
- case I2C_IT_MTDWS:
- if (dev->cli.operation == I2C_READ) {
- while (!(readl(dev->virtbase + I2C_RISR)
- & I2C_IT_RXFE)) {
- if (dev->cli.count == 0)
- break;
- *dev->cli.buffer =
- readb(dev->virtbase + I2C_RFR);
- dev->cli.buffer++;
- dev->cli.count--;
- dev->cli.xfer_bytes++;
- }
- }
-
- disable_all_interrupts(dev);
- clear_all_interrupts(dev);
-
- if (dev->cli.count) {
- dev->result = -EIO;
- dev_err(&dev->pdev->dev,
- "%lu bytes still remain to be xfered\n",
- dev->cli.count);
- (void) init_hw(dev);
- }
- complete(&dev->xfer_complete);
-
- break;
-
- /* Master Arbitration lost interrupt */
- case I2C_IT_MAL:
- dev->result = -EIO;
- (void) init_hw(dev);
-
- i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
- complete(&dev->xfer_complete);
-
- break;
-
- /*
- * Bus Error interrupt.
- * This happens when an unexpected start/stop condition occurs
- * during the transaction.
- */
- case I2C_IT_BERR:
- dev->result = -EIO;
- /* get the status */
- if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
- (void) init_hw(dev);
-
- i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_BERR);
- complete(&dev->xfer_complete);
-
- break;
-
- /*
- * Tx FIFO overrun interrupt.
- * This is set when a write operation in Tx FIFO is performed and
- * the Tx FIFO is full.
- */
- case I2C_IT_TXFOVR:
- dev->result = -EIO;
- (void) init_hw(dev);
-
- dev_err(&dev->pdev->dev, "Tx Fifo Over run\n");
- complete(&dev->xfer_complete);
-
- break;
-
- /* unhandled interrupts by this driver - TODO*/
- case I2C_IT_TXFE:
- case I2C_IT_TXFF:
- case I2C_IT_RXFE:
- case I2C_IT_RFSR:
- case I2C_IT_RFSE:
- case I2C_IT_WTSR:
- case I2C_IT_STD:
- dev_err(&dev->pdev->dev, "unhandled Interrupt\n");
- break;
- default:
- dev_err(&dev->pdev->dev, "spurious Interrupt..\n");
- break;
- }
-
- return IRQ_HANDLED;
-}
-
-
-#ifdef CONFIG_PM
-static int nmk_i2c_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct nmk_i2c_dev *nmk_i2c = platform_get_drvdata(pdev);
-
- if (nmk_i2c->busy)
- return -EBUSY;
-
- return 0;
-}
-
-static int nmk_i2c_resume(struct device *dev)
-{
- return 0;
-}
-#else
-#define nmk_i2c_suspend NULL
-#define nmk_i2c_resume NULL
-#endif
-
-/*
- * We use noirq so that we suspend late and resume before the wakeup interrupt
- * to ensure that we do the !pm_runtime_suspended() check in resume before
- * there has been a regular pm runtime resume (via pm_runtime_get_sync()).
- */
-static const struct dev_pm_ops nmk_i2c_pm = {
- .suspend_noirq = nmk_i2c_suspend,
- .resume_noirq = nmk_i2c_resume,
-};
-
-static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm nmk_i2c_algo = {
- .master_xfer = nmk_i2c_xfer,
- .functionality = nmk_i2c_functionality
-};
-
-static int __devinit nmk_i2c_probe(struct platform_device *pdev)
-{
- int ret = 0;
- struct resource *res;
- struct nmk_i2c_controller *pdata =
- pdev->dev.platform_data;
- struct nmk_i2c_dev *dev;
- struct i2c_adapter *adap;
-
- dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
- if (!dev) {
- dev_err(&pdev->dev, "cannot allocate memory\n");
- ret = -ENOMEM;
- goto err_no_mem;
- }
- dev->busy = false;
- dev->pdev = pdev;
- platform_set_drvdata(pdev, dev);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENOENT;
- goto err_no_resource;
- }
-
- if (request_mem_region(res->start, resource_size(res),
- DRIVER_NAME "I/O region") == NULL) {
- ret = -EBUSY;
- goto err_no_region;
- }
-
- dev->virtbase = ioremap(res->start, resource_size(res));
- if (!dev->virtbase) {
- ret = -ENOMEM;
- goto err_no_ioremap;
- }
-
- dev->irq = platform_get_irq(pdev, 0);
- ret = request_irq(dev->irq, i2c_irq_handler, 0,
- DRIVER_NAME, dev);
- if (ret) {
- dev_err(&pdev->dev, "cannot claim the irq %d\n", dev->irq);
- goto err_irq;
- }
-
- dev->regulator = regulator_get(&pdev->dev, "v-i2c");
- if (IS_ERR(dev->regulator)) {
- dev_warn(&pdev->dev, "could not get i2c regulator\n");
- dev->regulator = NULL;
- }
-
- pm_suspend_ignore_children(&pdev->dev, true);
- pm_runtime_enable(&pdev->dev);
-
- dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk)) {
- dev_err(&pdev->dev, "could not get i2c clock\n");
- ret = PTR_ERR(dev->clk);
- goto err_no_clk;
- }
-
- adap = &dev->adap;
- adap->dev.parent = &pdev->dev;
- adap->owner = THIS_MODULE;
- adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- adap->algo = &nmk_i2c_algo;
- adap->timeout = pdata->timeout ? msecs_to_jiffies(pdata->timeout) :
- msecs_to_jiffies(20000);
- snprintf(adap->name, sizeof(adap->name),
- "Nomadik I2C%d at %lx", pdev->id, (unsigned long)res->start);
-
- /* fetch the controller id */
- adap->nr = pdev->id;
-
- /* fetch the controller configuration from machine */
- dev->cfg.clk_freq = pdata->clk_freq;
- dev->cfg.slsu = pdata->slsu;
- dev->cfg.tft = pdata->tft;
- dev->cfg.rft = pdata->rft;
- dev->cfg.sm = pdata->sm;
-
- i2c_set_adapdata(adap, dev);
-
- dev_info(&pdev->dev,
- "initialize %s on virtual base %p\n",
- adap->name, dev->virtbase);
-
- ret = i2c_add_numbered_adapter(adap);
- if (ret) {
- dev_err(&pdev->dev, "failed to add adapter\n");
- goto err_add_adap;
- }
-
- return 0;
-
- err_add_adap:
- clk_put(dev->clk);
- err_no_clk:
- if (dev->regulator)
- regulator_put(dev->regulator);
- pm_runtime_disable(&pdev->dev);
- free_irq(dev->irq, dev);
- err_irq:
- iounmap(dev->virtbase);
- err_no_ioremap:
- release_mem_region(res->start, resource_size(res));
- err_no_region:
- platform_set_drvdata(pdev, NULL);
- err_no_resource:
- kfree(dev);
- err_no_mem:
-
- return ret;
-}
-
-static int __devexit nmk_i2c_remove(struct platform_device *pdev)
-{
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
-
- i2c_del_adapter(&dev->adap);
- flush_i2c_fifo(dev);
- disable_all_interrupts(dev);
- clear_all_interrupts(dev);
- /* disable the controller */
- i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
- free_irq(dev->irq, dev);
- iounmap(dev->virtbase);
- if (res)
- release_mem_region(res->start, resource_size(res));
- clk_put(dev->clk);
- if (dev->regulator)
- regulator_put(dev->regulator);
- pm_runtime_disable(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
- kfree(dev);
-
- return 0;
-}
-
-static struct platform_driver nmk_i2c_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = DRIVER_NAME,
- .pm = &nmk_i2c_pm,
- },
- .probe = nmk_i2c_probe,
- .remove = __devexit_p(nmk_i2c_remove),
-};
-
-static int __init nmk_i2c_init(void)
-{
- return platform_driver_register(&nmk_i2c_driver);
-}
-
-static void __exit nmk_i2c_exit(void)
-{
- platform_driver_unregister(&nmk_i2c_driver);
-}
-
-subsys_initcall(nmk_i2c_init);
-module_exit(nmk_i2c_exit);
-
-MODULE_AUTHOR("Sachin Verma, Srinidhi KASAGAR");
-MODULE_DESCRIPTION("Nomadik/Ux500 I2C driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nuc900.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-nuc900.c
deleted file mode 100644
index 03b61577..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-nuc900.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * linux/drivers/i2c/busses/i2c-nuc900.c
- *
- * Copyright (c) 2010 Nuvoton technology corporation.
- *
- * This driver based on S3C2410 I2C driver of Ben Dooks <ben-Y5A6D6n0/KfQXOPxS62xeg@public.gmane.org>.
- * Written by Wan ZongShun <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include <mach/mfp.h>
-#include <mach/i2c.h>
-
-/* nuc900 i2c registers offset */
-
-#define CSR 0x00
-#define DIVIDER 0x04
-#define CMDR 0x08
-#define SWR 0x0C
-#define RXR 0x10
-#define TXR 0x14
-
-/* nuc900 i2c CSR register bits */
-
-#define IRQEN 0x003
-#define I2CBUSY 0x400
-#define I2CSTART 0x018
-#define IRQFLAG 0x004
-#define ARBIT_LOST 0x200
-#define SLAVE_ACK 0x800
-
-/* nuc900 i2c CMDR register bits */
-
-#define I2C_CMD_START 0x10
-#define I2C_CMD_STOP 0x08
-#define I2C_CMD_READ 0x04
-#define I2C_CMD_WRITE 0x02
-#define I2C_CMD_NACK 0x01
-
-/* i2c controller state */
-
-enum nuc900_i2c_state {
- STATE_IDLE,
- STATE_START,
- STATE_READ,
- STATE_WRITE,
- STATE_STOP
-};
-
-/* i2c controller private data */
-
-struct nuc900_i2c {
- spinlock_t lock;
- wait_queue_head_t wait;
-
- struct i2c_msg *msg;
- unsigned int msg_num;
- unsigned int msg_idx;
- unsigned int msg_ptr;
- unsigned int irq;
-
- enum nuc900_i2c_state state;
-
- void __iomem *regs;
- struct clk *clk;
- struct device *dev;
- struct resource *ioarea;
- struct i2c_adapter adap;
-};
-
-/* nuc900_i2c_master_complete
- *
- * complete the message and wake up the caller, using the given return code,
- * or zero to mean ok.
-*/
-
-static inline void nuc900_i2c_master_complete(struct nuc900_i2c *i2c, int ret)
-{
- dev_dbg(i2c->dev, "master_complete %d\n", ret);
-
- i2c->msg_ptr = 0;
- i2c->msg = NULL;
- i2c->msg_idx++;
- i2c->msg_num = 0;
- if (ret)
- i2c->msg_idx = ret;
-
- wake_up(&i2c->wait);
-}
-
-/* irq enable/disable functions */
-
-static inline void nuc900_i2c_disable_irq(struct nuc900_i2c *i2c)
-{
- unsigned long tmp;
-
- tmp = readl(i2c->regs + CSR);
- writel(tmp & ~IRQEN, i2c->regs + CSR);
-}
-
-static inline void nuc900_i2c_enable_irq(struct nuc900_i2c *i2c)
-{
- unsigned long tmp;
-
- tmp = readl(i2c->regs + CSR);
- writel(tmp | IRQEN, i2c->regs + CSR);
-}
-
-
-/* nuc900_i2c_message_start
- *
- * put the start of a message onto the bus
-*/
-
-static void nuc900_i2c_message_start(struct nuc900_i2c *i2c,
- struct i2c_msg *msg)
-{
- unsigned int addr = (msg->addr & 0x7f) << 1;
-
- if (msg->flags & I2C_M_RD)
- addr |= 0x1;
- writel(addr & 0xff, i2c->regs + TXR);
- writel(I2C_CMD_START | I2C_CMD_WRITE, i2c->regs + CMDR);
-}
-
-static inline void nuc900_i2c_stop(struct nuc900_i2c *i2c, int ret)
-{
-
- dev_dbg(i2c->dev, "STOP\n");
-
- /* stop the transfer */
- i2c->state = STATE_STOP;
- writel(I2C_CMD_STOP, i2c->regs + CMDR);
-
- nuc900_i2c_master_complete(i2c, ret);
- nuc900_i2c_disable_irq(i2c);
-}
-
-/* helper functions to determine the current state in the set of
- * messages we are sending
-*/
-
-/* is_lastmsg()
- *
- * returns TRUE if the current message is the last in the set
-*/
-
-static inline int is_lastmsg(struct nuc900_i2c *i2c)
-{
- return i2c->msg_idx >= (i2c->msg_num - 1);
-}
-
-/* is_msglast
- *
- * returns TRUE if we this is the last byte in the current message
-*/
-
-static inline int is_msglast(struct nuc900_i2c *i2c)
-{
- return i2c->msg_ptr == i2c->msg->len-1;
-}
-
-/* is_msgend
- *
- * returns TRUE if we reached the end of the current message
-*/
-
-static inline int is_msgend(struct nuc900_i2c *i2c)
-{
- return i2c->msg_ptr >= i2c->msg->len;
-}
-
-/* i2c_nuc900_irq_nextbyte
- *
- * process an interrupt and work out what to do
- */
-
-static void i2c_nuc900_irq_nextbyte(struct nuc900_i2c *i2c,
- unsigned long iicstat)
-{
- unsigned char byte;
-
- switch (i2c->state) {
-
- case STATE_IDLE:
- dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
- break;
-
- case STATE_STOP:
- dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
- nuc900_i2c_disable_irq(i2c);
- break;
-
- case STATE_START:
- /* last thing we did was send a start condition on the
- * bus, or started a new i2c message
- */
-
- if (iicstat & SLAVE_ACK &&
- !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
- /* ack was not received... */
-
- dev_dbg(i2c->dev, "ack was not received\n");
- nuc900_i2c_stop(i2c, -ENXIO);
- break;
- }
-
- if (i2c->msg->flags & I2C_M_RD)
- i2c->state = STATE_READ;
- else
- i2c->state = STATE_WRITE;
-
- /* terminate the transfer if there is nothing to do
- * as this is used by the i2c probe to find devices.
- */
-
- if (is_lastmsg(i2c) && i2c->msg->len == 0) {
- nuc900_i2c_stop(i2c, 0);
- break;
- }
-
- if (i2c->state == STATE_READ)
- goto prepare_read;
-
- /* fall through to the write state, as we will need to
- * send a byte as well
- */
-
- case STATE_WRITE:
- /* we are writing data to the device... check for the
- * end of the message, and if so, work out what to do
- */
-
- if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
- if (iicstat & SLAVE_ACK) {
- dev_dbg(i2c->dev, "WRITE: No Ack\n");
-
- nuc900_i2c_stop(i2c, -ECONNREFUSED);
- break;
- }
- }
-
-retry_write:
-
- if (!is_msgend(i2c)) {
- byte = i2c->msg->buf[i2c->msg_ptr++];
- writeb(byte, i2c->regs + TXR);
- writel(I2C_CMD_WRITE, i2c->regs + CMDR);
-
- } else if (!is_lastmsg(i2c)) {
- /* we need to go to the next i2c message */
-
- dev_dbg(i2c->dev, "WRITE: Next Message\n");
-
- i2c->msg_ptr = 0;
- i2c->msg_idx++;
- i2c->msg++;
-
- /* check to see if we need to do another message */
- if (i2c->msg->flags & I2C_M_NOSTART) {
-
- if (i2c->msg->flags & I2C_M_RD) {
- /* cannot do this, the controller
- * forces us to send a new START
- * when we change direction
- */
-
- nuc900_i2c_stop(i2c, -EINVAL);
- }
-
- goto retry_write;
- } else {
- /* send the new start */
- nuc900_i2c_message_start(i2c, i2c->msg);
- i2c->state = STATE_START;
- }
-
- } else {
- /* send stop */
-
- nuc900_i2c_stop(i2c, 0);
- }
- break;
-
- case STATE_READ:
- /* we have a byte of data in the data register, do
- * something with it, and then work out wether we are
- * going to do any more read/write
- */
-
- byte = readb(i2c->regs + RXR);
- i2c->msg->buf[i2c->msg_ptr++] = byte;
-
-prepare_read:
- if (is_msglast(i2c)) {
- /* last byte of buffer */
-
- if (is_lastmsg(i2c))
- writel(I2C_CMD_READ | I2C_CMD_NACK,
- i2c->regs + CMDR);
-
- } else if (is_msgend(i2c)) {
- /* ok, we've read the entire buffer, see if there
- * is anything else we need to do
- */
-
- if (is_lastmsg(i2c)) {
- /* last message, send stop and complete */
- dev_dbg(i2c->dev, "READ: Send Stop\n");
-
- nuc900_i2c_stop(i2c, 0);
- } else {
- /* go to the next transfer */
- dev_dbg(i2c->dev, "READ: Next Transfer\n");
-
- i2c->msg_ptr = 0;
- i2c->msg_idx++;
- i2c->msg++;
-
- writel(I2C_CMD_READ, i2c->regs + CMDR);
- }
-
- } else {
- writel(I2C_CMD_READ, i2c->regs + CMDR);
- }
-
- break;
- }
-}
-
-/* nuc900_i2c_irq
- *
- * top level IRQ servicing routine
-*/
-
-static irqreturn_t nuc900_i2c_irq(int irqno, void *dev_id)
-{
- struct nuc900_i2c *i2c = dev_id;
- unsigned long status;
-
- status = readl(i2c->regs + CSR);
- writel(status | IRQFLAG, i2c->regs + CSR);
-
- if (status & ARBIT_LOST) {
- /* deal with arbitration loss */
- dev_err(i2c->dev, "deal with arbitration loss\n");
- goto out;
- }
-
- if (i2c->state == STATE_IDLE) {
- dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
- goto out;
- }
-
- /* pretty much this leaves us with the fact that we've
- * transmitted or received whatever byte we last sent
- */
-
- i2c_nuc900_irq_nextbyte(i2c, status);
-
- out:
- return IRQ_HANDLED;
-}
-
-
-/* nuc900_i2c_set_master
- *
- * get the i2c bus for a master transaction
-*/
-
-static int nuc900_i2c_set_master(struct nuc900_i2c *i2c)
-{
- int timeout = 400;
-
- while (timeout-- > 0) {
- if (((readl(i2c->regs + SWR) & I2CSTART) == I2CSTART) &&
- ((readl(i2c->regs + CSR) & I2CBUSY) == 0)) {
- return 0;
- }
-
- msleep(1);
- }
-
- return -ETIMEDOUT;
-}
-
-/* nuc900_i2c_doxfer
- *
- * this starts an i2c transfer
-*/
-
-static int nuc900_i2c_doxfer(struct nuc900_i2c *i2c,
- struct i2c_msg *msgs, int num)
-{
- unsigned long iicstat, timeout;
- int spins = 20;
- int ret;
-
- ret = nuc900_i2c_set_master(i2c);
- if (ret != 0) {
- dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
- ret = -EAGAIN;
- goto out;
- }
-
- spin_lock_irq(&i2c->lock);
-
- i2c->msg = msgs;
- i2c->msg_num = num;
- i2c->msg_ptr = 0;
- i2c->msg_idx = 0;
- i2c->state = STATE_START;
-
- nuc900_i2c_message_start(i2c, msgs);
- spin_unlock_irq(&i2c->lock);
-
- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
-
- ret = i2c->msg_idx;
-
- /* having these next two as dev_err() makes life very
- * noisy when doing an i2cdetect
- */
-
- if (timeout == 0)
- dev_dbg(i2c->dev, "timeout\n");
- else if (ret != num)
- dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
-
- /* ensure the stop has been through the bus */
-
- dev_dbg(i2c->dev, "waiting for bus idle\n");
-
- /* first, try busy waiting briefly */
- do {
- iicstat = readl(i2c->regs + CSR);
- } while ((iicstat & I2CBUSY) && --spins);
-
- /* if that timed out sleep */
- if (!spins) {
- msleep(1);
- iicstat = readl(i2c->regs + CSR);
- }
-
- if (iicstat & I2CBUSY)
- dev_warn(i2c->dev, "timeout waiting for bus idle\n");
-
- out:
- return ret;
-}
-
-/* nuc900_i2c_xfer
- *
- * first port of call from the i2c bus code when an message needs
- * transferring across the i2c bus.
-*/
-
-static int nuc900_i2c_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
-{
- struct nuc900_i2c *i2c = (struct nuc900_i2c *)adap->algo_data;
- int retry;
- int ret;
-
- nuc900_i2c_enable_irq(i2c);
-
- for (retry = 0; retry < adap->retries; retry++) {
-
- ret = nuc900_i2c_doxfer(i2c, msgs, num);
-
- if (ret != -EAGAIN)
- return ret;
-
- dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
-
- udelay(100);
- }
-
- return -EREMOTEIO;
-}
-
-/* declare our i2c functionality */
-static u32 nuc900_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
-}
-
-/* i2c bus registration info */
-
-static const struct i2c_algorithm nuc900_i2c_algorithm = {
- .master_xfer = nuc900_i2c_xfer,
- .functionality = nuc900_i2c_func,
-};
-
-/* nuc900_i2c_probe
- *
- * called by the bus driver when a suitable device is found
-*/
-
-static int __devinit nuc900_i2c_probe(struct platform_device *pdev)
-{
- struct nuc900_i2c *i2c;
- struct nuc900_platform_i2c *pdata;
- struct resource *res;
- int ret;
-
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
- i2c = kzalloc(sizeof(struct nuc900_i2c), GFP_KERNEL);
- if (!i2c) {
- dev_err(&pdev->dev, "no memory for state\n");
- return -ENOMEM;
- }
-
- strlcpy(i2c->adap.name, "nuc900-i2c0", sizeof(i2c->adap.name));
- i2c->adap.owner = THIS_MODULE;
- i2c->adap.algo = &nuc900_i2c_algorithm;
- i2c->adap.retries = 2;
- i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-
- spin_lock_init(&i2c->lock);
- init_waitqueue_head(&i2c->wait);
-
- /* find the clock and enable it */
-
- i2c->dev = &pdev->dev;
- i2c->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(i2c->clk)) {
- dev_err(&pdev->dev, "cannot get clock\n");
- ret = -ENOENT;
- goto err_noclk;
- }
-
- dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
-
- clk_enable(i2c->clk);
-
- /* map the registers */
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "cannot find IO resource\n");
- ret = -ENOENT;
- goto err_clk;
- }
-
- i2c->ioarea = request_mem_region(res->start, resource_size(res),
- pdev->name);
-
- if (i2c->ioarea == NULL) {
- dev_err(&pdev->dev, "cannot request IO\n");
- ret = -ENXIO;
- goto err_clk;
- }
-
- i2c->regs = ioremap(res->start, resource_size(res));
-
- if (i2c->regs == NULL) {
- dev_err(&pdev->dev, "cannot map IO\n");
- ret = -ENXIO;
- goto err_ioarea;
- }
-
- dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
- i2c->regs, i2c->ioarea, res);
-
- /* setup info block for the i2c core */
-
- i2c->adap.algo_data = i2c;
- i2c->adap.dev.parent = &pdev->dev;
-
- mfp_set_groupg(&pdev->dev, NULL);
-
- clk_get_rate(i2c->clk);
-
- ret = (i2c->clk.apbfreq)/(pdata->bus_freq * 5) - 1;
- writel(ret & 0xffff, i2c->regs + DIVIDER);
-
- /* find the IRQ for this unit (note, this relies on the init call to
- * ensure no current IRQs pending
- */
-
- i2c->irq = ret = platform_get_irq(pdev, 0);
- if (ret <= 0) {
- dev_err(&pdev->dev, "cannot find IRQ\n");
- goto err_iomap;
- }
-
- ret = request_irq(i2c->irq, nuc900_i2c_irq, IRQF_SHARED,
- dev_name(&pdev->dev), i2c);
-
- if (ret != 0) {
- dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
- goto err_iomap;
- }
-
- /* Note, previous versions of the driver used i2c_add_adapter()
- * to add the bus at any number. We now pass the bus number via
- * the platform data, so if unset it will now default to always
- * being bus 0.
- */
-
- i2c->adap.nr = pdata->bus_num;
-
- ret = i2c_add_numbered_adapter(&i2c->adap);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to add bus to i2c core\n");
- goto err_irq;
- }
-
- platform_set_drvdata(pdev, i2c);
-
- dev_info(&pdev->dev, "%s: NUC900 I2C adapter\n",
- dev_name(&i2c->adap.dev));
- return 0;
-
- err_irq:
- free_irq(i2c->irq, i2c);
-
- err_iomap:
- iounmap(i2c->regs);
-
- err_ioarea:
- release_resource(i2c->ioarea);
- kfree(i2c->ioarea);
-
- err_clk:
- clk_disable(i2c->clk);
- clk_put(i2c->clk);
-
- err_noclk:
- kfree(i2c);
- return ret;
-}
-
-/* nuc900_i2c_remove
- *
- * called when device is removed from the bus
-*/
-
-static int __devexit nuc900_i2c_remove(struct platform_device *pdev)
-{
- struct nuc900_i2c *i2c = platform_get_drvdata(pdev);
-
- i2c_del_adapter(&i2c->adap);
- free_irq(i2c->irq, i2c);
-
- clk_disable(i2c->clk);
- clk_put(i2c->clk);
-
- iounmap(i2c->regs);
-
- release_resource(i2c->ioarea);
- kfree(i2c->ioarea);
- kfree(i2c);
-
- return 0;
-}
-
-static struct platform_driver nuc900_i2c_driver = {
- .probe = nuc900_i2c_probe,
- .remove = __devexit_p(nuc900_i2c_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = "nuc900-i2c0",
- },
-};
-
-static int __init i2c_adap_nuc900_init(void)
-{
- return platform_driver_register(&nuc900_i2c_driver);
-}
-
-static void __exit i2c_adap_nuc900_exit(void)
-{
- platform_driver_unregister(&nuc900_i2c_driver);
-}
-subsys_initcall(i2c_adap_nuc900_init);
-module_exit(i2c_adap_nuc900_exit);
-
-MODULE_DESCRIPTION("NUC900 I2C Bus driver");
-MODULE_AUTHOR("Wan ZongShun, <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:nuc900-i2c0");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ocores.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-ocores.c
deleted file mode 100644
index 18068dee..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-ocores.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * i2c-ocores.c: I2C bus driver for OpenCores I2C controller
- * (http://www.opencores.org/projects.cgi/web/i2c/overview).
- *
- * Peter Korsgaard <jacmet@sunsite.dk>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-/*
- * Device tree configuration:
- *
- * Required properties:
- * - compatible : "opencores,i2c-ocores"
- * - reg : bus address start and address range size of device
- * - interrupts : interrupt number
- * - regstep : size of device registers in bytes
- * - clock-frequency : frequency of bus clock in Hz
- *
- * Example:
- *
- * i2c0: ocores@a0000000 {
- * compatible = "opencores,i2c-ocores";
- * reg = <0xa0000000 0x8>;
- * interrupts = <10>;
- *
- * regstep = <1>;
- * clock-frequency = <20000000>;
- *
- * -- Devices connected on this I2C bus get
- * -- defined here; address- and size-cells
- * -- apply to these child devices
- *
- * #address-cells = <1>;
- * #size-cells = <0>;
- *
- * dummy@60 {
- * compatible = "dummy";
- * reg = <60>;
- * };
- * };
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/i2c-ocores.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-struct ocores_i2c {
- void __iomem *base;
- int regstep;
- wait_queue_head_t wait;
- struct i2c_adapter adap;
- struct i2c_msg *msg;
- int pos;
- int nmsgs;
- int state; /* see STATE_ */
- int clock_khz;
-};
-
-/* registers */
-#define OCI2C_PRELOW 0
-#define OCI2C_PREHIGH 1
-#define OCI2C_CONTROL 2
-#define OCI2C_DATA 3
-#define OCI2C_CMD 4 /* write only */
-#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */
-
-#define OCI2C_CTRL_IEN 0x40
-#define OCI2C_CTRL_EN 0x80
-
-#define OCI2C_CMD_START 0x91
-#define OCI2C_CMD_STOP 0x41
-#define OCI2C_CMD_READ 0x21
-#define OCI2C_CMD_WRITE 0x11
-#define OCI2C_CMD_READ_ACK 0x21
-#define OCI2C_CMD_READ_NACK 0x29
-#define OCI2C_CMD_IACK 0x01
-
-#define OCI2C_STAT_IF 0x01
-#define OCI2C_STAT_TIP 0x02
-#define OCI2C_STAT_ARBLOST 0x20
-#define OCI2C_STAT_BUSY 0x40
-#define OCI2C_STAT_NACK 0x80
-
-#define STATE_DONE 0
-#define STATE_START 1
-#define STATE_WRITE 2
-#define STATE_READ 3
-#define STATE_ERROR 4
-
-static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
-{
- iowrite8(value, i2c->base + reg * i2c->regstep);
-}
-
-static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg)
-{
- return ioread8(i2c->base + reg * i2c->regstep);
-}
-
-static void ocores_process(struct ocores_i2c *i2c)
-{
- struct i2c_msg *msg = i2c->msg;
- u8 stat = oc_getreg(i2c, OCI2C_STATUS);
-
- if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) {
- /* stop has been sent */
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
- wake_up(&i2c->wait);
- return;
- }
-
- /* error? */
- if (stat & OCI2C_STAT_ARBLOST) {
- i2c->state = STATE_ERROR;
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
- return;
- }
-
- if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) {
- i2c->state =
- (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
-
- if (stat & OCI2C_STAT_NACK) {
- i2c->state = STATE_ERROR;
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
- return;
- }
- } else
- msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA);
-
- /* end of msg? */
- if (i2c->pos == msg->len) {
- i2c->nmsgs--;
- i2c->msg++;
- i2c->pos = 0;
- msg = i2c->msg;
-
- if (i2c->nmsgs) { /* end? */
- /* send start? */
- if (!(msg->flags & I2C_M_NOSTART)) {
- u8 addr = (msg->addr << 1);
-
- if (msg->flags & I2C_M_RD)
- addr |= 1;
-
- i2c->state = STATE_START;
-
- oc_setreg(i2c, OCI2C_DATA, addr);
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
- return;
- } else
- i2c->state = (msg->flags & I2C_M_RD)
- ? STATE_READ : STATE_WRITE;
- } else {
- i2c->state = STATE_DONE;
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
- return;
- }
- }
-
- if (i2c->state == STATE_READ) {
- oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ?
- OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK);
- } else {
- oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]);
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE);
- }
-}
-
-static irqreturn_t ocores_isr(int irq, void *dev_id)
-{
- struct ocores_i2c *i2c = dev_id;
-
- ocores_process(i2c);
-
- return IRQ_HANDLED;
-}
-
-static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct ocores_i2c *i2c = i2c_get_adapdata(adap);
-
- i2c->msg = msgs;
- i2c->pos = 0;
- i2c->nmsgs = num;
- i2c->state = STATE_START;
-
- oc_setreg(i2c, OCI2C_DATA,
- (i2c->msg->addr << 1) |
- ((i2c->msg->flags & I2C_M_RD) ? 1:0));
-
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
-
- if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
- (i2c->state == STATE_DONE), HZ))
- return (i2c->state == STATE_DONE) ? num : -EIO;
- else
- return -ETIMEDOUT;
-}
-
-static void ocores_init(struct ocores_i2c *i2c)
-{
- int prescale;
- u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
-
- /* make sure the device is disabled */
- oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
-
- prescale = (i2c->clock_khz / (5*100)) - 1;
- oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff);
- oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
-
- /* Init the device */
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
- oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN);
-}
-
-
-static u32 ocores_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm ocores_algorithm = {
- .master_xfer = ocores_xfer,
- .functionality = ocores_func,
-};
-
-static struct i2c_adapter ocores_adapter = {
- .owner = THIS_MODULE,
- .name = "i2c-ocores",
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &ocores_algorithm,
-};
-
-#ifdef CONFIG_OF
-static int ocores_i2c_of_probe(struct platform_device* pdev,
- struct ocores_i2c* i2c)
-{
- const __be32* val;
-
- val = of_get_property(pdev->dev.of_node, "regstep", NULL);
- if (!val) {
- dev_err(&pdev->dev, "Missing required parameter 'regstep'");
- return -ENODEV;
- }
- i2c->regstep = be32_to_cpup(val);
-
- val = of_get_property(pdev->dev.of_node, "clock-frequency", NULL);
- if (!val) {
- dev_err(&pdev->dev,
- "Missing required parameter 'clock-frequency'");
- return -ENODEV;
- }
- i2c->clock_khz = be32_to_cpup(val) / 1000;
-
- return 0;
-}
-#else
-#define ocores_i2c_of_probe(pdev,i2c) -ENODEV
-#endif
-
-static int __devinit ocores_i2c_probe(struct platform_device *pdev)
-{
- struct ocores_i2c *i2c;
- struct ocores_i2c_platform_data *pdata;
- struct resource *res, *res2;
- int ret;
- int i;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
-
- res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res2)
- return -ENODEV;
-
- i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
- if (!i2c)
- return -ENOMEM;
-
- if (!devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), pdev->name)) {
- dev_err(&pdev->dev, "Memory region busy\n");
- return -EBUSY;
- }
-
- i2c->base = devm_ioremap_nocache(&pdev->dev, res->start,
- resource_size(res));
- if (!i2c->base) {
- dev_err(&pdev->dev, "Unable to map registers\n");
- return -EIO;
- }
-
- pdata = pdev->dev.platform_data;
- if (pdata) {
- i2c->regstep = pdata->regstep;
- i2c->clock_khz = pdata->clock_khz;
- } else {
- ret = ocores_i2c_of_probe(pdev, i2c);
- if (ret)
- return ret;
- }
-
- ocores_init(i2c);
-
- init_waitqueue_head(&i2c->wait);
- ret = devm_request_irq(&pdev->dev, res2->start, ocores_isr, 0,
- pdev->name, i2c);
- if (ret) {
- dev_err(&pdev->dev, "Cannot claim IRQ\n");
- return ret;
- }
-
- /* hook up driver to tree */
- platform_set_drvdata(pdev, i2c);
- i2c->adap = ocores_adapter;
- i2c_set_adapdata(&i2c->adap, i2c);
- i2c->adap.dev.parent = &pdev->dev;
- i2c->adap.dev.of_node = pdev->dev.of_node;
-
- /* add i2c adapter to i2c tree */
- ret = i2c_add_adapter(&i2c->adap);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add adapter\n");
- return ret;
- }
-
- /* add in known devices to the bus */
- if (pdata) {
- for (i = 0; i < pdata->num_devices; i++)
- i2c_new_device(&i2c->adap, pdata->devices + i);
- }
-
- return 0;
-}
-
-static int __devexit ocores_i2c_remove(struct platform_device* pdev)
-{
- struct ocores_i2c *i2c = platform_get_drvdata(pdev);
-
- /* disable i2c logic */
- oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL)
- & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
-
- /* remove adapter & data */
- i2c_del_adapter(&i2c->adap);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ocores_i2c_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct ocores_i2c *i2c = platform_get_drvdata(pdev);
- u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
-
- /* make sure the device is disabled */
- oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
-
- return 0;
-}
-
-static int ocores_i2c_resume(struct platform_device *pdev)
-{
- struct ocores_i2c *i2c = platform_get_drvdata(pdev);
-
- ocores_init(i2c);
-
- return 0;
-}
-#else
-#define ocores_i2c_suspend NULL
-#define ocores_i2c_resume NULL
-#endif
-
-static struct of_device_id ocores_i2c_match[] = {
- { .compatible = "opencores,i2c-ocores", },
- {},
-};
-MODULE_DEVICE_TABLE(of, ocores_i2c_match);
-
-static struct platform_driver ocores_i2c_driver = {
- .probe = ocores_i2c_probe,
- .remove = __devexit_p(ocores_i2c_remove),
- .suspend = ocores_i2c_suspend,
- .resume = ocores_i2c_resume,
- .driver = {
- .owner = THIS_MODULE,
- .name = "ocores-i2c",
- .of_match_table = ocores_i2c_match,
- },
-};
-
-module_platform_driver(ocores_i2c_driver);
-
-MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
-MODULE_DESCRIPTION("OpenCores I2C bus driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ocores-i2c");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-octeon.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-octeon.c
deleted file mode 100644
index ee139a59..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-octeon.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * (C) Copyright 2009-2010
- * Nokia Siemens Networks, michael.lawnick.ext@nsn.com
- *
- * Portions Copyright (C) 2010 Cavium Networks, Inc.
- *
- * This is a driver for the i2c adapter in Cavium Networks' OCTEON processors.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-
-#include <asm/octeon/octeon.h>
-
-#define DRV_NAME "i2c-octeon"
-
-/* The previous out-of-tree version was implicitly version 1.0. */
-#define DRV_VERSION "2.0"
-
-/* register offsets */
-#define SW_TWSI 0x00
-#define TWSI_INT 0x10
-
-/* Controller command patterns */
-#define SW_TWSI_V 0x8000000000000000ull
-#define SW_TWSI_EOP_TWSI_DATA 0x0C00000100000000ull
-#define SW_TWSI_EOP_TWSI_CTL 0x0C00000200000000ull
-#define SW_TWSI_EOP_TWSI_CLKCTL 0x0C00000300000000ull
-#define SW_TWSI_EOP_TWSI_STAT 0x0C00000300000000ull
-#define SW_TWSI_EOP_TWSI_RST 0x0C00000700000000ull
-#define SW_TWSI_OP_TWSI_CLK 0x0800000000000000ull
-#define SW_TWSI_R 0x0100000000000000ull
-
-/* Controller command and status bits */
-#define TWSI_CTL_CE 0x80
-#define TWSI_CTL_ENAB 0x40
-#define TWSI_CTL_STA 0x20
-#define TWSI_CTL_STP 0x10
-#define TWSI_CTL_IFLG 0x08
-#define TWSI_CTL_AAK 0x04
-
-/* Some status values */
-#define STAT_START 0x08
-#define STAT_RSTART 0x10
-#define STAT_TXADDR_ACK 0x18
-#define STAT_TXDATA_ACK 0x28
-#define STAT_RXADDR_ACK 0x40
-#define STAT_RXDATA_ACK 0x50
-#define STAT_IDLE 0xF8
-
-struct octeon_i2c {
- wait_queue_head_t queue;
- struct i2c_adapter adap;
- int irq;
- int twsi_freq;
- int sys_freq;
- resource_size_t twsi_phys;
- void __iomem *twsi_base;
- resource_size_t regsize;
- struct device *dev;
-};
-
-/**
- * octeon_i2c_write_sw - write an I2C core register.
- * @i2c: The struct octeon_i2c.
- * @eop_reg: Register selector.
- * @data: Value to be written.
- *
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
- */
-static void octeon_i2c_write_sw(struct octeon_i2c *i2c,
- u64 eop_reg,
- u8 data)
-{
- u64 tmp;
-
- __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI);
- do {
- tmp = __raw_readq(i2c->twsi_base + SW_TWSI);
- } while ((tmp & SW_TWSI_V) != 0);
-}
-
-/**
- * octeon_i2c_read_sw - write an I2C core register.
- * @i2c: The struct octeon_i2c.
- * @eop_reg: Register selector.
- *
- * Returns the data.
- *
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
- */
-static u8 octeon_i2c_read_sw(struct octeon_i2c *i2c, u64 eop_reg)
-{
- u64 tmp;
-
- __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI);
- do {
- tmp = __raw_readq(i2c->twsi_base + SW_TWSI);
- } while ((tmp & SW_TWSI_V) != 0);
-
- return tmp & 0xFF;
-}
-
-/**
- * octeon_i2c_write_int - write the TWSI_INT register
- * @i2c: The struct octeon_i2c.
- * @data: Value to be written.
- */
-static void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
-{
- u64 tmp;
-
- __raw_writeq(data, i2c->twsi_base + TWSI_INT);
- tmp = __raw_readq(i2c->twsi_base + TWSI_INT);
-}
-
-/**
- * octeon_i2c_int_enable - enable the TS interrupt.
- * @i2c: The struct octeon_i2c.
- *
- * The interrupt will be asserted when there is non-STAT_IDLE state in
- * the SW_TWSI_EOP_TWSI_STAT register.
- */
-static void octeon_i2c_int_enable(struct octeon_i2c *i2c)
-{
- octeon_i2c_write_int(i2c, 0x40);
-}
-
-/**
- * octeon_i2c_int_disable - disable the TS interrupt.
- * @i2c: The struct octeon_i2c.
- */
-static void octeon_i2c_int_disable(struct octeon_i2c *i2c)
-{
- octeon_i2c_write_int(i2c, 0);
-}
-
-/**
- * octeon_i2c_unblock - unblock the bus.
- * @i2c: The struct octeon_i2c.
- *
- * If there was a reset while a device was driving 0 to bus,
- * bus is blocked. We toggle it free manually by some clock
- * cycles and send a stop.
- */
-static void octeon_i2c_unblock(struct octeon_i2c *i2c)
-{
- int i;
-
- dev_dbg(i2c->dev, "%s\n", __func__);
- for (i = 0; i < 9; i++) {
- octeon_i2c_write_int(i2c, 0x0);
- udelay(5);
- octeon_i2c_write_int(i2c, 0x200);
- udelay(5);
- }
- octeon_i2c_write_int(i2c, 0x300);
- udelay(5);
- octeon_i2c_write_int(i2c, 0x100);
- udelay(5);
- octeon_i2c_write_int(i2c, 0x0);
-}
-
-/**
- * octeon_i2c_isr - the interrupt service routine.
- * @int: The irq, unused.
- * @dev_id: Our struct octeon_i2c.
- */
-static irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
-{
- struct octeon_i2c *i2c = dev_id;
-
- octeon_i2c_int_disable(i2c);
- wake_up_interruptible(&i2c->queue);
-
- return IRQ_HANDLED;
-}
-
-
-static int octeon_i2c_test_iflg(struct octeon_i2c *i2c)
-{
- return (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_CTL) & TWSI_CTL_IFLG) != 0;
-}
-
-/**
- * octeon_i2c_wait - wait for the IFLG to be set.
- * @i2c: The struct octeon_i2c.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_wait(struct octeon_i2c *i2c)
-{
- int result;
-
- octeon_i2c_int_enable(i2c);
-
- result = wait_event_interruptible_timeout(i2c->queue,
- octeon_i2c_test_iflg(i2c),
- i2c->adap.timeout);
-
- octeon_i2c_int_disable(i2c);
-
- if (result < 0) {
- dev_dbg(i2c->dev, "%s: wait interrupted\n", __func__);
- return result;
- } else if (result == 0) {
- dev_dbg(i2c->dev, "%s: timeout\n", __func__);
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-/**
- * octeon_i2c_start - send START to the bus.
- * @i2c: The struct octeon_i2c.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_start(struct octeon_i2c *i2c)
-{
- u8 data;
- int result;
-
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
- TWSI_CTL_ENAB | TWSI_CTL_STA);
-
- result = octeon_i2c_wait(i2c);
- if (result) {
- if (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT) == STAT_IDLE) {
- /*
- * Controller refused to send start flag May
- * be a client is holding SDA low - let's try
- * to free it.
- */
- octeon_i2c_unblock(i2c);
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
- TWSI_CTL_ENAB | TWSI_CTL_STA);
-
- result = octeon_i2c_wait(i2c);
- }
- if (result)
- return result;
- }
-
- data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
- if ((data != STAT_START) && (data != STAT_RSTART)) {
- dev_err(i2c->dev, "%s: bad status (0x%x)\n", __func__, data);
- return -EIO;
- }
-
- return 0;
-}
-
-/**
- * octeon_i2c_stop - send STOP to the bus.
- * @i2c: The struct octeon_i2c.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_stop(struct octeon_i2c *i2c)
-{
- u8 data;
-
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
- TWSI_CTL_ENAB | TWSI_CTL_STP);
-
- data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
-
- if (data != STAT_IDLE) {
- dev_err(i2c->dev, "%s: bad status(0x%x)\n", __func__, data);
- return -EIO;
- }
- return 0;
-}
-
-/**
- * octeon_i2c_write - send data to the bus.
- * @i2c: The struct octeon_i2c.
- * @target: Target address.
- * @data: Pointer to the data to be sent.
- * @length: Length of the data.
- *
- * The address is sent over the bus, then the data.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
- const u8 *data, int length)
-{
- int i, result;
- u8 tmp;
-
- result = octeon_i2c_start(i2c);
- if (result)
- return result;
-
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, target << 1);
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
-
- result = octeon_i2c_wait(i2c);
- if (result)
- return result;
-
- for (i = 0; i < length; i++) {
- tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
- if ((tmp != STAT_TXADDR_ACK) && (tmp != STAT_TXDATA_ACK)) {
- dev_err(i2c->dev,
- "%s: bad status before write (0x%x)\n",
- __func__, tmp);
- return -EIO;
- }
-
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, data[i]);
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
-
- result = octeon_i2c_wait(i2c);
- if (result)
- return result;
- }
-
- return 0;
-}
-
-/**
- * octeon_i2c_read - receive data from the bus.
- * @i2c: The struct octeon_i2c.
- * @target: Target address.
- * @data: Pointer to the location to store the datae .
- * @length: Length of the data.
- *
- * The address is sent over the bus, then the data is read.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
- u8 *data, int length)
-{
- int i, result;
- u8 tmp;
-
- if (length < 1)
- return -EINVAL;
-
- result = octeon_i2c_start(i2c);
- if (result)
- return result;
-
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, (target<<1) | 1);
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
-
- result = octeon_i2c_wait(i2c);
- if (result)
- return result;
-
- for (i = 0; i < length; i++) {
- tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
- if ((tmp != STAT_RXDATA_ACK) && (tmp != STAT_RXADDR_ACK)) {
- dev_err(i2c->dev,
- "%s: bad status before read (0x%x)\n",
- __func__, tmp);
- return -EIO;
- }
-
- if (i+1 < length)
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
- TWSI_CTL_ENAB | TWSI_CTL_AAK);
- else
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
- TWSI_CTL_ENAB);
-
- result = octeon_i2c_wait(i2c);
- if (result)
- return result;
-
- data[i] = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_DATA);
- }
- return 0;
-}
-
-/**
- * octeon_i2c_xfer - The driver's master_xfer function.
- * @adap: Pointer to the i2c_adapter structure.
- * @msgs: Pointer to the messages to be processed.
- * @num: Length of the MSGS array.
- *
- * Returns the number of messages processed, or a negative errno on
- * failure.
- */
-static int octeon_i2c_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs,
- int num)
-{
- struct i2c_msg *pmsg;
- int i;
- int ret = 0;
- struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-
- for (i = 0; ret == 0 && i < num; i++) {
- pmsg = &msgs[i];
- dev_dbg(i2c->dev,
- "Doing %s %d byte(s) to/from 0x%02x - %d of %d messages\n",
- pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);
- if (pmsg->flags & I2C_M_RD)
- ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf,
- pmsg->len);
- else
- ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf,
- pmsg->len);
- }
- octeon_i2c_stop(i2c);
-
- return (ret != 0) ? ret : num;
-}
-
-static u32 octeon_i2c_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm octeon_i2c_algo = {
- .master_xfer = octeon_i2c_xfer,
- .functionality = octeon_i2c_functionality,
-};
-
-static struct i2c_adapter octeon_i2c_ops = {
- .owner = THIS_MODULE,
- .name = "OCTEON adapter",
- .algo = &octeon_i2c_algo,
- .timeout = 2,
-};
-
-/**
- * octeon_i2c_setclock - Calculate and set clock divisors.
- */
-static int __devinit octeon_i2c_setclock(struct octeon_i2c *i2c)
-{
- int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
- int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
-
- for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
- /*
- * An mdiv value of less than 2 seems to not work well
- * with ds1337 RTCs, so we constrain it to larger
- * values.
- */
- for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
- /*
- * For given ndiv and mdiv values check the
- * two closest thp values.
- */
- tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
- tclk *= (1 << ndiv_idx);
- thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
- for (inc = 0; inc <= 1; inc++) {
- thp_idx = thp_base + inc;
- if (thp_idx < 5 || thp_idx > 0xff)
- continue;
-
- foscl = i2c->sys_freq / (2 * (thp_idx + 1));
- foscl = foscl / (1 << ndiv_idx);
- foscl = foscl / (mdiv_idx + 1) / 10;
- diff = abs(foscl - i2c->twsi_freq);
- if (diff < delta_hz) {
- delta_hz = diff;
- thp = thp_idx;
- mdiv = mdiv_idx;
- ndiv = ndiv_idx;
- }
- }
- }
- }
- octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp);
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
-
- return 0;
-}
-
-static int __devinit octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
-{
- u8 status;
- int tries;
-
- /* disable high level controller, enable bus access */
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
-
- /* reset controller */
- octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0);
-
- for (tries = 10; tries; tries--) {
- udelay(1);
- status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
- if (status == STAT_IDLE)
- return 0;
- }
- dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status);
- return -EIO;
-}
-
-static int __devinit octeon_i2c_probe(struct platform_device *pdev)
-{
- int irq, result = 0;
- struct octeon_i2c *i2c;
- struct octeon_i2c_data *i2c_data;
- struct resource *res_mem;
-
- /* All adaptors have an irq. */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
- if (!i2c) {
- dev_err(&pdev->dev, "kzalloc failed\n");
- result = -ENOMEM;
- goto out;
- }
- i2c->dev = &pdev->dev;
- i2c_data = pdev->dev.platform_data;
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- if (res_mem == NULL) {
- dev_err(i2c->dev, "found no memory resource\n");
- result = -ENXIO;
- goto fail_region;
- }
-
- if (i2c_data == NULL) {
- dev_err(i2c->dev, "no I2C frequency data\n");
- result = -ENXIO;
- goto fail_region;
- }
-
- i2c->twsi_phys = res_mem->start;
- i2c->regsize = resource_size(res_mem);
- i2c->twsi_freq = i2c_data->i2c_freq;
- i2c->sys_freq = i2c_data->sys_freq;
-
- if (!request_mem_region(i2c->twsi_phys, i2c->regsize, res_mem->name)) {
- dev_err(i2c->dev, "request_mem_region failed\n");
- goto fail_region;
- }
- i2c->twsi_base = ioremap(i2c->twsi_phys, i2c->regsize);
-
- init_waitqueue_head(&i2c->queue);
-
- i2c->irq = irq;
-
- result = request_irq(i2c->irq, octeon_i2c_isr, 0, DRV_NAME, i2c);
- if (result < 0) {
- dev_err(i2c->dev, "failed to attach interrupt\n");
- goto fail_irq;
- }
-
- result = octeon_i2c_initlowlevel(i2c);
- if (result) {
- dev_err(i2c->dev, "init low level failed\n");
- goto fail_add;
- }
-
- result = octeon_i2c_setclock(i2c);
- if (result) {
- dev_err(i2c->dev, "clock init failed\n");
- goto fail_add;
- }
-
- i2c->adap = octeon_i2c_ops;
- i2c->adap.dev.parent = &pdev->dev;
- i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
- i2c_set_adapdata(&i2c->adap, i2c);
- platform_set_drvdata(pdev, i2c);
-
- result = i2c_add_numbered_adapter(&i2c->adap);
- if (result < 0) {
- dev_err(i2c->dev, "failed to add adapter\n");
- goto fail_add;
- }
-
- dev_info(i2c->dev, "version %s\n", DRV_VERSION);
-
- return result;
-
-fail_add:
- platform_set_drvdata(pdev, NULL);
- free_irq(i2c->irq, i2c);
-fail_irq:
- iounmap(i2c->twsi_base);
- release_mem_region(i2c->twsi_phys, i2c->regsize);
-fail_region:
- kfree(i2c);
-out:
- return result;
-};
-
-static int __devexit octeon_i2c_remove(struct platform_device *pdev)
-{
- struct octeon_i2c *i2c = platform_get_drvdata(pdev);
-
- i2c_del_adapter(&i2c->adap);
- platform_set_drvdata(pdev, NULL);
- free_irq(i2c->irq, i2c);
- iounmap(i2c->twsi_base);
- release_mem_region(i2c->twsi_phys, i2c->regsize);
- kfree(i2c);
- return 0;
-};
-
-static struct platform_driver octeon_i2c_driver = {
- .probe = octeon_i2c_probe,
- .remove = __devexit_p(octeon_i2c_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = DRV_NAME,
- },
-};
-
-module_platform_driver(octeon_i2c_driver);
-
-MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>");
-MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-omap.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-omap.c
deleted file mode 100644
index 801df600..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-omap.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-/*
- * TI OMAP I2C master mode driver
- *
- * Copyright (C) 2003 MontaVista Software, Inc.
- * Copyright (C) 2005 Nokia Corporation
- * Copyright (C) 2004 - 2007 Texas Instruments.
- *
- * Originally written by MontaVista Software, Inc.
- * Additional contributions by:
- * Tony Lindgren <tony@atomide.com>
- * Imre Deak <imre.deak@nokia.com>
- * Juha Yrjölä <juha.yrjola@solidboot.com>
- * Syed Khasim <x0khasim@ti.com>
- * Nishant Menon <nm@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/completion.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_i2c.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/i2c-omap.h>
-#include <linux/pm_runtime.h>
-
-/* I2C controller revisions */
-#define OMAP_I2C_OMAP1_REV_2 0x20
-
-/* I2C controller revisions present on specific hardware */
-#define OMAP_I2C_REV_ON_2430 0x36
-#define OMAP_I2C_REV_ON_3430 0x3C
-#define OMAP_I2C_REV_ON_3530_4430 0x40
-
-/* timeout waiting for the controller to respond */
-#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
-
-/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
-enum {
- OMAP_I2C_REV_REG = 0,
- OMAP_I2C_IE_REG,
- OMAP_I2C_STAT_REG,
- OMAP_I2C_IV_REG,
- OMAP_I2C_WE_REG,
- OMAP_I2C_SYSS_REG,
- OMAP_I2C_BUF_REG,
- OMAP_I2C_CNT_REG,
- OMAP_I2C_DATA_REG,
- OMAP_I2C_SYSC_REG,
- OMAP_I2C_CON_REG,
- OMAP_I2C_OA_REG,
- OMAP_I2C_SA_REG,
- OMAP_I2C_PSC_REG,
- OMAP_I2C_SCLL_REG,
- OMAP_I2C_SCLH_REG,
- OMAP_I2C_SYSTEST_REG,
- OMAP_I2C_BUFSTAT_REG,
- /* only on OMAP4430 */
- OMAP_I2C_IP_V2_REVNB_LO,
- OMAP_I2C_IP_V2_REVNB_HI,
- OMAP_I2C_IP_V2_IRQSTATUS_RAW,
- OMAP_I2C_IP_V2_IRQENABLE_SET,
- OMAP_I2C_IP_V2_IRQENABLE_CLR,
-};
-
-/* I2C Interrupt Enable Register (OMAP_I2C_IE): */
-#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */
-#define OMAP_I2C_IE_RDR (1 << 13) /* RX Buffer drain int enable */
-#define OMAP_I2C_IE_XRDY (1 << 4) /* TX data ready int enable */
-#define OMAP_I2C_IE_RRDY (1 << 3) /* RX data ready int enable */
-#define OMAP_I2C_IE_ARDY (1 << 2) /* Access ready int enable */
-#define OMAP_I2C_IE_NACK (1 << 1) /* No ack interrupt enable */
-#define OMAP_I2C_IE_AL (1 << 0) /* Arbitration lost int ena */
-
-/* I2C Status Register (OMAP_I2C_STAT): */
-#define OMAP_I2C_STAT_XDR (1 << 14) /* TX Buffer draining */
-#define OMAP_I2C_STAT_RDR (1 << 13) /* RX Buffer draining */
-#define OMAP_I2C_STAT_BB (1 << 12) /* Bus busy */
-#define OMAP_I2C_STAT_ROVR (1 << 11) /* Receive overrun */
-#define OMAP_I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
-#define OMAP_I2C_STAT_AAS (1 << 9) /* Address as slave */
-#define OMAP_I2C_STAT_AD0 (1 << 8) /* Address zero */
-#define OMAP_I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
-#define OMAP_I2C_STAT_RRDY (1 << 3) /* Receive data ready */
-#define OMAP_I2C_STAT_ARDY (1 << 2) /* Register access ready */
-#define OMAP_I2C_STAT_NACK (1 << 1) /* No ack interrupt enable */
-#define OMAP_I2C_STAT_AL (1 << 0) /* Arbitration lost int ena */
-
-/* I2C WE wakeup enable register */
-#define OMAP_I2C_WE_XDR_WE (1 << 14) /* TX drain wakup */
-#define OMAP_I2C_WE_RDR_WE (1 << 13) /* RX drain wakeup */
-#define OMAP_I2C_WE_AAS_WE (1 << 9) /* Address as slave wakeup*/
-#define OMAP_I2C_WE_BF_WE (1 << 8) /* Bus free wakeup */
-#define OMAP_I2C_WE_STC_WE (1 << 6) /* Start condition wakeup */
-#define OMAP_I2C_WE_GC_WE (1 << 5) /* General call wakeup */
-#define OMAP_I2C_WE_DRDY_WE (1 << 3) /* TX/RX data ready wakeup */
-#define OMAP_I2C_WE_ARDY_WE (1 << 2) /* Reg access ready wakeup */
-#define OMAP_I2C_WE_NACK_WE (1 << 1) /* No acknowledgment wakeup */
-#define OMAP_I2C_WE_AL_WE (1 << 0) /* Arbitration lost wakeup */
-
-#define OMAP_I2C_WE_ALL (OMAP_I2C_WE_XDR_WE | OMAP_I2C_WE_RDR_WE | \
- OMAP_I2C_WE_AAS_WE | OMAP_I2C_WE_BF_WE | \
- OMAP_I2C_WE_STC_WE | OMAP_I2C_WE_GC_WE | \
- OMAP_I2C_WE_DRDY_WE | OMAP_I2C_WE_ARDY_WE | \
- OMAP_I2C_WE_NACK_WE | OMAP_I2C_WE_AL_WE)
-
-/* I2C Buffer Configuration Register (OMAP_I2C_BUF): */
-#define OMAP_I2C_BUF_RDMA_EN (1 << 15) /* RX DMA channel enable */
-#define OMAP_I2C_BUF_RXFIF_CLR (1 << 14) /* RX FIFO Clear */
-#define OMAP_I2C_BUF_XDMA_EN (1 << 7) /* TX DMA channel enable */
-#define OMAP_I2C_BUF_TXFIF_CLR (1 << 6) /* TX FIFO Clear */
-
-/* I2C Configuration Register (OMAP_I2C_CON): */
-#define OMAP_I2C_CON_EN (1 << 15) /* I2C module enable */
-#define OMAP_I2C_CON_BE (1 << 14) /* Big endian mode */
-#define OMAP_I2C_CON_OPMODE_HS (1 << 12) /* High Speed support */
-#define OMAP_I2C_CON_STB (1 << 11) /* Start byte mode (master) */
-#define OMAP_I2C_CON_MST (1 << 10) /* Master/slave mode */
-#define OMAP_I2C_CON_TRX (1 << 9) /* TX/RX mode (master only) */
-#define OMAP_I2C_CON_XA (1 << 8) /* Expand address */
-#define OMAP_I2C_CON_RM (1 << 2) /* Repeat mode (master only) */
-#define OMAP_I2C_CON_STP (1 << 1) /* Stop cond (master only) */
-#define OMAP_I2C_CON_STT (1 << 0) /* Start condition (master) */
-
-/* I2C SCL time value when Master */
-#define OMAP_I2C_SCLL_HSSCLL 8
-#define OMAP_I2C_SCLH_HSSCLH 8
-
-/* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
-#define OMAP_I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
-#define OMAP_I2C_SYSTEST_FREE (1 << 14) /* Free running mode */
-#define OMAP_I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
-#define OMAP_I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense in */
-#define OMAP_I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive out */
-#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
-#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-#endif
-
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK (1 << 0)
-
-/* OCP_SYSCONFIG bit definitions */
-#define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
-#define SYSC_SIDLEMODE_MASK (0x3 << 3)
-#define SYSC_ENAWAKEUP_MASK (1 << 2)
-#define SYSC_SOFTRESET_MASK (1 << 1)
-#define SYSC_AUTOIDLE_MASK (1 << 0)
-
-#define SYSC_IDLEMODE_SMART 0x2
-#define SYSC_CLOCKACTIVITY_FCLK 0x2
-
-/* Errata definitions */
-#define I2C_OMAP_ERRATA_I207 (1 << 0)
-#define I2C_OMAP3_1P153 (1 << 1)
-
-struct omap_i2c_dev {
- struct device *dev;
- void __iomem *base; /* virtual */
- int irq;
- int reg_shift; /* bit shift for I2C register addresses */
- struct completion cmd_complete;
- struct resource *ioarea;
- u32 latency; /* maximum mpu wkup latency */
- void (*set_mpu_wkup_lat)(struct device *dev,
- long latency);
- u32 speed; /* Speed of bus in kHz */
- u32 dtrev; /* extra revision from DT */
- u32 flags;
- u16 cmd_err;
- u8 *buf;
- u8 *regs;
- size_t buf_len;
- struct i2c_adapter adapter;
- u8 fifo_size; /* use as flag and value
- * fifo_size==0 implies no fifo
- * if set, should be trsh+1
- */
- u8 rev;
- unsigned b_hw:1; /* bad h/w fixes */
- u16 iestate; /* Saved interrupt register */
- u16 pscstate;
- u16 scllstate;
- u16 sclhstate;
- u16 bufstate;
- u16 syscstate;
- u16 westate;
- u16 errata;
-};
-
-static const u8 reg_map_ip_v1[] = {
- [OMAP_I2C_REV_REG] = 0x00,
- [OMAP_I2C_IE_REG] = 0x01,
- [OMAP_I2C_STAT_REG] = 0x02,
- [OMAP_I2C_IV_REG] = 0x03,
- [OMAP_I2C_WE_REG] = 0x03,
- [OMAP_I2C_SYSS_REG] = 0x04,
- [OMAP_I2C_BUF_REG] = 0x05,
- [OMAP_I2C_CNT_REG] = 0x06,
- [OMAP_I2C_DATA_REG] = 0x07,
- [OMAP_I2C_SYSC_REG] = 0x08,
- [OMAP_I2C_CON_REG] = 0x09,
- [OMAP_I2C_OA_REG] = 0x0a,
- [OMAP_I2C_SA_REG] = 0x0b,
- [OMAP_I2C_PSC_REG] = 0x0c,
- [OMAP_I2C_SCLL_REG] = 0x0d,
- [OMAP_I2C_SCLH_REG] = 0x0e,
- [OMAP_I2C_SYSTEST_REG] = 0x0f,
- [OMAP_I2C_BUFSTAT_REG] = 0x10,
-};
-
-static const u8 reg_map_ip_v2[] = {
- [OMAP_I2C_REV_REG] = 0x04,
- [OMAP_I2C_IE_REG] = 0x2c,
- [OMAP_I2C_STAT_REG] = 0x28,
- [OMAP_I2C_IV_REG] = 0x34,
- [OMAP_I2C_WE_REG] = 0x34,
- [OMAP_I2C_SYSS_REG] = 0x90,
- [OMAP_I2C_BUF_REG] = 0x94,
- [OMAP_I2C_CNT_REG] = 0x98,
- [OMAP_I2C_DATA_REG] = 0x9c,
- [OMAP_I2C_SYSC_REG] = 0x10,
- [OMAP_I2C_CON_REG] = 0xa4,
- [OMAP_I2C_OA_REG] = 0xa8,
- [OMAP_I2C_SA_REG] = 0xac,
- [OMAP_I2C_PSC_REG] = 0xb0,
- [OMAP_I2C_SCLL_REG] = 0xb4,
- [OMAP_I2C_SCLH_REG] = 0xb8,
- [OMAP_I2C_SYSTEST_REG] = 0xbC,
- [OMAP_I2C_BUFSTAT_REG] = 0xc0,
- [OMAP_I2C_IP_V2_REVNB_LO] = 0x00,
- [OMAP_I2C_IP_V2_REVNB_HI] = 0x04,
- [OMAP_I2C_IP_V2_IRQSTATUS_RAW] = 0x24,
- [OMAP_I2C_IP_V2_IRQENABLE_SET] = 0x2c,
- [OMAP_I2C_IP_V2_IRQENABLE_CLR] = 0x30,
-};
-
-static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
- int reg, u16 val)
-{
- __raw_writew(val, i2c_dev->base +
- (i2c_dev->regs[reg] << i2c_dev->reg_shift));
-}
-
-static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
-{
- return __raw_readw(i2c_dev->base +
- (i2c_dev->regs[reg] << i2c_dev->reg_shift));
-}
-
-static void omap_i2c_unidle(struct omap_i2c_dev *dev)
-{
- if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->syscstate);
- omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
- }
-
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
-}
-
-static void omap_i2c_idle(struct omap_i2c_dev *dev)
-{
- u16 iv;
-
- dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
- if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
- omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
- else
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
-
- if (dev->rev < OMAP_I2C_OMAP1_REV_2) {
- iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
- } else {
- omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
-
- /* Flush posted write */
- omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
- }
-}
-
-static int omap_i2c_init(struct omap_i2c_dev *dev)
-{
- u16 psc = 0, scll = 0, sclh = 0, buf = 0;
- u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
- unsigned long fclk_rate = 12000000;
- unsigned long timeout;
- unsigned long internal_clk = 0;
- struct clk *fclk;
-
- if (dev->rev >= OMAP_I2C_OMAP1_REV_2) {
- /* Disable I2C controller before soft reset */
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
- omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) &
- ~(OMAP_I2C_CON_EN));
-
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK);
- /* For some reason we need to set the EN bit before the
- * reset done bit gets set. */
- timeout = jiffies + OMAP_I2C_TIMEOUT;
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
- while (!(omap_i2c_read_reg(dev, OMAP_I2C_SYSS_REG) &
- SYSS_RESETDONE_MASK)) {
- if (time_after(jiffies, timeout)) {
- dev_warn(dev->dev, "timeout waiting "
- "for controller reset\n");
- return -ETIMEDOUT;
- }
- msleep(1);
- }
-
- /* SYSC register is cleared by the reset; rewrite it */
- if (dev->rev == OMAP_I2C_REV_ON_2430) {
-
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
- SYSC_AUTOIDLE_MASK);
-
- } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
- dev->syscstate = SYSC_AUTOIDLE_MASK;
- dev->syscstate |= SYSC_ENAWAKEUP_MASK;
- dev->syscstate |= (SYSC_IDLEMODE_SMART <<
- __ffs(SYSC_SIDLEMODE_MASK));
- dev->syscstate |= (SYSC_CLOCKACTIVITY_FCLK <<
- __ffs(SYSC_CLOCKACTIVITY_MASK));
-
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
- dev->syscstate);
- /*
- * Enabling all wakup sources to stop I2C freezing on
- * WFI instruction.
- * REVISIT: Some wkup sources might not be needed.
- */
- dev->westate = OMAP_I2C_WE_ALL;
- omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
- dev->westate);
- }
- }
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
-
- if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
- /*
- * The I2C functional clock is the armxor_ck, so there's
- * no need to get "armxor_ck" separately. Now, if OMAP2420
- * always returns 12MHz for the functional clock, we can
- * do this bit unconditionally.
- */
- fclk = clk_get(dev->dev, "fck");
- fclk_rate = clk_get_rate(fclk);
- clk_put(fclk);
-
- /* TRM for 5912 says the I2C clock must be prescaled to be
- * between 7 - 12 MHz. The XOR input clock is typically
- * 12, 13 or 19.2 MHz. So we should have code that produces:
- *
- * XOR MHz Divider Prescaler
- * 12 1 0
- * 13 2 1
- * 19.2 2 1
- */
- if (fclk_rate > 12000000)
- psc = fclk_rate / 12000000;
- }
-
- if (!(dev->flags & OMAP_I2C_FLAG_SIMPLE_CLOCK)) {
-
- /*
- * HSI2C controller internal clk rate should be 19.2 Mhz for
- * HS and for all modes on 2430. On 34xx we can use lower rate
- * to get longer filter period for better noise suppression.
- * The filter is iclk (fclk for HS) period.
- */
- if (dev->speed > 400 ||
- dev->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK)
- internal_clk = 19200;
- else if (dev->speed > 100)
- internal_clk = 9600;
- else
- internal_clk = 4000;
- fclk = clk_get(dev->dev, "fck");
- fclk_rate = clk_get_rate(fclk) / 1000;
- clk_put(fclk);
-
- /* Compute prescaler divisor */
- psc = fclk_rate / internal_clk;
- psc = psc - 1;
-
- /* If configured for High Speed */
- if (dev->speed > 400) {
- unsigned long scl;
-
- /* For first phase of HS mode */
- scl = internal_clk / 400;
- fsscll = scl - (scl / 3) - 7;
- fssclh = (scl / 3) - 5;
-
- /* For second phase of HS mode */
- scl = fclk_rate / dev->speed;
- hsscll = scl - (scl / 3) - 7;
- hssclh = (scl / 3) - 5;
- } else if (dev->speed > 100) {
- unsigned long scl;
-
- /* Fast mode */
- scl = internal_clk / dev->speed;
- fsscll = scl - (scl / 3) - 7;
- fssclh = (scl / 3) - 5;
- } else {
- /* Standard mode */
- fsscll = internal_clk / (dev->speed * 2) - 7;
- fssclh = internal_clk / (dev->speed * 2) - 5;
- }
- scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll;
- sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh;
- } else {
- /* Program desired operating rate */
- fclk_rate /= (psc + 1) * 1000;
- if (psc > 2)
- psc = 2;
- scll = fclk_rate / (dev->speed * 2) - 7 + psc;
- sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
- }
-
- /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
- omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
-
- /* SCL low and high time values */
- omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
-
- if (dev->fifo_size) {
- /* Note: setup required fifo size - 1. RTRSH and XTRSH */
- buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
- (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
- }
-
- /* Take the I2C module out of reset: */
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
-
- dev->errata = 0;
-
- if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207)
- dev->errata |= I2C_OMAP_ERRATA_I207;
-
- /* Enable interrupts */
- dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
- OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
- OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
- (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
- if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- dev->pscstate = psc;
- dev->scllstate = scll;
- dev->sclhstate = sclh;
- dev->bufstate = buf;
- }
- return 0;
-}
-
-/*
- * Waiting on Bus Busy
- */
-static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
-{
- unsigned long timeout;
-
- timeout = jiffies + OMAP_I2C_TIMEOUT;
- while (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG) & OMAP_I2C_STAT_BB) {
- if (time_after(jiffies, timeout)) {
- dev_warn(dev->dev, "timeout waiting for bus ready\n");
- return -ETIMEDOUT;
- }
- msleep(1);
- }
-
- return 0;
-}
-
-/*
- * Low level master read/write transaction.
- */
-static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
- struct i2c_msg *msg, int stop)
-{
- struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
- int r;
- u16 w;
-
- dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
- msg->addr, msg->len, msg->flags, stop);
-
- if (msg->len == 0)
- return -EINVAL;
-
- omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);
-
- /* REVISIT: Could the STB bit of I2C_CON be used with probing? */
- dev->buf = msg->buf;
- dev->buf_len = msg->len;
-
- omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
-
- /* Clear the FIFO Buffers */
- w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
- w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
-
- init_completion(&dev->cmd_complete);
- dev->cmd_err = 0;
-
- w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
-
- /* High speed configuration */
- if (dev->speed > 400)
- w |= OMAP_I2C_CON_OPMODE_HS;
-
- if (msg->flags & I2C_M_TEN)
- w |= OMAP_I2C_CON_XA;
- if (!(msg->flags & I2C_M_RD))
- w |= OMAP_I2C_CON_TRX;
-
- if (!dev->b_hw && stop)
- w |= OMAP_I2C_CON_STP;
-
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
-
- /*
- * Don't write stt and stp together on some hardware.
- */
- if (dev->b_hw && stop) {
- unsigned long delay = jiffies + OMAP_I2C_TIMEOUT;
- u16 con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
- while (con & OMAP_I2C_CON_STT) {
- con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
-
- /* Let the user know if i2c is in a bad state */
- if (time_after(jiffies, delay)) {
- dev_err(dev->dev, "controller timed out "
- "waiting for start condition to finish\n");
- return -ETIMEDOUT;
- }
- cpu_relax();
- }
-
- w |= OMAP_I2C_CON_STP;
- w &= ~OMAP_I2C_CON_STT;
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
- }
-
- /*
- * REVISIT: We should abort the transfer on signals, but the bus goes
- * into arbitration and we're currently unable to recover from it.
- */
- r = wait_for_completion_timeout(&dev->cmd_complete,
- OMAP_I2C_TIMEOUT);
- dev->buf_len = 0;
- if (r < 0)
- return r;
- if (r == 0) {
- dev_err(dev->dev, "controller timed out\n");
- omap_i2c_init(dev);
- return -ETIMEDOUT;
- }
-
- if (likely(!dev->cmd_err))
- return 0;
-
- /* We have an error */
- if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR |
- OMAP_I2C_STAT_XUDF)) {
- omap_i2c_init(dev);
- return -EIO;
- }
-
- if (dev->cmd_err & OMAP_I2C_STAT_NACK) {
- if (msg->flags & I2C_M_IGNORE_NAK)
- return 0;
- if (stop) {
- w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
- w |= OMAP_I2C_CON_STP;
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
- }
- return -EREMOTEIO;
- }
- return -EIO;
-}
-
-
-/*
- * Prepare controller for a transaction and call omap_i2c_xfer_msg
- * to do the work during IRQ processing.
- */
-static int
-omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-{
- struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
- int i;
- int r;
-
- pm_runtime_get_sync(dev->dev);
-
- r = omap_i2c_wait_for_bb(dev);
- if (r < 0)
- goto out;
-
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, dev->latency);
-
- for (i = 0; i < num; i++) {
- r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
- if (r != 0)
- break;
- }
-
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, -1);
-
- if (r == 0)
- r = num;
-
- omap_i2c_wait_for_bb(dev);
-out:
- pm_runtime_put(dev->dev);
- return r;
-}
-
-static u32
-omap_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
-}
-
-static inline void
-omap_i2c_complete_cmd(struct omap_i2c_dev *dev, u16 err)
-{
- dev->cmd_err |= err;
- complete(&dev->cmd_complete);
-}
-
-static inline void
-omap_i2c_ack_stat(struct omap_i2c_dev *dev, u16 stat)
-{
- omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
-}
-
-static inline void i2c_omap_errata_i207(struct omap_i2c_dev *dev, u16 stat)
-{
- /*
- * I2C Errata(Errata Nos. OMAP2: 1.67, OMAP3: 1.8)
- * Not applicable for OMAP4.
- * Under certain rare conditions, RDR could be set again
- * when the bus is busy, then ignore the interrupt and
- * clear the interrupt.
- */
- if (stat & OMAP_I2C_STAT_RDR) {
- /* Step 1: If RDR is set, clear it */
- omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
-
- /* Step 2: */
- if (!(omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG)
- & OMAP_I2C_STAT_BB)) {
-
- /* Step 3: */
- if (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG)
- & OMAP_I2C_STAT_RDR) {
- omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
- dev_dbg(dev->dev, "RDR when bus is busy.\n");
- }
-
- }
- }
-}
-
-/* rev1 devices are apparently only on some 15xx */
-#ifdef CONFIG_ARCH_OMAP15XX
-
-static irqreturn_t
-omap_i2c_omap1_isr(int this_irq, void *dev_id)
-{
- struct omap_i2c_dev *dev = dev_id;
- u16 iv, w;
-
- if (pm_runtime_suspended(dev->dev))
- return IRQ_NONE;
-
- iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
- switch (iv) {
- case 0x00: /* None */
- break;
- case 0x01: /* Arbitration lost */
- dev_err(dev->dev, "Arbitration lost\n");
- omap_i2c_complete_cmd(dev, OMAP_I2C_STAT_AL);
- break;
- case 0x02: /* No acknowledgement */
- omap_i2c_complete_cmd(dev, OMAP_I2C_STAT_NACK);
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_STP);
- break;
- case 0x03: /* Register access ready */
- omap_i2c_complete_cmd(dev, 0);
- break;
- case 0x04: /* Receive data ready */
- if (dev->buf_len) {
- w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
- *dev->buf++ = w;
- dev->buf_len--;
- if (dev->buf_len) {
- *dev->buf++ = w >> 8;
- dev->buf_len--;
- }
- } else
- dev_err(dev->dev, "RRDY IRQ while no data requested\n");
- break;
- case 0x05: /* Transmit data ready */
- if (dev->buf_len) {
- w = *dev->buf++;
- dev->buf_len--;
- if (dev->buf_len) {
- w |= *dev->buf++ << 8;
- dev->buf_len--;
- }
- omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
- } else
- dev_err(dev->dev, "XRDY IRQ while no data to send\n");
- break;
- default:
- return IRQ_NONE;
- }
-
- return IRQ_HANDLED;
-}
-#else
-#define omap_i2c_omap1_isr NULL
-#endif
-
-/*
- * OMAP3430 Errata 1.153: When an XRDY/XDR is hit, wait for XUDF before writing
- * data to DATA_REG. Otherwise some data bytes can be lost while transferring
- * them from the memory to the I2C interface.
- */
-static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
-{
- unsigned long timeout = 10000;
-
- while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
- if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
- omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
- OMAP_I2C_STAT_XDR));
- *err |= OMAP_I2C_STAT_XUDF;
- return -ETIMEDOUT;
- }
-
- cpu_relax();
- *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
- }
-
- if (!timeout) {
- dev_err(dev->dev, "timeout waiting on XUDF bit\n");
- return 0;
- }
-
- return 0;
-}
-
-static irqreturn_t
-omap_i2c_isr(int this_irq, void *dev_id)
-{
- struct omap_i2c_dev *dev = dev_id;
- u16 bits;
- u16 stat, w;
- int err, count = 0;
-
- if (pm_runtime_suspended(dev->dev))
- return IRQ_NONE;
-
- bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
- while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
- dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
- if (count++ == 100) {
- dev_warn(dev->dev, "Too much work in one IRQ\n");
- break;
- }
-
- err = 0;
-complete:
- /*
- * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
- * acked after the data operation is complete.
- * Ref: TRM SWPU114Q Figure 18-31
- */
- omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
- ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
- OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
- if (stat & OMAP_I2C_STAT_NACK)
- err |= OMAP_I2C_STAT_NACK;
-
- if (stat & OMAP_I2C_STAT_AL) {
- dev_err(dev->dev, "Arbitration lost\n");
- err |= OMAP_I2C_STAT_AL;
- }
- /*
- * ProDB0017052: Clear ARDY bit twice
- */
- if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
- OMAP_I2C_STAT_AL)) {
- omap_i2c_ack_stat(dev, stat &
- (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
- OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
- OMAP_I2C_STAT_ARDY));
- omap_i2c_complete_cmd(dev, err);
- return IRQ_HANDLED;
- }
- if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
- u8 num_bytes = 1;
-
- if (dev->errata & I2C_OMAP_ERRATA_I207)
- i2c_omap_errata_i207(dev, stat);
-
- if (dev->fifo_size) {
- if (stat & OMAP_I2C_STAT_RRDY)
- num_bytes = dev->fifo_size;
- else /* read RXSTAT on RDR interrupt */
- num_bytes = (omap_i2c_read_reg(dev,
- OMAP_I2C_BUFSTAT_REG)
- >> 8) & 0x3F;
- }
- while (num_bytes) {
- num_bytes--;
- w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
- if (dev->buf_len) {
- *dev->buf++ = w;
- dev->buf_len--;
- /*
- * Data reg in 2430, omap3 and
- * omap4 is 8 bit wide
- */
- if (dev->flags &
- OMAP_I2C_FLAG_16BIT_DATA_REG) {
- if (dev->buf_len) {
- *dev->buf++ = w >> 8;
- dev->buf_len--;
- }
- }
- } else {
- if (stat & OMAP_I2C_STAT_RRDY)
- dev_err(dev->dev,
- "RRDY IRQ while no data"
- " requested\n");
- if (stat & OMAP_I2C_STAT_RDR)
- dev_err(dev->dev,
- "RDR IRQ while no data"
- " requested\n");
- break;
- }
- }
- omap_i2c_ack_stat(dev,
- stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
- continue;
- }
- if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
- u8 num_bytes = 1;
- if (dev->fifo_size) {
- if (stat & OMAP_I2C_STAT_XRDY)
- num_bytes = dev->fifo_size;
- else /* read TXSTAT on XDR interrupt */
- num_bytes = omap_i2c_read_reg(dev,
- OMAP_I2C_BUFSTAT_REG)
- & 0x3F;
- }
- while (num_bytes) {
- num_bytes--;
- w = 0;
- if (dev->buf_len) {
- w = *dev->buf++;
- dev->buf_len--;
- /*
- * Data reg in 2430, omap3 and
- * omap4 is 8 bit wide
- */
- if (dev->flags &
- OMAP_I2C_FLAG_16BIT_DATA_REG) {
- if (dev->buf_len) {
- w |= *dev->buf++ << 8;
- dev->buf_len--;
- }
- }
- } else {
- if (stat & OMAP_I2C_STAT_XRDY)
- dev_err(dev->dev,
- "XRDY IRQ while no "
- "data to send\n");
- if (stat & OMAP_I2C_STAT_XDR)
- dev_err(dev->dev,
- "XDR IRQ while no "
- "data to send\n");
- break;
- }
-
- if ((dev->errata & I2C_OMAP3_1P153) &&
- errata_omap3_1p153(dev, &stat, &err))
- goto complete;
-
- omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
- }
- omap_i2c_ack_stat(dev,
- stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
- continue;
- }
- if (stat & OMAP_I2C_STAT_ROVR) {
- dev_err(dev->dev, "Receive overrun\n");
- dev->cmd_err |= OMAP_I2C_STAT_ROVR;
- }
- if (stat & OMAP_I2C_STAT_XUDF) {
- dev_err(dev->dev, "Transmit underflow\n");
- dev->cmd_err |= OMAP_I2C_STAT_XUDF;
- }
- }
-
- return count ? IRQ_HANDLED : IRQ_NONE;
-}
-
-static const struct i2c_algorithm omap_i2c_algo = {
- .master_xfer = omap_i2c_xfer,
- .functionality = omap_i2c_func,
-};
-
-#ifdef CONFIG_OF
-static struct omap_i2c_bus_platform_data omap3_pdata = {
- .rev = OMAP_I2C_IP_VERSION_1,
- .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 |
- OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
- OMAP_I2C_FLAG_BUS_SHIFT_2,
-};
-
-static struct omap_i2c_bus_platform_data omap4_pdata = {
- .rev = OMAP_I2C_IP_VERSION_2,
-};
-
-static const struct of_device_id omap_i2c_of_match[] = {
- {
- .compatible = "ti,omap4-i2c",
- .data = &omap4_pdata,
- },
- {
- .compatible = "ti,omap3-i2c",
- .data = &omap3_pdata,
- },
- { },
-};
-MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
-#endif
-
-static int __devinit
-omap_i2c_probe(struct platform_device *pdev)
-{
- struct omap_i2c_dev *dev;
- struct i2c_adapter *adap;
- struct resource *mem, *irq, *ioarea;
- struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
- struct device_node *node = pdev->dev.of_node;
- const struct of_device_id *match;
- irq_handler_t isr;
- int r;
-
- /* NOTE: driver uses the static register mapping */
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "no mem resource?\n");
- return -ENODEV;
- }
- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!irq) {
- dev_err(&pdev->dev, "no irq resource?\n");
- return -ENODEV;
- }
-
- ioarea = request_mem_region(mem->start, resource_size(mem),
- pdev->name);
- if (!ioarea) {
- dev_err(&pdev->dev, "I2C region already claimed\n");
- return -EBUSY;
- }
-
- dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
- if (!dev) {
- r = -ENOMEM;
- goto err_release_region;
- }
-
- match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
- if (match) {
- u32 freq = 100000; /* default to 100000 Hz */
-
- pdata = match->data;
- dev->dtrev = pdata->rev;
- dev->flags = pdata->flags;
-
- of_property_read_u32(node, "clock-frequency", &freq);
- /* convert DT freq value in Hz into kHz for speed */
- dev->speed = freq / 1000;
- } else if (pdata != NULL) {
- dev->speed = pdata->clkrate;
- dev->flags = pdata->flags;
- dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
- dev->dtrev = pdata->rev;
- }
-
- dev->dev = &pdev->dev;
- dev->irq = irq->start;
- dev->base = ioremap(mem->start, resource_size(mem));
- if (!dev->base) {
- r = -ENOMEM;
- goto err_free_mem;
- }
-
- platform_set_drvdata(pdev, dev);
-
- dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
-
- if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
- dev->regs = (u8 *)reg_map_ip_v2;
- else
- dev->regs = (u8 *)reg_map_ip_v1;
-
- pm_runtime_enable(dev->dev);
- pm_runtime_get_sync(dev->dev);
-
- dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
-
- if (dev->rev <= OMAP_I2C_REV_ON_3430)
- dev->errata |= I2C_OMAP3_1P153;
-
- if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
- u16 s;
-
- /* Set up the fifo size - Get total size */
- s = (omap_i2c_read_reg(dev, OMAP_I2C_BUFSTAT_REG) >> 14) & 0x3;
- dev->fifo_size = 0x8 << s;
-
- /*
- * Set up notification threshold as half the total available
- * size. This is to ensure that we can handle the status on int
- * call back latencies.
- */
-
- dev->fifo_size = (dev->fifo_size / 2);
-
- if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
- dev->b_hw = 0; /* Disable hardware fixes */
- else
- dev->b_hw = 1; /* Enable hardware fixes */
-
- /* calculate wakeup latency constraint for MPU */
- if (dev->set_mpu_wkup_lat != NULL)
- dev->latency = (1000000 * dev->fifo_size) /
- (1000 * dev->speed / 8);
- }
-
- /* reset ASAP, clearing any IRQs */
- omap_i2c_init(dev);
-
- isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
- omap_i2c_isr;
- r = request_irq(dev->irq, isr, 0, pdev->name, dev);
-
- if (r) {
- dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
- goto err_unuse_clocks;
- }
-
- dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,
- dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
-
- pm_runtime_put(dev->dev);
-
- adap = &dev->adapter;
- i2c_set_adapdata(adap, dev);
- adap->owner = THIS_MODULE;
- adap->class = I2C_CLASS_HWMON;
- strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
- adap->algo = &omap_i2c_algo;
- adap->dev.parent = &pdev->dev;
- adap->dev.of_node = pdev->dev.of_node;
-
- /* i2c device drivers may be active on return from add_adapter() */
- adap->nr = pdev->id;
- r = i2c_add_numbered_adapter(adap);
- if (r) {
- dev_err(dev->dev, "failure adding adapter\n");
- goto err_free_irq;
- }
-
- of_i2c_register_devices(adap);
-
- return 0;
-
-err_free_irq:
- free_irq(dev->irq, dev);
-err_unuse_clocks:
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
- pm_runtime_put(dev->dev);
- iounmap(dev->base);
-err_free_mem:
- platform_set_drvdata(pdev, NULL);
- kfree(dev);
-err_release_region:
- release_mem_region(mem->start, resource_size(mem));
-
- return r;
-}
-
-static int
-omap_i2c_remove(struct platform_device *pdev)
-{
- struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
- struct resource *mem;
-
- platform_set_drvdata(pdev, NULL);
-
- free_irq(dev->irq, dev);
- i2c_del_adapter(&dev->adapter);
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
- iounmap(dev->base);
- kfree(dev);
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
- return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-static int omap_i2c_runtime_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
-
- omap_i2c_idle(_dev);
-
- return 0;
-}
-
-static int omap_i2c_runtime_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
-
- omap_i2c_unidle(_dev);
-
- return 0;
-}
-
-static struct dev_pm_ops omap_i2c_pm_ops = {
- .runtime_suspend = omap_i2c_runtime_suspend,
- .runtime_resume = omap_i2c_runtime_resume,
-};
-#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
-#else
-#define OMAP_I2C_PM_OPS NULL
-#endif
-
-static struct platform_driver omap_i2c_driver = {
- .probe = omap_i2c_probe,
- .remove = omap_i2c_remove,
- .driver = {
- .name = "omap_i2c",
- .owner = THIS_MODULE,
- .pm = OMAP_I2C_PM_OPS,
- .of_match_table = of_match_ptr(omap_i2c_of_match),
- },
-};
-
-/* I2C may be needed to bring up other drivers */
-static int __init
-omap_i2c_init_driver(void)
-{
- return platform_driver_register(&omap_i2c_driver);
-}
-subsys_initcall(omap_i2c_init_driver);
-
-static void __exit omap_i2c_exit_driver(void)
-{
- platform_driver_unregister(&omap_i2c_driver);
-}
-module_exit(omap_i2c_exit_driver);
-
-MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
-MODULE_DESCRIPTION("TI OMAP I2C bus adapter");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:omap_i2c");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport-light.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport-light.c
deleted file mode 100644
index 4b95f7a6..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport-light.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* ------------------------------------------------------------------------ *
- * i2c-parport-light.c I2C bus over parallel port *
- * ------------------------------------------------------------------------ *
- Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
-
- Based on older i2c-velleman.c driver
- Copyright (C) 1995-2000 Simon G. Vogl
- With some changes from:
- Frodo Looijaard <frodol@dds.nl>
- Kyösti Mälkki <kmalkki@cc.hut.fi>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ------------------------------------------------------------------------ */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/i2c-smbus.h>
-#include <linux/io.h>
-#include "i2c-parport.h"
-
-#define DEFAULT_BASE 0x378
-#define DRVNAME "i2c-parport-light"
-
-static struct platform_device *pdev;
-
-static u16 base;
-module_param(base, ushort, 0);
-MODULE_PARM_DESC(base, "Base I/O address");
-
-static int irq;
-module_param(irq, int, 0);
-MODULE_PARM_DESC(irq, "IRQ (optional)");
-
-/* ----- Low-level parallel port access ----------------------------------- */
-
-static inline void port_write(unsigned char p, unsigned char d)
-{
- outb(d, base+p);
-}
-
-static inline unsigned char port_read(unsigned char p)
-{
- return inb(base+p);
-}
-
-/* ----- Unified line operation functions --------------------------------- */
-
-static inline void line_set(int state, const struct lineop *op)
-{
- u8 oldval = port_read(op->port);
-
- /* Touch only the bit(s) needed */
- if ((op->inverted && !state) || (!op->inverted && state))
- port_write(op->port, oldval | op->val);
- else
- port_write(op->port, oldval & ~op->val);
-}
-
-static inline int line_get(const struct lineop *op)
-{
- u8 oldval = port_read(op->port);
-
- return ((op->inverted && (oldval & op->val) != op->val)
- || (!op->inverted && (oldval & op->val) == op->val));
-}
-
-/* ----- I2C algorithm call-back functions and structures ----------------- */
-
-static void parport_setscl(void *data, int state)
-{
- line_set(state, &adapter_parm[type].setscl);
-}
-
-static void parport_setsda(void *data, int state)
-{
- line_set(state, &adapter_parm[type].setsda);
-}
-
-static int parport_getscl(void *data)
-{
- return line_get(&adapter_parm[type].getscl);
-}
-
-static int parport_getsda(void *data)
-{
- return line_get(&adapter_parm[type].getsda);
-}
-
-/* Encapsulate the functions above in the correct structure
- Note that getscl will be set to NULL by the attaching code for adapters
- that cannot read SCL back */
-static struct i2c_algo_bit_data parport_algo_data = {
- .setsda = parport_setsda,
- .setscl = parport_setscl,
- .getsda = parport_getsda,
- .getscl = parport_getscl,
- .udelay = 50,
- .timeout = HZ,
-};
-
-/* ----- Driver registration ---------------------------------------------- */
-
-static struct i2c_adapter parport_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON,
- .algo_data = &parport_algo_data,
- .name = "Parallel port adapter (light)",
-};
-
-/* SMBus alert support */
-static struct i2c_smbus_alert_setup alert_data = {
- .alert_edge_triggered = 1,
-};
-static struct i2c_client *ara;
-static struct lineop parport_ctrl_irq = {
- .val = (1 << 4),
- .port = PORT_CTRL,
-};
-
-static int __devinit i2c_parport_probe(struct platform_device *pdev)
-{
- int err;
-
- /* Reset hardware to a sane state (SCL and SDA high) */
- parport_setsda(NULL, 1);
- parport_setscl(NULL, 1);
- /* Other init if needed (power on...) */
- if (adapter_parm[type].init.val) {
- line_set(1, &adapter_parm[type].init);
- /* Give powered devices some time to settle */
- msleep(100);
- }
-
- parport_adapter.dev.parent = &pdev->dev;
- err = i2c_bit_add_bus(&parport_adapter);
- if (err) {
- dev_err(&pdev->dev, "Unable to register with I2C\n");
- return err;
- }
-
- /* Setup SMBus alert if supported */
- if (adapter_parm[type].smbus_alert && irq) {
- alert_data.irq = irq;
- ara = i2c_setup_smbus_alert(&parport_adapter, &alert_data);
- if (ara)
- line_set(1, &parport_ctrl_irq);
- else
- dev_warn(&pdev->dev, "Failed to register ARA client\n");
- }
-
- return 0;
-}
-
-static int __devexit i2c_parport_remove(struct platform_device *pdev)
-{
- if (ara) {
- line_set(0, &parport_ctrl_irq);
- i2c_unregister_device(ara);
- ara = NULL;
- }
- i2c_del_adapter(&parport_adapter);
-
- /* Un-init if needed (power off...) */
- if (adapter_parm[type].init.val)
- line_set(0, &adapter_parm[type].init);
-
- return 0;
-}
-
-static struct platform_driver i2c_parport_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = DRVNAME,
- },
- .probe = i2c_parport_probe,
- .remove = __devexit_p(i2c_parport_remove),
-};
-
-static int __init i2c_parport_device_add(u16 address)
-{
- int err;
-
- pdev = platform_device_alloc(DRVNAME, -1);
- if (!pdev) {
- err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
- goto exit;
- }
-
- err = platform_device_add(pdev);
- if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
- goto exit_device_put;
- }
-
- return 0;
-
-exit_device_put:
- platform_device_put(pdev);
-exit:
- return err;
-}
-
-static int __init i2c_parport_init(void)
-{
- int err;
-
- if (type < 0) {
- printk(KERN_ERR DRVNAME ": adapter type unspecified\n");
- return -ENODEV;
- }
-
- if (type >= ARRAY_SIZE(adapter_parm)) {
- printk(KERN_ERR DRVNAME ": invalid type (%d)\n", type);
- return -ENODEV;
- }
-
- if (base == 0) {
- pr_info(DRVNAME ": using default base 0x%x\n", DEFAULT_BASE);
- base = DEFAULT_BASE;
- }
-
- if (!request_region(base, 3, DRVNAME))
- return -EBUSY;
-
- if (irq != 0)
- pr_info(DRVNAME ": using irq %d\n", irq);
-
- if (!adapter_parm[type].getscl.val)
- parport_algo_data.getscl = NULL;
-
- /* Sets global pdev as a side effect */
- err = i2c_parport_device_add(base);
- if (err)
- goto exit_release;
-
- err = platform_driver_register(&i2c_parport_driver);
- if (err)
- goto exit_device;
-
- return 0;
-
-exit_device:
- platform_device_unregister(pdev);
-exit_release:
- release_region(base, 3);
- return err;
-}
-
-static void __exit i2c_parport_exit(void)
-{
- platform_driver_unregister(&i2c_parport_driver);
- platform_device_unregister(pdev);
- release_region(base, 3);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("I2C bus over parallel port (light)");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_parport_init);
-module_exit(i2c_parport_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.c
deleted file mode 100644
index 24565687..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* ------------------------------------------------------------------------ *
- * i2c-parport.c I2C bus over parallel port *
- * ------------------------------------------------------------------------ *
- Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org>
-
- Based on older i2c-philips-par.c driver
- Copyright (C) 1995-2000 Simon G. Vogl
- With some changes from:
- Frodo Looijaard <frodol@dds.nl>
- Kyösti Mälkki <kmalkki@cc.hut.fi>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ------------------------------------------------------------------------ */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/parport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/i2c-smbus.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include "i2c-parport.h"
-
-/* ----- Device list ------------------------------------------------------ */
-
-struct i2c_par {
- struct pardevice *pdev;
- struct i2c_adapter adapter;
- struct i2c_algo_bit_data algo_data;
- struct i2c_smbus_alert_setup alert_data;
- struct i2c_client *ara;
- struct list_head node;
-};
-
-static LIST_HEAD(adapter_list);
-static DEFINE_MUTEX(adapter_list_lock);
-
-/* ----- Low-level parallel port access ----------------------------------- */
-
-static void port_write_data(struct parport *p, unsigned char d)
-{
- parport_write_data(p, d);
-}
-
-static void port_write_control(struct parport *p, unsigned char d)
-{
- parport_write_control(p, d);
-}
-
-static unsigned char port_read_data(struct parport *p)
-{
- return parport_read_data(p);
-}
-
-static unsigned char port_read_status(struct parport *p)
-{
- return parport_read_status(p);
-}
-
-static unsigned char port_read_control(struct parport *p)
-{
- return parport_read_control(p);
-}
-
-static void (* const port_write[])(struct parport *, unsigned char) = {
- port_write_data,
- NULL,
- port_write_control,
-};
-
-static unsigned char (* const port_read[])(struct parport *) = {
- port_read_data,
- port_read_status,
- port_read_control,
-};
-
-/* ----- Unified line operation functions --------------------------------- */
-
-static inline void line_set(struct parport *data, int state,
- const struct lineop *op)
-{
- u8 oldval = port_read[op->port](data);
-
- /* Touch only the bit(s) needed */
- if ((op->inverted && !state) || (!op->inverted && state))
- port_write[op->port](data, oldval | op->val);
- else
- port_write[op->port](data, oldval & ~op->val);
-}
-
-static inline int line_get(struct parport *data,
- const struct lineop *op)
-{
- u8 oldval = port_read[op->port](data);
-
- return ((op->inverted && (oldval & op->val) != op->val)
- || (!op->inverted && (oldval & op->val) == op->val));
-}
-
-/* ----- I2C algorithm call-back functions and structures ----------------- */
-
-static void parport_setscl(void *data, int state)
-{
- line_set((struct parport *) data, state, &adapter_parm[type].setscl);
-}
-
-static void parport_setsda(void *data, int state)
-{
- line_set((struct parport *) data, state, &adapter_parm[type].setsda);
-}
-
-static int parport_getscl(void *data)
-{
- return line_get((struct parport *) data, &adapter_parm[type].getscl);
-}
-
-static int parport_getsda(void *data)
-{
- return line_get((struct parport *) data, &adapter_parm[type].getsda);
-}
-
-/* Encapsulate the functions above in the correct structure.
- Note that this is only a template, from which the real structures are
- copied. The attaching code will set getscl to NULL for adapters that
- cannot read SCL back, and will also make the data field point to
- the parallel port structure. */
-static const struct i2c_algo_bit_data parport_algo_data = {
- .setsda = parport_setsda,
- .setscl = parport_setscl,
- .getsda = parport_getsda,
- .getscl = parport_getscl,
- .udelay = 10, /* ~50 kbps */
- .timeout = HZ,
-};
-
-/* ----- I2c and parallel port call-back functions and structures --------- */
-
-void i2c_parport_irq(void *data)
-{
- struct i2c_par *adapter = data;
- struct i2c_client *ara = adapter->ara;
-
- if (ara) {
- dev_dbg(&ara->dev, "SMBus alert received\n");
- i2c_handle_smbus_alert(ara);
- } else
- dev_dbg(&adapter->adapter.dev,
- "SMBus alert received but no ARA client!\n");
-}
-
-static void i2c_parport_attach(struct parport *port)
-{
- struct i2c_par *adapter;
-
- adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL);
- if (adapter == NULL) {
- printk(KERN_ERR "i2c-parport: Failed to kzalloc\n");
- return;
- }
-
- pr_debug("i2c-parport: attaching to %s\n", port->name);
- parport_disable_irq(port);
- adapter->pdev = parport_register_device(port, "i2c-parport",
- NULL, NULL, i2c_parport_irq, PARPORT_FLAG_EXCL, adapter);
- if (!adapter->pdev) {
- printk(KERN_ERR "i2c-parport: Unable to register with parport\n");
- goto err_free;
- }
-
- /* Fill the rest of the structure */
- adapter->adapter.owner = THIS_MODULE;
- adapter->adapter.class = I2C_CLASS_HWMON;
- strlcpy(adapter->adapter.name, "Parallel port adapter",
- sizeof(adapter->adapter.name));
- adapter->algo_data = parport_algo_data;
- /* Slow down if we can't sense SCL */
- if (!adapter_parm[type].getscl.val) {
- adapter->algo_data.getscl = NULL;
- adapter->algo_data.udelay = 50; /* ~10 kbps */
- }
- adapter->algo_data.data = port;
- adapter->adapter.algo_data = &adapter->algo_data;
- adapter->adapter.dev.parent = port->physport->dev;
-
- if (parport_claim_or_block(adapter->pdev) < 0) {
- printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
- goto err_unregister;
- }
-
- /* Reset hardware to a sane state (SCL and SDA high) */
- parport_setsda(port, 1);
- parport_setscl(port, 1);
- /* Other init if needed (power on...) */
- if (adapter_parm[type].init.val) {
- line_set(port, 1, &adapter_parm[type].init);
- /* Give powered devices some time to settle */
- msleep(100);
- }
-
- if (i2c_bit_add_bus(&adapter->adapter) < 0) {
- printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
- goto err_unregister;
- }
-
- /* Setup SMBus alert if supported */
- if (adapter_parm[type].smbus_alert) {
- adapter->alert_data.alert_edge_triggered = 1;
- adapter->ara = i2c_setup_smbus_alert(&adapter->adapter,
- &adapter->alert_data);
- if (adapter->ara)
- parport_enable_irq(port);
- else
- printk(KERN_WARNING "i2c-parport: Failed to register "
- "ARA client\n");
- }
-
- /* Add the new adapter to the list */
- mutex_lock(&adapter_list_lock);
- list_add_tail(&adapter->node, &adapter_list);
- mutex_unlock(&adapter_list_lock);
- return;
-
- err_unregister:
- parport_release(adapter->pdev);
- parport_unregister_device(adapter->pdev);
- err_free:
- kfree(adapter);
-}
-
-static void i2c_parport_detach(struct parport *port)
-{
- struct i2c_par *adapter, *_n;
-
- /* Walk the list */
- mutex_lock(&adapter_list_lock);
- list_for_each_entry_safe(adapter, _n, &adapter_list, node) {
- if (adapter->pdev->port == port) {
- if (adapter->ara) {
- parport_disable_irq(port);
- i2c_unregister_device(adapter->ara);
- }
- i2c_del_adapter(&adapter->adapter);
-
- /* Un-init if needed (power off...) */
- if (adapter_parm[type].init.val)
- line_set(port, 0, &adapter_parm[type].init);
-
- parport_release(adapter->pdev);
- parport_unregister_device(adapter->pdev);
- list_del(&adapter->node);
- kfree(adapter);
- }
- }
- mutex_unlock(&adapter_list_lock);
-}
-
-static struct parport_driver i2c_parport_driver = {
- .name = "i2c-parport",
- .attach = i2c_parport_attach,
- .detach = i2c_parport_detach,
-};
-
-/* ----- Module loading, unloading and information ------------------------ */
-
-static int __init i2c_parport_init(void)
-{
- if (type < 0) {
- printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
- return -ENODEV;
- }
-
- if (type >= ARRAY_SIZE(adapter_parm)) {
- printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
- return -ENODEV;
- }
-
- return parport_register_driver(&i2c_parport_driver);
-}
-
-static void __exit i2c_parport_exit(void)
-{
- parport_unregister_driver(&i2c_parport_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("I2C bus over parallel port");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_parport_init);
-module_exit(i2c_parport_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.h b/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.h
deleted file mode 100644
index 3fe65230..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-parport.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ------------------------------------------------------------------------ *
- * i2c-parport.h I2C bus over parallel port *
- * ------------------------------------------------------------------------ *
- Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * ------------------------------------------------------------------------ */
-
-#define PORT_DATA 0
-#define PORT_STAT 1
-#define PORT_CTRL 2
-
-struct lineop {
- u8 val;
- u8 port;
- u8 inverted;
-};
-
-struct adapter_parm {
- struct lineop setsda;
- struct lineop setscl;
- struct lineop getsda;
- struct lineop getscl;
- struct lineop init;
- unsigned int smbus_alert:1;
-};
-
-static const struct adapter_parm adapter_parm[] = {
- /* type 0: Philips adapter */
- {
- .setsda = { 0x80, PORT_DATA, 1 },
- .setscl = { 0x08, PORT_CTRL, 0 },
- .getsda = { 0x80, PORT_STAT, 0 },
- .getscl = { 0x08, PORT_STAT, 0 },
- },
- /* type 1: home brew teletext adapter */
- {
- .setsda = { 0x02, PORT_DATA, 0 },
- .setscl = { 0x01, PORT_DATA, 0 },
- .getsda = { 0x80, PORT_STAT, 1 },
- },
- /* type 2: Velleman K8000 adapter */
- {
- .setsda = { 0x02, PORT_CTRL, 1 },
- .setscl = { 0x08, PORT_CTRL, 1 },
- .getsda = { 0x10, PORT_STAT, 0 },
- },
- /* type 3: ELV adapter */
- {
- .setsda = { 0x02, PORT_DATA, 1 },
- .setscl = { 0x01, PORT_DATA, 1 },
- .getsda = { 0x40, PORT_STAT, 1 },
- .getscl = { 0x08, PORT_STAT, 1 },
- },
- /* type 4: ADM1032 evaluation board */
- {
- .setsda = { 0x02, PORT_DATA, 1 },
- .setscl = { 0x01, PORT_DATA, 1 },
- .getsda = { 0x10, PORT_STAT, 1 },
- .init = { 0xf0, PORT_DATA, 0 },
- .smbus_alert = 1,
- },
- /* type 5: ADM1025, ADM1030 and ADM1031 evaluation boards */
- {
- .setsda = { 0x02, PORT_DATA, 1 },
- .setscl = { 0x01, PORT_DATA, 1 },
- .getsda = { 0x10, PORT_STAT, 1 },
- },
- /* type 6: Barco LPT->DVI (K5800236) adapter */
- {
- .setsda = { 0x02, PORT_DATA, 1 },
- .setscl = { 0x01, PORT_DATA, 1 },
- .getsda = { 0x20, PORT_STAT, 0 },
- .getscl = { 0x40, PORT_STAT, 0 },
- .init = { 0xfc, PORT_DATA, 0 },
- },
- /* type 7: One For All JP1 parallel port adapter */
- {
- .setsda = { 0x01, PORT_DATA, 0 },
- .setscl = { 0x02, PORT_DATA, 0 },
- .getsda = { 0x80, PORT_STAT, 1 },
- .init = { 0x04, PORT_DATA, 1 },
- },
-};
-
-static int type = -1;
-module_param(type, int, 0);
-MODULE_PARM_DESC(type,
- "Type of adapter:\n"
- " 0 = Philips adapter\n"
- " 1 = home brew teletext adapter\n"
- " 2 = Velleman K8000 adapter\n"
- " 3 = ELV adapter\n"
- " 4 = ADM1032 evaluation board\n"
- " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
- " 6 = Barco LPT->DVI (K5800236) adapter\n"
- " 7 = One For All JP1 parallel port adapter\n"
-);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pasemi.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pasemi.c
deleted file mode 100644
index eaaea732..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pasemi.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (C) 2006-2007 PA Semi, Inc
- *
- * SMBus host driver for PA Semi PWRficient
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-static struct pci_driver pasemi_smb_driver;
-
-struct pasemi_smbus {
- struct pci_dev *dev;
- struct i2c_adapter adapter;
- unsigned long base;
- int size;
-};
-
-/* Register offsets */
-#define REG_MTXFIFO 0x00
-#define REG_MRXFIFO 0x04
-#define REG_SMSTA 0x14
-#define REG_CTL 0x1c
-
-/* Register defs */
-#define MTXFIFO_READ 0x00000400
-#define MTXFIFO_STOP 0x00000200
-#define MTXFIFO_START 0x00000100
-#define MTXFIFO_DATA_M 0x000000ff
-
-#define MRXFIFO_EMPTY 0x00000100
-#define MRXFIFO_DATA_M 0x000000ff
-
-#define SMSTA_XEN 0x08000000
-#define SMSTA_MTN 0x00200000
-
-#define CTL_MRR 0x00000400
-#define CTL_MTR 0x00000200
-#define CTL_CLK_M 0x000000ff
-
-#define CLK_100K_DIV 84
-#define CLK_400K_DIV 21
-
-static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
-{
- dev_dbg(&smbus->dev->dev, "smbus write reg %lx val %08x\n",
- smbus->base + reg, val);
- outl(val, smbus->base + reg);
-}
-
-static inline int reg_read(struct pasemi_smbus *smbus, int reg)
-{
- int ret;
- ret = inl(smbus->base + reg);
- dev_dbg(&smbus->dev->dev, "smbus read reg %lx val %08x\n",
- smbus->base + reg, ret);
- return ret;
-}
-
-#define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg))
-#define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO)
-
-static void pasemi_smb_clear(struct pasemi_smbus *smbus)
-{
- unsigned int status;
-
- status = reg_read(smbus, REG_SMSTA);
- reg_write(smbus, REG_SMSTA, status);
-}
-
-static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
-{
- int timeout = 10;
- unsigned int status;
-
- status = reg_read(smbus, REG_SMSTA);
-
- while (!(status & SMSTA_XEN) && timeout--) {
- msleep(1);
- status = reg_read(smbus, REG_SMSTA);
- }
-
- /* Got NACK? */
- if (status & SMSTA_MTN)
- return -ENXIO;
-
- if (timeout < 0) {
- dev_warn(&smbus->dev->dev, "Timeout, status 0x%08x\n", status);
- reg_write(smbus, REG_SMSTA, status);
- return -ETIME;
- }
-
- /* Clear XEN */
- reg_write(smbus, REG_SMSTA, SMSTA_XEN);
-
- return 0;
-}
-
-static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,
- struct i2c_msg *msg, int stop)
-{
- struct pasemi_smbus *smbus = adapter->algo_data;
- int read, i, err;
- u32 rd;
-
- read = msg->flags & I2C_M_RD ? 1 : 0;
-
- TXFIFO_WR(smbus, MTXFIFO_START | (msg->addr << 1) | read);
-
- if (read) {
- TXFIFO_WR(smbus, msg->len | MTXFIFO_READ |
- (stop ? MTXFIFO_STOP : 0));
-
- err = pasemi_smb_waitready(smbus);
- if (err)
- goto reset_out;
-
- for (i = 0; i < msg->len; i++) {
- rd = RXFIFO_RD(smbus);
- if (rd & MRXFIFO_EMPTY) {
- err = -ENODATA;
- goto reset_out;
- }
- msg->buf[i] = rd & MRXFIFO_DATA_M;
- }
- } else {
- for (i = 0; i < msg->len - 1; i++)
- TXFIFO_WR(smbus, msg->buf[i]);
-
- TXFIFO_WR(smbus, msg->buf[msg->len-1] |
- (stop ? MTXFIFO_STOP : 0));
- }
-
- return 0;
-
- reset_out:
- reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
- (CLK_100K_DIV & CTL_CLK_M)));
- return err;
-}
-
-static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
- struct i2c_msg *msgs, int num)
-{
- struct pasemi_smbus *smbus = adapter->algo_data;
- int ret, i;
-
- pasemi_smb_clear(smbus);
-
- ret = 0;
-
- for (i = 0; i < num && !ret; i++)
- ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
-
- return ret ? ret : num;
-}
-
-static int pasemi_smb_xfer(struct i2c_adapter *adapter,
- u16 addr, unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- struct pasemi_smbus *smbus = adapter->algo_data;
- unsigned int rd;
- int read_flag, err;
- int len = 0, i;
-
- /* All our ops take 8-bit shifted addresses */
- addr <<= 1;
- read_flag = read_write == I2C_SMBUS_READ;
-
- pasemi_smb_clear(smbus);
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START |
- MTXFIFO_STOP);
- break;
- case I2C_SMBUS_BYTE:
- TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START);
- if (read_write)
- TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ);
- else
- TXFIFO_WR(smbus, MTXFIFO_STOP | command);
- break;
- case I2C_SMBUS_BYTE_DATA:
- TXFIFO_WR(smbus, addr | MTXFIFO_START);
- TXFIFO_WR(smbus, command);
- if (read_write) {
- TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
- TXFIFO_WR(smbus, 1 | MTXFIFO_READ | MTXFIFO_STOP);
- } else {
- TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte);
- }
- break;
- case I2C_SMBUS_WORD_DATA:
- TXFIFO_WR(smbus, addr | MTXFIFO_START);
- TXFIFO_WR(smbus, command);
- if (read_write) {
- TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
- TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP);
- } else {
- TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
- TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8));
- }
- break;
- case I2C_SMBUS_BLOCK_DATA:
- TXFIFO_WR(smbus, addr | MTXFIFO_START);
- TXFIFO_WR(smbus, command);
- if (read_write) {
- TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
- TXFIFO_WR(smbus, 1 | MTXFIFO_READ);
- rd = RXFIFO_RD(smbus);
- len = min_t(u8, (rd & MRXFIFO_DATA_M),
- I2C_SMBUS_BLOCK_MAX);
- TXFIFO_WR(smbus, len | MTXFIFO_READ |
- MTXFIFO_STOP);
- } else {
- len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
- TXFIFO_WR(smbus, len);
- for (i = 1; i < len; i++)
- TXFIFO_WR(smbus, data->block[i]);
- TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP);
- }
- break;
- case I2C_SMBUS_PROC_CALL:
- read_write = I2C_SMBUS_READ;
- TXFIFO_WR(smbus, addr | MTXFIFO_START);
- TXFIFO_WR(smbus, command);
- TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
- TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M);
- TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
- TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ);
- break;
- case I2C_SMBUS_BLOCK_PROC_CALL:
- len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX - 1);
- read_write = I2C_SMBUS_READ;
- TXFIFO_WR(smbus, addr | MTXFIFO_START);
- TXFIFO_WR(smbus, command);
- TXFIFO_WR(smbus, len);
- for (i = 1; i <= len; i++)
- TXFIFO_WR(smbus, data->block[i]);
- TXFIFO_WR(smbus, addr | I2C_SMBUS_READ);
- TXFIFO_WR(smbus, MTXFIFO_READ | 1);
- rd = RXFIFO_RD(smbus);
- len = min_t(u8, (rd & MRXFIFO_DATA_M),
- I2C_SMBUS_BLOCK_MAX - len);
- TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP);
- break;
-
- default:
- dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
- return -EINVAL;
- }
-
- err = pasemi_smb_waitready(smbus);
- if (err)
- goto reset_out;
-
- if (read_write == I2C_SMBUS_WRITE)
- return 0;
-
- switch (size) {
- case I2C_SMBUS_BYTE:
- case I2C_SMBUS_BYTE_DATA:
- rd = RXFIFO_RD(smbus);
- if (rd & MRXFIFO_EMPTY) {
- err = -ENODATA;
- goto reset_out;
- }
- data->byte = rd & MRXFIFO_DATA_M;
- break;
- case I2C_SMBUS_WORD_DATA:
- case I2C_SMBUS_PROC_CALL:
- rd = RXFIFO_RD(smbus);
- if (rd & MRXFIFO_EMPTY) {
- err = -ENODATA;
- goto reset_out;
- }
- data->word = rd & MRXFIFO_DATA_M;
- rd = RXFIFO_RD(smbus);
- if (rd & MRXFIFO_EMPTY) {
- err = -ENODATA;
- goto reset_out;
- }
- data->word |= (rd & MRXFIFO_DATA_M) << 8;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- case I2C_SMBUS_BLOCK_PROC_CALL:
- data->block[0] = len;
- for (i = 1; i <= len; i ++) {
- rd = RXFIFO_RD(smbus);
- if (rd & MRXFIFO_EMPTY) {
- err = -ENODATA;
- goto reset_out;
- }
- data->block[i] = rd & MRXFIFO_DATA_M;
- }
- break;
- }
-
- return 0;
-
- reset_out:
- reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
- (CLK_100K_DIV & CTL_CLK_M)));
- return err;
-}
-
-static u32 pasemi_smb_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
- I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_I2C;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .master_xfer = pasemi_i2c_xfer,
- .smbus_xfer = pasemi_smb_xfer,
- .functionality = pasemi_smb_func,
-};
-
-static int __devinit pasemi_smb_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- struct pasemi_smbus *smbus;
- int error;
-
- if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
- return -ENODEV;
-
- smbus = kzalloc(sizeof(struct pasemi_smbus), GFP_KERNEL);
- if (!smbus)
- return -ENOMEM;
-
- smbus->dev = dev;
- smbus->base = pci_resource_start(dev, 0);
- smbus->size = pci_resource_len(dev, 0);
-
- if (!request_region(smbus->base, smbus->size,
- pasemi_smb_driver.name)) {
- error = -EBUSY;
- goto out_kfree;
- }
-
- smbus->adapter.owner = THIS_MODULE;
- snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
- "PA Semi SMBus adapter at 0x%lx", smbus->base);
- smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- smbus->adapter.algo = &smbus_algorithm;
- smbus->adapter.algo_data = smbus;
- smbus->adapter.nr = PCI_FUNC(dev->devfn);
-
- /* set up the sysfs linkage to our parent device */
- smbus->adapter.dev.parent = &dev->dev;
-
- reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
- (CLK_100K_DIV & CTL_CLK_M)));
-
- error = i2c_add_numbered_adapter(&smbus->adapter);
- if (error)
- goto out_release_region;
-
- pci_set_drvdata(dev, smbus);
-
- return 0;
-
- out_release_region:
- release_region(smbus->base, smbus->size);
- out_kfree:
- kfree(smbus);
- return error;
-}
-
-static void __devexit pasemi_smb_remove(struct pci_dev *dev)
-{
- struct pasemi_smbus *smbus = pci_get_drvdata(dev);
-
- i2c_del_adapter(&smbus->adapter);
- release_region(smbus->base, smbus->size);
- kfree(smbus);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(pasemi_smb_ids) = {
- { PCI_DEVICE(0x1959, 0xa003) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, pasemi_smb_ids);
-
-static struct pci_driver pasemi_smb_driver = {
- .name = "i2c-pasemi",
- .id_table = pasemi_smb_ids,
- .probe = pasemi_smb_probe,
- .remove = __devexit_p(pasemi_smb_remove),
-};
-
-static int __init pasemi_smb_init(void)
-{
- return pci_register_driver(&pasemi_smb_driver);
-}
-
-static void __exit pasemi_smb_exit(void)
-{
- pci_unregister_driver(&pasemi_smb_driver);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
-MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");
-
-module_init(pasemi_smb_init);
-module_exit(pasemi_smb_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-isa.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-isa.c
deleted file mode 100644
index 29933f87..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-isa.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * i2c-pca-isa.c driver for PCA9564 on ISA boards
- * Copyright (C) 2004 Arcom Control Systems
- * Copyright (C) 2008 Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/isa.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-pca.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-
-#define DRIVER "i2c-pca-isa"
-#define IO_SIZE 4
-
-static unsigned long base;
-static int irq = -1;
-
-/* Data sheet recommends 59kHz for 100kHz operation due to variation
- * in the actual clock rate */
-static int clock = 59000;
-
-static struct i2c_adapter pca_isa_ops;
-static wait_queue_head_t pca_wait;
-
-static void pca_isa_writebyte(void *pd, int reg, int val)
-{
-#ifdef DEBUG_IO
- static char *names[] = { "T/O", "DAT", "ADR", "CON" };
- printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg],
- base+reg, val);
-#endif
- outb(val, base+reg);
-}
-
-static int pca_isa_readbyte(void *pd, int reg)
-{
- int res = inb(base+reg);
-#ifdef DEBUG_IO
- {
- static char *names[] = { "STA", "DAT", "ADR", "CON" };
- printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res);
- }
-#endif
- return res;
-}
-
-static int pca_isa_waitforcompletion(void *pd)
-{
- unsigned long timeout;
- long ret;
-
- if (irq > -1) {
- ret = wait_event_timeout(pca_wait,
- pca_isa_readbyte(pd, I2C_PCA_CON)
- & I2C_PCA_CON_SI, pca_isa_ops.timeout);
- } else {
- /* Do polling */
- timeout = jiffies + pca_isa_ops.timeout;
- do {
- ret = time_before(jiffies, timeout);
- if (pca_isa_readbyte(pd, I2C_PCA_CON)
- & I2C_PCA_CON_SI)
- break;
- udelay(100);
- } while (ret);
- }
-
- return ret > 0;
-}
-
-static void pca_isa_resetchip(void *pd)
-{
- /* apparently only an external reset will do it. not a lot can be done */
- printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n");
-}
-
-static irqreturn_t pca_handler(int this_irq, void *dev_id) {
- wake_up(&pca_wait);
- return IRQ_HANDLED;
-}
-
-static struct i2c_algo_pca_data pca_isa_data = {
- /* .data intentionally left NULL, not needed with ISA */
- .write_byte = pca_isa_writebyte,
- .read_byte = pca_isa_readbyte,
- .wait_for_completion = pca_isa_waitforcompletion,
- .reset_chip = pca_isa_resetchip,
-};
-
-static struct i2c_adapter pca_isa_ops = {
- .owner = THIS_MODULE,
- .algo_data = &pca_isa_data,
- .name = "PCA9564/PCA9665 ISA Adapter",
- .timeout = HZ,
-};
-
-static int __devinit pca_isa_match(struct device *dev, unsigned int id)
-{
- int match = base != 0;
-
- if (match) {
- if (irq <= -1)
- dev_warn(dev, "Using polling mode (specify irq)\n");
- } else
- dev_err(dev, "Please specify I/O base\n");
-
- return match;
-}
-
-static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
-{
- init_waitqueue_head(&pca_wait);
-
- dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
-
-#ifdef CONFIG_PPC
- if (check_legacy_ioport(base)) {
- dev_err(dev, "I/O address %#08lx is not available\n", base);
- goto out;
- }
-#endif
-
- if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
- dev_err(dev, "I/O address %#08lx is in use\n", base);
- goto out;
- }
-
- if (irq > -1) {
- if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) {
- dev_err(dev, "Request irq%d failed\n", irq);
- goto out_region;
- }
- }
-
- pca_isa_data.i2c_clock = clock;
- if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
- dev_err(dev, "Failed to add i2c bus\n");
- goto out_irq;
- }
-
- return 0;
-
- out_irq:
- if (irq > -1)
- free_irq(irq, &pca_isa_ops);
- out_region:
- release_region(base, IO_SIZE);
- out:
- return -ENODEV;
-}
-
-static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
-{
- i2c_del_adapter(&pca_isa_ops);
-
- if (irq > -1) {
- disable_irq(irq);
- free_irq(irq, &pca_isa_ops);
- }
- release_region(base, IO_SIZE);
-
- return 0;
-}
-
-static struct isa_driver pca_isa_driver = {
- .match = pca_isa_match,
- .probe = pca_isa_probe,
- .remove = __devexit_p(pca_isa_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = DRIVER,
- }
-};
-
-static int __init pca_isa_init(void)
-{
- return isa_register_driver(&pca_isa_driver, 1);
-}
-
-static void __exit pca_isa_exit(void)
-{
- isa_unregister_driver(&pca_isa_driver);
-}
-
-MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
-MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver");
-MODULE_LICENSE("GPL");
-
-module_param(base, ulong, 0);
-MODULE_PARM_DESC(base, "I/O base address");
-
-module_param(irq, int, 0);
-MODULE_PARM_DESC(irq, "IRQ");
-module_param(clock, int, 0);
-MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t"
- "For PCA9564: 330000,288000,217000,146000,"
- "88000,59000,44000,36000\n"
- "\t\tFor PCA9665:\tStandard: 60300 - 100099\n"
- "\t\t\t\tFast: 100100 - 400099\n"
- "\t\t\t\tFast+: 400100 - 10000099\n"
- "\t\t\t\tTurbo: Up to 1265800");
-
-module_init(pca_isa_init);
-module_exit(pca_isa_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-platform.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-platform.c
deleted file mode 100644
index 2adbf1a8..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pca-platform.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * i2c_pca_platform.c
- *
- * Platform driver for the PCA9564 I2C controller.
- *
- * Copyright (C) 2008 Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c-algo-pca.h>
-#include <linux/i2c-pca-platform.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-
-struct i2c_pca_pf_data {
- void __iomem *reg_base;
- int irq; /* if 0, use polling */
- int gpio;
- wait_queue_head_t wait;
- struct i2c_adapter adap;
- struct i2c_algo_pca_data algo_data;
- unsigned long io_base;
- unsigned long io_size;
-};
-
-/* Read/Write functions for different register alignments */
-
-static int i2c_pca_pf_readbyte8(void *pd, int reg)
-{
- struct i2c_pca_pf_data *i2c = pd;
- return ioread8(i2c->reg_base + reg);
-}
-
-static int i2c_pca_pf_readbyte16(void *pd, int reg)
-{
- struct i2c_pca_pf_data *i2c = pd;
- return ioread8(i2c->reg_base + reg * 2);
-}
-
-static int i2c_pca_pf_readbyte32(void *pd, int reg)
-{
- struct i2c_pca_pf_data *i2c = pd;
- return ioread8(i2c->reg_base + reg * 4);
-}
-
-static void i2c_pca_pf_writebyte8(void *pd, int reg, int val)
-{
- struct i2c_pca_pf_data *i2c = pd;
- iowrite8(val, i2c->reg_base + reg);
-}
-
-static void i2c_pca_pf_writebyte16(void *pd, int reg, int val)
-{
- struct i2c_pca_pf_data *i2c = pd;
- iowrite8(val, i2c->reg_base + reg * 2);
-}
-
-static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
-{
- struct i2c_pca_pf_data *i2c = pd;
- iowrite8(val, i2c->reg_base + reg * 4);
-}
-
-
-static int i2c_pca_pf_waitforcompletion(void *pd)
-{
- struct i2c_pca_pf_data *i2c = pd;
- unsigned long timeout;
- long ret;
-
- if (i2c->irq) {
- ret = wait_event_timeout(i2c->wait,
- i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
- & I2C_PCA_CON_SI, i2c->adap.timeout);
- } else {
- /* Do polling */
- timeout = jiffies + i2c->adap.timeout;
- do {
- ret = time_before(jiffies, timeout);
- if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
- & I2C_PCA_CON_SI)
- break;
- udelay(100);
- } while (ret);
- }
-
- return ret > 0;
-}
-
-static void i2c_pca_pf_dummyreset(void *pd)
-{
- struct i2c_pca_pf_data *i2c = pd;
- printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n",
- i2c->adap.name);
-}
-
-static void i2c_pca_pf_resetchip(void *pd)
-{
- struct i2c_pca_pf_data *i2c = pd;
-
- gpio_set_value(i2c->gpio, 0);
- ndelay(100);
- gpio_set_value(i2c->gpio, 1);
-}
-
-static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
-{
- struct i2c_pca_pf_data *i2c = dev_id;
-
- if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
- return IRQ_NONE;
-
- wake_up(&i2c->wait);
-
- return IRQ_HANDLED;
-}
-
-
-static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
-{
- struct i2c_pca_pf_data *i2c;
- struct resource *res;
- struct i2c_pca9564_pf_platform_data *platform_data =
- pdev->dev.platform_data;
- int ret = 0;
- int irq;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- /* If irq is 0, we do polling. */
-
- if (res == NULL) {
- ret = -ENODEV;
- goto e_print;
- }
-
- if (!request_mem_region(res->start, resource_size(res), res->name)) {
- ret = -ENOMEM;
- goto e_print;
- }
-
- i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL);
- if (!i2c) {
- ret = -ENOMEM;
- goto e_alloc;
- }
-
- init_waitqueue_head(&i2c->wait);
-
- i2c->reg_base = ioremap(res->start, resource_size(res));
- if (!i2c->reg_base) {
- ret = -ENOMEM;
- goto e_remap;
- }
- i2c->io_base = res->start;
- i2c->io_size = resource_size(res);
- i2c->irq = irq;
-
- i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
- i2c->adap.owner = THIS_MODULE;
- snprintf(i2c->adap.name, sizeof(i2c->adap.name),
- "PCA9564/PCA9665 at 0x%08lx",
- (unsigned long) res->start);
- i2c->adap.algo_data = &i2c->algo_data;
- i2c->adap.dev.parent = &pdev->dev;
-
- if (platform_data) {
- i2c->adap.timeout = platform_data->timeout;
- i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
- i2c->gpio = platform_data->gpio;
- } else {
- i2c->adap.timeout = HZ;
- i2c->algo_data.i2c_clock = 59000;
- i2c->gpio = -1;
- }
-
- i2c->algo_data.data = i2c;
- i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
- i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
-
- switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
- case IORESOURCE_MEM_32BIT:
- i2c->algo_data.write_byte = i2c_pca_pf_writebyte32;
- i2c->algo_data.read_byte = i2c_pca_pf_readbyte32;
- break;
- case IORESOURCE_MEM_16BIT:
- i2c->algo_data.write_byte = i2c_pca_pf_writebyte16;
- i2c->algo_data.read_byte = i2c_pca_pf_readbyte16;
- break;
- case IORESOURCE_MEM_8BIT:
- default:
- i2c->algo_data.write_byte = i2c_pca_pf_writebyte8;
- i2c->algo_data.read_byte = i2c_pca_pf_readbyte8;
- break;
- }
-
- /* Use gpio_is_valid() when in mainline */
- if (i2c->gpio > -1) {
- ret = gpio_request(i2c->gpio, i2c->adap.name);
- if (ret == 0) {
- gpio_direction_output(i2c->gpio, 1);
- i2c->algo_data.reset_chip = i2c_pca_pf_resetchip;
- } else {
- printk(KERN_WARNING "%s: Registering gpio failed!\n",
- i2c->adap.name);
- i2c->gpio = ret;
- }
- }
-
- if (irq) {
- ret = request_irq(irq, i2c_pca_pf_handler,
- IRQF_TRIGGER_FALLING, pdev->name, i2c);
- if (ret)
- goto e_reqirq;
- }
-
- if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) {
- ret = -ENODEV;
- goto e_adapt;
- }
-
- platform_set_drvdata(pdev, i2c);
-
- printk(KERN_INFO "%s registered.\n", i2c->adap.name);
-
- return 0;
-
-e_adapt:
- if (irq)
- free_irq(irq, i2c);
-e_reqirq:
- if (i2c->gpio > -1)
- gpio_free(i2c->gpio);
-
- iounmap(i2c->reg_base);
-e_remap:
- kfree(i2c);
-e_alloc:
- release_mem_region(res->start, resource_size(res));
-e_print:
- printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
- return ret;
-}
-
-static int __devexit i2c_pca_pf_remove(struct platform_device *pdev)
-{
- struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
-
- i2c_del_adapter(&i2c->adap);
-
- if (i2c->irq)
- free_irq(i2c->irq, i2c);
-
- if (i2c->gpio > -1)
- gpio_free(i2c->gpio);
-
- iounmap(i2c->reg_base);
- release_mem_region(i2c->io_base, i2c->io_size);
- kfree(i2c);
-
- return 0;
-}
-
-static struct platform_driver i2c_pca_pf_driver = {
- .probe = i2c_pca_pf_probe,
- .remove = __devexit_p(i2c_pca_pf_remove),
- .driver = {
- .name = "i2c-pca-platform",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(i2c_pca_pf_driver);
-
-MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-piix4.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-piix4.c
deleted file mode 100644
index c14d48dd..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-piix4.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- Supports:
- Intel PIIX4, 440MX
- Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
- ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
- AMD Hudson-2
- SMSC Victory66
-
- Note: we assume there can only be one device, with one SMBus interface.
-*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/dmi.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-
-/* PIIX4 SMBus address offsets */
-#define SMBHSTSTS (0 + piix4_smba)
-#define SMBHSLVSTS (1 + piix4_smba)
-#define SMBHSTCNT (2 + piix4_smba)
-#define SMBHSTCMD (3 + piix4_smba)
-#define SMBHSTADD (4 + piix4_smba)
-#define SMBHSTDAT0 (5 + piix4_smba)
-#define SMBHSTDAT1 (6 + piix4_smba)
-#define SMBBLKDAT (7 + piix4_smba)
-#define SMBSLVCNT (8 + piix4_smba)
-#define SMBSHDWCMD (9 + piix4_smba)
-#define SMBSLVEVT (0xA + piix4_smba)
-#define SMBSLVDAT (0xC + piix4_smba)
-
-/* count for request_region */
-#define SMBIOSIZE 8
-
-/* PCI Address Constants */
-#define SMBBA 0x090
-#define SMBHSTCFG 0x0D2
-#define SMBSLVC 0x0D3
-#define SMBSHDW1 0x0D4
-#define SMBSHDW2 0x0D5
-#define SMBREV 0x0D6
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-#define ENABLE_INT9 0
-
-/* PIIX4 constants */
-#define PIIX4_QUICK 0x00
-#define PIIX4_BYTE 0x04
-#define PIIX4_BYTE_DATA 0x08
-#define PIIX4_WORD_DATA 0x0C
-#define PIIX4_BLOCK_DATA 0x14
-
-/* insmod parameters */
-
-/* If force is set to anything different from 0, we forcibly enable the
- PIIX4. DANGEROUS! */
-static int force;
-module_param (force, int, 0);
-MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!");
-
-/* If force_addr is set to anything different from 0, we forcibly enable
- the PIIX4 at the given address. VERY DANGEROUS! */
-static int force_addr;
-module_param (force_addr, int, 0);
-MODULE_PARM_DESC(force_addr,
- "Forcibly enable the PIIX4 at the given address. "
- "EXTREMELY DANGEROUS!");
-
-static unsigned short piix4_smba;
-static int srvrworks_csb5_delay;
-static struct pci_driver piix4_driver;
-static struct i2c_adapter piix4_adapter;
-
-static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
- {
- .ident = "Sapphire AM2RD790",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
- DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
- },
- },
- {
- .ident = "DFI Lanparty UT 790FX",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
- DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
- },
- },
- { }
-};
-
-/* The IBM entry is in a separate table because we only check it
- on Intel-based systems */
-static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
- {
- .ident = "IBM",
- .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
- },
- { },
-};
-
-static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
- const struct pci_device_id *id)
-{
- unsigned char temp;
-
- if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
- (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
- srvrworks_csb5_delay = 1;
-
- /* On some motherboards, it was reported that accessing the SMBus
- caused severe hardware problems */
- if (dmi_check_system(piix4_dmi_blacklist)) {
- dev_err(&PIIX4_dev->dev,
- "Accessing the SMBus on this system is unsafe!\n");
- return -EPERM;
- }
-
- /* Don't access SMBus on IBM systems which get corrupted eeproms */
- if (dmi_check_system(piix4_dmi_ibm) &&
- PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
- dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
- "may corrupt your serial eeprom! Refusing to load "
- "module!\n");
- return -EPERM;
- }
-
- /* Determine the address of the SMBus areas */
- if (force_addr) {
- piix4_smba = force_addr & 0xfff0;
- force = 0;
- } else {
- pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
- piix4_smba &= 0xfff0;
- if(piix4_smba == 0) {
- dev_err(&PIIX4_dev->dev, "SMBus base address "
- "uninitialized - upgrade BIOS or use "
- "force_addr=0xaddr\n");
- return -ENODEV;
- }
- }
-
- if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
- return -ENODEV;
-
- if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
- dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
- piix4_smba);
- return -EBUSY;
- }
-
- pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
-
- /* If force_addr is set, we program the new address here. Just to make
- sure, we disable the PIIX4 first. */
- if (force_addr) {
- pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp & 0xfe);
- pci_write_config_word(PIIX4_dev, SMBBA, piix4_smba);
- pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp | 0x01);
- dev_info(&PIIX4_dev->dev, "WARNING: SMBus interface set to "
- "new address %04x!\n", piix4_smba);
- } else if ((temp & 1) == 0) {
- if (force) {
- /* This should never need to be done, but has been
- * noted that many Dell machines have the SMBus
- * interface on the PIIX4 disabled!? NOTE: This assumes
- * I/O space and other allocations WERE done by the
- * Bios! Don't complain if your hardware does weird
- * things after enabling this. :') Check for Bios
- * updates before resorting to this.
- */
- pci_write_config_byte(PIIX4_dev, SMBHSTCFG,
- temp | 1);
- dev_printk(KERN_NOTICE, &PIIX4_dev->dev,
- "WARNING: SMBus interface has been "
- "FORCEFULLY ENABLED!\n");
- } else {
- dev_err(&PIIX4_dev->dev,
- "Host SMBus controller not enabled!\n");
- release_region(piix4_smba, SMBIOSIZE);
- piix4_smba = 0;
- return -ENODEV;
- }
- }
-
- if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
- dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n");
- else if ((temp & 0x0E) == 0)
- dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n");
- else
- dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
- "(or code out of date)!\n");
-
- pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
- dev_info(&PIIX4_dev->dev,
- "SMBus Host Controller at 0x%x, revision %d\n",
- piix4_smba, temp);
-
- return 0;
-}
-
-static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
- const struct pci_device_id *id)
-{
- unsigned short smba_idx = 0xcd6;
- u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
-
- /* SB800 and later SMBus does not support forcing address */
- if (force || force_addr) {
- dev_err(&PIIX4_dev->dev, "SMBus does not support "
- "forcing address!\n");
- return -EINVAL;
- }
-
- /* Determine the address of the SMBus areas */
- if (!request_region(smba_idx, 2, "smba_idx")) {
- dev_err(&PIIX4_dev->dev, "SMBus base address index region "
- "0x%x already in use!\n", smba_idx);
- return -EBUSY;
- }
- outb_p(smb_en, smba_idx);
- smba_en_lo = inb_p(smba_idx + 1);
- outb_p(smb_en + 1, smba_idx);
- smba_en_hi = inb_p(smba_idx + 1);
- release_region(smba_idx, 2);
-
- if ((smba_en_lo & 1) == 0) {
- dev_err(&PIIX4_dev->dev,
- "Host SMBus controller not enabled!\n");
- return -ENODEV;
- }
-
- piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
- if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
- return -ENODEV;
-
- if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
- dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
- piix4_smba);
- return -EBUSY;
- }
-
- /* Request the SMBus I2C bus config region */
- if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
- dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
- "0x%x already in use!\n", piix4_smba + i2ccfg_offset);
- release_region(piix4_smba, SMBIOSIZE);
- piix4_smba = 0;
- return -EBUSY;
- }
- i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
- release_region(piix4_smba + i2ccfg_offset, 1);
-
- if (i2ccfg & 1)
- dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n");
- else
- dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n");
-
- dev_info(&PIIX4_dev->dev,
- "SMBus Host Controller at 0x%x, revision %d\n",
- piix4_smba, i2ccfg >> 4);
-
- return 0;
-}
-
-static int piix4_transaction(void)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- dev_dbg(&piix4_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
- inb_p(SMBHSTDAT1));
-
- /* Make sure the SMBus host is ready to start transmitting */
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
- dev_dbg(&piix4_adapter.dev, "SMBus busy (%02x). "
- "Resetting...\n", temp);
- outb_p(temp, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
- dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
- return -EBUSY;
- } else {
- dev_dbg(&piix4_adapter.dev, "Successful!\n");
- }
- }
-
- /* start the transaction by setting bit 6 */
- outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
-
- /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
- if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
- msleep(2);
- else
- msleep(1);
-
- while ((++timeout < MAX_TIMEOUT) &&
- ((temp = inb_p(SMBHSTSTS)) & 0x01))
- msleep(1);
-
- /* If the SMBus is still busy, we give up */
- if (timeout == MAX_TIMEOUT) {
- dev_err(&piix4_adapter.dev, "SMBus Timeout!\n");
- result = -ETIMEDOUT;
- }
-
- if (temp & 0x10) {
- result = -EIO;
- dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n");
- }
-
- if (temp & 0x08) {
- result = -EIO;
- dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be "
- "locked until next hard reset. (sorry!)\n");
- /* Clock stops and slave is stuck in mid-transmission */
- }
-
- if (temp & 0x04) {
- result = -ENXIO;
- dev_dbg(&piix4_adapter.dev, "Error: no response!\n");
- }
-
- if (inb_p(SMBHSTSTS) != 0x00)
- outb_p(inb(SMBHSTSTS), SMBHSTSTS);
-
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
- dev_err(&piix4_adapter.dev, "Failed reset at end of "
- "transaction (%02x)\n", temp);
- }
- dev_dbg(&piix4_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
- inb_p(SMBHSTDAT1));
- return result;
-}
-
-/* Return negative errno on error. */
-static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data * data)
-{
- int i, len;
- int status;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- outb_p((addr << 1) | read_write,
- SMBHSTADD);
- size = PIIX4_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- outb_p((addr << 1) | read_write,
- SMBHSTADD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, SMBHSTCMD);
- size = PIIX4_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- outb_p((addr << 1) | read_write,
- SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMBHSTDAT0);
- size = PIIX4_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- outb_p((addr << 1) | read_write,
- SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMBHSTDAT0);
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
- }
- size = PIIX4_WORD_DATA;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- outb_p((addr << 1) | read_write,
- SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
- return -EINVAL;
- outb_p(len, SMBHSTDAT0);
- i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
- for (i = 1; i <= len; i++)
- outb_p(data->block[i], SMBBLKDAT);
- }
- size = PIIX4_BLOCK_DATA;
- break;
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
-
- status = piix4_transaction();
- if (status)
- return status;
-
- if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK))
- return 0;
-
-
- switch (size) {
- case PIIX4_BYTE:
- case PIIX4_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case PIIX4_WORD_DATA:
- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
- break;
- case PIIX4_BLOCK_DATA:
- data->block[0] = inb_p(SMBHSTDAT0);
- if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
- return -EPROTO;
- i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
- for (i = 1; i <= data->block[0]; i++)
- data->block[i] = inb_p(SMBBLKDAT);
- break;
- }
- return 0;
-}
-
-static u32 piix4_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = piix4_access,
- .functionality = piix4_func,
-};
-
-static struct i2c_adapter piix4_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
- { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) },
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_OSB4) },
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_CSB5) },
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_CSB6) },
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, piix4_ids);
-
-static int __devinit piix4_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- int retval;
-
- if ((dev->vendor == PCI_VENDOR_ID_ATI &&
- dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
- dev->revision >= 0x40) ||
- dev->vendor == PCI_VENDOR_ID_AMD)
- /* base address location etc changed in SB800 */
- retval = piix4_setup_sb800(dev, id);
- else
- retval = piix4_setup(dev, id);
-
- if (retval)
- return retval;
-
- /* set up the sysfs linkage to our parent device */
- piix4_adapter.dev.parent = &dev->dev;
-
- snprintf(piix4_adapter.name, sizeof(piix4_adapter.name),
- "SMBus PIIX4 adapter at %04x", piix4_smba);
-
- if ((retval = i2c_add_adapter(&piix4_adapter))) {
- dev_err(&dev->dev, "Couldn't register adapter!\n");
- release_region(piix4_smba, SMBIOSIZE);
- piix4_smba = 0;
- }
-
- return retval;
-}
-
-static void __devexit piix4_remove(struct pci_dev *dev)
-{
- if (piix4_smba) {
- i2c_del_adapter(&piix4_adapter);
- release_region(piix4_smba, SMBIOSIZE);
- piix4_smba = 0;
- }
-}
-
-static struct pci_driver piix4_driver = {
- .name = "piix4_smbus",
- .id_table = piix4_ids,
- .probe = piix4_probe,
- .remove = __devexit_p(piix4_remove),
-};
-
-static int __init i2c_piix4_init(void)
-{
- return pci_register_driver(&piix4_driver);
-}
-
-static void __exit i2c_piix4_exit(void)
-{
- pci_unregister_driver(&piix4_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
- "Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("PIIX4 SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_piix4_init);
-module_exit(i2c_piix4_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pmcmsp.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pmcmsp.c
deleted file mode 100644
index 07b7447e..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pmcmsp.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * Specific bus support for PMC-TWI compliant implementation on MSP71xx.
- *
- * Copyright 2005-2007 PMC-Sierra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#define DRV_NAME "pmcmsptwi"
-
-#define MSP_TWI_SF_CLK_REG_OFFSET 0x00
-#define MSP_TWI_HS_CLK_REG_OFFSET 0x04
-#define MSP_TWI_CFG_REG_OFFSET 0x08
-#define MSP_TWI_CMD_REG_OFFSET 0x0c
-#define MSP_TWI_ADD_REG_OFFSET 0x10
-#define MSP_TWI_DAT_0_REG_OFFSET 0x14
-#define MSP_TWI_DAT_1_REG_OFFSET 0x18
-#define MSP_TWI_INT_STS_REG_OFFSET 0x1c
-#define MSP_TWI_INT_MSK_REG_OFFSET 0x20
-#define MSP_TWI_BUSY_REG_OFFSET 0x24
-
-#define MSP_TWI_INT_STS_DONE (1 << 0)
-#define MSP_TWI_INT_STS_LOST_ARBITRATION (1 << 1)
-#define MSP_TWI_INT_STS_NO_RESPONSE (1 << 2)
-#define MSP_TWI_INT_STS_DATA_COLLISION (1 << 3)
-#define MSP_TWI_INT_STS_BUSY (1 << 4)
-#define MSP_TWI_INT_STS_ALL 0x1f
-
-#define MSP_MAX_BYTES_PER_RW 8
-#define MSP_MAX_POLL 5
-#define MSP_POLL_DELAY 10
-#define MSP_IRQ_TIMEOUT (MSP_MAX_POLL * MSP_POLL_DELAY)
-
-/* IO Operation macros */
-#define pmcmsptwi_readl __raw_readl
-#define pmcmsptwi_writel __raw_writel
-
-/* TWI command type */
-enum pmcmsptwi_cmd_type {
- MSP_TWI_CMD_WRITE = 0, /* Write only */
- MSP_TWI_CMD_READ = 1, /* Read only */
- MSP_TWI_CMD_WRITE_READ = 2, /* Write then Read */
-};
-
-/* The possible results of the xferCmd */
-enum pmcmsptwi_xfer_result {
- MSP_TWI_XFER_OK = 0,
- MSP_TWI_XFER_TIMEOUT,
- MSP_TWI_XFER_BUSY,
- MSP_TWI_XFER_DATA_COLLISION,
- MSP_TWI_XFER_NO_RESPONSE,
- MSP_TWI_XFER_LOST_ARBITRATION,
-};
-
-/* Corresponds to a PMCTWI clock configuration register */
-struct pmcmsptwi_clock {
- u8 filter; /* Bits 15:12, default = 0x03 */
- u16 clock; /* Bits 9:0, default = 0x001f */
-};
-
-struct pmcmsptwi_clockcfg {
- struct pmcmsptwi_clock standard; /* The standard/fast clock config */
- struct pmcmsptwi_clock highspeed; /* The highspeed clock config */
-};
-
-/* Corresponds to the main TWI configuration register */
-struct pmcmsptwi_cfg {
- u8 arbf; /* Bits 15:12, default=0x03 */
- u8 nak; /* Bits 11:8, default=0x03 */
- u8 add10; /* Bit 7, default=0x00 */
- u8 mst_code; /* Bits 6:4, default=0x00 */
- u8 arb; /* Bit 1, default=0x01 */
- u8 highspeed; /* Bit 0, default=0x00 */
-};
-
-/* A single pmctwi command to issue */
-struct pmcmsptwi_cmd {
- u16 addr; /* The slave address (7 or 10 bits) */
- enum pmcmsptwi_cmd_type type; /* The command type */
- u8 write_len; /* Number of bytes in the write buffer */
- u8 read_len; /* Number of bytes in the read buffer */
- u8 *write_data; /* Buffer of characters to send */
- u8 *read_data; /* Buffer to fill with incoming data */
-};
-
-/* The private data */
-struct pmcmsptwi_data {
- void __iomem *iobase; /* iomapped base for IO */
- int irq; /* IRQ to use (0 disables) */
- struct completion wait; /* Completion for xfer */
- struct mutex lock; /* Used for threadsafeness */
- enum pmcmsptwi_xfer_result last_result; /* result of last xfer */
-};
-
-/* The default settings */
-static const struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = {
- .standard = {
- .filter = 0x3,
- .clock = 0x1f,
- },
- .highspeed = {
- .filter = 0x3,
- .clock = 0x1f,
- },
-};
-
-static const struct pmcmsptwi_cfg pmcmsptwi_defcfg = {
- .arbf = 0x03,
- .nak = 0x03,
- .add10 = 0x00,
- .mst_code = 0x00,
- .arb = 0x01,
- .highspeed = 0x00,
-};
-
-static struct pmcmsptwi_data pmcmsptwi_data;
-
-static struct i2c_adapter pmcmsptwi_adapter;
-
-/* inline helper functions */
-static inline u32 pmcmsptwi_clock_to_reg(
- const struct pmcmsptwi_clock *clock)
-{
- return ((clock->filter & 0xf) << 12) | (clock->clock & 0x03ff);
-}
-
-static inline void pmcmsptwi_reg_to_clock(
- u32 reg, struct pmcmsptwi_clock *clock)
-{
- clock->filter = (reg >> 12) & 0xf;
- clock->clock = reg & 0x03ff;
-}
-
-static inline u32 pmcmsptwi_cfg_to_reg(const struct pmcmsptwi_cfg *cfg)
-{
- return ((cfg->arbf & 0xf) << 12) |
- ((cfg->nak & 0xf) << 8) |
- ((cfg->add10 & 0x1) << 7) |
- ((cfg->mst_code & 0x7) << 4) |
- ((cfg->arb & 0x1) << 1) |
- (cfg->highspeed & 0x1);
-}
-
-static inline void pmcmsptwi_reg_to_cfg(u32 reg, struct pmcmsptwi_cfg *cfg)
-{
- cfg->arbf = (reg >> 12) & 0xf;
- cfg->nak = (reg >> 8) & 0xf;
- cfg->add10 = (reg >> 7) & 0x1;
- cfg->mst_code = (reg >> 4) & 0x7;
- cfg->arb = (reg >> 1) & 0x1;
- cfg->highspeed = reg & 0x1;
-}
-
-/*
- * Sets the current clock configuration
- */
-static void pmcmsptwi_set_clock_config(const struct pmcmsptwi_clockcfg *cfg,
- struct pmcmsptwi_data *data)
-{
- mutex_lock(&data->lock);
- pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->standard),
- data->iobase + MSP_TWI_SF_CLK_REG_OFFSET);
- pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->highspeed),
- data->iobase + MSP_TWI_HS_CLK_REG_OFFSET);
- mutex_unlock(&data->lock);
-}
-
-/*
- * Gets the current TWI bus configuration
- */
-static void pmcmsptwi_get_twi_config(struct pmcmsptwi_cfg *cfg,
- struct pmcmsptwi_data *data)
-{
- mutex_lock(&data->lock);
- pmcmsptwi_reg_to_cfg(pmcmsptwi_readl(
- data->iobase + MSP_TWI_CFG_REG_OFFSET), cfg);
- mutex_unlock(&data->lock);
-}
-
-/*
- * Sets the current TWI bus configuration
- */
-static void pmcmsptwi_set_twi_config(const struct pmcmsptwi_cfg *cfg,
- struct pmcmsptwi_data *data)
-{
- mutex_lock(&data->lock);
- pmcmsptwi_writel(pmcmsptwi_cfg_to_reg(cfg),
- data->iobase + MSP_TWI_CFG_REG_OFFSET);
- mutex_unlock(&data->lock);
-}
-
-/*
- * Parses the 'int_sts' register and returns a well-defined error code
- */
-static enum pmcmsptwi_xfer_result pmcmsptwi_get_result(u32 reg)
-{
- if (reg & MSP_TWI_INT_STS_LOST_ARBITRATION) {
- dev_dbg(&pmcmsptwi_adapter.dev,
- "Result: Lost arbitration\n");
- return MSP_TWI_XFER_LOST_ARBITRATION;
- } else if (reg & MSP_TWI_INT_STS_NO_RESPONSE) {
- dev_dbg(&pmcmsptwi_adapter.dev,
- "Result: No response\n");
- return MSP_TWI_XFER_NO_RESPONSE;
- } else if (reg & MSP_TWI_INT_STS_DATA_COLLISION) {
- dev_dbg(&pmcmsptwi_adapter.dev,
- "Result: Data collision\n");
- return MSP_TWI_XFER_DATA_COLLISION;
- } else if (reg & MSP_TWI_INT_STS_BUSY) {
- dev_dbg(&pmcmsptwi_adapter.dev,
- "Result: Bus busy\n");
- return MSP_TWI_XFER_BUSY;
- }
-
- dev_dbg(&pmcmsptwi_adapter.dev, "Result: Operation succeeded\n");
- return MSP_TWI_XFER_OK;
-}
-
-/*
- * In interrupt mode, handle the interrupt.
- * NOTE: Assumes data->lock is held.
- */
-static irqreturn_t pmcmsptwi_interrupt(int irq, void *ptr)
-{
- struct pmcmsptwi_data *data = ptr;
-
- u32 reason = pmcmsptwi_readl(data->iobase +
- MSP_TWI_INT_STS_REG_OFFSET);
- pmcmsptwi_writel(reason, data->iobase + MSP_TWI_INT_STS_REG_OFFSET);
-
- dev_dbg(&pmcmsptwi_adapter.dev, "Got interrupt 0x%08x\n", reason);
- if (!(reason & MSP_TWI_INT_STS_DONE))
- return IRQ_NONE;
-
- data->last_result = pmcmsptwi_get_result(reason);
- complete(&data->wait);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Probe for and register the device and return 0 if there is one.
- */
-static int __devinit pmcmsptwi_probe(struct platform_device *pldev)
-{
- struct resource *res;
- int rc = -ENODEV;
-
- /* get the static platform resources */
- res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pldev->dev, "IOMEM resource not found\n");
- goto ret_err;
- }
-
- /* reserve the memory region */
- if (!request_mem_region(res->start, resource_size(res),
- pldev->name)) {
- dev_err(&pldev->dev,
- "Unable to get memory/io address region 0x%08x\n",
- res->start);
- rc = -EBUSY;
- goto ret_err;
- }
-
- /* remap the memory */
- pmcmsptwi_data.iobase = ioremap_nocache(res->start,
- resource_size(res));
- if (!pmcmsptwi_data.iobase) {
- dev_err(&pldev->dev,
- "Unable to ioremap address 0x%08x\n", res->start);
- rc = -EIO;
- goto ret_unreserve;
- }
-
- /* request the irq */
- pmcmsptwi_data.irq = platform_get_irq(pldev, 0);
- if (pmcmsptwi_data.irq) {
- rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- pldev->name, &pmcmsptwi_data);
- if (rc == 0) {
- /*
- * Enable 'DONE' interrupt only.
- *
- * If you enable all interrupts, you will get one on
- * error and another when the operation completes.
- * This way you only have to handle one interrupt,
- * but you can still check all result flags.
- */
- pmcmsptwi_writel(MSP_TWI_INT_STS_DONE,
- pmcmsptwi_data.iobase +
- MSP_TWI_INT_MSK_REG_OFFSET);
- } else {
- dev_warn(&pldev->dev,
- "Could not assign TWI IRQ handler "
- "to irq %d (continuing with poll)\n",
- pmcmsptwi_data.irq);
- pmcmsptwi_data.irq = 0;
- }
- }
-
- init_completion(&pmcmsptwi_data.wait);
- mutex_init(&pmcmsptwi_data.lock);
-
- pmcmsptwi_set_clock_config(&pmcmsptwi_defclockcfg, &pmcmsptwi_data);
- pmcmsptwi_set_twi_config(&pmcmsptwi_defcfg, &pmcmsptwi_data);
-
- printk(KERN_INFO DRV_NAME ": Registering MSP71xx I2C adapter\n");
-
- pmcmsptwi_adapter.dev.parent = &pldev->dev;
- platform_set_drvdata(pldev, &pmcmsptwi_adapter);
- i2c_set_adapdata(&pmcmsptwi_adapter, &pmcmsptwi_data);
-
- rc = i2c_add_adapter(&pmcmsptwi_adapter);
- if (rc) {
- dev_err(&pldev->dev, "Unable to register I2C adapter\n");
- goto ret_unmap;
- }
-
- return 0;
-
-ret_unmap:
- platform_set_drvdata(pldev, NULL);
- if (pmcmsptwi_data.irq) {
- pmcmsptwi_writel(0,
- pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
- free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data);
- }
-
- iounmap(pmcmsptwi_data.iobase);
-
-ret_unreserve:
- release_mem_region(res->start, resource_size(res));
-
-ret_err:
- return rc;
-}
-
-/*
- * Release the device and return 0 if there is one.
- */
-static int __devexit pmcmsptwi_remove(struct platform_device *pldev)
-{
- struct resource *res;
-
- i2c_del_adapter(&pmcmsptwi_adapter);
-
- platform_set_drvdata(pldev, NULL);
- if (pmcmsptwi_data.irq) {
- pmcmsptwi_writel(0,
- pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
- free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data);
- }
-
- iounmap(pmcmsptwi_data.iobase);
-
- res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- return 0;
-}
-
-/*
- * Polls the 'busy' register until the command is complete.
- * NOTE: Assumes data->lock is held.
- */
-static void pmcmsptwi_poll_complete(struct pmcmsptwi_data *data)
-{
- int i;
-
- for (i = 0; i < MSP_MAX_POLL; i++) {
- u32 val = pmcmsptwi_readl(data->iobase +
- MSP_TWI_BUSY_REG_OFFSET);
- if (val == 0) {
- u32 reason = pmcmsptwi_readl(data->iobase +
- MSP_TWI_INT_STS_REG_OFFSET);
- pmcmsptwi_writel(reason, data->iobase +
- MSP_TWI_INT_STS_REG_OFFSET);
- data->last_result = pmcmsptwi_get_result(reason);
- return;
- }
- udelay(MSP_POLL_DELAY);
- }
-
- dev_dbg(&pmcmsptwi_adapter.dev, "Result: Poll timeout\n");
- data->last_result = MSP_TWI_XFER_TIMEOUT;
-}
-
-/*
- * Do the transfer (low level):
- * May use interrupt-driven or polling, depending on if an IRQ is
- * presently registered.
- * NOTE: Assumes data->lock is held.
- */
-static enum pmcmsptwi_xfer_result pmcmsptwi_do_xfer(
- u32 reg, struct pmcmsptwi_data *data)
-{
- dev_dbg(&pmcmsptwi_adapter.dev, "Writing cmd reg 0x%08x\n", reg);
- pmcmsptwi_writel(reg, data->iobase + MSP_TWI_CMD_REG_OFFSET);
- if (data->irq) {
- unsigned long timeleft = wait_for_completion_timeout(
- &data->wait, MSP_IRQ_TIMEOUT);
- if (timeleft == 0) {
- dev_dbg(&pmcmsptwi_adapter.dev,
- "Result: IRQ timeout\n");
- complete(&data->wait);
- data->last_result = MSP_TWI_XFER_TIMEOUT;
- }
- } else
- pmcmsptwi_poll_complete(data);
-
- return data->last_result;
-}
-
-/*
- * Helper routine, converts 'pmctwi_cmd' struct to register format
- */
-static inline u32 pmcmsptwi_cmd_to_reg(const struct pmcmsptwi_cmd *cmd)
-{
- return ((cmd->type & 0x3) << 8) |
- (((cmd->write_len - 1) & 0x7) << 4) |
- ((cmd->read_len - 1) & 0x7);
-}
-
-/*
- * Do the transfer (high level)
- */
-static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
- struct pmcmsptwi_cmd *cmd,
- struct pmcmsptwi_data *data)
-{
- enum pmcmsptwi_xfer_result retval;
-
- if ((cmd->type == MSP_TWI_CMD_WRITE && cmd->write_len == 0) ||
- (cmd->type == MSP_TWI_CMD_READ && cmd->read_len == 0) ||
- (cmd->type == MSP_TWI_CMD_WRITE_READ &&
- (cmd->read_len == 0 || cmd->write_len == 0))) {
- dev_err(&pmcmsptwi_adapter.dev,
- "%s: Cannot transfer less than 1 byte\n",
- __func__);
- return -EINVAL;
- }
-
- if (cmd->read_len > MSP_MAX_BYTES_PER_RW ||
- cmd->write_len > MSP_MAX_BYTES_PER_RW) {
- dev_err(&pmcmsptwi_adapter.dev,
- "%s: Cannot transfer more than %d bytes\n",
- __func__, MSP_MAX_BYTES_PER_RW);
- return -EINVAL;
- }
-
- mutex_lock(&data->lock);
- dev_dbg(&pmcmsptwi_adapter.dev,
- "Setting address to 0x%04x\n", cmd->addr);
- pmcmsptwi_writel(cmd->addr, data->iobase + MSP_TWI_ADD_REG_OFFSET);
-
- if (cmd->type == MSP_TWI_CMD_WRITE ||
- cmd->type == MSP_TWI_CMD_WRITE_READ) {
- u64 tmp = be64_to_cpup((__be64 *)cmd->write_data);
- tmp >>= (MSP_MAX_BYTES_PER_RW - cmd->write_len) * 8;
- dev_dbg(&pmcmsptwi_adapter.dev, "Writing 0x%016llx\n", tmp);
- pmcmsptwi_writel(tmp & 0x00000000ffffffffLL,
- data->iobase + MSP_TWI_DAT_0_REG_OFFSET);
- if (cmd->write_len > 4)
- pmcmsptwi_writel(tmp >> 32,
- data->iobase + MSP_TWI_DAT_1_REG_OFFSET);
- }
-
- retval = pmcmsptwi_do_xfer(pmcmsptwi_cmd_to_reg(cmd), data);
- if (retval != MSP_TWI_XFER_OK)
- goto xfer_err;
-
- if (cmd->type == MSP_TWI_CMD_READ ||
- cmd->type == MSP_TWI_CMD_WRITE_READ) {
- int i;
- u64 rmsk = ~(0xffffffffffffffffLL << (cmd->read_len * 8));
- u64 tmp = (u64)pmcmsptwi_readl(data->iobase +
- MSP_TWI_DAT_0_REG_OFFSET);
- if (cmd->read_len > 4)
- tmp |= (u64)pmcmsptwi_readl(data->iobase +
- MSP_TWI_DAT_1_REG_OFFSET) << 32;
- tmp &= rmsk;
- dev_dbg(&pmcmsptwi_adapter.dev, "Read 0x%016llx\n", tmp);
-
- for (i = 0; i < cmd->read_len; i++)
- cmd->read_data[i] = tmp >> i;
- }
-
-xfer_err:
- mutex_unlock(&data->lock);
-
- return retval;
-}
-
-/* -- Algorithm functions -- */
-
-/*
- * Sends an i2c command out on the adapter
- */
-static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msg, int num)
-{
- struct pmcmsptwi_data *data = i2c_get_adapdata(adap);
- struct pmcmsptwi_cmd cmd;
- struct pmcmsptwi_cfg oldcfg, newcfg;
- int ret;
-
- if (num > 2) {
- dev_dbg(&adap->dev, "%d messages unsupported\n", num);
- return -EINVAL;
- } else if (num == 2) {
- /* Check for a dual write-then-read command */
- struct i2c_msg *nextmsg = msg + 1;
- if (!(msg->flags & I2C_M_RD) &&
- (nextmsg->flags & I2C_M_RD) &&
- msg->addr == nextmsg->addr) {
- cmd.type = MSP_TWI_CMD_WRITE_READ;
- cmd.write_len = msg->len;
- cmd.write_data = msg->buf;
- cmd.read_len = nextmsg->len;
- cmd.read_data = nextmsg->buf;
- } else {
- dev_dbg(&adap->dev,
- "Non write-read dual messages unsupported\n");
- return -EINVAL;
- }
- } else if (msg->flags & I2C_M_RD) {
- cmd.type = MSP_TWI_CMD_READ;
- cmd.read_len = msg->len;
- cmd.read_data = msg->buf;
- cmd.write_len = 0;
- cmd.write_data = NULL;
- } else {
- cmd.type = MSP_TWI_CMD_WRITE;
- cmd.read_len = 0;
- cmd.read_data = NULL;
- cmd.write_len = msg->len;
- cmd.write_data = msg->buf;
- }
-
- if (msg->len == 0) {
- dev_err(&adap->dev, "Zero-byte messages unsupported\n");
- return -EINVAL;
- }
-
- cmd.addr = msg->addr;
-
- if (msg->flags & I2C_M_TEN) {
- pmcmsptwi_get_twi_config(&newcfg, data);
- memcpy(&oldcfg, &newcfg, sizeof(oldcfg));
-
- /* Set the special 10-bit address flag */
- newcfg.add10 = 1;
-
- pmcmsptwi_set_twi_config(&newcfg, data);
- }
-
- /* Execute the command */
- ret = pmcmsptwi_xfer_cmd(&cmd, data);
-
- if (msg->flags & I2C_M_TEN)
- pmcmsptwi_set_twi_config(&oldcfg, data);
-
- dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n",
- (msg->flags & I2C_M_RD) ? "read" : "write", msg->len,
- (ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed");
-
- if (ret != MSP_TWI_XFER_OK) {
- /*
- * TODO: We could potentially loop and retry in the case
- * of MSP_TWI_XFER_TIMEOUT.
- */
- return -1;
- }
-
- return 0;
-}
-
-static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
- I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL;
-}
-
-/* -- Initialization -- */
-
-static struct i2c_algorithm pmcmsptwi_algo = {
- .master_xfer = pmcmsptwi_master_xfer,
- .functionality = pmcmsptwi_i2c_func,
-};
-
-static struct i2c_adapter pmcmsptwi_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &pmcmsptwi_algo,
- .name = DRV_NAME,
-};
-
-static struct platform_driver pmcmsptwi_driver = {
- .probe = pmcmsptwi_probe,
- .remove = __devexit_p(pmcmsptwi_remove),
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(pmcmsptwi_driver);
-
-MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pnx.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pnx.c
deleted file mode 100644
index eb8ad538..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pnx.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * Provides I2C support for Philips PNX010x/PNX4008 boards.
- *
- * Authors: Dennis Kovalev <dkovalev@ru.mvista.com>
- * Vitaly Wool <vwool@ru.mvista.com>
- *
- * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/timer.h>
-#include <linux/completion.h>
-#include <linux/platform_device.h>
-#include <linux/i2c-pnx.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-
-#define I2C_PNX_TIMEOUT 10 /* msec */
-#define I2C_PNX_SPEED_KHZ 100
-#define I2C_PNX_REGION_SIZE 0x100
-
-static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)
-{
- while (timeout > 0 &&
- (ioread32(I2C_REG_STS(data)) & mstatus_active)) {
- mdelay(1);
- timeout--;
- }
- return (timeout <= 0);
-}
-
-static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data)
-{
- while (timeout > 0 &&
- (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
- mdelay(1);
- timeout--;
- }
- return (timeout <= 0);
-}
-
-static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
-{
- struct timer_list *timer = &alg_data->mif.timer;
- unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT);
-
- if (expires <= 1)
- expires = 2;
-
- del_timer_sync(timer);
-
- dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
- jiffies, expires);
-
- timer->expires = jiffies + expires;
- timer->data = (unsigned long)alg_data;
-
- add_timer(timer);
-}
-
-/**
- * i2c_pnx_start - start a device
- * @slave_addr: slave address
- * @adap: pointer to adapter structure
- *
- * Generate a START signal in the desired mode.
- */
-static int i2c_pnx_start(unsigned char slave_addr,
- struct i2c_pnx_algo_data *alg_data)
-{
- dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,
- slave_addr, alg_data->mif.mode);
-
- /* Check for 7 bit slave addresses only */
- if (slave_addr & ~0x7f) {
- dev_err(&alg_data->adapter.dev,
- "%s: Invalid slave address %x. Only 7-bit addresses are supported\n",
- alg_data->adapter.name, slave_addr);
- return -EINVAL;
- }
-
- /* First, make sure bus is idle */
- if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {
- /* Somebody else is monopolizing the bus */
- dev_err(&alg_data->adapter.dev,
- "%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n",
- alg_data->adapter.name, slave_addr,
- ioread32(I2C_REG_CTL(alg_data)),
- ioread32(I2C_REG_STS(alg_data)));
- return -EBUSY;
- } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
- /* Sorry, we lost the bus */
- dev_err(&alg_data->adapter.dev,
- "%s: Arbitration failure. Slave addr = %02x\n",
- alg_data->adapter.name, slave_addr);
- return -EIO;
- }
-
- /*
- * OK, I2C is enabled and we have the bus.
- * Clear the current TDI and AFI status flags.
- */
- iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
- I2C_REG_STS(alg_data));
-
- dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,
- (slave_addr << 1) | start_bit | alg_data->mif.mode);
-
- /* Write the slave address, START bit and R/W bit */
- iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
- I2C_REG_TX(alg_data));
-
- dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);
-
- return 0;
-}
-
-/**
- * i2c_pnx_stop - stop a device
- * @adap: pointer to I2C adapter structure
- *
- * Generate a STOP signal to terminate the master transaction.
- */
-static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)
-{
- /* Only 1 msec max timeout due to interrupt context */
- long timeout = 1000;
-
- dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-
- /* Write a STOP bit to TX FIFO */
- iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
-
- /* Wait until the STOP is seen. */
- while (timeout > 0 &&
- (ioread32(I2C_REG_STS(alg_data)) & mstatus_active)) {
- /* may be called from interrupt context */
- udelay(1);
- timeout--;
- }
-
- dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-}
-
-/**
- * i2c_pnx_master_xmit - transmit data to slave
- * @adap: pointer to I2C adapter structure
- *
- * Sends one byte of data to the slave
- */
-static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
-{
- u32 val;
-
- dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-
- if (alg_data->mif.len > 0) {
- /* We still have something to talk about... */
- val = *alg_data->mif.buf++;
-
- if (alg_data->mif.len == 1)
- val |= stop_bit;
-
- alg_data->mif.len--;
- iowrite32(val, I2C_REG_TX(alg_data));
-
- dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n",
- __func__, val, alg_data->mif.len + 1);
-
- if (alg_data->mif.len == 0) {
- if (alg_data->last) {
- /* Wait until the STOP is seen. */
- if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
- dev_err(&alg_data->adapter.dev,
- "The bus is still active after timeout\n");
- }
- /* Disable master interrupts */
- iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
- ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
- I2C_REG_CTL(alg_data));
-
- del_timer_sync(&alg_data->mif.timer);
-
- dev_dbg(&alg_data->adapter.dev,
- "%s(): Waking up xfer routine.\n",
- __func__);
-
- complete(&alg_data->mif.complete);
- }
- } else if (alg_data->mif.len == 0) {
- /* zero-sized transfer */
- i2c_pnx_stop(alg_data);
-
- /* Disable master interrupts. */
- iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
- ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
- I2C_REG_CTL(alg_data));
-
- /* Stop timer. */
- del_timer_sync(&alg_data->mif.timer);
- dev_dbg(&alg_data->adapter.dev,
- "%s(): Waking up xfer routine after zero-xfer.\n",
- __func__);
-
- complete(&alg_data->mif.complete);
- }
-
- dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-
- return 0;
-}
-
-/**
- * i2c_pnx_master_rcv - receive data from slave
- * @adap: pointer to I2C adapter structure
- *
- * Reads one byte data from the slave
- */
-static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
-{
- unsigned int val = 0;
- u32 ctl = 0;
-
- dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-
- /* Check, whether there is already data,
- * or we didn't 'ask' for it yet.
- */
- if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
- dev_dbg(&alg_data->adapter.dev,
- "%s(): Write dummy data to fill Rx-fifo...\n",
- __func__);
-
- if (alg_data->mif.len == 1) {
- /* Last byte, do not acknowledge next rcv. */
- val |= stop_bit;
-
- /*
- * Enable interrupt RFDAIE (data in Rx fifo),
- * and disable DRMIE (need data for Tx)
- */
- ctl = ioread32(I2C_REG_CTL(alg_data));
- ctl |= mcntrl_rffie | mcntrl_daie;
- ctl &= ~mcntrl_drmie;
- iowrite32(ctl, I2C_REG_CTL(alg_data));
- }
-
- /*
- * Now we'll 'ask' for data:
- * For each byte we want to receive, we must
- * write a (dummy) byte to the Tx-FIFO.
- */
- iowrite32(val, I2C_REG_TX(alg_data));
-
- return 0;
- }
-
- /* Handle data. */
- if (alg_data->mif.len > 0) {
- val = ioread32(I2C_REG_RX(alg_data));
- *alg_data->mif.buf++ = (u8) (val & 0xff);
- dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n",
- __func__, val, alg_data->mif.len);
-
- alg_data->mif.len--;
- if (alg_data->mif.len == 0) {
- if (alg_data->last)
- /* Wait until the STOP is seen. */
- if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
- dev_err(&alg_data->adapter.dev,
- "The bus is still active after timeout\n");
-
- /* Disable master interrupts */
- ctl = ioread32(I2C_REG_CTL(alg_data));
- ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
- mcntrl_drmie | mcntrl_daie);
- iowrite32(ctl, I2C_REG_CTL(alg_data));
-
- /* Kill timer. */
- del_timer_sync(&alg_data->mif.timer);
- complete(&alg_data->mif.complete);
- }
- }
-
- dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-
- return 0;
-}
-
-static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
-{
- struct i2c_pnx_algo_data *alg_data = dev_id;
- u32 stat, ctl;
-
- dev_dbg(&alg_data->adapter.dev,
- "%s(): mstat = %x mctrl = %x, mode = %d\n",
- __func__,
- ioread32(I2C_REG_STS(alg_data)),
- ioread32(I2C_REG_CTL(alg_data)),
- alg_data->mif.mode);
- stat = ioread32(I2C_REG_STS(alg_data));
-
- /* let's see what kind of event this is */
- if (stat & mstatus_afi) {
- /* We lost arbitration in the midst of a transfer */
- alg_data->mif.ret = -EIO;
-
- /* Disable master interrupts. */
- ctl = ioread32(I2C_REG_CTL(alg_data));
- ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
- mcntrl_drmie);
- iowrite32(ctl, I2C_REG_CTL(alg_data));
-
- /* Stop timer, to prevent timeout. */
- del_timer_sync(&alg_data->mif.timer);
- complete(&alg_data->mif.complete);
- } else if (stat & mstatus_nai) {
- /* Slave did not acknowledge, generate a STOP */
- dev_dbg(&alg_data->adapter.dev,
- "%s(): Slave did not acknowledge, generating a STOP.\n",
- __func__);
- i2c_pnx_stop(alg_data);
-
- /* Disable master interrupts. */
- ctl = ioread32(I2C_REG_CTL(alg_data));
- ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
- mcntrl_drmie);
- iowrite32(ctl, I2C_REG_CTL(alg_data));
-
- /* Our return value. */
- alg_data->mif.ret = -EIO;
-
- /* Stop timer, to prevent timeout. */
- del_timer_sync(&alg_data->mif.timer);
- complete(&alg_data->mif.complete);
- } else {
- /*
- * Two options:
- * - Master Tx needs data.
- * - There is data in the Rx-fifo
- * The latter is only the case if we have requested for data,
- * via a dummy write. (See 'i2c_pnx_master_rcv'.)
- * We therefore check, as a sanity check, whether that interrupt
- * has been enabled.
- */
- if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
- if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
- i2c_pnx_master_xmit(alg_data);
- } else if (alg_data->mif.mode == I2C_SMBUS_READ) {
- i2c_pnx_master_rcv(alg_data);
- }
- }
- }
-
- /* Clear TDI and AFI bits */
- stat = ioread32(I2C_REG_STS(alg_data));
- iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
-
- dev_dbg(&alg_data->adapter.dev,
- "%s(): exiting, stat = %x ctrl = %x.\n",
- __func__, ioread32(I2C_REG_STS(alg_data)),
- ioread32(I2C_REG_CTL(alg_data)));
-
- return IRQ_HANDLED;
-}
-
-static void i2c_pnx_timeout(unsigned long data)
-{
- struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data;
- u32 ctl;
-
- dev_err(&alg_data->adapter.dev,
- "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n",
- ioread32(I2C_REG_STS(alg_data)),
- ioread32(I2C_REG_CTL(alg_data)));
-
- /* Reset master and disable interrupts */
- ctl = ioread32(I2C_REG_CTL(alg_data));
- ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie);
- iowrite32(ctl, I2C_REG_CTL(alg_data));
-
- ctl |= mcntrl_reset;
- iowrite32(ctl, I2C_REG_CTL(alg_data));
- wait_reset(I2C_PNX_TIMEOUT, alg_data);
- alg_data->mif.ret = -EIO;
- complete(&alg_data->mif.complete);
-}
-
-static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
-{
- u32 stat;
-
- if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
- dev_err(&alg_data->adapter.dev,
- "%s: Bus is still active after xfer. Reset it...\n",
- alg_data->adapter.name);
- iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
- I2C_REG_CTL(alg_data));
- wait_reset(I2C_PNX_TIMEOUT, alg_data);
- } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) {
- /* If there is data in the fifo's after transfer,
- * flush fifo's by reset.
- */
- iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
- I2C_REG_CTL(alg_data));
- wait_reset(I2C_PNX_TIMEOUT, alg_data);
- } else if (stat & mstatus_nai) {
- iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
- I2C_REG_CTL(alg_data));
- wait_reset(I2C_PNX_TIMEOUT, alg_data);
- }
-}
-
-/**
- * i2c_pnx_xfer - generic transfer entry point
- * @adap: pointer to I2C adapter structure
- * @msgs: array of messages
- * @num: number of messages
- *
- * Initiates the transfer
- */
-static int
-i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct i2c_msg *pmsg;
- int rc = 0, completed = 0, i;
- struct i2c_pnx_algo_data *alg_data = adap->algo_data;
- u32 stat = ioread32(I2C_REG_STS(alg_data));
-
- dev_dbg(&alg_data->adapter.dev,
- "%s(): entering: %d messages, stat = %04x.\n",
- __func__, num, ioread32(I2C_REG_STS(alg_data)));
-
- bus_reset_if_active(alg_data);
-
- /* Process transactions in a loop. */
- for (i = 0; rc >= 0 && i < num; i++) {
- u8 addr;
-
- pmsg = &msgs[i];
- addr = pmsg->addr;
-
- if (pmsg->flags & I2C_M_TEN) {
- dev_err(&alg_data->adapter.dev,
- "%s: 10 bits addr not supported!\n",
- alg_data->adapter.name);
- rc = -EINVAL;
- break;
- }
-
- alg_data->mif.buf = pmsg->buf;
- alg_data->mif.len = pmsg->len;
- alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
- I2C_SMBUS_READ : I2C_SMBUS_WRITE;
- alg_data->mif.ret = 0;
- alg_data->last = (i == num - 1);
-
- dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
- __func__, alg_data->mif.mode, alg_data->mif.len);
-
- i2c_pnx_arm_timer(alg_data);
-
- /* initialize the completion var */
- init_completion(&alg_data->mif.complete);
-
- /* Enable master interrupt */
- iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie |
- mcntrl_naie | mcntrl_drmie,
- I2C_REG_CTL(alg_data));
-
- /* Put start-code and slave-address on the bus. */
- rc = i2c_pnx_start(addr, alg_data);
- if (rc < 0)
- break;
-
- /* Wait for completion */
- wait_for_completion(&alg_data->mif.complete);
-
- if (!(rc = alg_data->mif.ret))
- completed++;
- dev_dbg(&alg_data->adapter.dev,
- "%s(): Complete, return code = %d.\n",
- __func__, rc);
-
- /* Clear TDI and AFI bits in case they are set. */
- if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
- dev_dbg(&alg_data->adapter.dev,
- "%s: TDI still set... clearing now.\n",
- alg_data->adapter.name);
- iowrite32(stat, I2C_REG_STS(alg_data));
- }
- if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
- dev_dbg(&alg_data->adapter.dev,
- "%s: AFI still set... clearing now.\n",
- alg_data->adapter.name);
- iowrite32(stat, I2C_REG_STS(alg_data));
- }
- }
-
- bus_reset_if_active(alg_data);
-
- /* Cleanup to be sure... */
- alg_data->mif.buf = NULL;
- alg_data->mif.len = 0;
-
- dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
- __func__, ioread32(I2C_REG_STS(alg_data)));
-
- if (completed != num)
- return ((rc < 0) ? rc : -EREMOTEIO);
-
- return num;
-}
-
-static u32 i2c_pnx_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm pnx_algorithm = {
- .master_xfer = i2c_pnx_xfer,
- .functionality = i2c_pnx_func,
-};
-
-#ifdef CONFIG_PM
-static int i2c_pnx_controller_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
-
- clk_disable(alg_data->clk);
-
- return 0;
-}
-
-static int i2c_pnx_controller_resume(struct platform_device *pdev)
-{
- struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
-
- return clk_enable(alg_data->clk);
-}
-#else
-#define i2c_pnx_controller_suspend NULL
-#define i2c_pnx_controller_resume NULL
-#endif
-
-static int __devinit i2c_pnx_probe(struct platform_device *pdev)
-{
- unsigned long tmp;
- int ret = 0;
- struct i2c_pnx_algo_data *alg_data;
- unsigned long freq;
- struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;
-
- if (!i2c_pnx || !i2c_pnx->name) {
- dev_err(&pdev->dev, "%s: no platform data supplied\n",
- __func__);
- ret = -EINVAL;
- goto out;
- }
-
- alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
- if (!alg_data) {
- ret = -ENOMEM;
- goto err_kzalloc;
- }
-
- platform_set_drvdata(pdev, alg_data);
-
- strlcpy(alg_data->adapter.name, i2c_pnx->name,
- sizeof(alg_data->adapter.name));
- alg_data->adapter.dev.parent = &pdev->dev;
- alg_data->adapter.algo = &pnx_algorithm;
- alg_data->adapter.algo_data = alg_data;
- alg_data->adapter.nr = pdev->id;
- alg_data->i2c_pnx = i2c_pnx;
-
- alg_data->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(alg_data->clk)) {
- ret = PTR_ERR(alg_data->clk);
- goto out_drvdata;
- }
-
- init_timer(&alg_data->mif.timer);
- alg_data->mif.timer.function = i2c_pnx_timeout;
- alg_data->mif.timer.data = (unsigned long)alg_data;
-
- /* Register I/O resource */
- if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE,
- pdev->name)) {
- dev_err(&pdev->dev,
- "I/O region 0x%08x for I2C already in use.\n",
- i2c_pnx->base);
- ret = -ENODEV;
- goto out_clkget;
- }
-
- alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE);
- if (!alg_data->ioaddr) {
- dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
- ret = -ENOMEM;
- goto out_release;
- }
-
- ret = clk_enable(alg_data->clk);
- if (ret)
- goto out_unmap;
-
- freq = clk_get_rate(alg_data->clk);
-
- /*
- * Clock Divisor High This value is the number of system clocks
- * the serial clock (SCL) will be high.
- * For example, if the system clock period is 50 ns and the maximum
- * desired serial period is 10000 ns (100 kHz), then CLKHI would be
- * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
- * programmed into CLKHI will vary from this slightly due to
- * variations in the output pad's rise and fall times as well as
- * the deglitching filter length.
- */
-
- tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
- if (tmp > 0x3FF)
- tmp = 0x3FF;
- iowrite32(tmp, I2C_REG_CKH(alg_data));
- iowrite32(tmp, I2C_REG_CKL(alg_data));
-
- iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
- if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
- ret = -ENODEV;
- goto out_clock;
- }
- init_completion(&alg_data->mif.complete);
-
- ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt,
- 0, pdev->name, alg_data);
- if (ret)
- goto out_clock;
-
- /* Register this adapter with the I2C subsystem */
- ret = i2c_add_numbered_adapter(&alg_data->adapter);
- if (ret < 0) {
- dev_err(&pdev->dev, "I2C: Failed to add bus\n");
- goto out_irq;
- }
-
- dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
- alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq);
-
- return 0;
-
-out_irq:
- free_irq(i2c_pnx->irq, alg_data);
-out_clock:
- clk_disable(alg_data->clk);
-out_unmap:
- iounmap(alg_data->ioaddr);
-out_release:
- release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
-out_clkget:
- clk_put(alg_data->clk);
-out_drvdata:
- kfree(alg_data);
-err_kzalloc:
- platform_set_drvdata(pdev, NULL);
-out:
- return ret;
-}
-
-static int __devexit i2c_pnx_remove(struct platform_device *pdev)
-{
- struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
- struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx;
-
- free_irq(i2c_pnx->irq, alg_data);
- i2c_del_adapter(&alg_data->adapter);
- clk_disable(alg_data->clk);
- iounmap(alg_data->ioaddr);
- release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
- clk_put(alg_data->clk);
- kfree(alg_data);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver i2c_pnx_driver = {
- .driver = {
- .name = "pnx-i2c",
- .owner = THIS_MODULE,
- },
- .probe = i2c_pnx_probe,
- .remove = __devexit_p(i2c_pnx_remove),
- .suspend = i2c_pnx_controller_suspend,
- .resume = i2c_pnx_controller_resume,
-};
-
-static int __init i2c_adap_pnx_init(void)
-{
- return platform_driver_register(&i2c_pnx_driver);
-}
-
-static void __exit i2c_adap_pnx_exit(void)
-{
- platform_driver_unregister(&i2c_pnx_driver);
-}
-
-MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
-MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pnx-i2c");
-
-/* We need to make sure I2C is initialized before USB */
-subsys_initcall(i2c_adap_pnx_init);
-module_exit(i2c_adap_pnx_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-powermac.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-powermac.c
deleted file mode 100644
index 7b397c6f..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-powermac.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- i2c Support for Apple SMU Controller
-
- Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
- <benh@kernel.crashing.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <asm/prom.h>
-#include <asm/pmac_low_i2c.h>
-
-MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
-MODULE_DESCRIPTION("I2C driver for Apple PowerMac");
-MODULE_LICENSE("GPL");
-
-/*
- * SMBUS-type transfer entrypoint
- */
-static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap,
- u16 addr,
- unsigned short flags,
- char read_write,
- u8 command,
- int size,
- union i2c_smbus_data* data)
-{
- struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
- int rc = 0;
- int read = (read_write == I2C_SMBUS_READ);
- int addrdir = (addr << 1) | read;
- int mode, subsize, len;
- u32 subaddr;
- u8 *buf;
- u8 local[2];
-
- if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE) {
- mode = pmac_i2c_mode_std;
- subsize = 0;
- subaddr = 0;
- } else {
- mode = read ? pmac_i2c_mode_combined : pmac_i2c_mode_stdsub;
- subsize = 1;
- subaddr = command;
- }
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- buf = NULL;
- len = 0;
- break;
- case I2C_SMBUS_BYTE:
- case I2C_SMBUS_BYTE_DATA:
- buf = &data->byte;
- len = 1;
- break;
- case I2C_SMBUS_WORD_DATA:
- if (!read) {
- local[0] = data->word & 0xff;
- local[1] = (data->word >> 8) & 0xff;
- }
- buf = local;
- len = 2;
- break;
-
- /* Note that these are broken vs. the expected smbus API where
- * on reads, the length is actually returned from the function,
- * but I think the current API makes no sense and I don't want
- * any driver that I haven't verified for correctness to go
- * anywhere near a pmac i2c bus anyway ...
- *
- * I'm also not completely sure what kind of phases to do between
- * the actual command and the data (what I am _supposed_ to do that
- * is). For now, I assume writes are a single stream and reads have
- * a repeat start/addr phase (but not stop in between)
- */
- case I2C_SMBUS_BLOCK_DATA:
- buf = data->block;
- len = data->block[0] + 1;
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- buf = &data->block[1];
- len = data->block[0];
- break;
-
- default:
- return -EINVAL;
- }
-
- rc = pmac_i2c_open(bus, 0);
- if (rc) {
- dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
- return rc;
- }
-
- rc = pmac_i2c_setmode(bus, mode);
- if (rc) {
- dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
- mode, rc);
- goto bail;
- }
-
- rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
- if (rc) {
- if (rc == -ENXIO)
- dev_dbg(&adap->dev,
- "I2C transfer at 0x%02x failed, size %d, "
- "err %d\n", addrdir >> 1, size, rc);
- else
- dev_err(&adap->dev,
- "I2C transfer at 0x%02x failed, size %d, "
- "err %d\n", addrdir >> 1, size, rc);
- goto bail;
- }
-
- if (size == I2C_SMBUS_WORD_DATA && read) {
- data->word = ((u16)local[1]) << 8;
- data->word |= local[0];
- }
-
- bail:
- pmac_i2c_close(bus);
- return rc;
-}
-
-/*
- * Generic i2c master transfer entrypoint. This driver only support single
- * messages (for "lame i2c" transfers). Anything else should use the smbus
- * entry point
- */
-static int i2c_powermac_master_xfer( struct i2c_adapter *adap,
- struct i2c_msg *msgs,
- int num)
-{
- struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
- int rc = 0;
- int read;
- int addrdir;
-
- if (num != 1) {
- dev_err(&adap->dev,
- "Multi-message I2C transactions not supported\n");
- return -EOPNOTSUPP;
- }
-
- if (msgs->flags & I2C_M_TEN)
- return -EINVAL;
- read = (msgs->flags & I2C_M_RD) != 0;
- addrdir = (msgs->addr << 1) | read;
-
- rc = pmac_i2c_open(bus, 0);
- if (rc) {
- dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
- return rc;
- }
- rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
- if (rc) {
- dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
- pmac_i2c_mode_std, rc);
- goto bail;
- }
- rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
- if (rc < 0) {
- if (rc == -ENXIO)
- dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
- addrdir & 1 ? "read from" : "write to",
- addrdir >> 1, rc);
- else
- dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
- addrdir & 1 ? "read from" : "write to",
- addrdir >> 1, rc);
- }
- bail:
- pmac_i2c_close(bus);
- return rc < 0 ? rc : 1;
-}
-
-static u32 i2c_powermac_func(struct i2c_adapter * adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C;
-}
-
-/* For now, we only handle smbus */
-static const struct i2c_algorithm i2c_powermac_algorithm = {
- .smbus_xfer = i2c_powermac_smbus_xfer,
- .master_xfer = i2c_powermac_master_xfer,
- .functionality = i2c_powermac_func,
-};
-
-
-static int __devexit i2c_powermac_remove(struct platform_device *dev)
-{
- struct i2c_adapter *adapter = platform_get_drvdata(dev);
- int rc;
-
- rc = i2c_del_adapter(adapter);
- /* We aren't that prepared to deal with this... */
- if (rc)
- printk(KERN_WARNING
- "i2c-powermac.c: Failed to remove bus %s !\n",
- adapter->name);
- platform_set_drvdata(dev, NULL);
- memset(adapter, 0, sizeof(*adapter));
-
- return 0;
-}
-
-
-static int __devinit i2c_powermac_probe(struct platform_device *dev)
-{
- struct pmac_i2c_bus *bus = dev->dev.platform_data;
- struct device_node *parent = NULL;
- struct i2c_adapter *adapter;
- const char *basename;
- int rc;
-
- if (bus == NULL)
- return -EINVAL;
- adapter = pmac_i2c_get_adapter(bus);
-
- /* Ok, now we need to make up a name for the interface that will
- * match what we used to do in the past, that is basically the
- * controller's parent device node for keywest. PMU didn't have a
- * naming convention and SMU has a different one
- */
- switch(pmac_i2c_get_type(bus)) {
- case pmac_i2c_bus_keywest:
- parent = of_get_parent(pmac_i2c_get_controller(bus));
- if (parent == NULL)
- return -EINVAL;
- basename = parent->name;
- break;
- case pmac_i2c_bus_pmu:
- basename = "pmu";
- break;
- case pmac_i2c_bus_smu:
- /* This is not what we used to do but I'm fixing drivers at
- * the same time as this change
- */
- basename = "smu";
- break;
- default:
- return -EINVAL;
- }
- snprintf(adapter->name, sizeof(adapter->name), "%s %d", basename,
- pmac_i2c_get_channel(bus));
- of_node_put(parent);
-
- platform_set_drvdata(dev, adapter);
- adapter->algo = &i2c_powermac_algorithm;
- i2c_set_adapdata(adapter, bus);
- adapter->dev.parent = &dev->dev;
- rc = i2c_add_adapter(adapter);
- if (rc) {
- printk(KERN_ERR "i2c-powermac: Adapter %s registration "
- "failed\n", adapter->name);
- memset(adapter, 0, sizeof(*adapter));
- }
-
- printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
-
- if (!strncmp(basename, "uni-n", 5)) {
- struct device_node *np;
- const u32 *prop;
- struct i2c_board_info info;
-
- /* Instantiate I2C motion sensor if present */
- np = of_find_node_by_name(NULL, "accelerometer");
- if (np && of_device_is_compatible(np, "AAPL,accelerometer_1") &&
- (prop = of_get_property(np, "reg", NULL))) {
- int i2c_bus;
- const char *tmp_bus;
-
- /* look for bus either using "reg" or by path */
- tmp_bus = strstr(np->full_name, "/i2c-bus@");
- if (tmp_bus)
- i2c_bus = *(tmp_bus + 9) - '0';
- else
- i2c_bus = ((*prop) >> 8) & 0x0f;
-
- if (pmac_i2c_get_channel(bus) == i2c_bus) {
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = ((*prop) & 0xff) >> 1;
- strlcpy(info.type, "ams", I2C_NAME_SIZE);
- i2c_new_device(adapter, &info);
- }
- }
- }
-
- return rc;
-}
-
-static struct platform_driver i2c_powermac_driver = {
- .probe = i2c_powermac_probe,
- .remove = __devexit_p(i2c_powermac_remove),
- .driver = {
- .name = "i2c-powermac",
- .bus = &platform_bus_type,
- },
-};
-
-module_platform_driver(i2c_powermac_driver);
-
-MODULE_ALIAS("platform:i2c-powermac");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-puv3.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-puv3.c
deleted file mode 100644
index 93709fbe..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-puv3.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * I2C driver for PKUnity-v3 SoC
- * Code specific to PKUnity SoC and UniCore ISA
- *
- * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
- * Copyright (C) 2001-2010 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-
-/*
- * Poll the i2c status register until the specified bit is set.
- * Returns 0 if timed out (100 msec).
- */
-static short poll_status(unsigned long bit)
-{
- int loop_cntr = 1000;
-
- if (bit & I2C_STATUS_TFNF) {
- do {
- udelay(10);
- } while (!(readl(I2C_STATUS) & bit) && (--loop_cntr > 0));
- } else {
- /* RXRDY handler */
- do {
- if (readl(I2C_TAR) == I2C_TAR_EEPROM)
- msleep(20);
- else
- udelay(10);
- } while (!(readl(I2C_RXFLR) & 0xf) && (--loop_cntr > 0));
- }
-
- return (loop_cntr > 0);
-}
-
-static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
- int i2c_reg = *buf;
-
- /* Read data */
- while (length--) {
- if (!poll_status(I2C_STATUS_TFNF)) {
- dev_dbg(&adap->dev, "Tx FIFO Not Full timeout\n");
- return -ETIMEDOUT;
- }
-
- /* send addr */
- writel(i2c_reg | I2C_DATACMD_WRITE, I2C_DATACMD);
-
- /* get ready to next write */
- i2c_reg++;
-
- /* send read CMD */
- writel(I2C_DATACMD_READ, I2C_DATACMD);
-
- /* wait until the Rx FIFO have available */
- if (!poll_status(I2C_STATUS_RFNE)) {
- dev_dbg(&adap->dev, "RXRDY timeout\n");
- return -ETIMEDOUT;
- }
-
- /* read the data to buf */
- *buf = (readl(I2C_DATACMD) & I2C_DATACMD_DAT_MASK);
- buf++;
- }
-
- return 0;
-}
-
-static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
- int i2c_reg = *buf;
-
- /* Do nothing but storing the reg_num to a static variable */
- if (i2c_reg == -1) {
- printk(KERN_WARNING "Error i2c reg\n");
- return -ETIMEDOUT;
- }
-
- if (length == 1)
- return 0;
-
- buf++;
- length--;
- while (length--) {
- /* send addr */
- writel(i2c_reg | I2C_DATACMD_WRITE, I2C_DATACMD);
-
- /* send write CMD */
- writel(*buf | I2C_DATACMD_WRITE, I2C_DATACMD);
-
- /* wait until the Rx FIFO have available */
- msleep(20);
-
- /* read the data to buf */
- i2c_reg++;
- buf++;
- }
-
- return 0;
-}
-
-/*
- * Generic i2c master transfer entrypoint.
- *
- */
-static int puv3_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg,
- int num)
-{
- int i, ret;
- unsigned char swap;
-
- /* Disable i2c */
- writel(I2C_ENABLE_DISABLE, I2C_ENABLE);
-
- /* Set the work mode and speed*/
- writel(I2C_CON_MASTER | I2C_CON_SPEED_STD | I2C_CON_SLAVEDISABLE, I2C_CON);
-
- writel(pmsg->addr, I2C_TAR);
-
- /* Enable i2c */
- writel(I2C_ENABLE_ENABLE, I2C_ENABLE);
-
- dev_dbg(&adap->dev, "puv3_i2c_xfer: processing %d messages:\n", num);
-
- for (i = 0; i < num; i++) {
- dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
- pmsg->flags & I2C_M_RD ? "read" : "writ",
- pmsg->len, pmsg->len > 1 ? "s" : "",
- pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr);
-
- if (pmsg->len && pmsg->buf) { /* sanity check */
- if (pmsg->flags & I2C_M_RD)
- ret = xfer_read(adap, pmsg->buf, pmsg->len);
- else
- ret = xfer_write(adap, pmsg->buf, pmsg->len);
-
- if (ret)
- return ret;
-
- }
- dev_dbg(&adap->dev, "transfer complete\n");
- pmsg++; /* next message */
- }
-
- /* XXX: fixup be16_to_cpu in bq27x00_battery.c */
- if (pmsg->addr == I2C_TAR_PWIC) {
- swap = pmsg->buf[0];
- pmsg->buf[0] = pmsg->buf[1];
- pmsg->buf[1] = swap;
- }
-
- return i;
-}
-
-/*
- * Return list of supported functionality.
- */
-static u32 puv3_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm puv3_i2c_algorithm = {
- .master_xfer = puv3_i2c_xfer,
- .functionality = puv3_i2c_func,
-};
-
-/*
- * Main initialization routine.
- */
-static int __devinit puv3_i2c_probe(struct platform_device *pdev)
-{
- struct i2c_adapter *adapter;
- struct resource *mem;
- int rc;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem)
- return -ENODEV;
-
- if (!request_mem_region(mem->start, resource_size(mem), "puv3_i2c"))
- return -EBUSY;
-
- adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
- if (adapter == NULL) {
- dev_err(&pdev->dev, "can't allocate inteface!\n");
- rc = -ENOMEM;
- goto fail_nomem;
- }
- snprintf(adapter->name, sizeof(adapter->name), "PUV3-I2C at 0x%08x",
- mem->start);
- adapter->algo = &puv3_i2c_algorithm;
- adapter->class = I2C_CLASS_HWMON;
- adapter->dev.parent = &pdev->dev;
-
- platform_set_drvdata(pdev, adapter);
-
- adapter->nr = pdev->id;
- rc = i2c_add_numbered_adapter(adapter);
- if (rc) {
- dev_err(&pdev->dev, "Adapter '%s' registration failed\n",
- adapter->name);
- goto fail_add_adapter;
- }
-
- dev_info(&pdev->dev, "PKUnity v3 i2c bus adapter.\n");
- return 0;
-
-fail_add_adapter:
- platform_set_drvdata(pdev, NULL);
- kfree(adapter);
-fail_nomem:
- release_mem_region(mem->start, resource_size(mem));
-
- return rc;
-}
-
-static int __devexit puv3_i2c_remove(struct platform_device *pdev)
-{
- struct i2c_adapter *adapter = platform_get_drvdata(pdev);
- struct resource *mem;
- int rc;
-
- rc = i2c_del_adapter(adapter);
- if (rc) {
- dev_err(&pdev->dev, "Adapter '%s' delete fail\n",
- adapter->name);
- return rc;
- }
-
- put_device(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
-
- return rc;
-}
-
-#ifdef CONFIG_PM
-static int puv3_i2c_suspend(struct platform_device *dev, pm_message_t state)
-{
- int poll_count;
- /* Disable the IIC */
- writel(I2C_ENABLE_DISABLE, I2C_ENABLE);
- for (poll_count = 0; poll_count < 50; poll_count++) {
- if (readl(I2C_ENSTATUS) & I2C_ENSTATUS_ENABLE)
- udelay(25);
- }
-
- return 0;
-}
-
-static int puv3_i2c_resume(struct platform_device *dev)
-{
- return 0 ;
-}
-#else
-#define puv3_i2c_suspend NULL
-#define puv3_i2c_resume NULL
-#endif
-
-static struct platform_driver puv3_i2c_driver = {
- .probe = puv3_i2c_probe,
- .remove = __devexit_p(puv3_i2c_remove),
- .suspend = puv3_i2c_suspend,
- .resume = puv3_i2c_resume,
- .driver = {
- .name = "PKUnity-v3-I2C",
- .owner = THIS_MODULE,
- }
-};
-
-module_platform_driver(puv3_i2c_driver);
-
-MODULE_DESCRIPTION("PKUnity v3 I2C driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:puv3_i2c");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa-pci.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa-pci.c
deleted file mode 100644
index a0581798..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa-pci.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * The CE4100's I2C device is more or less the same one as found on PXA.
- * It does not support slave mode, the register slightly moved. This PCI
- * device provides three bars, every contains a single I2C controller.
- */
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/i2c/pxa-i2c.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_address.h>
-
-#define CE4100_PCI_I2C_DEVS 3
-
-struct ce4100_devices {
- struct platform_device *pdev[CE4100_PCI_I2C_DEVS];
-};
-
-static struct platform_device *add_i2c_device(struct pci_dev *dev, int bar)
-{
- struct platform_device *pdev;
- struct i2c_pxa_platform_data pdata;
- struct resource res[2];
- struct device_node *child;
- static int devnum;
- int ret;
-
- memset(&pdata, 0, sizeof(struct i2c_pxa_platform_data));
- memset(&res, 0, sizeof(res));
-
- res[0].flags = IORESOURCE_MEM;
- res[0].start = pci_resource_start(dev, bar);
- res[0].end = pci_resource_end(dev, bar);
-
- res[1].flags = IORESOURCE_IRQ;
- res[1].start = dev->irq;
- res[1].end = dev->irq;
-
- for_each_child_of_node(dev->dev.of_node, child) {
- const void *prop;
- struct resource r;
- int ret;
-
- ret = of_address_to_resource(child, 0, &r);
- if (ret < 0)
- continue;
- if (r.start != res[0].start)
- continue;
- if (r.end != res[0].end)
- continue;
- if (r.flags != res[0].flags)
- continue;
-
- prop = of_get_property(child, "fast-mode", NULL);
- if (prop)
- pdata.fast_mode = 1;
-
- break;
- }
-
- if (!child) {
- dev_err(&dev->dev, "failed to match a DT node for bar %d.\n",
- bar);
- ret = -EINVAL;
- goto out;
- }
-
- pdev = platform_device_alloc("ce4100-i2c", devnum);
- if (!pdev) {
- of_node_put(child);
- ret = -ENOMEM;
- goto out;
- }
- pdev->dev.parent = &dev->dev;
- pdev->dev.of_node = child;
-
- ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
- if (ret)
- goto err;
-
- ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
- if (ret)
- goto err;
-
- ret = platform_device_add(pdev);
- if (ret)
- goto err;
- devnum++;
- return pdev;
-err:
- platform_device_put(pdev);
-out:
- return ERR_PTR(ret);
-}
-
-static int __devinit ce4100_i2c_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
-{
- int ret;
- int i;
- struct ce4100_devices *sds;
-
- ret = pci_enable_device_mem(dev);
- if (ret)
- return ret;
-
- if (!dev->dev.of_node) {
- dev_err(&dev->dev, "Missing device tree node.\n");
- return -EINVAL;
- }
- sds = kzalloc(sizeof(*sds), GFP_KERNEL);
- if (!sds) {
- ret = -ENOMEM;
- goto err_mem;
- }
-
- for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
- sds->pdev[i] = add_i2c_device(dev, i);
- if (IS_ERR(sds->pdev[i])) {
- ret = PTR_ERR(sds->pdev[i]);
- while (--i >= 0)
- platform_device_unregister(sds->pdev[i]);
- goto err_dev_add;
- }
- }
- pci_set_drvdata(dev, sds);
- return 0;
-
-err_dev_add:
- pci_set_drvdata(dev, NULL);
- kfree(sds);
-err_mem:
- pci_disable_device(dev);
- return ret;
-}
-
-static void __devexit ce4100_i2c_remove(struct pci_dev *dev)
-{
- struct ce4100_devices *sds;
- unsigned int i;
-
- sds = pci_get_drvdata(dev);
- pci_set_drvdata(dev, NULL);
-
- for (i = 0; i < ARRAY_SIZE(sds->pdev); i++)
- platform_device_unregister(sds->pdev[i]);
-
- pci_disable_device(dev);
- kfree(sds);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(ce4100_i2c_devices) = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
- { },
-};
-MODULE_DEVICE_TABLE(pci, ce4100_i2c_devices);
-
-static struct pci_driver ce4100_i2c_driver = {
- .name = "ce4100_i2c",
- .id_table = ce4100_i2c_devices,
- .probe = ce4100_i2c_probe,
- .remove = __devexit_p(ce4100_i2c_remove),
-};
-
-static int __init ce4100_i2c_init(void)
-{
- return pci_register_driver(&ce4100_i2c_driver);
-}
-module_init(ce4100_i2c_init);
-
-static void __exit ce4100_i2c_exit(void)
-{
- pci_unregister_driver(&ce4100_i2c_driver);
-}
-module_exit(ce4100_i2c_exit);
-
-MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa.c
deleted file mode 100644
index f6733267..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-pxa.c
+++ /dev/null
@@ -1,1308 +0,0 @@
-/*
- * i2c_adap_pxa.c
- *
- * I2C adapter for the PXA I2C bus access.
- *
- * Copyright (C) 2002 Intrinsyc Software Inc.
- * Copyright (C) 2004-2005 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * History:
- * Apr 2002: Initial version [CS]
- * Jun 2002: Properly separated algo/adap [FB]
- * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
- * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
- * Sep 2004: Major rework to ensure efficient bus handling [RMK]
- * Dec 2004: Added support for PXA27x and slave device probing [Liam Girdwood]
- * Feb 2005: Rework slave mode handling [RMK]
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/i2c-pxa.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_i2c.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/i2c/pxa-i2c.h>
-
-#include <asm/irq.h>
-
-#ifndef CONFIG_HAVE_CLK
-#define clk_get(dev, id) NULL
-#define clk_put(clk) do { } while (0)
-#define clk_disable(clk) do { } while (0)
-#define clk_enable(clk) do { } while (0)
-#endif
-
-struct pxa_reg_layout {
- u32 ibmr;
- u32 idbr;
- u32 icr;
- u32 isr;
- u32 isar;
-};
-
-enum pxa_i2c_types {
- REGS_PXA2XX,
- REGS_PXA3XX,
- REGS_CE4100,
-};
-
-/*
- * I2C registers definitions
- */
-static struct pxa_reg_layout pxa_reg_layout[] = {
- [REGS_PXA2XX] = {
- .ibmr = 0x00,
- .idbr = 0x08,
- .icr = 0x10,
- .isr = 0x18,
- .isar = 0x20,
- },
- [REGS_PXA3XX] = {
- .ibmr = 0x00,
- .idbr = 0x04,
- .icr = 0x08,
- .isr = 0x0c,
- .isar = 0x10,
- },
- [REGS_CE4100] = {
- .ibmr = 0x14,
- .idbr = 0x0c,
- .icr = 0x00,
- .isr = 0x04,
- /* no isar register */
- },
-};
-
-static const struct platform_device_id i2c_pxa_id_table[] = {
- { "pxa2xx-i2c", REGS_PXA2XX },
- { "pxa3xx-pwri2c", REGS_PXA3XX },
- { "ce4100-i2c", REGS_CE4100 },
- { },
-};
-MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
-
-/*
- * I2C bit definitions
- */
-
-#define ICR_START (1 << 0) /* start bit */
-#define ICR_STOP (1 << 1) /* stop bit */
-#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */
-#define ICR_TB (1 << 3) /* transfer byte bit */
-#define ICR_MA (1 << 4) /* master abort */
-#define ICR_SCLE (1 << 5) /* master clock enable */
-#define ICR_IUE (1 << 6) /* unit enable */
-#define ICR_GCD (1 << 7) /* general call disable */
-#define ICR_ITEIE (1 << 8) /* enable tx interrupts */
-#define ICR_IRFIE (1 << 9) /* enable rx interrupts */
-#define ICR_BEIE (1 << 10) /* enable bus error ints */
-#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */
-#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */
-#define ICR_SADIE (1 << 13) /* slave address detected int enable */
-#define ICR_UR (1 << 14) /* unit reset */
-#define ICR_FM (1 << 15) /* fast mode */
-
-#define ISR_RWM (1 << 0) /* read/write mode */
-#define ISR_ACKNAK (1 << 1) /* ack/nak status */
-#define ISR_UB (1 << 2) /* unit busy */
-#define ISR_IBB (1 << 3) /* bus busy */
-#define ISR_SSD (1 << 4) /* slave stop detected */
-#define ISR_ALD (1 << 5) /* arbitration loss detected */
-#define ISR_ITE (1 << 6) /* tx buffer empty */
-#define ISR_IRF (1 << 7) /* rx buffer full */
-#define ISR_GCAD (1 << 8) /* general call address detected */
-#define ISR_SAD (1 << 9) /* slave address detected */
-#define ISR_BED (1 << 10) /* bus error no ACK/NAK */
-
-struct pxa_i2c {
- spinlock_t lock;
- wait_queue_head_t wait;
- struct i2c_msg *msg;
- unsigned int msg_num;
- unsigned int msg_idx;
- unsigned int msg_ptr;
- unsigned int slave_addr;
-
- struct i2c_adapter adap;
- struct clk *clk;
-#ifdef CONFIG_I2C_PXA_SLAVE
- struct i2c_slave_client *slave;
-#endif
-
- unsigned int irqlogidx;
- u32 isrlog[32];
- u32 icrlog[32];
-
- void __iomem *reg_base;
- void __iomem *reg_ibmr;
- void __iomem *reg_idbr;
- void __iomem *reg_icr;
- void __iomem *reg_isr;
- void __iomem *reg_isar;
-
- unsigned long iobase;
- unsigned long iosize;
-
- int irq;
- unsigned int use_pio :1;
- unsigned int fast_mode :1;
-};
-
-#define _IBMR(i2c) ((i2c)->reg_ibmr)
-#define _IDBR(i2c) ((i2c)->reg_idbr)
-#define _ICR(i2c) ((i2c)->reg_icr)
-#define _ISR(i2c) ((i2c)->reg_isr)
-#define _ISAR(i2c) ((i2c)->reg_isar)
-
-/*
- * I2C Slave mode address
- */
-#define I2C_PXA_SLAVE_ADDR 0x1
-
-#ifdef DEBUG
-
-struct bits {
- u32 mask;
- const char *set;
- const char *unset;
-};
-#define PXA_BIT(m, s, u) { .mask = m, .set = s, .unset = u }
-
-static inline void
-decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
-{
- printk("%s %08x: ", prefix, val);
- while (num--) {
- const char *str = val & bits->mask ? bits->set : bits->unset;
- if (str)
- printk("%s ", str);
- bits++;
- }
-}
-
-static const struct bits isr_bits[] = {
- PXA_BIT(ISR_RWM, "RX", "TX"),
- PXA_BIT(ISR_ACKNAK, "NAK", "ACK"),
- PXA_BIT(ISR_UB, "Bsy", "Rdy"),
- PXA_BIT(ISR_IBB, "BusBsy", "BusRdy"),
- PXA_BIT(ISR_SSD, "SlaveStop", NULL),
- PXA_BIT(ISR_ALD, "ALD", NULL),
- PXA_BIT(ISR_ITE, "TxEmpty", NULL),
- PXA_BIT(ISR_IRF, "RxFull", NULL),
- PXA_BIT(ISR_GCAD, "GenCall", NULL),
- PXA_BIT(ISR_SAD, "SlaveAddr", NULL),
- PXA_BIT(ISR_BED, "BusErr", NULL),
-};
-
-static void decode_ISR(unsigned int val)
-{
- decode_bits(KERN_DEBUG "ISR", isr_bits, ARRAY_SIZE(isr_bits), val);
- printk("\n");
-}
-
-static const struct bits icr_bits[] = {
- PXA_BIT(ICR_START, "START", NULL),
- PXA_BIT(ICR_STOP, "STOP", NULL),
- PXA_BIT(ICR_ACKNAK, "ACKNAK", NULL),
- PXA_BIT(ICR_TB, "TB", NULL),
- PXA_BIT(ICR_MA, "MA", NULL),
- PXA_BIT(ICR_SCLE, "SCLE", "scle"),
- PXA_BIT(ICR_IUE, "IUE", "iue"),
- PXA_BIT(ICR_GCD, "GCD", NULL),
- PXA_BIT(ICR_ITEIE, "ITEIE", NULL),
- PXA_BIT(ICR_IRFIE, "IRFIE", NULL),
- PXA_BIT(ICR_BEIE, "BEIE", NULL),
- PXA_BIT(ICR_SSDIE, "SSDIE", NULL),
- PXA_BIT(ICR_ALDIE, "ALDIE", NULL),
- PXA_BIT(ICR_SADIE, "SADIE", NULL),
- PXA_BIT(ICR_UR, "UR", "ur"),
-};
-
-#ifdef CONFIG_I2C_PXA_SLAVE
-static void decode_ICR(unsigned int val)
-{
- decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val);
- printk("\n");
-}
-#endif
-
-static unsigned int i2c_debug = DEBUG;
-
-static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
-{
- dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno,
- readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
-}
-
-#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __func__)
-
-static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
-{
- unsigned int i;
- printk(KERN_ERR "i2c: error: %s\n", why);
- printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
- i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
- printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n",
- readl(_ICR(i2c)), readl(_ISR(i2c)));
- printk(KERN_DEBUG "i2c: log: ");
- for (i = 0; i < i2c->irqlogidx; i++)
- printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
- printk("\n");
-}
-
-#else /* ifdef DEBUG */
-
-#define i2c_debug 0
-
-#define show_state(i2c) do { } while (0)
-#define decode_ISR(val) do { } while (0)
-#define decode_ICR(val) do { } while (0)
-#define i2c_pxa_scream_blue_murder(i2c, why) do { } while (0)
-
-#endif /* ifdef DEBUG / else */
-
-static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
-static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
-
-static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
-{
- return !(readl(_ICR(i2c)) & ICR_SCLE);
-}
-
-static void i2c_pxa_abort(struct pxa_i2c *i2c)
-{
- int i = 250;
-
- if (i2c_pxa_is_slavemode(i2c)) {
- dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__);
- return;
- }
-
- while ((i > 0) && (readl(_IBMR(i2c)) & 0x1) == 0) {
- unsigned long icr = readl(_ICR(i2c));
-
- icr &= ~ICR_START;
- icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
-
- writel(icr, _ICR(i2c));
-
- show_state(i2c);
-
- mdelay(1);
- i --;
- }
-
- writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP),
- _ICR(i2c));
-}
-
-static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
-{
- int timeout = DEF_TIMEOUT;
-
- while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
- if ((readl(_ISR(i2c)) & ISR_SAD) != 0)
- timeout += 4;
-
- msleep(2);
- show_state(i2c);
- }
-
- if (timeout < 0)
- show_state(i2c);
-
- return timeout < 0 ? I2C_RETRY : 0;
-}
-
-static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
-{
- unsigned long timeout = jiffies + HZ*4;
-
- while (time_before(jiffies, timeout)) {
- if (i2c_debug > 1)
- dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
- __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
-
- if (readl(_ISR(i2c)) & ISR_SAD) {
- if (i2c_debug > 0)
- dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
- goto out;
- }
-
- /* wait for unit and bus being not busy, and we also do a
- * quick check of the i2c lines themselves to ensure they've
- * gone high...
- */
- if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 && readl(_IBMR(i2c)) == 3) {
- if (i2c_debug > 0)
- dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
- return 1;
- }
-
- msleep(1);
- }
-
- if (i2c_debug > 0)
- dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
- out:
- return 0;
-}
-
-static int i2c_pxa_set_master(struct pxa_i2c *i2c)
-{
- if (i2c_debug)
- dev_dbg(&i2c->adap.dev, "setting to bus master\n");
-
- if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) {
- dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
- if (!i2c_pxa_wait_master(i2c)) {
- dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
- return I2C_RETRY;
- }
- }
-
- writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
- return 0;
-}
-
-#ifdef CONFIG_I2C_PXA_SLAVE
-static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
-{
- unsigned long timeout = jiffies + HZ*1;
-
- /* wait for stop */
-
- show_state(i2c);
-
- while (time_before(jiffies, timeout)) {
- if (i2c_debug > 1)
- dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
- __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
-
- if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 ||
- (readl(_ISR(i2c)) & ISR_SAD) != 0 ||
- (readl(_ICR(i2c)) & ICR_SCLE) == 0) {
- if (i2c_debug > 1)
- dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
- return 1;
- }
-
- msleep(1);
- }
-
- if (i2c_debug > 0)
- dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
- return 0;
-}
-
-/*
- * clear the hold on the bus, and take of anything else
- * that has been configured
- */
-static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
-{
- show_state(i2c);
-
- if (errcode < 0) {
- udelay(100); /* simple delay */
- } else {
- /* we need to wait for the stop condition to end */
-
- /* if we where in stop, then clear... */
- if (readl(_ICR(i2c)) & ICR_STOP) {
- udelay(100);
- writel(readl(_ICR(i2c)) & ~ICR_STOP, _ICR(i2c));
- }
-
- if (!i2c_pxa_wait_slave(i2c)) {
- dev_err(&i2c->adap.dev, "%s: wait timedout\n",
- __func__);
- return;
- }
- }
-
- writel(readl(_ICR(i2c)) & ~(ICR_STOP|ICR_ACKNAK|ICR_MA), _ICR(i2c));
- writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
-
- if (i2c_debug) {
- dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", readl(_ICR(i2c)), readl(_ISR(i2c)));
- decode_ICR(readl(_ICR(i2c)));
- }
-}
-#else
-#define i2c_pxa_set_slave(i2c, err) do { } while (0)
-#endif
-
-static void i2c_pxa_reset(struct pxa_i2c *i2c)
-{
- pr_debug("Resetting I2C Controller Unit\n");
-
- /* abort any transfer currently under way */
- i2c_pxa_abort(i2c);
-
- /* reset according to 9.8 */
- writel(ICR_UR, _ICR(i2c));
- writel(I2C_ISR_INIT, _ISR(i2c));
- writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
-
- if (i2c->reg_isar)
- writel(i2c->slave_addr, _ISAR(i2c));
-
- /* set control register values */
- writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
-
-#ifdef CONFIG_I2C_PXA_SLAVE
- dev_info(&i2c->adap.dev, "Enabling slave mode\n");
- writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c));
-#endif
-
- i2c_pxa_set_slave(i2c, 0);
-
- /* enable unit */
- writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
- udelay(100);
-}
-
-
-#ifdef CONFIG_I2C_PXA_SLAVE
-/*
- * PXA I2C Slave mode
- */
-
-static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
-{
- if (isr & ISR_BED) {
- /* what should we do here? */
- } else {
- int ret = 0;
-
- if (i2c->slave != NULL)
- ret = i2c->slave->read(i2c->slave->data);
-
- writel(ret, _IDBR(i2c));
- writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c)); /* allow next byte */
- }
-}
-
-static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
-{
- unsigned int byte = readl(_IDBR(i2c));
-
- if (i2c->slave != NULL)
- i2c->slave->write(i2c->slave->data, byte);
-
- writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
-}
-
-static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
-{
- int timeout;
-
- if (i2c_debug > 0)
- dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n",
- (isr & ISR_RWM) ? 'r' : 't');
-
- if (i2c->slave != NULL)
- i2c->slave->event(i2c->slave->data,
- (isr & ISR_RWM) ? I2C_SLAVE_EVENT_START_READ : I2C_SLAVE_EVENT_START_WRITE);
-
- /*
- * slave could interrupt in the middle of us generating a
- * start condition... if this happens, we'd better back off
- * and stop holding the poor thing up
- */
- writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
- writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
-
- timeout = 0x10000;
-
- while (1) {
- if ((readl(_IBMR(i2c)) & 2) == 2)
- break;
-
- timeout--;
-
- if (timeout <= 0) {
- dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
- break;
- }
- }
-
- writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
-}
-
-static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
-{
- if (i2c_debug > 2)
- dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n");
-
- if (i2c->slave != NULL)
- i2c->slave->event(i2c->slave->data, I2C_SLAVE_EVENT_STOP);
-
- if (i2c_debug > 2)
- dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n");
-
- /*
- * If we have a master-mode message waiting,
- * kick it off now that the slave has completed.
- */
- if (i2c->msg)
- i2c_pxa_master_complete(i2c, I2C_RETRY);
-}
-#else
-static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
-{
- if (isr & ISR_BED) {
- /* what should we do here? */
- } else {
- writel(0, _IDBR(i2c));
- writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
- }
-}
-
-static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
-{
- writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
-}
-
-static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
-{
- int timeout;
-
- /*
- * slave could interrupt in the middle of us generating a
- * start condition... if this happens, we'd better back off
- * and stop holding the poor thing up
- */
- writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
- writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
-
- timeout = 0x10000;
-
- while (1) {
- if ((readl(_IBMR(i2c)) & 2) == 2)
- break;
-
- timeout--;
-
- if (timeout <= 0) {
- dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
- break;
- }
- }
-
- writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
-}
-
-static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
-{
- if (i2c->msg)
- i2c_pxa_master_complete(i2c, I2C_RETRY);
-}
-#endif
-
-/*
- * PXA I2C Master mode
- */
-
-static inline unsigned int i2c_pxa_addr_byte(struct i2c_msg *msg)
-{
- unsigned int addr = (msg->addr & 0x7f) << 1;
-
- if (msg->flags & I2C_M_RD)
- addr |= 1;
-
- return addr;
-}
-
-static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
-{
- u32 icr;
-
- /*
- * Step 1: target slave address into IDBR
- */
- writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
-
- /*
- * Step 2: initiate the write.
- */
- icr = readl(_ICR(i2c)) & ~(ICR_STOP | ICR_ALDIE);
- writel(icr | ICR_START | ICR_TB, _ICR(i2c));
-}
-
-static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
-{
- u32 icr;
-
- /*
- * Clear the STOP and ACK flags
- */
- icr = readl(_ICR(i2c));
- icr &= ~(ICR_STOP | ICR_ACKNAK);
- writel(icr, _ICR(i2c));
-}
-
-static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
-{
- /* make timeout the same as for interrupt based functions */
- long timeout = 2 * DEF_TIMEOUT;
-
- /*
- * Wait for the bus to become free.
- */
- while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
- udelay(1000);
- show_state(i2c);
- }
-
- if (timeout < 0) {
- show_state(i2c);
- dev_err(&i2c->adap.dev,
- "i2c_pxa: timeout waiting for bus free\n");
- return I2C_RETRY;
- }
-
- /*
- * Set master mode.
- */
- writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
-
- return 0;
-}
-
-static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
- struct i2c_msg *msg, int num)
-{
- unsigned long timeout = 500000; /* 5 seconds */
- int ret = 0;
-
- ret = i2c_pxa_pio_set_master(i2c);
- if (ret)
- goto out;
-
- i2c->msg = msg;
- i2c->msg_num = num;
- i2c->msg_idx = 0;
- i2c->msg_ptr = 0;
- i2c->irqlogidx = 0;
-
- i2c_pxa_start_message(i2c);
-
- while (i2c->msg_num > 0 && --timeout) {
- i2c_pxa_handler(0, i2c);
- udelay(10);
- }
-
- i2c_pxa_stop_message(i2c);
-
- /*
- * We place the return code in i2c->msg_idx.
- */
- ret = i2c->msg_idx;
-
-out:
- if (timeout == 0)
- i2c_pxa_scream_blue_murder(i2c, "timeout");
-
- return ret;
-}
-
-/*
- * We are protected by the adapter bus mutex.
- */
-static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
-{
- long timeout;
- int ret;
-
- /*
- * Wait for the bus to become free.
- */
- ret = i2c_pxa_wait_bus_not_busy(i2c);
- if (ret) {
- dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
- goto out;
- }
-
- /*
- * Set master mode.
- */
- ret = i2c_pxa_set_master(i2c);
- if (ret) {
- dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
- goto out;
- }
-
- spin_lock_irq(&i2c->lock);
-
- i2c->msg = msg;
- i2c->msg_num = num;
- i2c->msg_idx = 0;
- i2c->msg_ptr = 0;
- i2c->irqlogidx = 0;
-
- i2c_pxa_start_message(i2c);
-
- spin_unlock_irq(&i2c->lock);
-
- /*
- * The rest of the processing occurs in the interrupt handler.
- */
- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
- i2c_pxa_stop_message(i2c);
-
- /*
- * We place the return code in i2c->msg_idx.
- */
- ret = i2c->msg_idx;
-
- if (!timeout && i2c->msg_num) {
- i2c_pxa_scream_blue_murder(i2c, "timeout");
- ret = I2C_RETRY;
- }
-
- out:
- return ret;
-}
-
-static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
- struct i2c_msg msgs[], int num)
-{
- struct pxa_i2c *i2c = adap->algo_data;
- int ret, i;
-
- /* If the I2C controller is disabled we need to reset it
- (probably due to a suspend/resume destroying state). We do
- this here as we can then avoid worrying about resuming the
- controller before its users. */
- if (!(readl(_ICR(i2c)) & ICR_IUE))
- i2c_pxa_reset(i2c);
-
- for (i = adap->retries; i >= 0; i--) {
- ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
- if (ret != I2C_RETRY)
- goto out;
-
- if (i2c_debug)
- dev_dbg(&adap->dev, "Retrying transmission\n");
- udelay(100);
- }
- i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
- ret = -EREMOTEIO;
- out:
- i2c_pxa_set_slave(i2c, ret);
- return ret;
-}
-
-/*
- * i2c_pxa_master_complete - complete the message and wake up.
- */
-static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
-{
- i2c->msg_ptr = 0;
- i2c->msg = NULL;
- i2c->msg_idx ++;
- i2c->msg_num = 0;
- if (ret)
- i2c->msg_idx = ret;
- if (!i2c->use_pio)
- wake_up(&i2c->wait);
-}
-
-static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
-{
- u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
-
- again:
- /*
- * If ISR_ALD is set, we lost arbitration.
- */
- if (isr & ISR_ALD) {
- /*
- * Do we need to do anything here? The PXA docs
- * are vague about what happens.
- */
- i2c_pxa_scream_blue_murder(i2c, "ALD set");
-
- /*
- * We ignore this error. We seem to see spurious ALDs
- * for seemingly no reason. If we handle them as I think
- * they should, we end up causing an I2C error, which
- * is painful for some systems.
- */
- return; /* ignore */
- }
-
- if (isr & ISR_BED) {
- int ret = BUS_ERROR;
-
- /*
- * I2C bus error - either the device NAK'd us, or
- * something more serious happened. If we were NAK'd
- * on the initial address phase, we can retry.
- */
- if (isr & ISR_ACKNAK) {
- if (i2c->msg_ptr == 0 && i2c->msg_idx == 0)
- ret = I2C_RETRY;
- else
- ret = XFER_NAKED;
- }
- i2c_pxa_master_complete(i2c, ret);
- } else if (isr & ISR_RWM) {
- /*
- * Read mode. We have just sent the address byte, and
- * now we must initiate the transfer.
- */
- if (i2c->msg_ptr == i2c->msg->len - 1 &&
- i2c->msg_idx == i2c->msg_num - 1)
- icr |= ICR_STOP | ICR_ACKNAK;
-
- icr |= ICR_ALDIE | ICR_TB;
- } else if (i2c->msg_ptr < i2c->msg->len) {
- /*
- * Write mode. Write the next data byte.
- */
- writel(i2c->msg->buf[i2c->msg_ptr++], _IDBR(i2c));
-
- icr |= ICR_ALDIE | ICR_TB;
-
- /*
- * If this is the last byte of the last message, send
- * a STOP.
- */
- if (i2c->msg_ptr == i2c->msg->len &&
- i2c->msg_idx == i2c->msg_num - 1)
- icr |= ICR_STOP;
- } else if (i2c->msg_idx < i2c->msg_num - 1) {
- /*
- * Next segment of the message.
- */
- i2c->msg_ptr = 0;
- i2c->msg_idx ++;
- i2c->msg++;
-
- /*
- * If we aren't doing a repeated start and address,
- * go back and try to send the next byte. Note that
- * we do not support switching the R/W direction here.
- */
- if (i2c->msg->flags & I2C_M_NOSTART)
- goto again;
-
- /*
- * Write the next address.
- */
- writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
-
- /*
- * And trigger a repeated start, and send the byte.
- */
- icr &= ~ICR_ALDIE;
- icr |= ICR_START | ICR_TB;
- } else {
- if (i2c->msg->len == 0) {
- /*
- * Device probes have a message length of zero
- * and need the bus to be reset before it can
- * be used again.
- */
- i2c_pxa_reset(i2c);
- }
- i2c_pxa_master_complete(i2c, 0);
- }
-
- i2c->icrlog[i2c->irqlogidx-1] = icr;
-
- writel(icr, _ICR(i2c));
- show_state(i2c);
-}
-
-static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
-{
- u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
-
- /*
- * Read the byte.
- */
- i2c->msg->buf[i2c->msg_ptr++] = readl(_IDBR(i2c));
-
- if (i2c->msg_ptr < i2c->msg->len) {
- /*
- * If this is the last byte of the last
- * message, send a STOP.
- */
- if (i2c->msg_ptr == i2c->msg->len - 1)
- icr |= ICR_STOP | ICR_ACKNAK;
-
- icr |= ICR_ALDIE | ICR_TB;
- } else {
- i2c_pxa_master_complete(i2c, 0);
- }
-
- i2c->icrlog[i2c->irqlogidx-1] = icr;
-
- writel(icr, _ICR(i2c));
-}
-
-#define VALID_INT_SOURCE (ISR_SSD | ISR_ALD | ISR_ITE | ISR_IRF | \
- ISR_SAD | ISR_BED)
-static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
-{
- struct pxa_i2c *i2c = dev_id;
- u32 isr = readl(_ISR(i2c));
-
- if (!(isr & VALID_INT_SOURCE))
- return IRQ_NONE;
-
- if (i2c_debug > 2 && 0) {
- dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
- __func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
- decode_ISR(isr);
- }
-
- if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog))
- i2c->isrlog[i2c->irqlogidx++] = isr;
-
- show_state(i2c);
-
- /*
- * Always clear all pending IRQs.
- */
- writel(isr & VALID_INT_SOURCE, _ISR(i2c));
-
- if (isr & ISR_SAD)
- i2c_pxa_slave_start(i2c, isr);
- if (isr & ISR_SSD)
- i2c_pxa_slave_stop(i2c);
-
- if (i2c_pxa_is_slavemode(i2c)) {
- if (isr & ISR_ITE)
- i2c_pxa_slave_txempty(i2c, isr);
- if (isr & ISR_IRF)
- i2c_pxa_slave_rxfull(i2c, isr);
- } else if (i2c->msg) {
- if (isr & ISR_ITE)
- i2c_pxa_irq_txempty(i2c, isr);
- if (isr & ISR_IRF)
- i2c_pxa_irq_rxfull(i2c, isr);
- } else {
- i2c_pxa_scream_blue_murder(i2c, "spurious irq");
- }
-
- return IRQ_HANDLED;
-}
-
-
-static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-{
- struct pxa_i2c *i2c = adap->algo_data;
- int ret, i;
-
- for (i = adap->retries; i >= 0; i--) {
- ret = i2c_pxa_do_xfer(i2c, msgs, num);
- if (ret != I2C_RETRY)
- goto out;
-
- if (i2c_debug)
- dev_dbg(&adap->dev, "Retrying transmission\n");
- udelay(100);
- }
- i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
- ret = -EREMOTEIO;
- out:
- i2c_pxa_set_slave(i2c, ret);
- return ret;
-}
-
-static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm i2c_pxa_algorithm = {
- .master_xfer = i2c_pxa_xfer,
- .functionality = i2c_pxa_functionality,
-};
-
-static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
- .master_xfer = i2c_pxa_pio_xfer,
- .functionality = i2c_pxa_functionality,
-};
-
-static struct of_device_id i2c_pxa_dt_ids[] = {
- { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
- { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
- { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
- {}
-};
-MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
-
-static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
- enum pxa_i2c_types *i2c_types)
-{
- struct device_node *np = pdev->dev.of_node;
- const struct of_device_id *of_id =
- of_match_device(i2c_pxa_dt_ids, &pdev->dev);
- int ret;
-
- if (!of_id)
- return 1;
- ret = of_alias_get_id(np, "i2c");
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
- return ret;
- }
- pdev->id = ret;
- if (of_get_property(np, "mrvl,i2c-polling", NULL))
- i2c->use_pio = 1;
- if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
- i2c->fast_mode = 1;
- *i2c_types = (u32)(of_id->data);
- return 0;
-}
-
-static int i2c_pxa_probe_pdata(struct platform_device *pdev,
- struct pxa_i2c *i2c,
- enum pxa_i2c_types *i2c_types)
-{
- struct i2c_pxa_platform_data *plat = pdev->dev.platform_data;
- const struct platform_device_id *id = platform_get_device_id(pdev);
-
- *i2c_types = id->driver_data;
- if (plat) {
- i2c->use_pio = plat->use_pio;
- i2c->fast_mode = plat->fast_mode;
- }
- return 0;
-}
-
-static int i2c_pxa_probe(struct platform_device *dev)
-{
- struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
- enum pxa_i2c_types i2c_type;
- struct pxa_i2c *i2c;
- struct resource *res = NULL;
- int ret, irq;
-
- i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
- if (!i2c) {
- ret = -ENOMEM;
- goto emalloc;
- }
-
- ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
- if (ret > 0)
- ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type);
- if (ret < 0)
- goto eclk;
-
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(dev, 0);
- if (res == NULL || irq < 0) {
- ret = -ENODEV;
- goto eclk;
- }
-
- if (!request_mem_region(res->start, resource_size(res), res->name)) {
- ret = -ENOMEM;
- goto eclk;
- }
-
- i2c->adap.owner = THIS_MODULE;
- i2c->adap.retries = 5;
-
- spin_lock_init(&i2c->lock);
- init_waitqueue_head(&i2c->wait);
-
- /*
- * If "dev->id" is negative we consider it as zero.
- * The reason to do so is to avoid sysfs names that only make
- * sense when there are multiple adapters.
- */
- i2c->adap.nr = dev->id;
- snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u",
- i2c->adap.nr);
-
- i2c->clk = clk_get(&dev->dev, NULL);
- if (IS_ERR(i2c->clk)) {
- ret = PTR_ERR(i2c->clk);
- goto eclk;
- }
-
- i2c->reg_base = ioremap(res->start, resource_size(res));
- if (!i2c->reg_base) {
- ret = -EIO;
- goto eremap;
- }
-
- i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr;
- i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
- i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
- i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
- if (i2c_type != REGS_CE4100)
- i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
-
- i2c->iobase = res->start;
- i2c->iosize = resource_size(res);
-
- i2c->irq = irq;
-
- i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
-
- if (plat) {
-#ifdef CONFIG_I2C_PXA_SLAVE
- i2c->slave_addr = plat->slave_addr;
- i2c->slave = plat->slave;
-#endif
- i2c->adap.class = plat->class;
- }
-
- clk_enable(i2c->clk);
-
- if (i2c->use_pio) {
- i2c->adap.algo = &i2c_pxa_pio_algorithm;
- } else {
- i2c->adap.algo = &i2c_pxa_algorithm;
- ret = request_irq(irq, i2c_pxa_handler, IRQF_SHARED,
- i2c->adap.name, i2c);
- if (ret)
- goto ereqirq;
- }
-
- i2c_pxa_reset(i2c);
-
- i2c->adap.algo_data = i2c;
- i2c->adap.dev.parent = &dev->dev;
-#ifdef CONFIG_OF
- i2c->adap.dev.of_node = dev->dev.of_node;
-#endif
-
- ret = i2c_add_numbered_adapter(&i2c->adap);
- if (ret < 0) {
- printk(KERN_INFO "I2C: Failed to add bus\n");
- goto eadapt;
- }
- of_i2c_register_devices(&i2c->adap);
-
- platform_set_drvdata(dev, i2c);
-
-#ifdef CONFIG_I2C_PXA_SLAVE
- printk(KERN_INFO "I2C: %s: PXA I2C adapter, slave address %d\n",
- dev_name(&i2c->adap.dev), i2c->slave_addr);
-#else
- printk(KERN_INFO "I2C: %s: PXA I2C adapter\n",
- dev_name(&i2c->adap.dev));
-#endif
- return 0;
-
-eadapt:
- if (!i2c->use_pio)
- free_irq(irq, i2c);
-ereqirq:
- clk_disable(i2c->clk);
- iounmap(i2c->reg_base);
-eremap:
- clk_put(i2c->clk);
-eclk:
- kfree(i2c);
-emalloc:
- release_mem_region(res->start, resource_size(res));
- return ret;
-}
-
-static int __exit i2c_pxa_remove(struct platform_device *dev)
-{
- struct pxa_i2c *i2c = platform_get_drvdata(dev);
-
- platform_set_drvdata(dev, NULL);
-
- i2c_del_adapter(&i2c->adap);
- if (!i2c->use_pio)
- free_irq(i2c->irq, i2c);
-
- clk_disable(i2c->clk);
- clk_put(i2c->clk);
-
- iounmap(i2c->reg_base);
- release_mem_region(i2c->iobase, i2c->iosize);
- kfree(i2c);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int i2c_pxa_suspend_noirq(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pxa_i2c *i2c = platform_get_drvdata(pdev);
-
- clk_disable(i2c->clk);
-
- return 0;
-}
-
-static int i2c_pxa_resume_noirq(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pxa_i2c *i2c = platform_get_drvdata(pdev);
-
- clk_enable(i2c->clk);
- i2c_pxa_reset(i2c);
-
- return 0;
-}
-
-static const struct dev_pm_ops i2c_pxa_dev_pm_ops = {
- .suspend_noirq = i2c_pxa_suspend_noirq,
- .resume_noirq = i2c_pxa_resume_noirq,
-};
-
-#define I2C_PXA_DEV_PM_OPS (&i2c_pxa_dev_pm_ops)
-#else
-#define I2C_PXA_DEV_PM_OPS NULL
-#endif
-
-static struct platform_driver i2c_pxa_driver = {
- .probe = i2c_pxa_probe,
- .remove = __exit_p(i2c_pxa_remove),
- .driver = {
- .name = "pxa2xx-i2c",
- .owner = THIS_MODULE,
- .pm = I2C_PXA_DEV_PM_OPS,
- .of_match_table = i2c_pxa_dt_ids,
- },
- .id_table = i2c_pxa_id_table,
-};
-
-static int __init i2c_adap_pxa_init(void)
-{
- return platform_driver_register(&i2c_pxa_driver);
-}
-
-static void __exit i2c_adap_pxa_exit(void)
-{
- platform_driver_unregister(&i2c_pxa_driver);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pxa2xx-i2c");
-
-subsys_initcall(i2c_adap_pxa_init);
-module_exit(i2c_adap_pxa_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-s3c2410.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-s3c2410.c
deleted file mode 100644
index 737f7218..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-s3c2410.c
+++ /dev/null
@@ -1,1161 +0,0 @@
-/* linux/drivers/i2c/busses/i2c-s3c2410.c
- *
- * Copyright (C) 2004,2005,2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 I2C Controller
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/of_i2c.h>
-#include <linux/of_gpio.h>
-
-#include <asm/irq.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-
-/* i2c controller state */
-
-enum s3c24xx_i2c_state {
- STATE_IDLE,
- STATE_START,
- STATE_READ,
- STATE_WRITE,
- STATE_STOP
-};
-
-enum s3c24xx_i2c_type {
- TYPE_S3C2410,
- TYPE_S3C2440,
-};
-
-struct s3c24xx_i2c {
- spinlock_t lock;
- wait_queue_head_t wait;
- unsigned int suspended:1;
-
- struct i2c_msg *msg;
- unsigned int msg_num;
- unsigned int msg_idx;
- unsigned int msg_ptr;
-
- unsigned int tx_setup;
- unsigned int irq;
-
- enum s3c24xx_i2c_state state;
- unsigned long clkrate;
-
- void __iomem *regs;
- struct clk *clk;
- struct device *dev;
- struct resource *ioarea;
- struct i2c_adapter adap;
-
- struct s3c2410_platform_i2c *pdata;
- int gpios[2];
-#ifdef CONFIG_CPU_FREQ
- struct notifier_block freq_transition;
-#endif
-};
-
-/* default platform data removed, dev should always carry data. */
-
-/* s3c24xx_i2c_is2440()
- *
- * return true is this is an s3c2440
-*/
-
-static inline int s3c24xx_i2c_is2440(struct s3c24xx_i2c *i2c)
-{
- struct platform_device *pdev = to_platform_device(i2c->dev);
- enum s3c24xx_i2c_type type;
-
-#ifdef CONFIG_OF
- if (i2c->dev->of_node)
- return of_device_is_compatible(i2c->dev->of_node,
- "samsung,s3c2440-i2c");
-#endif
-
- type = platform_get_device_id(pdev)->driver_data;
- return type == TYPE_S3C2440;
-}
-
-/* s3c24xx_i2c_master_complete
- *
- * complete the message and wake up the caller, using the given return code,
- * or zero to mean ok.
-*/
-
-static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
-{
- dev_dbg(i2c->dev, "master_complete %d\n", ret);
-
- i2c->msg_ptr = 0;
- i2c->msg = NULL;
- i2c->msg_idx++;
- i2c->msg_num = 0;
- if (ret)
- i2c->msg_idx = ret;
-
- wake_up(&i2c->wait);
-}
-
-static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
-{
- unsigned long tmp;
-
- tmp = readl(i2c->regs + S3C2410_IICCON);
- writel(tmp & ~S3C2410_IICCON_ACKEN, i2c->regs + S3C2410_IICCON);
-}
-
-static inline void s3c24xx_i2c_enable_ack(struct s3c24xx_i2c *i2c)
-{
- unsigned long tmp;
-
- tmp = readl(i2c->regs + S3C2410_IICCON);
- writel(tmp | S3C2410_IICCON_ACKEN, i2c->regs + S3C2410_IICCON);
-}
-
-/* irq enable/disable functions */
-
-static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
-{
- unsigned long tmp;
-
- tmp = readl(i2c->regs + S3C2410_IICCON);
- writel(tmp & ~S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
-}
-
-static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
-{
- unsigned long tmp;
-
- tmp = readl(i2c->regs + S3C2410_IICCON);
- writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
-}
-
-
-/* s3c24xx_i2c_message_start
- *
- * put the start of a message onto the bus
-*/
-
-static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
- struct i2c_msg *msg)
-{
- unsigned int addr = (msg->addr & 0x7f) << 1;
- unsigned long stat;
- unsigned long iiccon;
-
- stat = 0;
- stat |= S3C2410_IICSTAT_TXRXEN;
-
- if (msg->flags & I2C_M_RD) {
- stat |= S3C2410_IICSTAT_MASTER_RX;
- addr |= 1;
- } else
- stat |= S3C2410_IICSTAT_MASTER_TX;
-
- if (msg->flags & I2C_M_REV_DIR_ADDR)
- addr ^= 1;
-
- /* todo - check for wether ack wanted or not */
- s3c24xx_i2c_enable_ack(i2c);
-
- iiccon = readl(i2c->regs + S3C2410_IICCON);
- writel(stat, i2c->regs + S3C2410_IICSTAT);
-
- dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
- writeb(addr, i2c->regs + S3C2410_IICDS);
-
- /* delay here to ensure the data byte has gotten onto the bus
- * before the transaction is started */
-
- ndelay(i2c->tx_setup);
-
- dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
- writel(iiccon, i2c->regs + S3C2410_IICCON);
-
- stat |= S3C2410_IICSTAT_START;
- writel(stat, i2c->regs + S3C2410_IICSTAT);
-}
-
-static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
-{
- unsigned long iicstat = readl(i2c->regs + S3C2410_IICSTAT);
-
- dev_dbg(i2c->dev, "STOP\n");
-
- /* stop the transfer */
- iicstat &= ~S3C2410_IICSTAT_START;
- writel(iicstat, i2c->regs + S3C2410_IICSTAT);
-
- i2c->state = STATE_STOP;
-
- s3c24xx_i2c_master_complete(i2c, ret);
- s3c24xx_i2c_disable_irq(i2c);
-}
-
-/* helper functions to determine the current state in the set of
- * messages we are sending */
-
-/* is_lastmsg()
- *
- * returns TRUE if the current message is the last in the set
-*/
-
-static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
-{
- return i2c->msg_idx >= (i2c->msg_num - 1);
-}
-
-/* is_msglast
- *
- * returns TRUE if we this is the last byte in the current message
-*/
-
-static inline int is_msglast(struct s3c24xx_i2c *i2c)
-{
- return i2c->msg_ptr == i2c->msg->len-1;
-}
-
-/* is_msgend
- *
- * returns TRUE if we reached the end of the current message
-*/
-
-static inline int is_msgend(struct s3c24xx_i2c *i2c)
-{
- return i2c->msg_ptr >= i2c->msg->len;
-}
-
-/* i2c_s3c_irq_nextbyte
- *
- * process an interrupt and work out what to do
- */
-
-static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
-{
- unsigned long tmp;
- unsigned char byte;
- int ret = 0;
-
- switch (i2c->state) {
-
- case STATE_IDLE:
- dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
- goto out;
-
- case STATE_STOP:
- dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
- s3c24xx_i2c_disable_irq(i2c);
- goto out_ack;
-
- case STATE_START:
- /* last thing we did was send a start condition on the
- * bus, or started a new i2c message
- */
-
- if (iicstat & S3C2410_IICSTAT_LASTBIT &&
- !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
- /* ack was not received... */
-
- dev_dbg(i2c->dev, "ack was not received\n");
- s3c24xx_i2c_stop(i2c, -ENXIO);
- goto out_ack;
- }
-
- if (i2c->msg->flags & I2C_M_RD)
- i2c->state = STATE_READ;
- else
- i2c->state = STATE_WRITE;
-
- /* terminate the transfer if there is nothing to do
- * as this is used by the i2c probe to find devices. */
-
- if (is_lastmsg(i2c) && i2c->msg->len == 0) {
- s3c24xx_i2c_stop(i2c, 0);
- goto out_ack;
- }
-
- if (i2c->state == STATE_READ)
- goto prepare_read;
-
- /* fall through to the write state, as we will need to
- * send a byte as well */
-
- case STATE_WRITE:
- /* we are writing data to the device... check for the
- * end of the message, and if so, work out what to do
- */
-
- if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
- if (iicstat & S3C2410_IICSTAT_LASTBIT) {
- dev_dbg(i2c->dev, "WRITE: No Ack\n");
-
- s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
- goto out_ack;
- }
- }
-
- retry_write:
-
- if (!is_msgend(i2c)) {
- byte = i2c->msg->buf[i2c->msg_ptr++];
- writeb(byte, i2c->regs + S3C2410_IICDS);
-
- /* delay after writing the byte to allow the
- * data setup time on the bus, as writing the
- * data to the register causes the first bit
- * to appear on SDA, and SCL will change as
- * soon as the interrupt is acknowledged */
-
- ndelay(i2c->tx_setup);
-
- } else if (!is_lastmsg(i2c)) {
- /* we need to go to the next i2c message */
-
- dev_dbg(i2c->dev, "WRITE: Next Message\n");
-
- i2c->msg_ptr = 0;
- i2c->msg_idx++;
- i2c->msg++;
-
- /* check to see if we need to do another message */
- if (i2c->msg->flags & I2C_M_NOSTART) {
-
- if (i2c->msg->flags & I2C_M_RD) {
- /* cannot do this, the controller
- * forces us to send a new START
- * when we change direction */
-
- s3c24xx_i2c_stop(i2c, -EINVAL);
- }
-
- goto retry_write;
- } else {
- /* send the new start */
- s3c24xx_i2c_message_start(i2c, i2c->msg);
- i2c->state = STATE_START;
- }
-
- } else {
- /* send stop */
-
- s3c24xx_i2c_stop(i2c, 0);
- }
- break;
-
- case STATE_READ:
- /* we have a byte of data in the data register, do
- * something with it, and then work out wether we are
- * going to do any more read/write
- */
-
- byte = readb(i2c->regs + S3C2410_IICDS);
- i2c->msg->buf[i2c->msg_ptr++] = byte;
-
- prepare_read:
- if (is_msglast(i2c)) {
- /* last byte of buffer */
-
- if (is_lastmsg(i2c))
- s3c24xx_i2c_disable_ack(i2c);
-
- } else if (is_msgend(i2c)) {
- /* ok, we've read the entire buffer, see if there
- * is anything else we need to do */
-
- if (is_lastmsg(i2c)) {
- /* last message, send stop and complete */
- dev_dbg(i2c->dev, "READ: Send Stop\n");
-
- s3c24xx_i2c_stop(i2c, 0);
- } else {
- /* go to the next transfer */
- dev_dbg(i2c->dev, "READ: Next Transfer\n");
-
- i2c->msg_ptr = 0;
- i2c->msg_idx++;
- i2c->msg++;
- }
- }
-
- break;
- }
-
- /* acknowlegde the IRQ and get back on with the work */
-
- out_ack:
- tmp = readl(i2c->regs + S3C2410_IICCON);
- tmp &= ~S3C2410_IICCON_IRQPEND;
- writel(tmp, i2c->regs + S3C2410_IICCON);
- out:
- return ret;
-}
-
-/* s3c24xx_i2c_irq
- *
- * top level IRQ servicing routine
-*/
-
-static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
-{
- struct s3c24xx_i2c *i2c = dev_id;
- unsigned long status;
- unsigned long tmp;
-
- status = readl(i2c->regs + S3C2410_IICSTAT);
-
- if (status & S3C2410_IICSTAT_ARBITR) {
- /* deal with arbitration loss */
- dev_err(i2c->dev, "deal with arbitration loss\n");
- }
-
- if (i2c->state == STATE_IDLE) {
- dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
-
- tmp = readl(i2c->regs + S3C2410_IICCON);
- tmp &= ~S3C2410_IICCON_IRQPEND;
- writel(tmp, i2c->regs + S3C2410_IICCON);
- goto out;
- }
-
- /* pretty much this leaves us with the fact that we've
- * transmitted or received whatever byte we last sent */
-
- i2c_s3c_irq_nextbyte(i2c, status);
-
- out:
- return IRQ_HANDLED;
-}
-
-
-/* s3c24xx_i2c_set_master
- *
- * get the i2c bus for a master transaction
-*/
-
-static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
-{
- unsigned long iicstat;
- int timeout = 400;
-
- while (timeout-- > 0) {
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
-
- if (!(iicstat & S3C2410_IICSTAT_BUSBUSY))
- return 0;
-
- msleep(1);
- }
-
- return -ETIMEDOUT;
-}
-
-/* s3c24xx_i2c_doxfer
- *
- * this starts an i2c transfer
-*/
-
-static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
- struct i2c_msg *msgs, int num)
-{
- unsigned long iicstat, timeout;
- int spins = 20;
- int ret;
-
- if (i2c->suspended)
- return -EIO;
-
- ret = s3c24xx_i2c_set_master(i2c);
- if (ret != 0) {
- dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
- ret = -EAGAIN;
- goto out;
- }
-
- spin_lock_irq(&i2c->lock);
-
- i2c->msg = msgs;
- i2c->msg_num = num;
- i2c->msg_ptr = 0;
- i2c->msg_idx = 0;
- i2c->state = STATE_START;
-
- s3c24xx_i2c_enable_irq(i2c);
- s3c24xx_i2c_message_start(i2c, msgs);
- spin_unlock_irq(&i2c->lock);
-
- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
-
- ret = i2c->msg_idx;
-
- /* having these next two as dev_err() makes life very
- * noisy when doing an i2cdetect */
-
- if (timeout == 0)
- dev_dbg(i2c->dev, "timeout\n");
- else if (ret != num)
- dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
-
- /* ensure the stop has been through the bus */
-
- dev_dbg(i2c->dev, "waiting for bus idle\n");
-
- /* first, try busy waiting briefly */
- do {
- cpu_relax();
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
- } while ((iicstat & S3C2410_IICSTAT_START) && --spins);
-
- /* if that timed out sleep */
- if (!spins) {
- msleep(1);
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
- }
-
- if (iicstat & S3C2410_IICSTAT_START)
- dev_warn(i2c->dev, "timeout waiting for bus idle\n");
-
- out:
- return ret;
-}
-
-/* s3c24xx_i2c_xfer
- *
- * first port of call from the i2c bus code when an message needs
- * transferring across the i2c bus.
-*/
-
-static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
-{
- struct s3c24xx_i2c *i2c = (struct s3c24xx_i2c *)adap->algo_data;
- int retry;
- int ret;
-
- pm_runtime_get_sync(&adap->dev);
- clk_enable(i2c->clk);
-
- for (retry = 0; retry < adap->retries; retry++) {
-
- ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
-
- if (ret != -EAGAIN) {
- clk_disable(i2c->clk);
- pm_runtime_put_sync(&adap->dev);
- return ret;
- }
-
- dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
-
- udelay(100);
- }
-
- clk_disable(i2c->clk);
- pm_runtime_put_sync(&adap->dev);
- return -EREMOTEIO;
-}
-
-/* declare our i2c functionality */
-static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
-}
-
-/* i2c bus registration info */
-
-static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
- .master_xfer = s3c24xx_i2c_xfer,
- .functionality = s3c24xx_i2c_func,
-};
-
-/* s3c24xx_i2c_calcdivisor
- *
- * return the divisor settings for a given frequency
-*/
-
-static int s3c24xx_i2c_calcdivisor(unsigned long clkin, unsigned int wanted,
- unsigned int *div1, unsigned int *divs)
-{
- unsigned int calc_divs = clkin / wanted;
- unsigned int calc_div1;
-
- if (calc_divs > (16*16))
- calc_div1 = 512;
- else
- calc_div1 = 16;
-
- calc_divs += calc_div1-1;
- calc_divs /= calc_div1;
-
- if (calc_divs == 0)
- calc_divs = 1;
- if (calc_divs > 17)
- calc_divs = 17;
-
- *divs = calc_divs;
- *div1 = calc_div1;
-
- return clkin / (calc_divs * calc_div1);
-}
-
-/* s3c24xx_i2c_clockrate
- *
- * work out a divisor for the user requested frequency setting,
- * either by the requested frequency, or scanning the acceptable
- * range of frequencies until something is found
-*/
-
-static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
-{
- struct s3c2410_platform_i2c *pdata = i2c->pdata;
- unsigned long clkin = clk_get_rate(i2c->clk);
- unsigned int divs, div1;
- unsigned long target_frequency;
- u32 iiccon;
- int freq;
-
- i2c->clkrate = clkin;
- clkin /= 1000; /* clkin now in KHz */
-
- dev_dbg(i2c->dev, "pdata desired frequency %lu\n", pdata->frequency);
-
- target_frequency = pdata->frequency ? pdata->frequency : 100000;
-
- target_frequency /= 1000; /* Target frequency now in KHz */
-
- freq = s3c24xx_i2c_calcdivisor(clkin, target_frequency, &div1, &divs);
-
- if (freq > target_frequency) {
- dev_err(i2c->dev,
- "Unable to achieve desired frequency %luKHz." \
- " Lowest achievable %dKHz\n", target_frequency, freq);
- return -EINVAL;
- }
-
- *got = freq;
-
- iiccon = readl(i2c->regs + S3C2410_IICCON);
- iiccon &= ~(S3C2410_IICCON_SCALEMASK | S3C2410_IICCON_TXDIV_512);
- iiccon |= (divs-1);
-
- if (div1 == 512)
- iiccon |= S3C2410_IICCON_TXDIV_512;
-
- writel(iiccon, i2c->regs + S3C2410_IICCON);
-
- if (s3c24xx_i2c_is2440(i2c)) {
- unsigned long sda_delay;
-
- if (pdata->sda_delay) {
- sda_delay = clkin * pdata->sda_delay;
- sda_delay = DIV_ROUND_UP(sda_delay, 1000000);
- sda_delay = DIV_ROUND_UP(sda_delay, 5);
- if (sda_delay > 3)
- sda_delay = 3;
- sda_delay |= S3C2410_IICLC_FILTER_ON;
- } else
- sda_delay = 0;
-
- dev_dbg(i2c->dev, "IICLC=%08lx\n", sda_delay);
- writel(sda_delay, i2c->regs + S3C2440_IICLC);
- }
-
- return 0;
-}
-
-#ifdef CONFIG_CPU_FREQ
-
-#define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition)
-
-static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
- unsigned long val, void *data)
-{
- struct s3c24xx_i2c *i2c = freq_to_i2c(nb);
- unsigned long flags;
- unsigned int got;
- int delta_f;
- int ret;
-
- delta_f = clk_get_rate(i2c->clk) - i2c->clkrate;
-
- /* if we're post-change and the input clock has slowed down
- * or at pre-change and the clock is about to speed up, then
- * adjust our clock rate. <0 is slow, >0 speedup.
- */
-
- if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
- (val == CPUFREQ_PRECHANGE && delta_f > 0)) {
- spin_lock_irqsave(&i2c->lock, flags);
- ret = s3c24xx_i2c_clockrate(i2c, &got);
- spin_unlock_irqrestore(&i2c->lock, flags);
-
- if (ret < 0)
- dev_err(i2c->dev, "cannot find frequency\n");
- else
- dev_info(i2c->dev, "setting freq %d\n", got);
- }
-
- return 0;
-}
-
-static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
-{
- i2c->freq_transition.notifier_call = s3c24xx_i2c_cpufreq_transition;
-
- return cpufreq_register_notifier(&i2c->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
-{
- cpufreq_unregister_notifier(&i2c->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-#else
-static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
-{
- return 0;
-}
-
-static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
-{
-}
-#endif
-
-#ifdef CONFIG_OF
-static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
-{
- int idx, gpio, ret;
-
- for (idx = 0; idx < 2; idx++) {
- gpio = of_get_gpio(i2c->dev->of_node, idx);
- if (!gpio_is_valid(gpio)) {
- dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);
- goto free_gpio;
- }
-
- ret = gpio_request(gpio, "i2c-bus");
- if (ret) {
- dev_err(i2c->dev, "gpio [%d] request failed\n", gpio);
- goto free_gpio;
- }
- }
- return 0;
-
-free_gpio:
- while (--idx >= 0)
- gpio_free(i2c->gpios[idx]);
- return -EINVAL;
-}
-
-static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c)
-{
- unsigned int idx;
- for (idx = 0; idx < 2; idx++)
- gpio_free(i2c->gpios[idx]);
-}
-#else
-static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
-{
- return 0;
-}
-
-static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c)
-{
-}
-#endif
-
-/* s3c24xx_i2c_init
- *
- * initialise the controller, set the IO lines and frequency
-*/
-
-static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
-{
- unsigned long iicon = S3C2410_IICCON_IRQEN | S3C2410_IICCON_ACKEN;
- struct s3c2410_platform_i2c *pdata;
- unsigned int freq;
-
- /* get the plafrom data */
-
- pdata = i2c->pdata;
-
- /* inititalise the gpio */
-
- if (pdata->cfg_gpio)
- pdata->cfg_gpio(to_platform_device(i2c->dev));
- else
- if (s3c24xx_i2c_parse_dt_gpio(i2c))
- return -EINVAL;
-
- /* write slave address */
-
- writeb(pdata->slave_addr, i2c->regs + S3C2410_IICADD);
-
- dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
-
- writel(iicon, i2c->regs + S3C2410_IICCON);
-
- /* we need to work out the divisors for the clock... */
-
- if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) {
- writel(0, i2c->regs + S3C2410_IICCON);
- dev_err(i2c->dev, "cannot meet bus frequency required\n");
- return -EINVAL;
- }
-
- /* todo - check that the i2c lines aren't being dragged anywhere */
-
- dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
- dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
-
- return 0;
-}
-
-#ifdef CONFIG_OF
-/* s3c24xx_i2c_parse_dt
- *
- * Parse the device tree node and retreive the platform data.
-*/
-
-static void
-s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c)
-{
- struct s3c2410_platform_i2c *pdata = i2c->pdata;
-
- if (!np)
- return;
-
- pdata->bus_num = -1; /* i2c bus number is dynamically assigned */
- of_property_read_u32(np, "samsung,i2c-sda-delay", &pdata->sda_delay);
- of_property_read_u32(np, "samsung,i2c-slave-addr", &pdata->slave_addr);
- of_property_read_u32(np, "samsung,i2c-max-bus-freq",
- (u32 *)&pdata->frequency);
-}
-#else
-static void
-s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c)
-{
- return;
-}
-#endif
-
-/* s3c24xx_i2c_probe
- *
- * called by the bus driver when a suitable device is found
-*/
-
-static int s3c24xx_i2c_probe(struct platform_device *pdev)
-{
- struct s3c24xx_i2c *i2c;
- struct s3c2410_platform_i2c *pdata = NULL;
- struct resource *res;
- int ret;
-
- if (!pdev->dev.of_node) {
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
- }
-
- i2c = devm_kzalloc(&pdev->dev, sizeof(struct s3c24xx_i2c), GFP_KERNEL);
- if (!i2c) {
- dev_err(&pdev->dev, "no memory for state\n");
- return -ENOMEM;
- }
-
- i2c->pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!i2c->pdata) {
- ret = -ENOMEM;
- goto err_noclk;
- }
-
- if (pdata)
- memcpy(i2c->pdata, pdata, sizeof(*pdata));
- else
- s3c24xx_i2c_parse_dt(pdev->dev.of_node, i2c);
-
- strlcpy(i2c->adap.name, "s3c2410-i2c", sizeof(i2c->adap.name));
- i2c->adap.owner = THIS_MODULE;
- i2c->adap.algo = &s3c24xx_i2c_algorithm;
- i2c->adap.retries = 2;
- i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- i2c->tx_setup = 50;
-
- spin_lock_init(&i2c->lock);
- init_waitqueue_head(&i2c->wait);
-
- /* find the clock and enable it */
-
- i2c->dev = &pdev->dev;
- i2c->clk = clk_get(&pdev->dev, "i2c");
- if (IS_ERR(i2c->clk)) {
- dev_err(&pdev->dev, "cannot get clock\n");
- ret = -ENOENT;
- goto err_noclk;
- }
-
- dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
-
- clk_enable(i2c->clk);
-
- /* map the registers */
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "cannot find IO resource\n");
- ret = -ENOENT;
- goto err_clk;
- }
-
- i2c->ioarea = request_mem_region(res->start, resource_size(res),
- pdev->name);
-
- if (i2c->ioarea == NULL) {
- dev_err(&pdev->dev, "cannot request IO\n");
- ret = -ENXIO;
- goto err_clk;
- }
-
- i2c->regs = ioremap(res->start, resource_size(res));
-
- if (i2c->regs == NULL) {
- dev_err(&pdev->dev, "cannot map IO\n");
- ret = -ENXIO;
- goto err_ioarea;
- }
-
- dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
- i2c->regs, i2c->ioarea, res);
-
- /* setup info block for the i2c core */
-
- i2c->adap.algo_data = i2c;
- i2c->adap.dev.parent = &pdev->dev;
-
- /* initialise the i2c controller */
-
- ret = s3c24xx_i2c_init(i2c);
- if (ret != 0)
- goto err_iomap;
-
- /* find the IRQ for this unit (note, this relies on the init call to
- * ensure no current IRQs pending
- */
-
- i2c->irq = ret = platform_get_irq(pdev, 0);
- if (ret <= 0) {
- dev_err(&pdev->dev, "cannot find IRQ\n");
- goto err_iomap;
- }
-
- ret = request_irq(i2c->irq, s3c24xx_i2c_irq, 0,
- dev_name(&pdev->dev), i2c);
-
- if (ret != 0) {
- dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
- goto err_iomap;
- }
-
- ret = s3c24xx_i2c_register_cpufreq(i2c);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
- goto err_irq;
- }
-
- /* Note, previous versions of the driver used i2c_add_adapter()
- * to add the bus at any number. We now pass the bus number via
- * the platform data, so if unset it will now default to always
- * being bus 0.
- */
-
- i2c->adap.nr = i2c->pdata->bus_num;
- i2c->adap.dev.of_node = pdev->dev.of_node;
-
- ret = i2c_add_numbered_adapter(&i2c->adap);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to add bus to i2c core\n");
- goto err_cpufreq;
- }
-
- of_i2c_register_devices(&i2c->adap);
- platform_set_drvdata(pdev, i2c);
-
- pm_runtime_enable(&pdev->dev);
- pm_runtime_enable(&i2c->adap.dev);
-
- dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
- clk_disable(i2c->clk);
- return 0;
-
- err_cpufreq:
- s3c24xx_i2c_deregister_cpufreq(i2c);
-
- err_irq:
- free_irq(i2c->irq, i2c);
-
- err_iomap:
- iounmap(i2c->regs);
-
- err_ioarea:
- release_resource(i2c->ioarea);
- kfree(i2c->ioarea);
-
- err_clk:
- clk_disable(i2c->clk);
- clk_put(i2c->clk);
-
- err_noclk:
- return ret;
-}
-
-/* s3c24xx_i2c_remove
- *
- * called when device is removed from the bus
-*/
-
-static int s3c24xx_i2c_remove(struct platform_device *pdev)
-{
- struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
-
- pm_runtime_disable(&i2c->adap.dev);
- pm_runtime_disable(&pdev->dev);
-
- s3c24xx_i2c_deregister_cpufreq(i2c);
-
- i2c_del_adapter(&i2c->adap);
- free_irq(i2c->irq, i2c);
-
- clk_disable(i2c->clk);
- clk_put(i2c->clk);
-
- iounmap(i2c->regs);
-
- release_resource(i2c->ioarea);
- s3c24xx_i2c_dt_gpio_free(i2c);
- kfree(i2c->ioarea);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int s3c24xx_i2c_suspend_noirq(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
-
- i2c->suspended = 1;
-
- return 0;
-}
-
-static int s3c24xx_i2c_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
-
- i2c->suspended = 0;
- clk_enable(i2c->clk);
- s3c24xx_i2c_init(i2c);
- clk_disable(i2c->clk);
-
- return 0;
-}
-
-static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = {
- .suspend_noirq = s3c24xx_i2c_suspend_noirq,
- .resume = s3c24xx_i2c_resume,
-};
-
-#define S3C24XX_DEV_PM_OPS (&s3c24xx_i2c_dev_pm_ops)
-#else
-#define S3C24XX_DEV_PM_OPS NULL
-#endif
-
-/* device driver for platform bus bits */
-
-static struct platform_device_id s3c24xx_driver_ids[] = {
- {
- .name = "s3c2410-i2c",
- .driver_data = TYPE_S3C2410,
- }, {
- .name = "s3c2440-i2c",
- .driver_data = TYPE_S3C2440,
- }, { },
-};
-MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
-
-#ifdef CONFIG_OF
-static const struct of_device_id s3c24xx_i2c_match[] = {
- { .compatible = "samsung,s3c2410-i2c" },
- { .compatible = "samsung,s3c2440-i2c" },
- {},
-};
-MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
-#else
-#define s3c24xx_i2c_match NULL
-#endif
-
-static struct platform_driver s3c24xx_i2c_driver = {
- .probe = s3c24xx_i2c_probe,
- .remove = s3c24xx_i2c_remove,
- .id_table = s3c24xx_driver_ids,
- .driver = {
- .owner = THIS_MODULE,
- .name = "s3c-i2c",
- .pm = S3C24XX_DEV_PM_OPS,
- .of_match_table = s3c24xx_i2c_match,
- },
-};
-
-static int __init i2c_adap_s3c_init(void)
-{
- return platform_driver_register(&s3c24xx_i2c_driver);
-}
-subsys_initcall(i2c_adap_s3c_init);
-
-static void __exit i2c_adap_s3c_exit(void)
-{
- platform_driver_unregister(&s3c24xx_i2c_driver);
-}
-module_exit(i2c_adap_s3c_exit);
-
-MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.c
deleted file mode 100644
index c64ba736..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * drivers/i2c/busses/i2c-s6000.c
- *
- * Description: Driver for S6000 Family I2C Interface
- * Copyright (c) 2008 emlix GmbH
- * Author: Oskar Schirmer <os@emlix.com>
- *
- * Partially based on i2c-bfin-twi.c driver by <sonic.zhang@analog.com>
- * Copyright (c) 2005-2007 Analog Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/i2c/s6000.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include "i2c-s6000.h"
-
-#define DRV_NAME "i2c-s6000"
-
-#define POLL_TIMEOUT (2 * HZ)
-
-struct s6i2c_if {
- u8 __iomem *reg; /* memory mapped registers */
- int irq;
- spinlock_t lock;
- struct i2c_msg *msgs; /* messages currently handled */
- int msgs_num; /* nb of msgs to do */
- int msgs_push; /* nb of msgs read/written */
- int msgs_done; /* nb of msgs finally handled */
- unsigned push; /* nb of bytes read/written in msg */
- unsigned done; /* nb of bytes finally handled */
- int timeout_count; /* timeout retries left */
- struct timer_list timeout_timer;
- struct i2c_adapter adap;
- struct completion complete;
- struct clk *clk;
- struct resource *res;
-};
-
-static inline u16 i2c_rd16(struct s6i2c_if *iface, unsigned n)
-{
- return readw(iface->reg + (n));
-}
-
-static inline void i2c_wr16(struct s6i2c_if *iface, unsigned n, u16 v)
-{
- writew(v, iface->reg + (n));
-}
-
-static inline u32 i2c_rd32(struct s6i2c_if *iface, unsigned n)
-{
- return readl(iface->reg + (n));
-}
-
-static inline void i2c_wr32(struct s6i2c_if *iface, unsigned n, u32 v)
-{
- writel(v, iface->reg + (n));
-}
-
-static struct s6i2c_if s6i2c_if;
-
-static void s6i2c_handle_interrupt(struct s6i2c_if *iface)
-{
- if (i2c_rd16(iface, S6_I2C_INTRSTAT) & (1 << S6_I2C_INTR_TXABRT)) {
- i2c_rd16(iface, S6_I2C_CLRTXABRT);
- i2c_wr16(iface, S6_I2C_INTRMASK, 0);
- complete(&iface->complete);
- return;
- }
- if (iface->msgs_done >= iface->msgs_num) {
- dev_err(&iface->adap.dev, "s6i2c: spurious I2C irq: %04x\n",
- i2c_rd16(iface, S6_I2C_INTRSTAT));
- i2c_wr16(iface, S6_I2C_INTRMASK, 0);
- return;
- }
- while ((iface->msgs_push < iface->msgs_num)
- && (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_TFNF))) {
- struct i2c_msg *m = &iface->msgs[iface->msgs_push];
- if (!(m->flags & I2C_M_RD))
- i2c_wr16(iface, S6_I2C_DATACMD, m->buf[iface->push]);
- else
- i2c_wr16(iface, S6_I2C_DATACMD,
- 1 << S6_I2C_DATACMD_READ);
- if (++iface->push >= m->len) {
- iface->push = 0;
- iface->msgs_push += 1;
- }
- }
- do {
- struct i2c_msg *m = &iface->msgs[iface->msgs_done];
- if (!(m->flags & I2C_M_RD)) {
- if (iface->msgs_done < iface->msgs_push)
- iface->msgs_done += 1;
- else
- break;
- } else if (i2c_rd16(iface, S6_I2C_STATUS)
- & (1 << S6_I2C_STATUS_RFNE)) {
- m->buf[iface->done] = i2c_rd16(iface, S6_I2C_DATACMD);
- if (++iface->done >= m->len) {
- iface->done = 0;
- iface->msgs_done += 1;
- }
- } else{
- break;
- }
- } while (iface->msgs_done < iface->msgs_num);
- if (iface->msgs_done >= iface->msgs_num) {
- i2c_wr16(iface, S6_I2C_INTRMASK, 1 << S6_I2C_INTR_TXABRT);
- complete(&iface->complete);
- } else if (iface->msgs_push >= iface->msgs_num) {
- i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXABRT) |
- (1 << S6_I2C_INTR_RXFULL));
- } else {
- i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXABRT) |
- (1 << S6_I2C_INTR_TXEMPTY) |
- (1 << S6_I2C_INTR_RXFULL));
- }
-}
-
-static irqreturn_t s6i2c_interrupt_entry(int irq, void *dev_id)
-{
- struct s6i2c_if *iface = dev_id;
- if (!(i2c_rd16(iface, S6_I2C_STATUS) & ((1 << S6_I2C_INTR_RXUNDER)
- | (1 << S6_I2C_INTR_RXOVER)
- | (1 << S6_I2C_INTR_RXFULL)
- | (1 << S6_I2C_INTR_TXOVER)
- | (1 << S6_I2C_INTR_TXEMPTY)
- | (1 << S6_I2C_INTR_RDREQ)
- | (1 << S6_I2C_INTR_TXABRT)
- | (1 << S6_I2C_INTR_RXDONE)
- | (1 << S6_I2C_INTR_ACTIVITY)
- | (1 << S6_I2C_INTR_STOPDET)
- | (1 << S6_I2C_INTR_STARTDET)
- | (1 << S6_I2C_INTR_GENCALL))))
- return IRQ_NONE;
-
- spin_lock(&iface->lock);
- del_timer(&iface->timeout_timer);
- s6i2c_handle_interrupt(iface);
- spin_unlock(&iface->lock);
- return IRQ_HANDLED;
-}
-
-static void s6i2c_timeout(unsigned long data)
-{
- struct s6i2c_if *iface = (struct s6i2c_if *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&iface->lock, flags);
- s6i2c_handle_interrupt(iface);
- if (--iface->timeout_count > 0) {
- iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
- add_timer(&iface->timeout_timer);
- } else {
- complete(&iface->complete);
- i2c_wr16(iface, S6_I2C_INTRMASK, 0);
- }
- spin_unlock_irqrestore(&iface->lock, flags);
-}
-
-static int s6i2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
-{
- struct s6i2c_if *iface = adap->algo_data;
- int i;
- if (num == 0)
- return 0;
- if (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_ACTIVITY))
- yield();
- i2c_wr16(iface, S6_I2C_INTRMASK, 0);
- i2c_rd16(iface, S6_I2C_CLRINTR);
- for (i = 0; i < num; i++) {
- if (msgs[i].flags & I2C_M_TEN) {
- dev_err(&adap->dev,
- "s6i2c: 10 bits addr not supported\n");
- return -EINVAL;
- }
- if (msgs[i].len == 0) {
- dev_err(&adap->dev,
- "s6i2c: zero length message not supported\n");
- return -EINVAL;
- }
- if (msgs[i].addr != msgs[0].addr) {
- dev_err(&adap->dev,
- "s6i2c: multiple xfer cannot change target\n");
- return -EINVAL;
- }
- }
-
- iface->msgs = msgs;
- iface->msgs_num = num;
- iface->msgs_push = 0;
- iface->msgs_done = 0;
- iface->push = 0;
- iface->done = 0;
- iface->timeout_count = 10;
- i2c_wr16(iface, S6_I2C_TAR, msgs[0].addr);
- i2c_wr16(iface, S6_I2C_ENABLE, 1);
- i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXEMPTY) |
- (1 << S6_I2C_INTR_TXABRT));
-
- iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
- add_timer(&iface->timeout_timer);
- wait_for_completion(&iface->complete);
- del_timer_sync(&iface->timeout_timer);
- while (i2c_rd32(iface, S6_I2C_TXFLR) > 0)
- schedule();
- while (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_ACTIVITY))
- schedule();
-
- i2c_wr16(iface, S6_I2C_INTRMASK, 0);
- i2c_wr16(iface, S6_I2C_ENABLE, 0);
- return iface->msgs_done;
-}
-
-static u32 s6i2c_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm s6i2c_algorithm = {
- .master_xfer = s6i2c_master_xfer,
- .functionality = s6i2c_functionality,
-};
-
-static u16 __devinit nanoseconds_on_clk(struct s6i2c_if *iface, u32 ns)
-{
- u32 dividend = ((clk_get_rate(iface->clk) / 1000) * ns) / 1000000;
- if (dividend > 0xffff)
- return 0xffff;
- return dividend;
-}
-
-static int __devinit s6i2c_probe(struct platform_device *dev)
-{
- struct s6i2c_if *iface = &s6i2c_if;
- struct i2c_adapter *p_adap;
- const char *clock;
- int bus_num, rc;
- spin_lock_init(&iface->lock);
- init_completion(&iface->complete);
- iface->irq = platform_get_irq(dev, 0);
- if (iface->irq < 0) {
- rc = iface->irq;
- goto err_out;
- }
- iface->res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!iface->res) {
- rc = -ENXIO;
- goto err_out;
- }
- iface->res = request_mem_region(iface->res->start,
- resource_size(iface->res),
- dev->dev.bus_id);
- if (!iface->res) {
- rc = -EBUSY;
- goto err_out;
- }
- iface->reg = ioremap_nocache(iface->res->start,
- resource_size(iface->res));
- if (!iface->reg) {
- rc = -ENOMEM;
- goto err_reg;
- }
-
- clock = 0;
- bus_num = -1;
- if (dev->dev.platform_data) {
- struct s6_i2c_platform_data *pdata = dev->dev.platform_data;
- bus_num = pdata->bus_num;
- clock = pdata->clock;
- }
- iface->clk = clk_get(&dev->dev, clock);
- if (IS_ERR(iface->clk)) {
- rc = PTR_ERR(iface->clk);
- goto err_map;
- }
- rc = clk_enable(iface->clk);
- if (rc < 0)
- goto err_clk_put;
- init_timer(&iface->timeout_timer);
- iface->timeout_timer.function = s6i2c_timeout;
- iface->timeout_timer.data = (unsigned long)iface;
-
- p_adap = &iface->adap;
- strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
- p_adap->algo = &s6i2c_algorithm;
- p_adap->algo_data = iface;
- p_adap->nr = bus_num;
- p_adap->class = 0;
- p_adap->dev.parent = &dev->dev;
- i2c_wr16(iface, S6_I2C_INTRMASK, 0);
- rc = request_irq(iface->irq, s6i2c_interrupt_entry,
- IRQF_SHARED, dev->name, iface);
- if (rc) {
- dev_err(&p_adap->dev, "s6i2c: can't get IRQ %d\n", iface->irq);
- goto err_clk_dis;
- }
-
- i2c_wr16(iface, S6_I2C_ENABLE, 0);
- udelay(1);
- i2c_wr32(iface, S6_I2C_SRESET, 1 << S6_I2C_SRESET_IC_SRST);
- i2c_wr16(iface, S6_I2C_CLRTXABRT, 1);
- i2c_wr16(iface, S6_I2C_CON,
- (1 << S6_I2C_CON_MASTER) |
- (S6_I2C_CON_SPEED_NORMAL << S6_I2C_CON_SPEED) |
- (0 << S6_I2C_CON_10BITSLAVE) |
- (0 << S6_I2C_CON_10BITMASTER) |
- (1 << S6_I2C_CON_RESTARTENA) |
- (1 << S6_I2C_CON_SLAVEDISABLE));
- i2c_wr16(iface, S6_I2C_SSHCNT, nanoseconds_on_clk(iface, 4000));
- i2c_wr16(iface, S6_I2C_SSLCNT, nanoseconds_on_clk(iface, 4700));
- i2c_wr16(iface, S6_I2C_FSHCNT, nanoseconds_on_clk(iface, 600));
- i2c_wr16(iface, S6_I2C_FSLCNT, nanoseconds_on_clk(iface, 1300));
- i2c_wr16(iface, S6_I2C_RXTL, 0);
- i2c_wr16(iface, S6_I2C_TXTL, 0);
-
- platform_set_drvdata(dev, iface);
- rc = i2c_add_numbered_adapter(p_adap);
- if (rc)
- goto err_irq_free;
- return 0;
-
-err_irq_free:
- free_irq(iface->irq, iface);
-err_clk_dis:
- clk_disable(iface->clk);
-err_clk_put:
- clk_put(iface->clk);
-err_map:
- iounmap(iface->reg);
-err_reg:
- release_mem_region(iface->res->start,
- resource_size(iface->res));
-err_out:
- return rc;
-}
-
-static int __devexit s6i2c_remove(struct platform_device *pdev)
-{
- struct s6i2c_if *iface = platform_get_drvdata(pdev);
- i2c_wr16(iface, S6_I2C_ENABLE, 0);
- platform_set_drvdata(pdev, NULL);
- i2c_del_adapter(&iface->adap);
- free_irq(iface->irq, iface);
- clk_disable(iface->clk);
- clk_put(iface->clk);
- iounmap(iface->reg);
- release_mem_region(iface->res->start,
- resource_size(iface->res));
- return 0;
-}
-
-static struct platform_driver s6i2c_driver = {
- .probe = s6i2c_probe,
- .remove = __devexit_p(s6i2c_remove),
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s6i2c_init(void)
-{
- pr_info("I2C: S6000 I2C driver\n");
- return platform_driver_register(&s6i2c_driver);
-}
-
-static void __exit s6i2c_exit(void)
-{
- platform_driver_unregister(&s6i2c_driver);
-}
-
-MODULE_DESCRIPTION("I2C-Bus adapter routines for S6000 I2C");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
-
-subsys_initcall(s6i2c_init);
-module_exit(s6i2c_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.h b/ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.h
deleted file mode 100644
index ff23b81d..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-s6000.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * drivers/i2c/busses/i2c-s6000.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2008 Emlix GmbH <info@emlix.com>
- * Author: Oskar Schirmer <os@emlix.com>
- */
-
-#ifndef __DRIVERS_I2C_BUSSES_I2C_S6000_H
-#define __DRIVERS_I2C_BUSSES_I2C_S6000_H
-
-#define S6_I2C_CON 0x000
-#define S6_I2C_CON_MASTER 0
-#define S6_I2C_CON_SPEED 1
-#define S6_I2C_CON_SPEED_NORMAL 1
-#define S6_I2C_CON_SPEED_FAST 2
-#define S6_I2C_CON_SPEED_MASK 3
-#define S6_I2C_CON_10BITSLAVE 3
-#define S6_I2C_CON_10BITMASTER 4
-#define S6_I2C_CON_RESTARTENA 5
-#define S6_I2C_CON_SLAVEDISABLE 6
-#define S6_I2C_TAR 0x004
-#define S6_I2C_TAR_GCORSTART 10
-#define S6_I2C_TAR_SPECIAL 11
-#define S6_I2C_SAR 0x008
-#define S6_I2C_HSMADDR 0x00C
-#define S6_I2C_DATACMD 0x010
-#define S6_I2C_DATACMD_READ 8
-#define S6_I2C_SSHCNT 0x014
-#define S6_I2C_SSLCNT 0x018
-#define S6_I2C_FSHCNT 0x01C
-#define S6_I2C_FSLCNT 0x020
-#define S6_I2C_INTRSTAT 0x02C
-#define S6_I2C_INTRMASK 0x030
-#define S6_I2C_RAWINTR 0x034
-#define S6_I2C_INTR_RXUNDER 0
-#define S6_I2C_INTR_RXOVER 1
-#define S6_I2C_INTR_RXFULL 2
-#define S6_I2C_INTR_TXOVER 3
-#define S6_I2C_INTR_TXEMPTY 4
-#define S6_I2C_INTR_RDREQ 5
-#define S6_I2C_INTR_TXABRT 6
-#define S6_I2C_INTR_RXDONE 7
-#define S6_I2C_INTR_ACTIVITY 8
-#define S6_I2C_INTR_STOPDET 9
-#define S6_I2C_INTR_STARTDET 10
-#define S6_I2C_INTR_GENCALL 11
-#define S6_I2C_RXTL 0x038
-#define S6_I2C_TXTL 0x03C
-#define S6_I2C_CLRINTR 0x040
-#define S6_I2C_CLRRXUNDER 0x044
-#define S6_I2C_CLRRXOVER 0x048
-#define S6_I2C_CLRTXOVER 0x04C
-#define S6_I2C_CLRRDREQ 0x050
-#define S6_I2C_CLRTXABRT 0x054
-#define S6_I2C_CLRRXDONE 0x058
-#define S6_I2C_CLRACTIVITY 0x05C
-#define S6_I2C_CLRSTOPDET 0x060
-#define S6_I2C_CLRSTARTDET 0x064
-#define S6_I2C_CLRGENCALL 0x068
-#define S6_I2C_ENABLE 0x06C
-#define S6_I2C_STATUS 0x070
-#define S6_I2C_STATUS_ACTIVITY 0
-#define S6_I2C_STATUS_TFNF 1
-#define S6_I2C_STATUS_TFE 2
-#define S6_I2C_STATUS_RFNE 3
-#define S6_I2C_STATUS_RFF 4
-#define S6_I2C_TXFLR 0x074
-#define S6_I2C_RXFLR 0x078
-#define S6_I2C_SRESET 0x07C
-#define S6_I2C_SRESET_IC_SRST 0
-#define S6_I2C_SRESET_IC_MASTER_SRST 1
-#define S6_I2C_SRESET_IC_SLAVE_SRST 2
-#define S6_I2C_TXABRTSOURCE 0x080
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-scmi.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-scmi.c
deleted file mode 100644
index 388cbdc9..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-scmi.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * SMBus driver for ACPI SMBus CMI
- *
- * Copyright (C) 2009 Crane Cai <crane.cai@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-
-#define ACPI_SMBUS_HC_CLASS "smbus"
-#define ACPI_SMBUS_HC_DEVICE_NAME "cmi"
-
-ACPI_MODULE_NAME("smbus_cmi");
-
-struct smbus_methods_t {
- char *mt_info;
- char *mt_sbr;
- char *mt_sbw;
-};
-
-struct acpi_smbus_cmi {
- acpi_handle handle;
- struct i2c_adapter adapter;
- u8 cap_info:1;
- u8 cap_read:1;
- u8 cap_write:1;
- struct smbus_methods_t *methods;
-};
-
-static const struct smbus_methods_t smbus_methods = {
- .mt_info = "_SBI",
- .mt_sbr = "_SBR",
- .mt_sbw = "_SBW",
-};
-
-/* Some IBM BIOSes omit the leading underscore */
-static const struct smbus_methods_t ibm_smbus_methods = {
- .mt_info = "SBI_",
- .mt_sbr = "SBR_",
- .mt_sbw = "SBW_",
-};
-
-static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
- {"SMBUS01", (kernel_ulong_t)&smbus_methods},
- {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
- {"", 0}
-};
-MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
-
-#define ACPI_SMBUS_STATUS_OK 0x00
-#define ACPI_SMBUS_STATUS_FAIL 0x07
-#define ACPI_SMBUS_STATUS_DNAK 0x10
-#define ACPI_SMBUS_STATUS_DERR 0x11
-#define ACPI_SMBUS_STATUS_CMD_DENY 0x12
-#define ACPI_SMBUS_STATUS_UNKNOWN 0x13
-#define ACPI_SMBUS_STATUS_ACC_DENY 0x17
-#define ACPI_SMBUS_STATUS_TIMEOUT 0x18
-#define ACPI_SMBUS_STATUS_NOTSUP 0x19
-#define ACPI_SMBUS_STATUS_BUSY 0x1a
-#define ACPI_SMBUS_STATUS_PEC 0x1f
-
-#define ACPI_SMBUS_PRTCL_WRITE 0x00
-#define ACPI_SMBUS_PRTCL_READ 0x01
-#define ACPI_SMBUS_PRTCL_QUICK 0x02
-#define ACPI_SMBUS_PRTCL_BYTE 0x04
-#define ACPI_SMBUS_PRTCL_BYTE_DATA 0x06
-#define ACPI_SMBUS_PRTCL_WORD_DATA 0x08
-#define ACPI_SMBUS_PRTCL_BLOCK_DATA 0x0a
-
-
-static int
-acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
- char read_write, u8 command, int size,
- union i2c_smbus_data *data)
-{
- int result = 0;
- struct acpi_smbus_cmi *smbus_cmi = adap->algo_data;
- unsigned char protocol;
- acpi_status status = 0;
- struct acpi_object_list input;
- union acpi_object mt_params[5];
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- union acpi_object *pkg;
- char *method;
- int len = 0;
-
- dev_dbg(&adap->dev, "access size: %d %s\n", size,
- (read_write) ? "READ" : "WRITE");
- switch (size) {
- case I2C_SMBUS_QUICK:
- protocol = ACPI_SMBUS_PRTCL_QUICK;
- command = 0;
- if (read_write == I2C_SMBUS_WRITE) {
- mt_params[3].type = ACPI_TYPE_INTEGER;
- mt_params[3].integer.value = 0;
- mt_params[4].type = ACPI_TYPE_INTEGER;
- mt_params[4].integer.value = 0;
- }
- break;
-
- case I2C_SMBUS_BYTE:
- protocol = ACPI_SMBUS_PRTCL_BYTE;
- if (read_write == I2C_SMBUS_WRITE) {
- mt_params[3].type = ACPI_TYPE_INTEGER;
- mt_params[3].integer.value = 0;
- mt_params[4].type = ACPI_TYPE_INTEGER;
- mt_params[4].integer.value = 0;
- } else {
- command = 0;
- }
- break;
-
- case I2C_SMBUS_BYTE_DATA:
- protocol = ACPI_SMBUS_PRTCL_BYTE_DATA;
- if (read_write == I2C_SMBUS_WRITE) {
- mt_params[3].type = ACPI_TYPE_INTEGER;
- mt_params[3].integer.value = 1;
- mt_params[4].type = ACPI_TYPE_INTEGER;
- mt_params[4].integer.value = data->byte;
- }
- break;
-
- case I2C_SMBUS_WORD_DATA:
- protocol = ACPI_SMBUS_PRTCL_WORD_DATA;
- if (read_write == I2C_SMBUS_WRITE) {
- mt_params[3].type = ACPI_TYPE_INTEGER;
- mt_params[3].integer.value = 2;
- mt_params[4].type = ACPI_TYPE_INTEGER;
- mt_params[4].integer.value = data->word;
- }
- break;
-
- case I2C_SMBUS_BLOCK_DATA:
- protocol = ACPI_SMBUS_PRTCL_BLOCK_DATA;
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
- return -EINVAL;
- mt_params[3].type = ACPI_TYPE_INTEGER;
- mt_params[3].integer.value = len;
- mt_params[4].type = ACPI_TYPE_BUFFER;
- mt_params[4].buffer.pointer = data->block + 1;
- }
- break;
-
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- if (read_write == I2C_SMBUS_READ) {
- protocol |= ACPI_SMBUS_PRTCL_READ;
- method = smbus_cmi->methods->mt_sbr;
- input.count = 3;
- } else {
- protocol |= ACPI_SMBUS_PRTCL_WRITE;
- method = smbus_cmi->methods->mt_sbw;
- input.count = 5;
- }
-
- input.pointer = mt_params;
- mt_params[0].type = ACPI_TYPE_INTEGER;
- mt_params[0].integer.value = protocol;
- mt_params[1].type = ACPI_TYPE_INTEGER;
- mt_params[1].integer.value = addr;
- mt_params[2].type = ACPI_TYPE_INTEGER;
- mt_params[2].integer.value = command;
-
- status = acpi_evaluate_object(smbus_cmi->handle, method, &input,
- &buffer);
- if (ACPI_FAILURE(status)) {
- ACPI_ERROR((AE_INFO, "Evaluating %s: %i", method, status));
- return -EIO;
- }
-
- pkg = buffer.pointer;
- if (pkg && pkg->type == ACPI_TYPE_PACKAGE)
- obj = pkg->package.elements;
- else {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- result = -EIO;
- goto out;
- }
- if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- result = -EIO;
- goto out;
- }
-
- result = obj->integer.value;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s return status: %i\n",
- method, result));
-
- switch (result) {
- case ACPI_SMBUS_STATUS_OK:
- result = 0;
- break;
- case ACPI_SMBUS_STATUS_BUSY:
- result = -EBUSY;
- goto out;
- case ACPI_SMBUS_STATUS_TIMEOUT:
- result = -ETIMEDOUT;
- goto out;
- case ACPI_SMBUS_STATUS_DNAK:
- result = -ENXIO;
- goto out;
- default:
- result = -EIO;
- goto out;
- }
-
- if (read_write == I2C_SMBUS_WRITE || size == I2C_SMBUS_QUICK)
- goto out;
-
- obj = pkg->package.elements + 1;
- if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- result = -EIO;
- goto out;
- }
-
- len = obj->integer.value;
- obj = pkg->package.elements + 2;
- switch (size) {
- case I2C_SMBUS_BYTE:
- case I2C_SMBUS_BYTE_DATA:
- case I2C_SMBUS_WORD_DATA:
- if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- result = -EIO;
- goto out;
- }
- if (len == 2)
- data->word = obj->integer.value;
- else
- data->byte = obj->integer.value;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- if (obj == NULL || obj->type != ACPI_TYPE_BUFFER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- result = -EIO;
- goto out;
- }
- if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
- return -EPROTO;
- data->block[0] = len;
- memcpy(data->block + 1, obj->buffer.pointer, len);
- break;
- }
-
-out:
- kfree(buffer.pointer);
- dev_dbg(&adap->dev, "Transaction status: %i\n", result);
- return result;
-}
-
-static u32 acpi_smbus_cmi_func(struct i2c_adapter *adapter)
-{
- struct acpi_smbus_cmi *smbus_cmi = adapter->algo_data;
- u32 ret;
-
- ret = smbus_cmi->cap_read | smbus_cmi->cap_write ?
- I2C_FUNC_SMBUS_QUICK : 0;
-
- ret |= smbus_cmi->cap_read ?
- (I2C_FUNC_SMBUS_READ_BYTE |
- I2C_FUNC_SMBUS_READ_BYTE_DATA |
- I2C_FUNC_SMBUS_READ_WORD_DATA |
- I2C_FUNC_SMBUS_READ_BLOCK_DATA) : 0;
-
- ret |= smbus_cmi->cap_write ?
- (I2C_FUNC_SMBUS_WRITE_BYTE |
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
- I2C_FUNC_SMBUS_WRITE_WORD_DATA |
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) : 0;
-
- return ret;
-}
-
-static const struct i2c_algorithm acpi_smbus_cmi_algorithm = {
- .smbus_xfer = acpi_smbus_cmi_access,
- .functionality = acpi_smbus_cmi_func,
-};
-
-
-static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
- const char *name)
-{
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- acpi_status status;
-
- if (!strcmp(name, smbus_cmi->methods->mt_info)) {
- status = acpi_evaluate_object(smbus_cmi->handle,
- smbus_cmi->methods->mt_info,
- NULL, &buffer);
- if (ACPI_FAILURE(status)) {
- ACPI_ERROR((AE_INFO, "Evaluating %s: %i",
- smbus_cmi->methods->mt_info, status));
- return -EIO;
- }
-
- obj = buffer.pointer;
- if (obj && obj->type == ACPI_TYPE_PACKAGE)
- obj = obj->package.elements;
- else {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- kfree(buffer.pointer);
- return -EIO;
- }
-
- if (obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
- kfree(buffer.pointer);
- return -EIO;
- } else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SMBus CMI Version %x"
- "\n", (int)obj->integer.value));
-
- kfree(buffer.pointer);
- smbus_cmi->cap_info = 1;
- } else if (!strcmp(name, smbus_cmi->methods->mt_sbr))
- smbus_cmi->cap_read = 1;
- else if (!strcmp(name, smbus_cmi->methods->mt_sbw))
- smbus_cmi->cap_write = 1;
- else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported CMI method: %s\n",
- name));
-
- return 0;
-}
-
-static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level,
- void *context, void **return_value)
-{
- char node_name[5];
- struct acpi_buffer buffer = { sizeof(node_name), node_name };
- struct acpi_smbus_cmi *smbus_cmi = context;
- acpi_status status;
-
- status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
-
- if (ACPI_SUCCESS(status))
- acpi_smbus_cmi_add_cap(smbus_cmi, node_name);
-
- return AE_OK;
-}
-
-static int acpi_smbus_cmi_add(struct acpi_device *device)
-{
- struct acpi_smbus_cmi *smbus_cmi;
- const struct acpi_device_id *id;
-
- smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL);
- if (!smbus_cmi)
- return -ENOMEM;
-
- smbus_cmi->handle = device->handle;
- strcpy(acpi_device_name(device), ACPI_SMBUS_HC_DEVICE_NAME);
- strcpy(acpi_device_class(device), ACPI_SMBUS_HC_CLASS);
- device->driver_data = smbus_cmi;
- smbus_cmi->cap_info = 0;
- smbus_cmi->cap_read = 0;
- smbus_cmi->cap_write = 0;
-
- for (id = acpi_smbus_cmi_ids; id->id[0]; id++)
- if (!strcmp(id->id, acpi_device_hid(device)))
- smbus_cmi->methods =
- (struct smbus_methods_t *) id->driver_data;
-
- acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
- acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
-
- if (smbus_cmi->cap_info == 0)
- goto err;
-
- snprintf(smbus_cmi->adapter.name, sizeof(smbus_cmi->adapter.name),
- "SMBus CMI adapter %s",
- acpi_device_name(device));
- smbus_cmi->adapter.owner = THIS_MODULE;
- smbus_cmi->adapter.algo = &acpi_smbus_cmi_algorithm;
- smbus_cmi->adapter.algo_data = smbus_cmi;
- smbus_cmi->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- smbus_cmi->adapter.dev.parent = &device->dev;
-
- if (i2c_add_adapter(&smbus_cmi->adapter)) {
- dev_err(&device->dev, "Couldn't register adapter!\n");
- goto err;
- }
-
- return 0;
-
-err:
- kfree(smbus_cmi);
- device->driver_data = NULL;
- return -EIO;
-}
-
-static int acpi_smbus_cmi_remove(struct acpi_device *device, int type)
-{
- struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device);
-
- i2c_del_adapter(&smbus_cmi->adapter);
- kfree(smbus_cmi);
- device->driver_data = NULL;
-
- return 0;
-}
-
-static struct acpi_driver acpi_smbus_cmi_driver = {
- .name = ACPI_SMBUS_HC_DEVICE_NAME,
- .class = ACPI_SMBUS_HC_CLASS,
- .ids = acpi_smbus_cmi_ids,
- .ops = {
- .add = acpi_smbus_cmi_add,
- .remove = acpi_smbus_cmi_remove,
- },
-};
-
-static int __init acpi_smbus_cmi_init(void)
-{
- return acpi_bus_register_driver(&acpi_smbus_cmi_driver);
-}
-
-static void __exit acpi_smbus_cmi_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_smbus_cmi_driver);
-}
-
-module_init(acpi_smbus_cmi_init);
-module_exit(acpi_smbus_cmi_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>");
-MODULE_DESCRIPTION("ACPI SMBus CMI driver");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sh7760.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sh7760.c
deleted file mode 100644
index c0c9dffb..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sh7760.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * I2C bus driver for the SH7760 I2C Interfaces.
- *
- * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
- *
- * licensed under the terms outlined in the file COPYING.
- *
- */
-
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-
-#include <asm/clock.h>
-#include <asm/i2c-sh7760.h>
-
-/* register offsets */
-#define I2CSCR 0x0 /* slave ctrl */
-#define I2CMCR 0x4 /* master ctrl */
-#define I2CSSR 0x8 /* slave status */
-#define I2CMSR 0xC /* master status */
-#define I2CSIER 0x10 /* slave irq enable */
-#define I2CMIER 0x14 /* master irq enable */
-#define I2CCCR 0x18 /* clock dividers */
-#define I2CSAR 0x1c /* slave address */
-#define I2CMAR 0x20 /* master address */
-#define I2CRXTX 0x24 /* data port */
-#define I2CFCR 0x28 /* fifo control */
-#define I2CFSR 0x2C /* fifo status */
-#define I2CFIER 0x30 /* fifo irq enable */
-#define I2CRFDR 0x34 /* rx fifo count */
-#define I2CTFDR 0x38 /* tx fifo count */
-
-#define REGSIZE 0x3C
-
-#define MCR_MDBS 0x80 /* non-fifo mode switch */
-#define MCR_FSCL 0x40 /* override SCL pin */
-#define MCR_FSDA 0x20 /* override SDA pin */
-#define MCR_OBPC 0x10 /* override pins */
-#define MCR_MIE 0x08 /* master if enable */
-#define MCR_TSBE 0x04
-#define MCR_FSB 0x02 /* force stop bit */
-#define MCR_ESG 0x01 /* en startbit gen. */
-
-#define MSR_MNR 0x40 /* nack received */
-#define MSR_MAL 0x20 /* arbitration lost */
-#define MSR_MST 0x10 /* sent a stop */
-#define MSR_MDE 0x08
-#define MSR_MDT 0x04
-#define MSR_MDR 0x02
-#define MSR_MAT 0x01 /* slave addr xfer done */
-
-#define MIE_MNRE 0x40 /* nack irq en */
-#define MIE_MALE 0x20 /* arblos irq en */
-#define MIE_MSTE 0x10 /* stop irq en */
-#define MIE_MDEE 0x08
-#define MIE_MDTE 0x04
-#define MIE_MDRE 0x02
-#define MIE_MATE 0x01 /* address sent irq en */
-
-#define FCR_RFRST 0x02 /* reset rx fifo */
-#define FCR_TFRST 0x01 /* reset tx fifo */
-
-#define FSR_TEND 0x04 /* last byte sent */
-#define FSR_RDF 0x02 /* rx fifo trigger */
-#define FSR_TDFE 0x01 /* tx fifo empty */
-
-#define FIER_TEIE 0x04 /* tx fifo empty irq en */
-#define FIER_RXIE 0x02 /* rx fifo trig irq en */
-#define FIER_TXIE 0x01 /* tx fifo trig irq en */
-
-#define FIFO_SIZE 16
-
-struct cami2c {
- void __iomem *iobase;
- struct i2c_adapter adap;
-
- /* message processing */
- struct i2c_msg *msg;
-#define IDF_SEND 1
-#define IDF_RECV 2
-#define IDF_STOP 4
- int flags;
-
-#define IDS_DONE 1
-#define IDS_ARBLOST 2
-#define IDS_NACK 4
- int status;
- struct completion xfer_done;
-
- int irq;
- struct resource *ioarea;
-};
-
-static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
-{
- __raw_writel(val, (unsigned long)cam->iobase + reg);
-}
-
-static inline unsigned long IN32(struct cami2c *cam, int reg)
-{
- return __raw_readl((unsigned long)cam->iobase + reg);
-}
-
-static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
-{
- struct cami2c *id = ptr;
- struct i2c_msg *msg = id->msg;
- char *data = msg->buf;
- unsigned long msr, fsr, fier, len;
-
- msr = IN32(id, I2CMSR);
- fsr = IN32(id, I2CFSR);
-
- /* arbitration lost */
- if (msr & MSR_MAL) {
- OUT32(id, I2CMCR, 0);
- OUT32(id, I2CSCR, 0);
- OUT32(id, I2CSAR, 0);
- id->status |= IDS_DONE | IDS_ARBLOST;
- goto out;
- }
-
- if (msr & MSR_MNR) {
- /* NACK handling is very screwed up. After receiving a
- * NAK IRQ one has to wait a bit before writing to any
- * registers, or the ctl will lock up. After that delay
- * do a normal i2c stop. Then wait at least 1 ms before
- * attempting another transfer or ctl will stop working
- */
- udelay(100); /* wait or risk ctl hang */
- OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
- OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
- OUT32(id, I2CFIER, 0);
- OUT32(id, I2CMIER, MIE_MSTE);
- OUT32(id, I2CSCR, 0);
- OUT32(id, I2CSAR, 0);
- id->status |= IDS_NACK;
- msr &= ~MSR_MAT;
- fsr = 0;
- /* In some cases the MST bit is also set. */
- }
-
- /* i2c-stop was sent */
- if (msr & MSR_MST) {
- id->status |= IDS_DONE;
- goto out;
- }
-
- /* i2c slave addr was sent; set to "normal" operation */
- if (msr & MSR_MAT)
- OUT32(id, I2CMCR, MCR_MIE);
-
- fier = IN32(id, I2CFIER);
-
- if (fsr & FSR_RDF) {
- len = IN32(id, I2CRFDR);
- if (msg->len <= len) {
- if (id->flags & IDF_STOP) {
- OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
- OUT32(id, I2CFIER, 0);
- /* manual says: wait >= 0.5 SCL times */
- udelay(5);
- /* next int should be MST */
- } else {
- id->status |= IDS_DONE;
- /* keep the RDF bit: ctrl holds SCL low
- * until the setup for the next i2c_msg
- * clears this bit.
- */
- fsr &= ~FSR_RDF;
- }
- }
- while (msg->len && len) {
- *data++ = IN32(id, I2CRXTX);
- msg->len--;
- len--;
- }
-
- if (msg->len) {
- len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1
- : msg->len - 1;
-
- OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4));
- }
-
- } else if (id->flags & IDF_SEND) {
- if ((fsr & FSR_TEND) && (msg->len < 1)) {
- if (id->flags & IDF_STOP) {
- OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
- } else {
- id->status |= IDS_DONE;
- /* keep the TEND bit: ctl holds SCL low
- * until the setup for the next i2c_msg
- * clears this bit.
- */
- fsr &= ~FSR_TEND;
- }
- }
- if (fsr & FSR_TDFE) {
- while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) {
- OUT32(id, I2CRXTX, *data++);
- msg->len--;
- }
-
- if (msg->len < 1) {
- fier &= ~FIER_TXIE;
- OUT32(id, I2CFIER, fier);
- } else {
- len = (msg->len >= FIFO_SIZE) ? 2 : 0;
- OUT32(id, I2CFCR,
- FCR_RFRST | ((len & 3) << 2));
- }
- }
- }
-out:
- if (id->status & IDS_DONE) {
- OUT32(id, I2CMIER, 0);
- OUT32(id, I2CFIER, 0);
- id->msg = NULL;
- complete(&id->xfer_done);
- }
- /* clear status flags and ctrl resumes work */
- OUT32(id, I2CMSR, ~msr);
- OUT32(id, I2CFSR, ~fsr);
- OUT32(id, I2CSSR, 0);
-
- return IRQ_HANDLED;
-}
-
-
-/* prepare and start a master receive operation */
-static void sh7760_i2c_mrecv(struct cami2c *id)
-{
- int len;
-
- id->flags |= IDF_RECV;
-
- /* set the slave addr reg; otherwise rcv wont work! */
- OUT32(id, I2CSAR, 0xfe);
- OUT32(id, I2CMAR, (id->msg->addr << 1) | 1);
-
- /* adjust rx fifo trigger */
- if (id->msg->len >= FIFO_SIZE)
- len = FIFO_SIZE - 1; /* trigger at fifo full */
- else
- len = id->msg->len - 1; /* trigger before all received */
-
- OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
- OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4));
-
- OUT32(id, I2CMSR, 0);
- OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
- OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
- OUT32(id, I2CFIER, FIER_RXIE);
-}
-
-/* prepare and start a master send operation */
-static void sh7760_i2c_msend(struct cami2c *id)
-{
- int len;
-
- id->flags |= IDF_SEND;
-
- /* set the slave addr reg; otherwise xmit wont work! */
- OUT32(id, I2CSAR, 0xfe);
- OUT32(id, I2CMAR, (id->msg->addr << 1) | 0);
-
- /* adjust tx fifo trigger */
- if (id->msg->len >= FIFO_SIZE)
- len = 2; /* trig: 2 bytes left in TX fifo */
- else
- len = 0; /* trig: 8 bytes left in TX fifo */
-
- OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
- OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2));
-
- while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) {
- OUT32(id, I2CRXTX, *(id->msg->buf));
- (id->msg->len)--;
- (id->msg->buf)++;
- }
-
- OUT32(id, I2CMSR, 0);
- OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
- OUT32(id, I2CFSR, 0);
- OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
- OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0));
-}
-
-static inline int sh7760_i2c_busy_check(struct cami2c *id)
-{
- return (IN32(id, I2CMCR) & MCR_FSDA);
-}
-
-static int sh7760_i2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs,
- int num)
-{
- struct cami2c *id = adap->algo_data;
- int i, retr;
-
- if (sh7760_i2c_busy_check(id)) {
- dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr);
- return -EBUSY;
- }
-
- i = 0;
- while (i < num) {
- retr = adap->retries;
-retry:
- id->flags = ((i == (num-1)) ? IDF_STOP : 0);
- id->status = 0;
- id->msg = msgs;
- init_completion(&id->xfer_done);
-
- if (msgs->flags & I2C_M_RD)
- sh7760_i2c_mrecv(id);
- else
- sh7760_i2c_msend(id);
-
- wait_for_completion(&id->xfer_done);
-
- if (id->status == 0) {
- num = -EIO;
- break;
- }
-
- if (id->status & IDS_NACK) {
- /* wait a bit or i2c module stops working */
- mdelay(1);
- num = -EREMOTEIO;
- break;
- }
-
- if (id->status & IDS_ARBLOST) {
- if (retr--) {
- mdelay(2);
- goto retry;
- }
- num = -EREMOTEIO;
- break;
- }
-
- msgs++;
- i++;
- }
-
- id->msg = NULL;
- id->flags = 0;
- id->status = 0;
-
- OUT32(id, I2CMCR, 0);
- OUT32(id, I2CMSR, 0);
- OUT32(id, I2CMIER, 0);
- OUT32(id, I2CFIER, 0);
-
- /* reset slave module registers too: master mode enables slave
- * module for receive ops (ack, data). Without this reset,
- * eternal bus activity might be reported after NACK / ARBLOST.
- */
- OUT32(id, I2CSCR, 0);
- OUT32(id, I2CSAR, 0);
- OUT32(id, I2CSSR, 0);
-
- return num;
-}
-
-static u32 sh7760_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
-}
-
-static const struct i2c_algorithm sh7760_i2c_algo = {
- .master_xfer = sh7760_i2c_master_xfer,
- .functionality = sh7760_i2c_func,
-};
-
-/* calculate CCR register setting for a desired scl clock. SCL clock is
- * derived from I2C module clock (iclk) which in turn is derived from
- * peripheral module clock (mclk, usually around 33MHz):
- * iclk = mclk/(CDF + 1). iclk must be < 20MHz.
- * scl = iclk/(SCGD*8 + 20).
- */
-static int __devinit calc_CCR(unsigned long scl_hz)
-{
- struct clk *mclk;
- unsigned long mck, m1, dff, odff, iclk;
- signed char cdf, cdfm;
- int scgd, scgdm, scgds;
-
- mclk = clk_get(NULL, "peripheral_clk");
- if (IS_ERR(mclk)) {
- return PTR_ERR(mclk);
- } else {
- mck = mclk->rate;
- clk_put(mclk);
- }
-
- odff = scl_hz;
- scgdm = cdfm = m1 = 0;
- for (cdf = 3; cdf >= 0; cdf--) {
- iclk = mck / (1 + cdf);
- if (iclk >= 20000000)
- continue;
- scgds = ((iclk / scl_hz) - 20) >> 3;
- for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) {
- m1 = iclk / (20 + (scgd << 3));
- dff = abs(scl_hz - m1);
- if (dff < odff) {
- odff = dff;
- cdfm = cdf;
- scgdm = scgd;
- }
- }
- }
- /* fail if more than 25% off of requested SCL */
- if (odff > (scl_hz >> 2))
- return -EINVAL;
-
- /* create a CCR register value */
- return ((scgdm << 2) | cdfm);
-}
-
-static int __devinit sh7760_i2c_probe(struct platform_device *pdev)
-{
- struct sh7760_i2c_platdata *pd;
- struct resource *res;
- struct cami2c *id;
- int ret;
-
- pd = pdev->dev.platform_data;
- if (!pd) {
- dev_err(&pdev->dev, "no platform_data!\n");
- ret = -ENODEV;
- goto out0;
- }
-
- id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
- if (!id) {
- dev_err(&pdev->dev, "no mem for private data\n");
- ret = -ENOMEM;
- goto out0;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "no mmio resources\n");
- ret = -ENODEV;
- goto out1;
- }
-
- id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name);
- if (!id->ioarea) {
- dev_err(&pdev->dev, "mmio already reserved\n");
- ret = -EBUSY;
- goto out1;
- }
-
- id->iobase = ioremap(res->start, REGSIZE);
- if (!id->iobase) {
- dev_err(&pdev->dev, "cannot ioremap\n");
- ret = -ENODEV;
- goto out2;
- }
-
- id->irq = platform_get_irq(pdev, 0);
-
- id->adap.nr = pdev->id;
- id->adap.algo = &sh7760_i2c_algo;
- id->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- id->adap.retries = 3;
- id->adap.algo_data = id;
- id->adap.dev.parent = &pdev->dev;
- snprintf(id->adap.name, sizeof(id->adap.name),
- "SH7760 I2C at %08lx", (unsigned long)res->start);
-
- OUT32(id, I2CMCR, 0);
- OUT32(id, I2CMSR, 0);
- OUT32(id, I2CMIER, 0);
- OUT32(id, I2CMAR, 0);
- OUT32(id, I2CSIER, 0);
- OUT32(id, I2CSAR, 0);
- OUT32(id, I2CSCR, 0);
- OUT32(id, I2CSSR, 0);
- OUT32(id, I2CFIER, 0);
- OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
- OUT32(id, I2CFSR, 0);
-
- ret = calc_CCR(pd->speed_khz * 1000);
- if (ret < 0) {
- dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n",
- pd->speed_khz);
- goto out3;
- }
- OUT32(id, I2CCCR, ret);
-
- if (request_irq(id->irq, sh7760_i2c_irq, 0,
- SH7760_I2C_DEVNAME, id)) {
- dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
- ret = -EBUSY;
- goto out3;
- }
-
- ret = i2c_add_numbered_adapter(&id->adap);
- if (ret < 0) {
- dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
- goto out4;
- }
-
- platform_set_drvdata(pdev, id);
-
- dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n",
- pd->speed_khz, res->start, id->irq);
-
- return 0;
-
-out4:
- free_irq(id->irq, id);
-out3:
- iounmap(id->iobase);
-out2:
- release_resource(id->ioarea);
- kfree(id->ioarea);
-out1:
- kfree(id);
-out0:
- return ret;
-}
-
-static int __devexit sh7760_i2c_remove(struct platform_device *pdev)
-{
- struct cami2c *id = platform_get_drvdata(pdev);
-
- i2c_del_adapter(&id->adap);
- free_irq(id->irq, id);
- iounmap(id->iobase);
- release_resource(id->ioarea);
- kfree(id->ioarea);
- kfree(id);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver sh7760_i2c_drv = {
- .driver = {
- .name = SH7760_I2C_DEVNAME,
- .owner = THIS_MODULE,
- },
- .probe = sh7760_i2c_probe,
- .remove = __devexit_p(sh7760_i2c_remove),
-};
-
-module_platform_driver(sh7760_i2c_drv);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SH7760 I2C bus driver");
-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sh_mobile.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sh_mobile.c
deleted file mode 100644
index 675c9692..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sh_mobile.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * SuperH Mobile I2C Controller
- *
- * Copyright (C) 2008 Magnus Damm
- *
- * Portions of the code based on out-of-tree driver i2c-sh7343.c
- * Copyright (c) 2006 Carlos Munoz <carlos@kenati.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/pm_runtime.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/i2c/i2c-sh_mobile.h>
-
-/* Transmit operation: */
-/* */
-/* 0 byte transmit */
-/* BUS: S A8 ACK P */
-/* IRQ: DTE WAIT */
-/* ICIC: */
-/* ICCR: 0x94 0x90 */
-/* ICDR: A8 */
-/* */
-/* 1 byte transmit */
-/* BUS: S A8 ACK D8(1) ACK P */
-/* IRQ: DTE WAIT WAIT */
-/* ICIC: -DTE */
-/* ICCR: 0x94 0x90 */
-/* ICDR: A8 D8(1) */
-/* */
-/* 2 byte transmit */
-/* BUS: S A8 ACK D8(1) ACK D8(2) ACK P */
-/* IRQ: DTE WAIT WAIT WAIT */
-/* ICIC: -DTE */
-/* ICCR: 0x94 0x90 */
-/* ICDR: A8 D8(1) D8(2) */
-/* */
-/* 3 bytes or more, +---------+ gets repeated */
-/* */
-/* */
-/* Receive operation: */
-/* */
-/* 0 byte receive - not supported since slave may hold SDA low */
-/* */
-/* 1 byte receive [TX] | [RX] */
-/* BUS: S A8 ACK | D8(1) ACK P */
-/* IRQ: DTE WAIT | WAIT DTE */
-/* ICIC: -DTE | +DTE */
-/* ICCR: 0x94 0x81 | 0xc0 */
-/* ICDR: A8 | D8(1) */
-/* */
-/* 2 byte receive [TX]| [RX] */
-/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK P */
-/* IRQ: DTE WAIT | WAIT WAIT DTE */
-/* ICIC: -DTE | +DTE */
-/* ICCR: 0x94 0x81 | 0xc0 */
-/* ICDR: A8 | D8(1) D8(2) */
-/* */
-/* 3 byte receive [TX] | [RX] */
-/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK D8(3) ACK P */
-/* IRQ: DTE WAIT | WAIT WAIT WAIT DTE */
-/* ICIC: -DTE | +DTE */
-/* ICCR: 0x94 0x81 | 0xc0 */
-/* ICDR: A8 | D8(1) D8(2) D8(3) */
-/* */
-/* 4 bytes or more, this part is repeated +---------+ */
-/* */
-/* */
-/* Interrupt order and BUSY flag */
-/* ___ _ */
-/* SDA ___\___XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAA___/ */
-/* SCL \_/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\___/9\_____/ */
-/* */
-/* S D7 D6 D5 D4 D3 D2 D1 D0 P */
-/* ___ */
-/* WAIT IRQ ________________________________/ \___________ */
-/* TACK IRQ ____________________________________/ \_______ */
-/* DTE IRQ __________________________________________/ \_ */
-/* AL IRQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
-/* _______________________________________________ */
-/* BUSY __/ \_ */
-/* */
-
-enum sh_mobile_i2c_op {
- OP_START = 0,
- OP_TX_FIRST,
- OP_TX,
- OP_TX_STOP,
- OP_TX_TO_RX,
- OP_RX,
- OP_RX_STOP,
- OP_RX_STOP_DATA,
-};
-
-struct sh_mobile_i2c_data {
- struct device *dev;
- void __iomem *reg;
- struct i2c_adapter adap;
- unsigned long bus_speed;
- struct clk *clk;
- u_int8_t icic;
- u_int8_t iccl;
- u_int8_t icch;
- u_int8_t flags;
-
- spinlock_t lock;
- wait_queue_head_t wait;
- struct i2c_msg *msg;
- int pos;
- int sr;
-};
-
-#define IIC_FLAG_HAS_ICIC67 (1 << 0)
-
-#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
-
-/* Register offsets */
-#define ICDR 0x00
-#define ICCR 0x04
-#define ICSR 0x08
-#define ICIC 0x0c
-#define ICCL 0x10
-#define ICCH 0x14
-
-/* Register bits */
-#define ICCR_ICE 0x80
-#define ICCR_RACK 0x40
-#define ICCR_TRS 0x10
-#define ICCR_BBSY 0x04
-#define ICCR_SCP 0x01
-
-#define ICSR_SCLM 0x80
-#define ICSR_SDAM 0x40
-#define SW_DONE 0x20
-#define ICSR_BUSY 0x10
-#define ICSR_AL 0x08
-#define ICSR_TACK 0x04
-#define ICSR_WAIT 0x02
-#define ICSR_DTE 0x01
-
-#define ICIC_ICCLB8 0x80
-#define ICIC_ICCHB8 0x40
-#define ICIC_ALE 0x08
-#define ICIC_TACKE 0x04
-#define ICIC_WAITE 0x02
-#define ICIC_DTEE 0x01
-
-static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
-{
- if (offs == ICIC)
- data |= pd->icic;
-
- iowrite8(data, pd->reg + offs);
-}
-
-static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs)
-{
- return ioread8(pd->reg + offs);
-}
-
-static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
- unsigned char set, unsigned char clr)
-{
- iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
-}
-
-static void activate_ch(struct sh_mobile_i2c_data *pd)
-{
- unsigned long i2c_clk;
- u_int32_t num;
- u_int32_t denom;
- u_int32_t tmp;
-
- /* Wake up device and enable clock */
- pm_runtime_get_sync(pd->dev);
- clk_enable(pd->clk);
-
- /* Get clock rate after clock is enabled */
- i2c_clk = clk_get_rate(pd->clk);
-
- /* Calculate the value for iccl. From the data sheet:
- * iccl = (p clock / transfer rate) * (L / (L + H))
- * where L and H are the SCL low/high ratio (5/4 in this case).
- * We also round off the result.
- */
- num = i2c_clk * 5;
- denom = pd->bus_speed * 9;
- tmp = num * 10 / denom;
- if (tmp % 10 >= 5)
- pd->iccl = (u_int8_t)((num/denom) + 1);
- else
- pd->iccl = (u_int8_t)(num/denom);
-
- /* one more bit of ICCL in ICIC */
- if (pd->flags & IIC_FLAG_HAS_ICIC67) {
- if ((num/denom) > 0xff)
- pd->icic |= ICIC_ICCLB8;
- else
- pd->icic &= ~ICIC_ICCLB8;
- }
-
- /* Calculate the value for icch. From the data sheet:
- icch = (p clock / transfer rate) * (H / (L + H)) */
- num = i2c_clk * 4;
- tmp = num * 10 / denom;
- if (tmp % 10 >= 5)
- pd->icch = (u_int8_t)((num/denom) + 1);
- else
- pd->icch = (u_int8_t)(num/denom);
-
- /* one more bit of ICCH in ICIC */
- if (pd->flags & IIC_FLAG_HAS_ICIC67) {
- if ((num/denom) > 0xff)
- pd->icic |= ICIC_ICCHB8;
- else
- pd->icic &= ~ICIC_ICCHB8;
- }
-
- /* Enable channel and configure rx ack */
- iic_set_clr(pd, ICCR, ICCR_ICE, 0);
-
- /* Mask all interrupts */
- iic_wr(pd, ICIC, 0);
-
- /* Set the clock */
- iic_wr(pd, ICCL, pd->iccl);
- iic_wr(pd, ICCH, pd->icch);
-}
-
-static void deactivate_ch(struct sh_mobile_i2c_data *pd)
-{
- /* Clear/disable interrupts */
- iic_wr(pd, ICSR, 0);
- iic_wr(pd, ICIC, 0);
-
- /* Disable channel */
- iic_set_clr(pd, ICCR, 0, ICCR_ICE);
-
- /* Disable clock and mark device as idle */
- clk_disable(pd->clk);
- pm_runtime_put_sync(pd->dev);
-}
-
-static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
- enum sh_mobile_i2c_op op, unsigned char data)
-{
- unsigned char ret = 0;
- unsigned long flags;
-
- dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data);
-
- spin_lock_irqsave(&pd->lock, flags);
-
- switch (op) {
- case OP_START: /* issue start and trigger DTE interrupt */
- iic_wr(pd, ICCR, 0x94);
- break;
- case OP_TX_FIRST: /* disable DTE interrupt and write data */
- iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
- iic_wr(pd, ICDR, data);
- break;
- case OP_TX: /* write data */
- iic_wr(pd, ICDR, data);
- break;
- case OP_TX_STOP: /* write data and issue a stop afterwards */
- iic_wr(pd, ICDR, data);
- iic_wr(pd, ICCR, 0x90);
- break;
- case OP_TX_TO_RX: /* select read mode */
- iic_wr(pd, ICCR, 0x81);
- break;
- case OP_RX: /* just read data */
- ret = iic_rd(pd, ICDR);
- break;
- case OP_RX_STOP: /* enable DTE interrupt, issue stop */
- iic_wr(pd, ICIC,
- ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
- iic_wr(pd, ICCR, 0xc0);
- break;
- case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */
- iic_wr(pd, ICIC,
- ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
- ret = iic_rd(pd, ICDR);
- iic_wr(pd, ICCR, 0xc0);
- break;
- }
-
- spin_unlock_irqrestore(&pd->lock, flags);
-
- dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret);
- return ret;
-}
-
-static int sh_mobile_i2c_is_first_byte(struct sh_mobile_i2c_data *pd)
-{
- if (pd->pos == -1)
- return 1;
-
- return 0;
-}
-
-static int sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd)
-{
- if (pd->pos == (pd->msg->len - 1))
- return 1;
-
- return 0;
-}
-
-static void sh_mobile_i2c_get_data(struct sh_mobile_i2c_data *pd,
- unsigned char *buf)
-{
- switch (pd->pos) {
- case -1:
- *buf = (pd->msg->addr & 0x7f) << 1;
- *buf |= (pd->msg->flags & I2C_M_RD) ? 1 : 0;
- break;
- default:
- *buf = pd->msg->buf[pd->pos];
- }
-}
-
-static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd)
-{
- unsigned char data;
-
- if (pd->pos == pd->msg->len)
- return 1;
-
- sh_mobile_i2c_get_data(pd, &data);
-
- if (sh_mobile_i2c_is_last_byte(pd))
- i2c_op(pd, OP_TX_STOP, data);
- else if (sh_mobile_i2c_is_first_byte(pd))
- i2c_op(pd, OP_TX_FIRST, data);
- else
- i2c_op(pd, OP_TX, data);
-
- pd->pos++;
- return 0;
-}
-
-static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
-{
- unsigned char data;
- int real_pos;
-
- do {
- if (pd->pos <= -1) {
- sh_mobile_i2c_get_data(pd, &data);
-
- if (sh_mobile_i2c_is_first_byte(pd))
- i2c_op(pd, OP_TX_FIRST, data);
- else
- i2c_op(pd, OP_TX, data);
- break;
- }
-
- if (pd->pos == 0) {
- i2c_op(pd, OP_TX_TO_RX, 0);
- break;
- }
-
- real_pos = pd->pos - 2;
-
- if (pd->pos == pd->msg->len) {
- if (real_pos < 0) {
- i2c_op(pd, OP_RX_STOP, 0);
- break;
- }
- data = i2c_op(pd, OP_RX_STOP_DATA, 0);
- } else
- data = i2c_op(pd, OP_RX, 0);
-
- if (real_pos >= 0)
- pd->msg->buf[real_pos] = data;
- } while (0);
-
- pd->pos++;
- return pd->pos == (pd->msg->len + 2);
-}
-
-static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
-{
- struct platform_device *dev = dev_id;
- struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
- unsigned char sr;
- int wakeup;
-
- sr = iic_rd(pd, ICSR);
- pd->sr |= sr; /* remember state */
-
- dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
- (pd->msg->flags & I2C_M_RD) ? "read" : "write",
- pd->pos, pd->msg->len);
-
- if (sr & (ICSR_AL | ICSR_TACK)) {
- /* don't interrupt transaction - continue to issue stop */
- iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK));
- wakeup = 0;
- } else if (pd->msg->flags & I2C_M_RD)
- wakeup = sh_mobile_i2c_isr_rx(pd);
- else
- wakeup = sh_mobile_i2c_isr_tx(pd);
-
- if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */
- iic_wr(pd, ICSR, sr & ~ICSR_WAIT);
-
- if (wakeup) {
- pd->sr |= SW_DONE;
- wake_up(&pd->wait);
- }
-
- return IRQ_HANDLED;
-}
-
-static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
-{
- if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) {
- dev_err(pd->dev, "Unsupported zero length i2c read\n");
- return -EIO;
- }
-
- /* Initialize channel registers */
- iic_set_clr(pd, ICCR, 0, ICCR_ICE);
-
- /* Enable channel and configure rx ack */
- iic_set_clr(pd, ICCR, ICCR_ICE, 0);
-
- /* Set the clock */
- iic_wr(pd, ICCL, pd->iccl);
- iic_wr(pd, ICCH, pd->icch);
-
- pd->msg = usr_msg;
- pd->pos = -1;
- pd->sr = 0;
-
- /* Enable all interrupts to begin with */
- iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
- return 0;
-}
-
-static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
- struct i2c_msg *msgs,
- int num)
-{
- struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
- struct i2c_msg *msg;
- int err = 0;
- u_int8_t val;
- int i, k, retry_count;
-
- activate_ch(pd);
-
- /* Process all messages */
- for (i = 0; i < num; i++) {
- msg = &msgs[i];
-
- err = start_ch(pd, msg);
- if (err)
- break;
-
- i2c_op(pd, OP_START, 0);
-
- /* The interrupt handler takes care of the rest... */
- k = wait_event_timeout(pd->wait,
- pd->sr & (ICSR_TACK | SW_DONE),
- 5 * HZ);
- if (!k)
- dev_err(pd->dev, "Transfer request timed out\n");
-
- retry_count = 1000;
-again:
- val = iic_rd(pd, ICSR);
-
- dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
-
- /* the interrupt handler may wake us up before the
- * transfer is finished, so poll the hardware
- * until we're done.
- */
- if (val & ICSR_BUSY) {
- udelay(10);
- if (retry_count--)
- goto again;
-
- err = -EIO;
- dev_err(pd->dev, "Polling timed out\n");
- break;
- }
-
- /* handle missing acknowledge and arbitration lost */
- if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
- err = -EIO;
- break;
- }
- }
-
- deactivate_ch(pd);
-
- if (!err)
- err = num;
- return err;
-}
-
-static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm sh_mobile_i2c_algorithm = {
- .functionality = sh_mobile_i2c_func,
- .master_xfer = sh_mobile_i2c_xfer,
-};
-
-static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
-{
- struct resource *res;
- int ret = -ENXIO;
- int n, k = 0;
-
- while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
- for (n = res->start; hook && n <= res->end; n++) {
- if (request_irq(n, sh_mobile_i2c_isr, 0,
- dev_name(&dev->dev), dev)) {
- for (n--; n >= res->start; n--)
- free_irq(n, dev);
-
- goto rollback;
- }
- }
- k++;
- }
-
- if (hook)
- return k > 0 ? 0 : -ENOENT;
-
- ret = 0;
-
- rollback:
- k--;
-
- while (k >= 0) {
- res = platform_get_resource(dev, IORESOURCE_IRQ, k);
- for (n = res->start; n <= res->end; n++)
- free_irq(n, dev);
-
- k--;
- }
-
- return ret;
-}
-
-static int sh_mobile_i2c_probe(struct platform_device *dev)
-{
- struct i2c_sh_mobile_platform_data *pdata = dev->dev.platform_data;
- struct sh_mobile_i2c_data *pd;
- struct i2c_adapter *adap;
- struct resource *res;
- int size;
- int ret;
-
- pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL);
- if (pd == NULL) {
- dev_err(&dev->dev, "cannot allocate private data\n");
- return -ENOMEM;
- }
-
- pd->clk = clk_get(&dev->dev, NULL);
- if (IS_ERR(pd->clk)) {
- dev_err(&dev->dev, "cannot get clock\n");
- ret = PTR_ERR(pd->clk);
- goto err;
- }
-
- ret = sh_mobile_i2c_hook_irqs(dev, 1);
- if (ret) {
- dev_err(&dev->dev, "cannot request IRQ\n");
- goto err_clk;
- }
-
- pd->dev = &dev->dev;
- platform_set_drvdata(dev, pd);
-
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&dev->dev, "cannot find IO resource\n");
- ret = -ENOENT;
- goto err_irq;
- }
-
- size = resource_size(res);
-
- pd->reg = ioremap(res->start, size);
- if (pd->reg == NULL) {
- dev_err(&dev->dev, "cannot map IO\n");
- ret = -ENXIO;
- goto err_irq;
- }
-
- /* Use platformd data bus speed or NORMAL_SPEED */
- pd->bus_speed = NORMAL_SPEED;
- if (pdata && pdata->bus_speed)
- pd->bus_speed = pdata->bus_speed;
-
- /* The IIC blocks on SH-Mobile ARM processors
- * come with two new bits in ICIC.
- */
- if (size > 0x17)
- pd->flags |= IIC_FLAG_HAS_ICIC67;
-
- /* Enable Runtime PM for this device.
- *
- * Also tell the Runtime PM core to ignore children
- * for this device since it is valid for us to suspend
- * this I2C master driver even though the slave devices
- * on the I2C bus may not be suspended.
- *
- * The state of the I2C hardware bus is unaffected by
- * the Runtime PM state.
- */
- pm_suspend_ignore_children(&dev->dev, true);
- pm_runtime_enable(&dev->dev);
-
- /* setup the private data */
- adap = &pd->adap;
- i2c_set_adapdata(adap, pd);
-
- adap->owner = THIS_MODULE;
- adap->algo = &sh_mobile_i2c_algorithm;
- adap->dev.parent = &dev->dev;
- adap->retries = 5;
- adap->nr = dev->id;
-
- strlcpy(adap->name, dev->name, sizeof(adap->name));
-
- spin_lock_init(&pd->lock);
- init_waitqueue_head(&pd->wait);
-
- ret = i2c_add_numbered_adapter(adap);
- if (ret < 0) {
- dev_err(&dev->dev, "cannot add numbered adapter\n");
- goto err_all;
- }
-
- dev_info(&dev->dev, "I2C adapter %d with bus speed %lu Hz\n",
- adap->nr, pd->bus_speed);
- return 0;
-
- err_all:
- iounmap(pd->reg);
- err_irq:
- sh_mobile_i2c_hook_irqs(dev, 0);
- err_clk:
- clk_put(pd->clk);
- err:
- kfree(pd);
- return ret;
-}
-
-static int sh_mobile_i2c_remove(struct platform_device *dev)
-{
- struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
-
- i2c_del_adapter(&pd->adap);
- iounmap(pd->reg);
- sh_mobile_i2c_hook_irqs(dev, 0);
- clk_put(pd->clk);
- pm_runtime_disable(&dev->dev);
- kfree(pd);
- return 0;
-}
-
-static int sh_mobile_i2c_runtime_nop(struct device *dev)
-{
- /* Runtime PM callback shared between ->runtime_suspend()
- * and ->runtime_resume(). Simply returns success.
- *
- * This driver re-initializes all registers after
- * pm_runtime_get_sync() anyway so there is no need
- * to save and restore registers here.
- */
- return 0;
-}
-
-static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
- .runtime_suspend = sh_mobile_i2c_runtime_nop,
- .runtime_resume = sh_mobile_i2c_runtime_nop,
-};
-
-static struct platform_driver sh_mobile_i2c_driver = {
- .driver = {
- .name = "i2c-sh_mobile",
- .owner = THIS_MODULE,
- .pm = &sh_mobile_i2c_dev_pm_ops,
- },
- .probe = sh_mobile_i2c_probe,
- .remove = sh_mobile_i2c_remove,
-};
-
-static int __init sh_mobile_i2c_adap_init(void)
-{
- return platform_driver_register(&sh_mobile_i2c_driver);
-}
-
-static void __exit sh_mobile_i2c_adap_exit(void)
-{
- platform_driver_unregister(&sh_mobile_i2c_driver);
-}
-
-subsys_initcall(sh_mobile_i2c_adap_init);
-module_exit(sh_mobile_i2c_adap_exit);
-
-MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
-MODULE_AUTHOR("Magnus Damm");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:i2c-sh_mobile");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sibyte.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sibyte.c
deleted file mode 100644
index 0fe505d7..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sibyte.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2004 Steven J. Hill
- * Copyright (C) 2001,2002,2003 Broadcom Corporation
- * Copyright (C) 1995-2000 Simon G. Vogl
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_smbus.h>
-
-
-struct i2c_algo_sibyte_data {
- void *data; /* private data */
- int bus; /* which bus */
- void *reg_base; /* CSR base */
-};
-
-/* ----- global defines ----------------------------------------------- */
-#define SMB_CSR(a,r) ((long)(a->reg_base + r))
-
-
-static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data * data)
-{
- struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
- int data_bytes = 0;
- int error;
-
- while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
- ;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- csr_out32((V_SMB_ADDR(addr) |
- (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) |
- V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START));
- break;
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_READ) {
- csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE),
- SMB_CSR(adap, R_SMB_START));
- data_bytes = 1;
- } else {
- csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
- csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE),
- SMB_CSR(adap, R_SMB_START));
- }
- break;
- case I2C_SMBUS_BYTE_DATA:
- csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
- if (read_write == I2C_SMBUS_READ) {
- csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE),
- SMB_CSR(adap, R_SMB_START));
- data_bytes = 1;
- } else {
- csr_out32(V_SMB_LB(data->byte),
- SMB_CSR(adap, R_SMB_DATA));
- csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
- SMB_CSR(adap, R_SMB_START));
- }
- break;
- case I2C_SMBUS_WORD_DATA:
- csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
- if (read_write == I2C_SMBUS_READ) {
- csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE),
- SMB_CSR(adap, R_SMB_START));
- data_bytes = 2;
- } else {
- csr_out32(V_SMB_LB(data->word & 0xff),
- SMB_CSR(adap, R_SMB_DATA));
- csr_out32(V_SMB_MB(data->word >> 8),
- SMB_CSR(adap, R_SMB_DATA));
- csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
- SMB_CSR(adap, R_SMB_START));
- }
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
- ;
-
- error = csr_in32(SMB_CSR(adap, R_SMB_STATUS));
- if (error & M_SMB_ERROR) {
- /* Clear error bit by writing a 1 */
- csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS));
- return (error & M_SMB_ERROR_TYPE) ? -EIO : -ENXIO;
- }
-
- if (data_bytes == 1)
- data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff;
- if (data_bytes == 2)
- data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff;
-
- return 0;
-}
-
-static u32 bit_func(struct i2c_adapter *adap)
-{
- return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA);
-}
-
-
-/* -----exported algorithm data: ------------------------------------- */
-
-static const struct i2c_algorithm i2c_sibyte_algo = {
- .smbus_xfer = smbus_xfer,
- .functionality = bit_func,
-};
-
-/*
- * registering functions to load algorithms at runtime
- */
-static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
-{
- struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
-
- /* Register new adapter to i2c module... */
- i2c_adap->algo = &i2c_sibyte_algo;
-
- /* Set the requested frequency. */
- csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
- csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
-
- return i2c_add_numbered_adapter(i2c_adap);
-}
-
-
-static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
- { NULL, 0, (void *) (CKSEG1+A_SMB_BASE(0)) },
- { NULL, 1, (void *) (CKSEG1+A_SMB_BASE(1)) }
-};
-
-static struct i2c_adapter sibyte_board_adapter[2] = {
- {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = NULL,
- .algo_data = &sibyte_board_data[0],
- .nr = 0,
- .name = "SiByte SMBus 0",
- },
- {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = NULL,
- .algo_data = &sibyte_board_data[1],
- .nr = 1,
- .name = "SiByte SMBus 1",
- },
-};
-
-static int __init i2c_sibyte_init(void)
-{
- pr_info("i2c-sibyte: i2c SMBus adapter module for SiByte board\n");
- if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0)
- return -ENODEV;
- if (i2c_sibyte_add_bus(&sibyte_board_adapter[1],
- K_SMB_FREQ_400KHZ) < 0) {
- i2c_del_adapter(&sibyte_board_adapter[0]);
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit i2c_sibyte_exit(void)
-{
- i2c_del_adapter(&sibyte_board_adapter[0]);
- i2c_del_adapter(&sibyte_board_adapter[1]);
-}
-
-module_init(i2c_sibyte_init);
-module_exit(i2c_sibyte_exit);
-
-MODULE_AUTHOR("Kip Walker (Broadcom Corp.), Steven J. Hill <sjhill@realitydiluted.com>");
-MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-simtec.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-simtec.c
deleted file mode 100644
index 4fc87e7c..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-simtec.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Simtec Generic I2C Controller
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-struct simtec_i2c_data {
- struct resource *ioarea;
- void __iomem *reg;
- struct i2c_adapter adap;
- struct i2c_algo_bit_data bit;
-};
-
-#define CMD_SET_SDA (1<<2)
-#define CMD_SET_SCL (1<<3)
-
-#define STATE_SDA (1<<0)
-#define STATE_SCL (1<<1)
-
-/* i2c bit-bus functions */
-
-static void simtec_i2c_setsda(void *pw, int state)
-{
- struct simtec_i2c_data *pd = pw;
- writeb(CMD_SET_SDA | (state ? STATE_SDA : 0), pd->reg);
-}
-
-static void simtec_i2c_setscl(void *pw, int state)
-{
- struct simtec_i2c_data *pd = pw;
- writeb(CMD_SET_SCL | (state ? STATE_SCL : 0), pd->reg);
-}
-
-static int simtec_i2c_getsda(void *pw)
-{
- struct simtec_i2c_data *pd = pw;
- return readb(pd->reg) & STATE_SDA ? 1 : 0;
-}
-
-static int simtec_i2c_getscl(void *pw)
-{
- struct simtec_i2c_data *pd = pw;
- return readb(pd->reg) & STATE_SCL ? 1 : 0;
-}
-
-/* device registration */
-
-static int simtec_i2c_probe(struct platform_device *dev)
-{
- struct simtec_i2c_data *pd;
- struct resource *res;
- int size;
- int ret;
-
- pd = kzalloc(sizeof(struct simtec_i2c_data), GFP_KERNEL);
- if (pd == NULL) {
- dev_err(&dev->dev, "cannot allocate private data\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(dev, pd);
-
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&dev->dev, "cannot find IO resource\n");
- ret = -ENOENT;
- goto err;
- }
-
- size = resource_size(res);
-
- pd->ioarea = request_mem_region(res->start, size, dev->name);
- if (pd->ioarea == NULL) {
- dev_err(&dev->dev, "cannot request IO\n");
- ret = -ENXIO;
- goto err;
- }
-
- pd->reg = ioremap(res->start, size);
- if (pd->reg == NULL) {
- dev_err(&dev->dev, "cannot map IO\n");
- ret = -ENXIO;
- goto err_res;
- }
-
- /* setup the private data */
-
- pd->adap.owner = THIS_MODULE;
- pd->adap.algo_data = &pd->bit;
- pd->adap.dev.parent = &dev->dev;
-
- strlcpy(pd->adap.name, "Simtec I2C", sizeof(pd->adap.name));
-
- pd->bit.data = pd;
- pd->bit.setsda = simtec_i2c_setsda;
- pd->bit.setscl = simtec_i2c_setscl;
- pd->bit.getsda = simtec_i2c_getsda;
- pd->bit.getscl = simtec_i2c_getscl;
- pd->bit.timeout = HZ;
- pd->bit.udelay = 20;
-
- ret = i2c_bit_add_bus(&pd->adap);
- if (ret)
- goto err_all;
-
- return 0;
-
- err_all:
- iounmap(pd->reg);
-
- err_res:
- release_resource(pd->ioarea);
- kfree(pd->ioarea);
-
- err:
- kfree(pd);
- return ret;
-}
-
-static int simtec_i2c_remove(struct platform_device *dev)
-{
- struct simtec_i2c_data *pd = platform_get_drvdata(dev);
-
- i2c_del_adapter(&pd->adap);
-
- iounmap(pd->reg);
- release_resource(pd->ioarea);
- kfree(pd->ioarea);
- kfree(pd);
-
- return 0;
-}
-
-/* device driver */
-
-static struct platform_driver simtec_i2c_driver = {
- .driver = {
- .name = "simtec-i2c",
- .owner = THIS_MODULE,
- },
- .probe = simtec_i2c_probe,
- .remove = simtec_i2c_remove,
-};
-
-module_platform_driver(simtec_i2c_driver);
-
-MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:simtec-i2c");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sirf.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sirf.c
deleted file mode 100644
index 5574a477..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sirf.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * I2C bus driver for CSR SiRFprimaII
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#define SIRFSOC_I2C_CLK_CTRL 0x00
-#define SIRFSOC_I2C_STATUS 0x0C
-#define SIRFSOC_I2C_CTRL 0x10
-#define SIRFSOC_I2C_IO_CTRL 0x14
-#define SIRFSOC_I2C_SDA_DELAY 0x18
-#define SIRFSOC_I2C_CMD_START 0x1C
-#define SIRFSOC_I2C_CMD_BUF 0x30
-#define SIRFSOC_I2C_DATA_BUF 0x80
-
-#define SIRFSOC_I2C_CMD_BUF_MAX 16
-#define SIRFSOC_I2C_DATA_BUF_MAX 16
-
-#define SIRFSOC_I2C_CMD(x) (SIRFSOC_I2C_CMD_BUF + (x)*0x04)
-#define SIRFSOC_I2C_DATA_MASK(x) (0xFF<<(((x)&3)*8))
-#define SIRFSOC_I2C_DATA_SHIFT(x) (((x)&3)*8)
-
-#define SIRFSOC_I2C_DIV_MASK (0xFFFF)
-
-/* I2C status flags */
-#define SIRFSOC_I2C_STAT_BUSY BIT(0)
-#define SIRFSOC_I2C_STAT_TIP BIT(1)
-#define SIRFSOC_I2C_STAT_NACK BIT(2)
-#define SIRFSOC_I2C_STAT_TR_INT BIT(4)
-#define SIRFSOC_I2C_STAT_STOP BIT(6)
-#define SIRFSOC_I2C_STAT_CMD_DONE BIT(8)
-#define SIRFSOC_I2C_STAT_ERR BIT(9)
-#define SIRFSOC_I2C_CMD_INDEX (0x1F<<16)
-
-/* I2C control flags */
-#define SIRFSOC_I2C_RESET BIT(0)
-#define SIRFSOC_I2C_CORE_EN BIT(1)
-#define SIRFSOC_I2C_MASTER_MODE BIT(2)
-#define SIRFSOC_I2C_CMD_DONE_EN BIT(11)
-#define SIRFSOC_I2C_ERR_INT_EN BIT(12)
-
-#define SIRFSOC_I2C_SDA_DELAY_MASK (0xFF)
-#define SIRFSOC_I2C_SCLF_FILTER (3<<8)
-
-#define SIRFSOC_I2C_START_CMD BIT(0)
-
-#define SIRFSOC_I2C_CMD_RP(x) ((x)&0x7)
-#define SIRFSOC_I2C_NACK BIT(3)
-#define SIRFSOC_I2C_WRITE BIT(4)
-#define SIRFSOC_I2C_READ BIT(5)
-#define SIRFSOC_I2C_STOP BIT(6)
-#define SIRFSOC_I2C_START BIT(7)
-
-#define SIRFSOC_I2C_DEFAULT_SPEED 100000
-
-struct sirfsoc_i2c {
- void __iomem *base;
- struct clk *clk;
- u32 cmd_ptr; /* Current position in CMD buffer */
- u8 *buf; /* Buffer passed by user */
- u32 msg_len; /* Message length */
- u32 finished_len; /* number of bytes read/written */
- u32 read_cmd_len; /* number of read cmd sent */
- int msg_read; /* 1 indicates a read message */
- int err_status; /* 1 indicates an error on bus */
-
- u32 sda_delay; /* For suspend/resume */
- u32 clk_div;
- int last; /* Last message in transfer, STOP cmd can be sent */
-
- struct completion done; /* indicates completion of message transfer */
- struct i2c_adapter adapter;
-};
-
-static void i2c_sirfsoc_read_data(struct sirfsoc_i2c *siic)
-{
- u32 data = 0;
- int i;
-
- for (i = 0; i < siic->read_cmd_len; i++) {
- if (!(i & 0x3))
- data = readl(siic->base + SIRFSOC_I2C_DATA_BUF + i);
- siic->buf[siic->finished_len++] =
- (u8)((data & SIRFSOC_I2C_DATA_MASK(i)) >>
- SIRFSOC_I2C_DATA_SHIFT(i));
- }
-}
-
-static void i2c_sirfsoc_queue_cmd(struct sirfsoc_i2c *siic)
-{
- u32 regval;
- int i = 0;
-
- if (siic->msg_read) {
- while (((siic->finished_len + i) < siic->msg_len)
- && (siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX)) {
- regval = SIRFSOC_I2C_READ | SIRFSOC_I2C_CMD_RP(0);
- if (((siic->finished_len + i) ==
- (siic->msg_len - 1)) && siic->last)
- regval |= SIRFSOC_I2C_STOP | SIRFSOC_I2C_NACK;
- writel(regval,
- siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
- i++;
- }
-
- siic->read_cmd_len = i;
- } else {
- while ((siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX - 1)
- && (siic->finished_len < siic->msg_len)) {
- regval = SIRFSOC_I2C_WRITE | SIRFSOC_I2C_CMD_RP(0);
- if ((siic->finished_len == (siic->msg_len - 1))
- && siic->last)
- regval |= SIRFSOC_I2C_STOP;
- writel(regval,
- siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
- writel(siic->buf[siic->finished_len++],
- siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
- }
- }
- siic->cmd_ptr = 0;
-
- /* Trigger the transfer */
- writel(SIRFSOC_I2C_START_CMD, siic->base + SIRFSOC_I2C_CMD_START);
-}
-
-static irqreturn_t i2c_sirfsoc_irq(int irq, void *dev_id)
-{
- struct sirfsoc_i2c *siic = (struct sirfsoc_i2c *)dev_id;
- u32 i2c_stat = readl(siic->base + SIRFSOC_I2C_STATUS);
-
- if (i2c_stat & SIRFSOC_I2C_STAT_ERR) {
- /* Error conditions */
- siic->err_status = 1;
- writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS);
-
- if (i2c_stat & SIRFSOC_I2C_STAT_NACK)
- dev_err(&siic->adapter.dev, "ACK not received\n");
- else
- dev_err(&siic->adapter.dev, "I2C error\n");
-
- complete(&siic->done);
- } else if (i2c_stat & SIRFSOC_I2C_STAT_CMD_DONE) {
- /* CMD buffer execution complete */
- if (siic->msg_read)
- i2c_sirfsoc_read_data(siic);
- if (siic->finished_len == siic->msg_len)
- complete(&siic->done);
- else /* Fill a new CMD buffer for left data */
- i2c_sirfsoc_queue_cmd(siic);
-
- writel(SIRFSOC_I2C_STAT_CMD_DONE, siic->base + SIRFSOC_I2C_STATUS);
- }
-
- return IRQ_HANDLED;
-}
-
-static void i2c_sirfsoc_set_address(struct sirfsoc_i2c *siic,
- struct i2c_msg *msg)
-{
- unsigned char addr;
- u32 regval = SIRFSOC_I2C_START | SIRFSOC_I2C_CMD_RP(0) | SIRFSOC_I2C_WRITE;
-
- /* no data and last message -> add STOP */
- if (siic->last && (msg->len == 0))
- regval |= SIRFSOC_I2C_STOP;
-
- writel(regval, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
-
- addr = msg->addr << 1; /* Generate address */
- if (msg->flags & I2C_M_RD)
- addr |= 1;
-
- writel(addr, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
-}
-
-static int i2c_sirfsoc_xfer_msg(struct sirfsoc_i2c *siic, struct i2c_msg *msg)
-{
- u32 regval = readl(siic->base + SIRFSOC_I2C_CTRL);
- /* timeout waiting for the xfer to finish or fail */
- int timeout = msecs_to_jiffies((msg->len + 1) * 50);
- int ret = 0;
-
- i2c_sirfsoc_set_address(siic, msg);
-
- writel(regval | SIRFSOC_I2C_CMD_DONE_EN | SIRFSOC_I2C_ERR_INT_EN,
- siic->base + SIRFSOC_I2C_CTRL);
- i2c_sirfsoc_queue_cmd(siic);
-
- if (wait_for_completion_timeout(&siic->done, timeout) == 0) {
- siic->err_status = 1;
- dev_err(&siic->adapter.dev, "Transfer timeout\n");
- }
-
- writel(regval & ~(SIRFSOC_I2C_CMD_DONE_EN | SIRFSOC_I2C_ERR_INT_EN),
- siic->base + SIRFSOC_I2C_CTRL);
- writel(0, siic->base + SIRFSOC_I2C_CMD_START);
-
- if (siic->err_status) {
- writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET,
- siic->base + SIRFSOC_I2C_CTRL);
- while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
- cpu_relax();
-
- ret = -EIO;
- }
-
- return ret;
-}
-
-static u32 i2c_sirfsoc_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static int i2c_sirfsoc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
-{
- struct sirfsoc_i2c *siic = adap->algo_data;
- int i, ret;
-
- clk_enable(siic->clk);
-
- for (i = 0; i < num; i++) {
- siic->buf = msgs[i].buf;
- siic->msg_len = msgs[i].len;
- siic->msg_read = !!(msgs[i].flags & I2C_M_RD);
- siic->err_status = 0;
- siic->cmd_ptr = 0;
- siic->finished_len = 0;
- siic->last = (i == (num - 1));
-
- ret = i2c_sirfsoc_xfer_msg(siic, &msgs[i]);
- if (ret) {
- clk_disable(siic->clk);
- return ret;
- }
- }
-
- clk_disable(siic->clk);
- return num;
-}
-
-/* I2C algorithms associated with this master controller driver */
-static const struct i2c_algorithm i2c_sirfsoc_algo = {
- .master_xfer = i2c_sirfsoc_xfer,
- .functionality = i2c_sirfsoc_func,
-};
-
-static int __devinit i2c_sirfsoc_probe(struct platform_device *pdev)
-{
- struct sirfsoc_i2c *siic;
- struct i2c_adapter *adap;
- struct resource *mem_res;
- struct clk *clk;
- int bitrate;
- int ctrl_speed;
- int irq;
-
- int err;
- u32 regval;
-
- clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(clk)) {
- err = PTR_ERR(clk);
- dev_err(&pdev->dev, "Clock get failed\n");
- goto err_get_clk;
- }
-
- err = clk_prepare(clk);
- if (err) {
- dev_err(&pdev->dev, "Clock prepare failed\n");
- goto err_clk_prep;
- }
-
- err = clk_enable(clk);
- if (err) {
- dev_err(&pdev->dev, "Clock enable failed\n");
- goto err_clk_en;
- }
-
- ctrl_speed = clk_get_rate(clk);
-
- siic = devm_kzalloc(&pdev->dev, sizeof(*siic), GFP_KERNEL);
- if (!siic) {
- dev_err(&pdev->dev, "Can't allocate driver data\n");
- err = -ENOMEM;
- goto out;
- }
- adap = &siic->adapter;
- adap->class = I2C_CLASS_HWMON;
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (mem_res == NULL) {
- dev_err(&pdev->dev, "Unable to get MEM resource\n");
- err = -EINVAL;
- goto out;
- }
-
- siic->base = devm_request_and_ioremap(&pdev->dev, mem_res);
- if (siic->base == NULL) {
- dev_err(&pdev->dev, "IO remap failed!\n");
- err = -ENOMEM;
- goto out;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- err = irq;
- goto out;
- }
- err = devm_request_irq(&pdev->dev, irq, i2c_sirfsoc_irq, 0,
- dev_name(&pdev->dev), siic);
- if (err)
- goto out;
-
- adap->algo = &i2c_sirfsoc_algo;
- adap->algo_data = siic;
-
- adap->dev.parent = &pdev->dev;
- adap->nr = pdev->id;
-
- strlcpy(adap->name, "sirfsoc-i2c", sizeof(adap->name));
-
- platform_set_drvdata(pdev, adap);
- init_completion(&siic->done);
-
- /* Controller Initalisation */
-
- writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
- while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
- cpu_relax();
- writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE,
- siic->base + SIRFSOC_I2C_CTRL);
-
- siic->clk = clk;
-
- err = of_property_read_u32(pdev->dev.of_node,
- "clock-frequency", &bitrate);
- if (err < 0)
- bitrate = SIRFSOC_I2C_DEFAULT_SPEED;
-
- if (bitrate < 100000)
- regval =
- (2 * ctrl_speed) / (2 * bitrate * 11);
- else
- regval = ctrl_speed / (bitrate * 5);
-
- writel(regval, siic->base + SIRFSOC_I2C_CLK_CTRL);
- if (regval > 0xFF)
- writel(0xFF, siic->base + SIRFSOC_I2C_SDA_DELAY);
- else
- writel(regval, siic->base + SIRFSOC_I2C_SDA_DELAY);
-
- err = i2c_add_numbered_adapter(adap);
- if (err < 0) {
- dev_err(&pdev->dev, "Can't add new i2c adapter\n");
- goto out;
- }
-
- clk_disable(clk);
-
- dev_info(&pdev->dev, " I2C adapter ready to operate\n");
-
- return 0;
-
-out:
- clk_disable(clk);
-err_clk_en:
- clk_unprepare(clk);
-err_clk_prep:
- clk_put(clk);
-err_get_clk:
- return err;
-}
-
-static int __devexit i2c_sirfsoc_remove(struct platform_device *pdev)
-{
- struct i2c_adapter *adapter = platform_get_drvdata(pdev);
- struct sirfsoc_i2c *siic = adapter->algo_data;
-
- writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
- i2c_del_adapter(adapter);
- clk_unprepare(siic->clk);
- clk_put(siic->clk);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int i2c_sirfsoc_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct i2c_adapter *adapter = platform_get_drvdata(pdev);
- struct sirfsoc_i2c *siic = adapter->algo_data;
-
- clk_enable(siic->clk);
- siic->sda_delay = readl(siic->base + SIRFSOC_I2C_SDA_DELAY);
- siic->clk_div = readl(siic->base + SIRFSOC_I2C_CLK_CTRL);
- clk_disable(siic->clk);
- return 0;
-}
-
-static int i2c_sirfsoc_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct i2c_adapter *adapter = platform_get_drvdata(pdev);
- struct sirfsoc_i2c *siic = adapter->algo_data;
-
- clk_enable(siic->clk);
- writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
- writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE,
- siic->base + SIRFSOC_I2C_CTRL);
- writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL);
- writel(siic->sda_delay, siic->base + SIRFSOC_I2C_SDA_DELAY);
- clk_disable(siic->clk);
- return 0;
-}
-
-static const struct dev_pm_ops i2c_sirfsoc_pm_ops = {
- .suspend = i2c_sirfsoc_suspend,
- .resume = i2c_sirfsoc_resume,
-};
-#endif
-
-static const struct of_device_id sirfsoc_i2c_of_match[] __devinitconst = {
- { .compatible = "sirf,prima2-i2c", },
- {},
-};
-MODULE_DEVICE_TABLE(of, sirfsoc_i2c_of_match);
-
-static struct platform_driver i2c_sirfsoc_driver = {
- .driver = {
- .name = "sirfsoc_i2c",
- .owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .pm = &i2c_sirfsoc_pm_ops,
-#endif
- .of_match_table = sirfsoc_i2c_of_match,
- },
- .probe = i2c_sirfsoc_probe,
- .remove = __devexit_p(i2c_sirfsoc_remove),
-};
-module_platform_driver(i2c_sirfsoc_driver);
-
-MODULE_DESCRIPTION("SiRF SoC I2C master controller driver");
-MODULE_AUTHOR("Zhiwu Song <Zhiwu.Song@csr.com>, "
- "Xiangzhen Ye <Xiangzhen.Ye@csr.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis5595.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis5595.c
deleted file mode 100644
index 87e5126d..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis5595.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Note: we assume there can only be one SIS5595 with one SMBus interface */
-
-/*
- Note: all have mfr. ID 0x1039.
- SUPPORTED PCI ID
- 5595 0008
-
- Note: these chips contain a 0008 device which is incompatible with the
- 5595. We recognize these by the presence of the listed
- "blacklist" PCI ID and refuse to load.
-
- NOT SUPPORTED PCI ID BLACKLIST PCI ID
- 540 0008 0540
- 550 0008 0550
- 5513 0008 5511
- 5581 0008 5597
- 5582 0008 5597
- 5597 0008 5597
- 5598 0008 5597/5598
- 630 0008 0630
- 645 0008 0645
- 646 0008 0646
- 648 0008 0648
- 650 0008 0650
- 651 0008 0651
- 730 0008 0730
- 735 0008 0735
- 745 0008 0745
- 746 0008 0746
-*/
-
-/* TO DO:
- * Add Block Transfers (ugly, but supported by the adapter)
- * Add adapter resets
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-static int blacklist[] = {
- PCI_DEVICE_ID_SI_540,
- PCI_DEVICE_ID_SI_550,
- PCI_DEVICE_ID_SI_630,
- PCI_DEVICE_ID_SI_645,
- PCI_DEVICE_ID_SI_646,
- PCI_DEVICE_ID_SI_648,
- PCI_DEVICE_ID_SI_650,
- PCI_DEVICE_ID_SI_651,
- PCI_DEVICE_ID_SI_730,
- PCI_DEVICE_ID_SI_735,
- PCI_DEVICE_ID_SI_745,
- PCI_DEVICE_ID_SI_746,
- PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but that ID
- shows up in other chips so we use the 5511
- ID for recognition */
- PCI_DEVICE_ID_SI_5597,
- PCI_DEVICE_ID_SI_5598,
- 0, /* terminates the list */
-};
-
-/* Length of ISA address segment */
-#define SIS5595_EXTENT 8
-/* SIS5595 SMBus registers */
-#define SMB_STS_LO 0x00
-#define SMB_STS_HI 0x01
-#define SMB_CTL_LO 0x02
-#define SMB_CTL_HI 0x03
-#define SMB_ADDR 0x04
-#define SMB_CMD 0x05
-#define SMB_PCNT 0x06
-#define SMB_CNT 0x07
-#define SMB_BYTE 0x08
-#define SMB_DEV 0x10
-#define SMB_DB0 0x11
-#define SMB_DB1 0x12
-#define SMB_HAA 0x13
-
-/* PCI Address Constants */
-#define SMB_INDEX 0x38
-#define SMB_DAT 0x39
-#define SIS5595_ENABLE_REG 0x40
-#define ACPI_BASE 0x90
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-
-/* SIS5595 constants */
-#define SIS5595_QUICK 0x00
-#define SIS5595_BYTE 0x02
-#define SIS5595_BYTE_DATA 0x04
-#define SIS5595_WORD_DATA 0x06
-#define SIS5595_PROC_CALL 0x08
-#define SIS5595_BLOCK_DATA 0x0A
-
-/* insmod parameters */
-
-/* If force_addr is set to anything different from 0, we forcibly enable
- the device at the given address. */
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
-
-static struct pci_driver sis5595_driver;
-static unsigned short sis5595_base;
-static struct pci_dev *sis5595_pdev;
-
-static u8 sis5595_read(u8 reg)
-{
- outb(reg, sis5595_base + SMB_INDEX);
- return inb(sis5595_base + SMB_DAT);
-}
-
-static void sis5595_write(u8 reg, u8 data)
-{
- outb(reg, sis5595_base + SMB_INDEX);
- outb(data, sis5595_base + SMB_DAT);
-}
-
-static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
-{
- u16 a;
- u8 val;
- int *i;
- int retval;
-
- /* Look for imposters */
- for (i = blacklist; *i != 0; i++) {
- struct pci_dev *dev;
- dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
- if (dev) {
- dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
- pci_dev_put(dev);
- return -ENODEV;
- }
- }
-
- /* Determine the address of the SMBus areas */
- pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
- if (sis5595_base == 0 && force_addr == 0) {
- dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
- return -ENODEV;
- }
-
- if (force_addr)
- sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
- dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
-
- /* NB: We grab just the two SMBus registers here, but this may still
- * interfere with ACPI :-( */
- retval = acpi_check_region(sis5595_base + SMB_INDEX, 2,
- sis5595_driver.name);
- if (retval)
- return retval;
-
- if (!request_region(sis5595_base + SMB_INDEX, 2,
- sis5595_driver.name)) {
- dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
- sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
- return -ENODEV;
- }
-
- if (force_addr) {
- dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
- if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)
- != PCIBIOS_SUCCESSFUL)
- goto error;
- if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)
- != PCIBIOS_SUCCESSFUL)
- goto error;
- if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
- /* doesn't work for some chips! */
- dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
- goto error;
- }
- }
-
- if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
- != PCIBIOS_SUCCESSFUL)
- goto error;
- if ((val & 0x80) == 0) {
- dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
- if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)
- != PCIBIOS_SUCCESSFUL)
- goto error;
- if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
- != PCIBIOS_SUCCESSFUL)
- goto error;
- if ((val & 0x80) == 0) {
- /* doesn't work for some chips? */
- dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
- goto error;
- }
- }
-
- /* Everything is happy */
- return 0;
-
-error:
- release_region(sis5595_base + SMB_INDEX, 2);
- return -ENODEV;
-}
-
-static int sis5595_transaction(struct i2c_adapter *adap)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- /* Make sure the SMBus host is ready to start transmitting */
- temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
- if (temp != 0x00) {
- dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
- sis5595_write(SMB_STS_LO, temp & 0xff);
- sis5595_write(SMB_STS_HI, temp >> 8);
- if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
- dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
- return -EBUSY;
- } else {
- dev_dbg(&adap->dev, "Successful!\n");
- }
- }
-
- /* start the transaction by setting bit 4 */
- sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
-
- /* We will always wait for a fraction of a second! */
- do {
- msleep(1);
- temp = sis5595_read(SMB_STS_LO);
- } while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- dev_dbg(&adap->dev, "SMBus Timeout!\n");
- result = -ETIMEDOUT;
- }
-
- if (temp & 0x10) {
- dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
- result = -ENXIO;
- }
-
- if (temp & 0x20) {
- dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
- "next hard reset (or not...)\n");
- /* Clock stops and slave is stuck in mid-transmission */
- result = -EIO;
- }
-
- temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
- if (temp != 0x00) {
- sis5595_write(SMB_STS_LO, temp & 0xff);
- sis5595_write(SMB_STS_HI, temp >> 8);
- }
-
- temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
- if (temp != 0x00)
- dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
-
- return result;
-}
-
-/* Return negative errno on error. */
-static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data *data)
-{
- int status;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- size = SIS5595_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- if (read_write == I2C_SMBUS_WRITE)
- sis5595_write(SMB_CMD, command);
- size = SIS5595_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- sis5595_write(SMB_CMD, command);
- if (read_write == I2C_SMBUS_WRITE)
- sis5595_write(SMB_BYTE, data->byte);
- size = SIS5595_BYTE_DATA;
- break;
- case I2C_SMBUS_PROC_CALL:
- case I2C_SMBUS_WORD_DATA:
- sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- sis5595_write(SMB_CMD, command);
- if (read_write == I2C_SMBUS_WRITE) {
- sis5595_write(SMB_BYTE, data->word & 0xff);
- sis5595_write(SMB_BYTE + 1,
- (data->word & 0xff00) >> 8);
- }
- size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
- break;
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
-
- status = sis5595_transaction(adap);
- if (status)
- return status;
-
- if ((size != SIS5595_PROC_CALL) &&
- ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
- return 0;
-
-
- switch (size) {
- case SIS5595_BYTE:
- case SIS5595_BYTE_DATA:
- data->byte = sis5595_read(SMB_BYTE);
- break;
- case SIS5595_WORD_DATA:
- case SIS5595_PROC_CALL:
- data->word = sis5595_read(SMB_BYTE) + (sis5595_read(SMB_BYTE + 1) << 8);
- break;
- }
- return 0;
-}
-
-static u32 sis5595_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_PROC_CALL;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = sis5595_access,
- .functionality = sis5595_func,
-};
-
-static struct i2c_adapter sis5595_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(sis5595_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, sis5595_ids);
-
-static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- int err;
-
- if (sis5595_setup(dev)) {
- dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
- return -ENODEV;
- }
-
- /* set up the sysfs linkage to our parent device */
- sis5595_adapter.dev.parent = &dev->dev;
-
- snprintf(sis5595_adapter.name, sizeof(sis5595_adapter.name),
- "SMBus SIS5595 adapter at %04x", sis5595_base + SMB_INDEX);
- err = i2c_add_adapter(&sis5595_adapter);
- if (err) {
- release_region(sis5595_base + SMB_INDEX, 2);
- return err;
- }
-
- /* Always return failure here. This is to allow other drivers to bind
- * to this pci device. We don't really want to have control over the
- * pci device, we only wanted to read as few register values from it.
- */
- sis5595_pdev = pci_dev_get(dev);
- return -ENODEV;
-}
-
-static struct pci_driver sis5595_driver = {
- .name = "sis5595_smbus",
- .id_table = sis5595_ids,
- .probe = sis5595_probe,
-};
-
-static int __init i2c_sis5595_init(void)
-{
- return pci_register_driver(&sis5595_driver);
-}
-
-static void __exit i2c_sis5595_exit(void)
-{
- pci_unregister_driver(&sis5595_driver);
- if (sis5595_pdev) {
- i2c_del_adapter(&sis5595_adapter);
- release_region(sis5595_base + SMB_INDEX, 2);
- pci_dev_put(sis5595_pdev);
- sis5595_pdev = NULL;
- }
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("SIS5595 SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_sis5595_init);
-module_exit(i2c_sis5595_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis630.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis630.c
deleted file mode 100644
index 15cf78f6..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis630.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- Copyright (c) 2002,2003 Alexander Malysh <amalysh@web.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- Changes:
- 24.08.2002
- Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
- Changed sis630_transaction.(Thanks to Mark M. Hoffman)
- 18.09.2002
- Added SIS730 as supported.
- 21.09.2002
- Added high_clock module option.If this option is set
- used Host Master Clock 56KHz (default 14KHz).For now we save old Host
- Master Clock and after transaction completed restore (otherwise
- it's confuse BIOS and hung Machine).
- 24.09.2002
- Fixed typo in sis630_access
- Fixed logical error by restoring of Host Master Clock
- 31.07.2003
- Added block data read/write support.
-*/
-
-/*
- Status: beta
-
- Supports:
- SIS 630
- SIS 730
-
- Note: we assume there can only be one device, with one SMBus interface.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-/* SIS630 SMBus registers */
-#define SMB_STS 0x80 /* status */
-#define SMB_EN 0x81 /* status enable */
-#define SMB_CNT 0x82
-#define SMBHOST_CNT 0x83
-#define SMB_ADDR 0x84
-#define SMB_CMD 0x85
-#define SMB_PCOUNT 0x86 /* processed count */
-#define SMB_COUNT 0x87
-#define SMB_BYTE 0x88 /* ~0x8F data byte field */
-#define SMBDEV_ADDR 0x90
-#define SMB_DB0 0x91
-#define SMB_DB1 0x92
-#define SMB_SAA 0x93
-
-/* register count for request_region */
-#define SIS630_SMB_IOREGION 20
-
-/* PCI address constants */
-/* acpi base address register */
-#define SIS630_ACPI_BASE_REG 0x74
-/* bios control register */
-#define SIS630_BIOS_CTL_REG 0x40
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-
-/* SIS630 constants */
-#define SIS630_QUICK 0x00
-#define SIS630_BYTE 0x01
-#define SIS630_BYTE_DATA 0x02
-#define SIS630_WORD_DATA 0x03
-#define SIS630_PCALL 0x04
-#define SIS630_BLOCK_DATA 0x05
-
-static struct pci_driver sis630_driver;
-
-/* insmod parameters */
-static bool high_clock;
-static bool force;
-module_param(high_clock, bool, 0);
-MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
-module_param(force, bool, 0);
-MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
-
-/* acpi base address */
-static unsigned short acpi_base;
-
-/* supported chips */
-static int supported[] = {
- PCI_DEVICE_ID_SI_630,
- PCI_DEVICE_ID_SI_730,
- 0 /* terminates the list */
-};
-
-static inline u8 sis630_read(u8 reg)
-{
- return inb(acpi_base + reg);
-}
-
-static inline void sis630_write(u8 reg, u8 data)
-{
- outb(data, acpi_base + reg);
-}
-
-static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldclock)
-{
- int temp;
-
- /* Make sure the SMBus host is ready to start transmitting. */
- if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
- dev_dbg(&adap->dev, "SMBus busy (%02x).Resetting...\n",temp);
- /* kill smbus transaction */
- sis630_write(SMBHOST_CNT, 0x20);
-
- if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
- dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
- return -EBUSY;
- } else {
- dev_dbg(&adap->dev, "Successful!\n");
- }
- }
-
- /* save old clock, so we can prevent machine for hung */
- *oldclock = sis630_read(SMB_CNT);
-
- dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock);
-
- /* disable timeout interrupt , set Host Master Clock to 56KHz if requested */
- if (high_clock)
- sis630_write(SMB_CNT, 0x20);
- else
- sis630_write(SMB_CNT, (*oldclock & ~0x40));
-
- /* clear all sticky bits */
- temp = sis630_read(SMB_STS);
- sis630_write(SMB_STS, temp & 0x1e);
-
- /* start the transaction by setting bit 4 and size */
- sis630_write(SMBHOST_CNT,0x10 | (size & 0x07));
-
- return 0;
-}
-
-static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
-{
- int temp, result = 0, timeout = 0;
-
- /* We will always wait for a fraction of a second! */
- do {
- msleep(1);
- temp = sis630_read(SMB_STS);
- /* check if block transmitted */
- if (size == SIS630_BLOCK_DATA && (temp & 0x10))
- break;
- } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- dev_dbg(&adap->dev, "SMBus Timeout!\n");
- result = -ETIMEDOUT;
- }
-
- if (temp & 0x02) {
- dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
- result = -ENXIO;
- }
-
- if (temp & 0x04) {
- dev_err(&adap->dev, "Bus collision!\n");
- result = -EIO;
- /*
- TBD: Datasheet say:
- the software should clear this bit and restart SMBUS operation.
- Should we do it or user start request again?
- */
- }
-
- return result;
-}
-
-static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock)
-{
- int temp = 0;
-
- /* clear all status "sticky" bits */
- sis630_write(SMB_STS, temp);
-
- dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT));
-
- /*
- * restore old Host Master Clock if high_clock is set
- * and oldclock was not 56KHz
- */
- if (high_clock && !(oldclock & 0x20))
- sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20));
-
- dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT));
-}
-
-static int sis630_transaction(struct i2c_adapter *adap, int size)
-{
- int result = 0;
- u8 oldclock = 0;
-
- result = sis630_transaction_start(adap, size, &oldclock);
- if (!result) {
- result = sis630_transaction_wait(adap, size);
- sis630_transaction_end(adap, oldclock);
- }
-
- return result;
-}
-
-static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write)
-{
- int i, len = 0, rc = 0;
- u8 oldclock = 0;
-
- if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len < 0)
- len = 0;
- else if (len > 32)
- len = 32;
- sis630_write(SMB_COUNT, len);
- for (i=1; i <= len; i++) {
- dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]);
- /* set data */
- sis630_write(SMB_BYTE+(i-1)%8, data->block[i]);
- if (i==8 || (len<8 && i==len)) {
- dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i);
- /* first transaction */
- rc = sis630_transaction_start(adap,
- SIS630_BLOCK_DATA, &oldclock);
- if (rc)
- return rc;
- }
- else if ((i-1)%8 == 7 || i==len) {
- dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i);
- if (i>8) {
- dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
- /*
- If this is not first transaction,
- we must clear sticky bit.
- clear SMBARY_STS
- */
- sis630_write(SMB_STS,0x10);
- }
- rc = sis630_transaction_wait(adap,
- SIS630_BLOCK_DATA);
- if (rc) {
- dev_dbg(&adap->dev, "trans_wait failed\n");
- break;
- }
- }
- }
- }
- else {
- /* read request */
- data->block[0] = len = 0;
- rc = sis630_transaction_start(adap,
- SIS630_BLOCK_DATA, &oldclock);
- if (rc)
- return rc;
- do {
- rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA);
- if (rc) {
- dev_dbg(&adap->dev, "trans_wait failed\n");
- break;
- }
- /* if this first transaction then read byte count */
- if (len == 0)
- data->block[0] = sis630_read(SMB_COUNT);
-
- /* just to be sure */
- if (data->block[0] > 32)
- data->block[0] = 32;
-
- dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
-
- for (i=0; i < 8 && len < data->block[0]; i++,len++) {
- dev_dbg(&adap->dev, "read i=%d len=%d\n", i, len);
- data->block[len+1] = sis630_read(SMB_BYTE+i);
- }
-
- dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
-
- /* clear SMBARY_STS */
- sis630_write(SMB_STS,0x10);
- } while(len < data->block[0]);
- }
-
- sis630_transaction_end(adap, oldclock);
-
- return rc;
-}
-
-/* Return negative errno on error. */
-static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data *data)
-{
- int status;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- size = SIS630_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- if (read_write == I2C_SMBUS_WRITE)
- sis630_write(SMB_CMD, command);
- size = SIS630_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- sis630_write(SMB_CMD, command);
- if (read_write == I2C_SMBUS_WRITE)
- sis630_write(SMB_BYTE, data->byte);
- size = SIS630_BYTE_DATA;
- break;
- case I2C_SMBUS_PROC_CALL:
- case I2C_SMBUS_WORD_DATA:
- sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
- sis630_write(SMB_CMD, command);
- if (read_write == I2C_SMBUS_WRITE) {
- sis630_write(SMB_BYTE, data->word & 0xff);
- sis630_write(SMB_BYTE + 1,(data->word & 0xff00) >> 8);
- }
- size = (size == I2C_SMBUS_PROC_CALL ? SIS630_PCALL : SIS630_WORD_DATA);
- break;
- case I2C_SMBUS_BLOCK_DATA:
- sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
- sis630_write(SMB_CMD, command);
- size = SIS630_BLOCK_DATA;
- return sis630_block_data(adap, data, read_write);
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n",
- size);
- return -EOPNOTSUPP;
- }
-
- status = sis630_transaction(adap, size);
- if (status)
- return status;
-
- if ((size != SIS630_PCALL) &&
- ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) {
- return 0;
- }
-
- switch(size) {
- case SIS630_BYTE:
- case SIS630_BYTE_DATA:
- data->byte = sis630_read(SMB_BYTE);
- break;
- case SIS630_PCALL:
- case SIS630_WORD_DATA:
- data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8);
- break;
- }
-
- return 0;
-}
-
-static u32 sis630_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-static int __devinit sis630_setup(struct pci_dev *sis630_dev)
-{
- unsigned char b;
- struct pci_dev *dummy = NULL;
- int retval, i;
-
- /* check for supported SiS devices */
- for (i=0; supported[i] > 0 ; i++) {
- if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy)))
- break; /* found */
- }
-
- if (dummy) {
- pci_dev_put(dummy);
- }
- else if (force) {
- dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but "
- "loading because of force option enabled\n");
- }
- else {
- return -ENODEV;
- }
-
- /*
- Enable ACPI first , so we can accsess reg 74-75
- in acpi io space and read acpi base addr
- */
- if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
- dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
- retval = -ENODEV;
- goto exit;
- }
- /* if ACPI already enabled , do nothing */
- if (!(b & 0x80) &&
- pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
- dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
- retval = -ENODEV;
- goto exit;
- }
-
- /* Determine the ACPI base address */
- if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
- dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
- retval = -ENODEV;
- goto exit;
- }
-
- dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
-
- retval = acpi_check_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
- sis630_driver.name);
- if (retval)
- goto exit;
-
- /* Everything is happy, let's grab the memory and set things up. */
- if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
- sis630_driver.name)) {
- dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
- "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
- retval = -EBUSY;
- goto exit;
- }
-
- retval = 0;
-
-exit:
- if (retval)
- acpi_base = 0;
- return retval;
-}
-
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = sis630_access,
- .functionality = sis630_func,
-};
-
-static struct i2c_adapter sis630_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, sis630_ids);
-
-static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- if (sis630_setup(dev)) {
- dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
- return -ENODEV;
- }
-
- /* set up the sysfs linkage to our parent device */
- sis630_adapter.dev.parent = &dev->dev;
-
- snprintf(sis630_adapter.name, sizeof(sis630_adapter.name),
- "SMBus SIS630 adapter at %04x", acpi_base + SMB_STS);
-
- return i2c_add_adapter(&sis630_adapter);
-}
-
-static void __devexit sis630_remove(struct pci_dev *dev)
-{
- if (acpi_base) {
- i2c_del_adapter(&sis630_adapter);
- release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
- acpi_base = 0;
- }
-}
-
-
-static struct pci_driver sis630_driver = {
- .name = "sis630_smbus",
- .id_table = sis630_ids,
- .probe = sis630_probe,
- .remove = __devexit_p(sis630_remove),
-};
-
-static int __init i2c_sis630_init(void)
-{
- return pci_register_driver(&sis630_driver);
-}
-
-
-static void __exit i2c_sis630_exit(void)
-{
- pci_unregister_driver(&sis630_driver);
-}
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>");
-MODULE_DESCRIPTION("SIS630 SMBus driver");
-
-module_init(i2c_sis630_init);
-module_exit(i2c_sis630_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis96x.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis96x.c
deleted file mode 100644
index cc5d1494..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-sis96x.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- This module must be considered BETA unless and until
- the chipset manufacturer releases a datasheet.
- The register definitions are based on the SiS630.
-
- This module relies on quirk_sis_96x_smbus (drivers/pci/quirks.c)
- for just about every machine for which users have reported.
- If this module isn't detecting your 96x south bridge, have a
- look there.
-
- We assume there can only be one SiS96x with one SMBus interface.
-*/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-/* base address register in PCI config space */
-#define SIS96x_BAR 0x04
-
-/* SiS96x SMBus registers */
-#define SMB_STS 0x00
-#define SMB_EN 0x01
-#define SMB_CNT 0x02
-#define SMB_HOST_CNT 0x03
-#define SMB_ADDR 0x04
-#define SMB_CMD 0x05
-#define SMB_PCOUNT 0x06
-#define SMB_COUNT 0x07
-#define SMB_BYTE 0x08
-#define SMB_DEV_ADDR 0x10
-#define SMB_DB0 0x11
-#define SMB_DB1 0x12
-#define SMB_SAA 0x13
-
-/* register count for request_region */
-#define SMB_IOSIZE 0x20
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-
-/* SiS96x SMBus constants */
-#define SIS96x_QUICK 0x00
-#define SIS96x_BYTE 0x01
-#define SIS96x_BYTE_DATA 0x02
-#define SIS96x_WORD_DATA 0x03
-#define SIS96x_PROC_CALL 0x04
-#define SIS96x_BLOCK_DATA 0x05
-
-static struct pci_driver sis96x_driver;
-static struct i2c_adapter sis96x_adapter;
-static u16 sis96x_smbus_base;
-
-static inline u8 sis96x_read(u8 reg)
-{
- return inb(sis96x_smbus_base + reg) ;
-}
-
-static inline void sis96x_write(u8 reg, u8 data)
-{
- outb(data, sis96x_smbus_base + reg) ;
-}
-
-/* Execute a SMBus transaction.
- int size is from SIS96x_QUICK to SIS96x_BLOCK_DATA
- */
-static int sis96x_transaction(int size)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- dev_dbg(&sis96x_adapter.dev, "SMBus transaction %d\n", size);
-
- /* Make sure the SMBus host is ready to start transmitting */
- if (((temp = sis96x_read(SMB_CNT)) & 0x03) != 0x00) {
-
- dev_dbg(&sis96x_adapter.dev, "SMBus busy (0x%02x). "
- "Resetting...\n", temp);
-
- /* kill the transaction */
- sis96x_write(SMB_HOST_CNT, 0x20);
-
- /* check it again */
- if (((temp = sis96x_read(SMB_CNT)) & 0x03) != 0x00) {
- dev_dbg(&sis96x_adapter.dev, "Failed (0x%02x)\n", temp);
- return -EBUSY;
- } else {
- dev_dbg(&sis96x_adapter.dev, "Successful\n");
- }
- }
-
- /* Turn off timeout interrupts, set fast host clock */
- sis96x_write(SMB_CNT, 0x20);
-
- /* clear all (sticky) status flags */
- temp = sis96x_read(SMB_STS);
- sis96x_write(SMB_STS, temp & 0x1e);
-
- /* start the transaction by setting bit 4 and size bits */
- sis96x_write(SMB_HOST_CNT, 0x10 | (size & 0x07));
-
- /* We will always wait for a fraction of a second! */
- do {
- msleep(1);
- temp = sis96x_read(SMB_STS);
- } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
- dev_dbg(&sis96x_adapter.dev, "SMBus Timeout! (0x%02x)\n", temp);
- result = -ETIMEDOUT;
- }
-
- /* device error - probably missing ACK */
- if (temp & 0x02) {
- dev_dbg(&sis96x_adapter.dev, "Failed bus transaction!\n");
- result = -ENXIO;
- }
-
- /* bus collision */
- if (temp & 0x04) {
- dev_dbg(&sis96x_adapter.dev, "Bus collision!\n");
- result = -EIO;
- }
-
- /* Finish up by resetting the bus */
- sis96x_write(SMB_STS, temp);
- if ((temp = sis96x_read(SMB_STS))) {
- dev_dbg(&sis96x_adapter.dev, "Failed reset at "
- "end of transaction! (0x%02x)\n", temp);
- }
-
- return result;
-}
-
-/* Return negative errno on error. */
-static s32 sis96x_access(struct i2c_adapter * adap, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data * data)
-{
- int status;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- sis96x_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- size = SIS96x_QUICK;
- break;
-
- case I2C_SMBUS_BYTE:
- sis96x_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- if (read_write == I2C_SMBUS_WRITE)
- sis96x_write(SMB_CMD, command);
- size = SIS96x_BYTE;
- break;
-
- case I2C_SMBUS_BYTE_DATA:
- sis96x_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- sis96x_write(SMB_CMD, command);
- if (read_write == I2C_SMBUS_WRITE)
- sis96x_write(SMB_BYTE, data->byte);
- size = SIS96x_BYTE_DATA;
- break;
-
- case I2C_SMBUS_PROC_CALL:
- case I2C_SMBUS_WORD_DATA:
- sis96x_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
- sis96x_write(SMB_CMD, command);
- if (read_write == I2C_SMBUS_WRITE) {
- sis96x_write(SMB_BYTE, data->word & 0xff);
- sis96x_write(SMB_BYTE + 1, (data->word & 0xff00) >> 8);
- }
- size = (size == I2C_SMBUS_PROC_CALL ?
- SIS96x_PROC_CALL : SIS96x_WORD_DATA);
- break;
-
- default:
- dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- status = sis96x_transaction(size);
- if (status)
- return status;
-
- if ((size != SIS96x_PROC_CALL) &&
- ((read_write == I2C_SMBUS_WRITE) || (size == SIS96x_QUICK)))
- return 0;
-
- switch (size) {
- case SIS96x_BYTE:
- case SIS96x_BYTE_DATA:
- data->byte = sis96x_read(SMB_BYTE);
- break;
-
- case SIS96x_WORD_DATA:
- case SIS96x_PROC_CALL:
- data->word = sis96x_read(SMB_BYTE) +
- (sis96x_read(SMB_BYTE + 1) << 8);
- break;
- }
- return 0;
-}
-
-static u32 sis96x_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_PROC_CALL;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = sis96x_access,
- .functionality = sis96x_func,
-};
-
-static struct i2c_adapter sis96x_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(sis96x_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, sis96x_ids);
-
-static int __devinit sis96x_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- u16 ww = 0;
- int retval;
-
- if (sis96x_smbus_base) {
- dev_err(&dev->dev, "Only one device supported.\n");
- return -EBUSY;
- }
-
- pci_read_config_word(dev, PCI_CLASS_DEVICE, &ww);
- if (PCI_CLASS_SERIAL_SMBUS != ww) {
- dev_err(&dev->dev, "Unsupported device class 0x%04x!\n", ww);
- return -ENODEV;
- }
-
- sis96x_smbus_base = pci_resource_start(dev, SIS96x_BAR);
- if (!sis96x_smbus_base) {
- dev_err(&dev->dev, "SiS96x SMBus base address "
- "not initialized!\n");
- return -EINVAL;
- }
- dev_info(&dev->dev, "SiS96x SMBus base address: 0x%04x\n",
- sis96x_smbus_base);
-
- retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
- if (retval)
- return -ENODEV;
-
- /* Everything is happy, let's grab the memory and set things up. */
- if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
- sis96x_driver.name)) {
- dev_err(&dev->dev, "SMBus registers 0x%04x-0x%04x "
- "already in use!\n", sis96x_smbus_base,
- sis96x_smbus_base + SMB_IOSIZE - 1);
-
- sis96x_smbus_base = 0;
- return -EINVAL;
- }
-
- /* set up the sysfs linkage to our parent device */
- sis96x_adapter.dev.parent = &dev->dev;
-
- snprintf(sis96x_adapter.name, sizeof(sis96x_adapter.name),
- "SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
-
- if ((retval = i2c_add_adapter(&sis96x_adapter))) {
- dev_err(&dev->dev, "Couldn't register adapter!\n");
- release_region(sis96x_smbus_base, SMB_IOSIZE);
- sis96x_smbus_base = 0;
- }
-
- return retval;
-}
-
-static void __devexit sis96x_remove(struct pci_dev *dev)
-{
- if (sis96x_smbus_base) {
- i2c_del_adapter(&sis96x_adapter);
- release_region(sis96x_smbus_base, SMB_IOSIZE);
- sis96x_smbus_base = 0;
- }
-}
-
-static struct pci_driver sis96x_driver = {
- .name = "sis96x_smbus",
- .id_table = sis96x_ids,
- .probe = sis96x_probe,
- .remove = __devexit_p(sis96x_remove),
-};
-
-static int __init i2c_sis96x_init(void)
-{
- return pci_register_driver(&sis96x_driver);
-}
-
-static void __exit i2c_sis96x_exit(void)
-{
- pci_unregister_driver(&sis96x_driver);
-}
-
-MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
-MODULE_DESCRIPTION("SiS96x SMBus driver");
-MODULE_LICENSE("GPL");
-
-/* Register initialization functions using helper macros */
-module_init(i2c_sis96x_init);
-module_exit(i2c_sis96x_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-stu300.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-stu300.c
deleted file mode 100644
index 4d44af18..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-stu300.c
+++ /dev/null
@@ -1,1057 +0,0 @@
-/*
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * ST DDC I2C master mode driver, used in e.g. U300 series platforms.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-/* the name of this kernel module */
-#define NAME "stu300"
-
-/* CR (Control Register) 8bit (R/W) */
-#define I2C_CR (0x00000000)
-#define I2C_CR_RESET_VALUE (0x00)
-#define I2C_CR_RESET_UMASK (0x00)
-#define I2C_CR_DDC1_ENABLE (0x80)
-#define I2C_CR_TRANS_ENABLE (0x40)
-#define I2C_CR_PERIPHERAL_ENABLE (0x20)
-#define I2C_CR_DDC2B_ENABLE (0x10)
-#define I2C_CR_START_ENABLE (0x08)
-#define I2C_CR_ACK_ENABLE (0x04)
-#define I2C_CR_STOP_ENABLE (0x02)
-#define I2C_CR_INTERRUPT_ENABLE (0x01)
-/* SR1 (Status Register 1) 8bit (R/-) */
-#define I2C_SR1 (0x00000004)
-#define I2C_SR1_RESET_VALUE (0x00)
-#define I2C_SR1_RESET_UMASK (0x00)
-#define I2C_SR1_EVF_IND (0x80)
-#define I2C_SR1_ADD10_IND (0x40)
-#define I2C_SR1_TRA_IND (0x20)
-#define I2C_SR1_BUSY_IND (0x10)
-#define I2C_SR1_BTF_IND (0x08)
-#define I2C_SR1_ADSL_IND (0x04)
-#define I2C_SR1_MSL_IND (0x02)
-#define I2C_SR1_SB_IND (0x01)
-/* SR2 (Status Register 2) 8bit (R/-) */
-#define I2C_SR2 (0x00000008)
-#define I2C_SR2_RESET_VALUE (0x00)
-#define I2C_SR2_RESET_UMASK (0x40)
-#define I2C_SR2_MASK (0xBF)
-#define I2C_SR2_SCLFAL_IND (0x80)
-#define I2C_SR2_ENDAD_IND (0x20)
-#define I2C_SR2_AF_IND (0x10)
-#define I2C_SR2_STOPF_IND (0x08)
-#define I2C_SR2_ARLO_IND (0x04)
-#define I2C_SR2_BERR_IND (0x02)
-#define I2C_SR2_DDC2BF_IND (0x01)
-/* CCR (Clock Control Register) 8bit (R/W) */
-#define I2C_CCR (0x0000000C)
-#define I2C_CCR_RESET_VALUE (0x00)
-#define I2C_CCR_RESET_UMASK (0x00)
-#define I2C_CCR_MASK (0xFF)
-#define I2C_CCR_FMSM (0x80)
-#define I2C_CCR_CC_MASK (0x7F)
-/* OAR1 (Own Address Register 1) 8bit (R/W) */
-#define I2C_OAR1 (0x00000010)
-#define I2C_OAR1_RESET_VALUE (0x00)
-#define I2C_OAR1_RESET_UMASK (0x00)
-#define I2C_OAR1_ADD_MASK (0xFF)
-/* OAR2 (Own Address Register 2) 8bit (R/W) */
-#define I2C_OAR2 (0x00000014)
-#define I2C_OAR2_RESET_VALUE (0x40)
-#define I2C_OAR2_RESET_UMASK (0x19)
-#define I2C_OAR2_MASK (0xE6)
-#define I2C_OAR2_FR_25_10MHZ (0x00)
-#define I2C_OAR2_FR_10_1667MHZ (0x20)
-#define I2C_OAR2_FR_1667_2667MHZ (0x40)
-#define I2C_OAR2_FR_2667_40MHZ (0x60)
-#define I2C_OAR2_FR_40_5333MHZ (0x80)
-#define I2C_OAR2_FR_5333_66MHZ (0xA0)
-#define I2C_OAR2_FR_66_80MHZ (0xC0)
-#define I2C_OAR2_FR_80_100MHZ (0xE0)
-#define I2C_OAR2_FR_MASK (0xE0)
-#define I2C_OAR2_ADD_MASK (0x06)
-/* DR (Data Register) 8bit (R/W) */
-#define I2C_DR (0x00000018)
-#define I2C_DR_RESET_VALUE (0x00)
-#define I2C_DR_RESET_UMASK (0xFF)
-#define I2C_DR_D_MASK (0xFF)
-/* ECCR (Extended Clock Control Register) 8bit (R/W) */
-#define I2C_ECCR (0x0000001C)
-#define I2C_ECCR_RESET_VALUE (0x00)
-#define I2C_ECCR_RESET_UMASK (0xE0)
-#define I2C_ECCR_MASK (0x1F)
-#define I2C_ECCR_CC_MASK (0x1F)
-
-/*
- * These events are more or less responses to commands
- * sent into the hardware, presumably reflecting the state
- * of an internal state machine.
- */
-enum stu300_event {
- STU300_EVENT_NONE = 0,
- STU300_EVENT_1,
- STU300_EVENT_2,
- STU300_EVENT_3,
- STU300_EVENT_4,
- STU300_EVENT_5,
- STU300_EVENT_6,
- STU300_EVENT_7,
- STU300_EVENT_8,
- STU300_EVENT_9
-};
-
-enum stu300_error {
- STU300_ERROR_NONE = 0,
- STU300_ERROR_ACKNOWLEDGE_FAILURE,
- STU300_ERROR_BUS_ERROR,
- STU300_ERROR_ARBITRATION_LOST,
- STU300_ERROR_UNKNOWN
-};
-
-/* timeout waiting for the controller to respond */
-#define STU300_TIMEOUT (msecs_to_jiffies(1000))
-
-/*
- * The number of address send athemps tried before giving up.
- * If the first one failes it seems like 5 to 8 attempts are required.
- */
-#define NUM_ADDR_RESEND_ATTEMPTS 12
-
-/* I2C clock speed, in Hz 0-400kHz*/
-static unsigned int scl_frequency = 100000;
-module_param(scl_frequency, uint, 0644);
-
-/**
- * struct stu300_dev - the stu300 driver state holder
- * @pdev: parent platform device
- * @adapter: corresponding I2C adapter
- * @phybase: location of I/O area in memory
- * @physize: size of I/O area in memory
- * @clk: hardware block clock
- * @irq: assigned interrupt line
- * @cmd_issue_lock: this locks the following cmd_ variables
- * @cmd_complete: acknowledge completion for an I2C command
- * @cmd_event: expected event coming in as a response to a command
- * @cmd_err: error code as response to a command
- * @speed: current bus speed in Hz
- * @msg_index: index of current message
- * @msg_len: length of current message
- */
-
-struct stu300_dev {
- struct platform_device *pdev;
- struct i2c_adapter adapter;
- resource_size_t phybase;
- resource_size_t physize;
- void __iomem *virtbase;
- struct clk *clk;
- int irq;
- spinlock_t cmd_issue_lock;
- struct completion cmd_complete;
- enum stu300_event cmd_event;
- enum stu300_error cmd_err;
- unsigned int speed;
- int msg_index;
- int msg_len;
-};
-
-/* Local forward function declarations */
-static int stu300_init_hw(struct stu300_dev *dev);
-
-/*
- * The block needs writes in both MSW and LSW in order
- * for all data lines to reach their destination.
- */
-static inline void stu300_wr8(u32 value, void __iomem *address)
-{
- writel((value << 16) | value, address);
-}
-
-/*
- * This merely masks off the duplicates which appear
- * in bytes 1-3. You _MUST_ use 32-bit bus access on this
- * device, else it will not work.
- */
-static inline u32 stu300_r8(void __iomem *address)
-{
- return readl(address) & 0x000000FFU;
-}
-
-static void stu300_irq_enable(struct stu300_dev *dev)
-{
- u32 val;
- val = stu300_r8(dev->virtbase + I2C_CR);
- val |= I2C_CR_INTERRUPT_ENABLE;
- /* Twice paranoia (possible HW glitch) */
- stu300_wr8(val, dev->virtbase + I2C_CR);
- stu300_wr8(val, dev->virtbase + I2C_CR);
-}
-
-static void stu300_irq_disable(struct stu300_dev *dev)
-{
- u32 val;
- val = stu300_r8(dev->virtbase + I2C_CR);
- val &= ~I2C_CR_INTERRUPT_ENABLE;
- /* Twice paranoia (possible HW glitch) */
- stu300_wr8(val, dev->virtbase + I2C_CR);
- stu300_wr8(val, dev->virtbase + I2C_CR);
-}
-
-
-/*
- * Tells whether a certain event or events occurred in
- * response to a command. The events represent states in
- * the internal state machine of the hardware. The events
- * are not very well described in the hardware
- * documentation and can only be treated as abstract state
- * machine states.
- *
- * @ret 0 = event has not occurred or unknown error, any
- * other value means the correct event occurred or an error.
- */
-
-static int stu300_event_occurred(struct stu300_dev *dev,
- enum stu300_event mr_event) {
- u32 status1;
- u32 status2;
-
- /* What event happened? */
- status1 = stu300_r8(dev->virtbase + I2C_SR1);
-
- if (!(status1 & I2C_SR1_EVF_IND))
- /* No event at all */
- return 0;
-
- status2 = stu300_r8(dev->virtbase + I2C_SR2);
-
- /* Block any multiple interrupts */
- stu300_irq_disable(dev);
-
- /* Check for errors first */
- if (status2 & I2C_SR2_AF_IND) {
- dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
- return 1;
- } else if (status2 & I2C_SR2_BERR_IND) {
- dev->cmd_err = STU300_ERROR_BUS_ERROR;
- return 1;
- } else if (status2 & I2C_SR2_ARLO_IND) {
- dev->cmd_err = STU300_ERROR_ARBITRATION_LOST;
- return 1;
- }
-
- switch (mr_event) {
- case STU300_EVENT_1:
- if (status1 & I2C_SR1_ADSL_IND)
- return 1;
- break;
- case STU300_EVENT_2:
- case STU300_EVENT_3:
- case STU300_EVENT_7:
- case STU300_EVENT_8:
- if (status1 & I2C_SR1_BTF_IND) {
- return 1;
- }
- break;
- case STU300_EVENT_4:
- if (status2 & I2C_SR2_STOPF_IND)
- return 1;
- break;
- case STU300_EVENT_5:
- if (status1 & I2C_SR1_SB_IND)
- /* Clear start bit */
- return 1;
- break;
- case STU300_EVENT_6:
- if (status2 & I2C_SR2_ENDAD_IND) {
- /* First check for any errors */
- return 1;
- }
- break;
- case STU300_EVENT_9:
- if (status1 & I2C_SR1_ADD10_IND)
- return 1;
- break;
- default:
- break;
- }
- /* If we get here, we're on thin ice.
- * Here we are in a status where we have
- * gotten a response that does not match
- * what we requested.
- */
- dev->cmd_err = STU300_ERROR_UNKNOWN;
- dev_err(&dev->pdev->dev,
- "Unhandled interrupt! %d sr1: 0x%x sr2: 0x%x\n",
- mr_event, status1, status2);
- return 0;
-}
-
-static irqreturn_t stu300_irh(int irq, void *data)
-{
- struct stu300_dev *dev = data;
- int res;
-
- /* Just make sure that the block is clocked */
- clk_enable(dev->clk);
-
- /* See if this was what we were waiting for */
- spin_lock(&dev->cmd_issue_lock);
-
- res = stu300_event_occurred(dev, dev->cmd_event);
- if (res || dev->cmd_err != STU300_ERROR_NONE)
- complete(&dev->cmd_complete);
-
- spin_unlock(&dev->cmd_issue_lock);
-
- clk_disable(dev->clk);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Sends a command and then waits for the bits masked by *flagmask*
- * to go high or low by IRQ awaiting.
- */
-static int stu300_start_and_await_event(struct stu300_dev *dev,
- u8 cr_value,
- enum stu300_event mr_event)
-{
- int ret;
-
- if (unlikely(irqs_disabled())) {
- /* TODO: implement polling for this case if need be. */
- WARN(1, "irqs are disabled, cannot poll for event\n");
- return -EIO;
- }
-
- /* Lock command issue, fill in an event we wait for */
- spin_lock_irq(&dev->cmd_issue_lock);
- init_completion(&dev->cmd_complete);
- dev->cmd_err = STU300_ERROR_NONE;
- dev->cmd_event = mr_event;
- spin_unlock_irq(&dev->cmd_issue_lock);
-
- /* Turn on interrupt, send command and wait. */
- cr_value |= I2C_CR_INTERRUPT_ENABLE;
- stu300_wr8(cr_value, dev->virtbase + I2C_CR);
- ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
- STU300_TIMEOUT);
- if (ret < 0) {
- dev_err(&dev->pdev->dev,
- "wait_for_completion_interruptible_timeout() "
- "returned %d waiting for event %04x\n", ret, mr_event);
- return ret;
- }
-
- if (ret == 0) {
- dev_err(&dev->pdev->dev, "controller timed out "
- "waiting for event %d, reinit hardware\n", mr_event);
- (void) stu300_init_hw(dev);
- return -ETIMEDOUT;
- }
-
- if (dev->cmd_err != STU300_ERROR_NONE) {
- dev_err(&dev->pdev->dev, "controller (start) "
- "error %d waiting for event %d, reinit hardware\n",
- dev->cmd_err, mr_event);
- (void) stu300_init_hw(dev);
- return -EIO;
- }
-
- return 0;
-}
-
-/*
- * This waits for a flag to be set, if it is not set on entry, an interrupt is
- * configured to wait for the flag using a completion.
- */
-static int stu300_await_event(struct stu300_dev *dev,
- enum stu300_event mr_event)
-{
- int ret;
-
- if (unlikely(irqs_disabled())) {
- /* TODO: implement polling for this case if need be. */
- dev_err(&dev->pdev->dev, "irqs are disabled on this "
- "system!\n");
- return -EIO;
- }
-
- /* Is it already here? */
- spin_lock_irq(&dev->cmd_issue_lock);
- dev->cmd_err = STU300_ERROR_NONE;
- dev->cmd_event = mr_event;
-
- init_completion(&dev->cmd_complete);
-
- /* Turn on the I2C interrupt for current operation */
- stu300_irq_enable(dev);
-
- /* Unlock the command block and wait for the event to occur */
- spin_unlock_irq(&dev->cmd_issue_lock);
-
- ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
- STU300_TIMEOUT);
- if (ret < 0) {
- dev_err(&dev->pdev->dev,
- "wait_for_completion_interruptible_timeout()"
- "returned %d waiting for event %04x\n", ret, mr_event);
- return ret;
- }
-
- if (ret == 0) {
- if (mr_event != STU300_EVENT_6) {
- dev_err(&dev->pdev->dev, "controller "
- "timed out waiting for event %d, reinit "
- "hardware\n", mr_event);
- (void) stu300_init_hw(dev);
- }
- return -ETIMEDOUT;
- }
-
- if (dev->cmd_err != STU300_ERROR_NONE) {
- if (mr_event != STU300_EVENT_6) {
- dev_err(&dev->pdev->dev, "controller "
- "error (await_event) %d waiting for event %d, "
- "reinit hardware\n", dev->cmd_err, mr_event);
- (void) stu300_init_hw(dev);
- }
- return -EIO;
- }
-
- return 0;
-}
-
-/*
- * Waits for the busy bit to go low by repeated polling.
- */
-#define BUSY_RELEASE_ATTEMPTS 10
-static int stu300_wait_while_busy(struct stu300_dev *dev)
-{
- unsigned long timeout;
- int i;
-
- for (i = 0; i < BUSY_RELEASE_ATTEMPTS; i++) {
- timeout = jiffies + STU300_TIMEOUT;
-
- while (!time_after(jiffies, timeout)) {
- /* Is not busy? */
- if ((stu300_r8(dev->virtbase + I2C_SR1) &
- I2C_SR1_BUSY_IND) == 0)
- return 0;
- msleep(1);
- }
-
- dev_err(&dev->pdev->dev, "transaction timed out "
- "waiting for device to be free (not busy). "
- "Attempt: %d\n", i+1);
-
- dev_err(&dev->pdev->dev, "base address = "
- "0x%08x, reinit hardware\n", (u32) dev->virtbase);
-
- (void) stu300_init_hw(dev);
- }
-
- dev_err(&dev->pdev->dev, "giving up after %d attempts "
- "to reset the bus.\n", BUSY_RELEASE_ATTEMPTS);
-
- return -ETIMEDOUT;
-}
-
-struct stu300_clkset {
- unsigned long rate;
- u32 setting;
-};
-
-static const struct stu300_clkset stu300_clktable[] = {
- { 0, 0xFFU },
- { 2500000, I2C_OAR2_FR_25_10MHZ },
- { 10000000, I2C_OAR2_FR_10_1667MHZ },
- { 16670000, I2C_OAR2_FR_1667_2667MHZ },
- { 26670000, I2C_OAR2_FR_2667_40MHZ },
- { 40000000, I2C_OAR2_FR_40_5333MHZ },
- { 53330000, I2C_OAR2_FR_5333_66MHZ },
- { 66000000, I2C_OAR2_FR_66_80MHZ },
- { 80000000, I2C_OAR2_FR_80_100MHZ },
- { 100000000, 0xFFU },
-};
-
-
-static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
-{
-
- u32 val;
- int i = 0;
-
- /* Locate the appropriate clock setting */
- while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
- stu300_clktable[i].rate < clkrate)
- i++;
-
- if (stu300_clktable[i].setting == 0xFFU) {
- dev_err(&dev->pdev->dev, "too %s clock rate requested "
- "(%lu Hz).\n", i ? "high" : "low", clkrate);
- return -EINVAL;
- }
-
- stu300_wr8(stu300_clktable[i].setting,
- dev->virtbase + I2C_OAR2);
-
- dev_dbg(&dev->pdev->dev, "Clock rate %lu Hz, I2C bus speed %d Hz "
- "virtbase %p\n", clkrate, dev->speed, dev->virtbase);
-
- if (dev->speed > 100000)
- /* Fast Mode I2C */
- val = ((clkrate/dev->speed) - 9)/3 + 1;
- else
- /* Standard Mode I2C */
- val = ((clkrate/dev->speed) - 7)/2 + 1;
-
- /* According to spec the divider must be > 2 */
- if (val < 0x002) {
- dev_err(&dev->pdev->dev, "too low clock rate (%lu Hz).\n",
- clkrate);
- return -EINVAL;
- }
-
- /* We have 12 bits clock divider only! */
- if (val & 0xFFFFF000U) {
- dev_err(&dev->pdev->dev, "too high clock rate (%lu Hz).\n",
- clkrate);
- return -EINVAL;
- }
-
- if (dev->speed > 100000) {
- /* CC6..CC0 */
- stu300_wr8((val & I2C_CCR_CC_MASK) | I2C_CCR_FMSM,
- dev->virtbase + I2C_CCR);
- dev_dbg(&dev->pdev->dev, "set clock divider to 0x%08x, "
- "Fast Mode I2C\n", val);
- } else {
- /* CC6..CC0 */
- stu300_wr8((val & I2C_CCR_CC_MASK),
- dev->virtbase + I2C_CCR);
- dev_dbg(&dev->pdev->dev, "set clock divider to "
- "0x%08x, Standard Mode I2C\n", val);
- }
-
- /* CC11..CC7 */
- stu300_wr8(((val >> 7) & 0x1F),
- dev->virtbase + I2C_ECCR);
-
- return 0;
-}
-
-
-static int stu300_init_hw(struct stu300_dev *dev)
-{
- u32 dummy;
- unsigned long clkrate;
- int ret;
-
- /* Disable controller */
- stu300_wr8(0x00, dev->virtbase + I2C_CR);
- /*
- * Set own address to some default value (0x00).
- * We do not support slave mode anyway.
- */
- stu300_wr8(0x00, dev->virtbase + I2C_OAR1);
- /*
- * The I2C controller only operates properly in 26 MHz but we
- * program this driver as if we didn't know. This will also set the two
- * high bits of the own address to zero as well.
- * There is no known hardware issue with running in 13 MHz
- * However, speeds over 200 kHz are not used.
- */
- clkrate = clk_get_rate(dev->clk);
- ret = stu300_set_clk(dev, clkrate);
-
- if (ret)
- return ret;
- /*
- * Enable block, do it TWICE (hardware glitch)
- * Setting bit 7 can enable DDC mode. (Not used currently.)
- */
- stu300_wr8(I2C_CR_PERIPHERAL_ENABLE,
- dev->virtbase + I2C_CR);
- stu300_wr8(I2C_CR_PERIPHERAL_ENABLE,
- dev->virtbase + I2C_CR);
- /* Make a dummy read of the status register SR1 & SR2 */
- dummy = stu300_r8(dev->virtbase + I2C_SR2);
- dummy = stu300_r8(dev->virtbase + I2C_SR1);
-
- return 0;
-}
-
-
-
-/* Send slave address. */
-static int stu300_send_address(struct stu300_dev *dev,
- struct i2c_msg *msg, int resend)
-{
- u32 val;
- int ret;
-
- if (msg->flags & I2C_M_TEN)
- /* This is probably how 10 bit addresses look */
- val = (0xf0 | (((u32) msg->addr & 0x300) >> 7)) &
- I2C_DR_D_MASK;
- else
- val = ((msg->addr << 1) & I2C_DR_D_MASK);
-
- if (msg->flags & I2C_M_RD) {
- /* This is the direction bit */
- val |= 0x01;
- if (resend)
- dev_dbg(&dev->pdev->dev, "read resend\n");
- } else if (resend)
- dev_dbg(&dev->pdev->dev, "write resend\n");
- stu300_wr8(val, dev->virtbase + I2C_DR);
-
- /* For 10bit addressing, await 10bit request (EVENT 9) */
- if (msg->flags & I2C_M_TEN) {
- ret = stu300_await_event(dev, STU300_EVENT_9);
- /*
- * The slave device wants a 10bit address, send the rest
- * of the bits (the LSBits)
- */
- val = msg->addr & I2C_DR_D_MASK;
- /* This clears "event 9" */
- stu300_wr8(val, dev->virtbase + I2C_DR);
- if (ret != 0)
- return ret;
- }
- /* FIXME: Why no else here? two events for 10bit?
- * Await event 6 (normal) or event 9 (10bit)
- */
-
- if (resend)
- dev_dbg(&dev->pdev->dev, "await event 6\n");
- ret = stu300_await_event(dev, STU300_EVENT_6);
-
- /*
- * Clear any pending EVENT 6 no matter what happened during
- * await_event.
- */
- val = stu300_r8(dev->virtbase + I2C_CR);
- val |= I2C_CR_PERIPHERAL_ENABLE;
- stu300_wr8(val, dev->virtbase + I2C_CR);
-
- return ret;
-}
-
-static int stu300_xfer_msg(struct i2c_adapter *adap,
- struct i2c_msg *msg, int stop)
-{
- u32 cr;
- u32 val;
- u32 i;
- int ret;
- int attempts = 0;
- struct stu300_dev *dev = i2c_get_adapdata(adap);
-
- clk_enable(dev->clk);
-
- /* Remove this if (0) to trace each and every message. */
- if (0) {
- dev_dbg(&dev->pdev->dev, "I2C message to: 0x%04x, len: %d, "
- "flags: 0x%04x, stop: %d\n",
- msg->addr, msg->len, msg->flags, stop);
- }
-
- /* Zero-length messages are not supported by this hardware */
- if (msg->len == 0) {
- ret = -EINVAL;
- goto exit_disable;
- }
-
- /*
- * For some reason, sending the address sometimes fails when running
- * on the 13 MHz clock. No interrupt arrives. This is a work around,
- * which tries to restart and send the address up to 10 times before
- * really giving up. Usually 5 to 8 attempts are enough.
- */
- do {
- if (attempts)
- dev_dbg(&dev->pdev->dev, "wait while busy\n");
- /* Check that the bus is free, or wait until some timeout */
- ret = stu300_wait_while_busy(dev);
- if (ret != 0)
- goto exit_disable;
-
- if (attempts)
- dev_dbg(&dev->pdev->dev, "re-int hw\n");
- /*
- * According to ST, there is no problem if the clock is
- * changed between 13 and 26 MHz during a transfer.
- */
- ret = stu300_init_hw(dev);
- if (ret)
- goto exit_disable;
-
- /* Send a start condition */
- cr = I2C_CR_PERIPHERAL_ENABLE;
- /* Setting the START bit puts the block in master mode */
- if (!(msg->flags & I2C_M_NOSTART))
- cr |= I2C_CR_START_ENABLE;
- if ((msg->flags & I2C_M_RD) && (msg->len > 1))
- /* On read more than 1 byte, we need ack. */
- cr |= I2C_CR_ACK_ENABLE;
- /* Check that it gets through */
- if (!(msg->flags & I2C_M_NOSTART)) {
- if (attempts)
- dev_dbg(&dev->pdev->dev, "send start event\n");
- ret = stu300_start_and_await_event(dev, cr,
- STU300_EVENT_5);
- }
-
- if (attempts)
- dev_dbg(&dev->pdev->dev, "send address\n");
-
- if (ret == 0)
- /* Send address */
- ret = stu300_send_address(dev, msg, attempts != 0);
-
- if (ret != 0) {
- attempts++;
- dev_dbg(&dev->pdev->dev, "failed sending address, "
- "retrying. Attempt: %d msg_index: %d/%d\n",
- attempts, dev->msg_index, dev->msg_len);
- }
-
- } while (ret != 0 && attempts < NUM_ADDR_RESEND_ATTEMPTS);
-
- if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) {
- dev_dbg(&dev->pdev->dev, "managed to get address "
- "through after %d attempts\n", attempts);
- } else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) {
- dev_dbg(&dev->pdev->dev, "I give up, tried %d times "
- "to resend address.\n",
- NUM_ADDR_RESEND_ATTEMPTS);
- goto exit_disable;
- }
-
-
- if (msg->flags & I2C_M_RD) {
- /* READ: we read the actual bytes one at a time */
- for (i = 0; i < msg->len; i++) {
- if (i == msg->len-1) {
- /*
- * Disable ACK and set STOP condition before
- * reading last byte
- */
- val = I2C_CR_PERIPHERAL_ENABLE;
-
- if (stop)
- val |= I2C_CR_STOP_ENABLE;
-
- stu300_wr8(val,
- dev->virtbase + I2C_CR);
- }
- /* Wait for this byte... */
- ret = stu300_await_event(dev, STU300_EVENT_7);
- if (ret != 0)
- goto exit_disable;
- /* This clears event 7 */
- msg->buf[i] = (u8) stu300_r8(dev->virtbase + I2C_DR);
- }
- } else {
- /* WRITE: we send the actual bytes one at a time */
- for (i = 0; i < msg->len; i++) {
- /* Write the byte */
- stu300_wr8(msg->buf[i],
- dev->virtbase + I2C_DR);
- /* Check status */
- ret = stu300_await_event(dev, STU300_EVENT_8);
- /* Next write to DR will clear event 8 */
- if (ret != 0) {
- dev_err(&dev->pdev->dev, "error awaiting "
- "event 8 (%d)\n", ret);
- goto exit_disable;
- }
- }
- /* Check NAK */
- if (!(msg->flags & I2C_M_IGNORE_NAK)) {
- if (stu300_r8(dev->virtbase + I2C_SR2) &
- I2C_SR2_AF_IND) {
- dev_err(&dev->pdev->dev, "I2C payload "
- "send returned NAK!\n");
- ret = -EIO;
- goto exit_disable;
- }
- }
- if (stop) {
- /* Send stop condition */
- val = I2C_CR_PERIPHERAL_ENABLE;
- val |= I2C_CR_STOP_ENABLE;
- stu300_wr8(val, dev->virtbase + I2C_CR);
- }
- }
-
- /* Check that the bus is free, or wait until some timeout occurs */
- ret = stu300_wait_while_busy(dev);
- if (ret != 0) {
- dev_err(&dev->pdev->dev, "timout waiting for transfer "
- "to commence.\n");
- goto exit_disable;
- }
-
- /* Dummy read status registers */
- val = stu300_r8(dev->virtbase + I2C_SR2);
- val = stu300_r8(dev->virtbase + I2C_SR1);
- ret = 0;
-
- exit_disable:
- /* Disable controller */
- stu300_wr8(0x00, dev->virtbase + I2C_CR);
- clk_disable(dev->clk);
- return ret;
-}
-
-static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
-{
- int ret = -1;
- int i;
-
- struct stu300_dev *dev = i2c_get_adapdata(adap);
- dev->msg_len = num;
-
- for (i = 0; i < num; i++) {
- /*
- * Another driver appears to send stop for each message,
- * here we only do that for the last message. Possibly some
- * peripherals require this behaviour, then their drivers
- * have to send single messages in order to get "stop" for
- * each message.
- */
- dev->msg_index = i;
-
- ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1)));
-
- if (ret != 0) {
- num = ret;
- break;
- }
- }
-
- return num;
-}
-
-static u32 stu300_func(struct i2c_adapter *adap)
-{
- /* This is the simplest thing you can think of... */
- return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
-}
-
-static const struct i2c_algorithm stu300_algo = {
- .master_xfer = stu300_xfer,
- .functionality = stu300_func,
-};
-
-static int __init
-stu300_probe(struct platform_device *pdev)
-{
- struct stu300_dev *dev;
- struct i2c_adapter *adap;
- struct resource *res;
- int bus_nr;
- int ret = 0;
- char clk_name[] = "I2C0";
-
- dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL);
- if (!dev) {
- dev_err(&pdev->dev, "could not allocate device struct\n");
- ret = -ENOMEM;
- goto err_no_devmem;
- }
-
- bus_nr = pdev->id;
- clk_name[3] += (char)bus_nr;
- dev->clk = clk_get(&pdev->dev, clk_name);
- if (IS_ERR(dev->clk)) {
- ret = PTR_ERR(dev->clk);
- dev_err(&pdev->dev, "could not retrieve i2c bus clock\n");
- goto err_no_clk;
- }
-
- dev->pdev = pdev;
- platform_set_drvdata(pdev, dev);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENOENT;
- goto err_no_resource;
- }
-
- dev->phybase = res->start;
- dev->physize = resource_size(res);
-
- if (request_mem_region(dev->phybase, dev->physize,
- NAME " I/O Area") == NULL) {
- ret = -EBUSY;
- goto err_no_ioregion;
- }
-
- dev->virtbase = ioremap(dev->phybase, dev->physize);
- dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
- "base %p\n", bus_nr, dev->virtbase);
- if (!dev->virtbase) {
- ret = -ENOMEM;
- goto err_no_ioremap;
- }
-
- dev->irq = platform_get_irq(pdev, 0);
- if (request_irq(dev->irq, stu300_irh, 0,
- NAME, dev)) {
- ret = -EIO;
- goto err_no_irq;
- }
-
- dev->speed = scl_frequency;
-
- clk_enable(dev->clk);
- ret = stu300_init_hw(dev);
- clk_disable(dev->clk);
-
- if (ret != 0) {
- dev_err(&dev->pdev->dev, "error initializing hardware.\n");
- goto err_init_hw;
- }
-
- /* IRQ event handling initialization */
- spin_lock_init(&dev->cmd_issue_lock);
- dev->cmd_event = STU300_EVENT_NONE;
- dev->cmd_err = STU300_ERROR_NONE;
-
- adap = &dev->adapter;
- adap->owner = THIS_MODULE;
- /* DDC class but actually often used for more generic I2C */
- adap->class = I2C_CLASS_DDC;
- strlcpy(adap->name, "ST Microelectronics DDC I2C adapter",
- sizeof(adap->name));
- adap->nr = bus_nr;
- adap->algo = &stu300_algo;
- adap->dev.parent = &pdev->dev;
- i2c_set_adapdata(adap, dev);
-
- /* i2c device drivers may be active on return from add_adapter() */
- ret = i2c_add_numbered_adapter(adap);
- if (ret) {
- dev_err(&dev->pdev->dev, "failure adding ST Micro DDC "
- "I2C adapter\n");
- goto err_add_adapter;
- }
- return 0;
-
- err_add_adapter:
- err_init_hw:
- free_irq(dev->irq, dev);
- err_no_irq:
- iounmap(dev->virtbase);
- err_no_ioremap:
- release_mem_region(dev->phybase, dev->physize);
- err_no_ioregion:
- platform_set_drvdata(pdev, NULL);
- err_no_resource:
- clk_put(dev->clk);
- err_no_clk:
- kfree(dev);
- err_no_devmem:
- dev_err(&pdev->dev, "failed to add " NAME " adapter: %d\n",
- pdev->id);
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int stu300_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct stu300_dev *dev = platform_get_drvdata(pdev);
-
- /* Turn off everything */
- stu300_wr8(0x00, dev->virtbase + I2C_CR);
- return 0;
-}
-
-static int stu300_resume(struct platform_device *pdev)
-{
- int ret = 0;
- struct stu300_dev *dev = platform_get_drvdata(pdev);
-
- clk_enable(dev->clk);
- ret = stu300_init_hw(dev);
- clk_disable(dev->clk);
-
- if (ret != 0)
- dev_err(&pdev->dev, "error re-initializing hardware.\n");
- return ret;
-}
-#else
-#define stu300_suspend NULL
-#define stu300_resume NULL
-#endif
-
-static int __exit
-stu300_remove(struct platform_device *pdev)
-{
- struct stu300_dev *dev = platform_get_drvdata(pdev);
-
- i2c_del_adapter(&dev->adapter);
- /* Turn off everything */
- stu300_wr8(0x00, dev->virtbase + I2C_CR);
- free_irq(dev->irq, dev);
- iounmap(dev->virtbase);
- release_mem_region(dev->phybase, dev->physize);
- clk_put(dev->clk);
- platform_set_drvdata(pdev, NULL);
- kfree(dev);
- return 0;
-}
-
-static struct platform_driver stu300_i2c_driver = {
- .driver = {
- .name = NAME,
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(stu300_remove),
- .suspend = stu300_suspend,
- .resume = stu300_resume,
-
-};
-
-static int __init stu300_init(void)
-{
- return platform_driver_probe(&stu300_i2c_driver, stu300_probe);
-}
-
-static void __exit stu300_exit(void)
-{
- platform_driver_unregister(&stu300_i2c_driver);
-}
-
-/*
- * The systems using this bus often have very basic devices such
- * as regulators on the I2C bus, so this needs to be loaded early.
- * Therefore it is registered in the subsys_initcall().
- */
-subsys_initcall(stu300_init);
-module_exit(stu300_exit);
-
-MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
-MODULE_DESCRIPTION("ST Micro DDC I2C adapter (" NAME ")");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-stub.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-stub.c
deleted file mode 100644
index b1b34479..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-stub.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- i2c-stub.c - I2C/SMBus chip emulator
-
- Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
- Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define DEBUG 1
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-
-#define MAX_CHIPS 10
-#define STUB_FUNC (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | \
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | \
- I2C_FUNC_SMBUS_I2C_BLOCK)
-
-static unsigned short chip_addr[MAX_CHIPS];
-module_param_array(chip_addr, ushort, NULL, S_IRUGO);
-MODULE_PARM_DESC(chip_addr,
- "Chip addresses (up to 10, between 0x03 and 0x77)");
-
-static unsigned long functionality = STUB_FUNC;
-module_param(functionality, ulong, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(functionality, "Override functionality bitfield");
-
-struct stub_chip {
- u8 pointer;
- u16 words[256]; /* Byte operations use the LSB as per SMBus
- specification */
-};
-
-static struct stub_chip *stub_chips;
-
-/* Return negative errno on error. */
-static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
- char read_write, u8 command, int size, union i2c_smbus_data * data)
-{
- s32 ret;
- int i, len;
- struct stub_chip *chip = NULL;
-
- /* Search for the right chip */
- for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) {
- if (addr == chip_addr[i]) {
- chip = stub_chips + i;
- break;
- }
- }
- if (!chip)
- return -ENODEV;
-
- switch (size) {
-
- case I2C_SMBUS_QUICK:
- dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr);
- ret = 0;
- break;
-
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_WRITE) {
- chip->pointer = command;
- dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
- "wrote 0x%02x.\n",
- addr, command);
- } else {
- data->byte = chip->words[chip->pointer++] & 0xff;
- dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
- "read 0x%02x.\n",
- addr, data->byte);
- }
-
- ret = 0;
- break;
-
- case I2C_SMBUS_BYTE_DATA:
- if (read_write == I2C_SMBUS_WRITE) {
- chip->words[command] &= 0xff00;
- chip->words[command] |= data->byte;
- dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
- "wrote 0x%02x at 0x%02x.\n",
- addr, data->byte, command);
- } else {
- data->byte = chip->words[command] & 0xff;
- dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
- "read 0x%02x at 0x%02x.\n",
- addr, data->byte, command);
- }
- chip->pointer = command + 1;
-
- ret = 0;
- break;
-
- case I2C_SMBUS_WORD_DATA:
- if (read_write == I2C_SMBUS_WRITE) {
- chip->words[command] = data->word;
- dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
- "wrote 0x%04x at 0x%02x.\n",
- addr, data->word, command);
- } else {
- data->word = chip->words[command];
- dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
- "read 0x%04x at 0x%02x.\n",
- addr, data->word, command);
- }
-
- ret = 0;
- break;
-
- case I2C_SMBUS_I2C_BLOCK_DATA:
- len = data->block[0];
- if (read_write == I2C_SMBUS_WRITE) {
- for (i = 0; i < len; i++) {
- chip->words[command + i] &= 0xff00;
- chip->words[command + i] |= data->block[1 + i];
- }
- dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
- "wrote %d bytes at 0x%02x.\n",
- addr, len, command);
- } else {
- for (i = 0; i < len; i++) {
- data->block[1 + i] =
- chip->words[command + i] & 0xff;
- }
- dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
- "read %d bytes at 0x%02x.\n",
- addr, len, command);
- }
-
- ret = 0;
- break;
-
- default:
- dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
- ret = -EOPNOTSUPP;
- break;
- } /* switch (size) */
-
- return ret;
-}
-
-static u32 stub_func(struct i2c_adapter *adapter)
-{
- return STUB_FUNC & functionality;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .functionality = stub_func,
- .smbus_xfer = stub_xfer,
-};
-
-static struct i2c_adapter stub_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
- .name = "SMBus stub driver",
-};
-
-static int __init i2c_stub_init(void)
-{
- int i, ret;
-
- if (!chip_addr[0]) {
- printk(KERN_ERR "i2c-stub: Please specify a chip address\n");
- return -ENODEV;
- }
-
- for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) {
- if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) {
- printk(KERN_ERR "i2c-stub: Invalid chip address "
- "0x%02x\n", chip_addr[i]);
- return -EINVAL;
- }
-
- printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n",
- chip_addr[i]);
- }
-
- /* Allocate memory for all chips at once */
- stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL);
- if (!stub_chips) {
- printk(KERN_ERR "i2c-stub: Out of memory\n");
- return -ENOMEM;
- }
-
- ret = i2c_add_adapter(&stub_adapter);
- if (ret)
- kfree(stub_chips);
- return ret;
-}
-
-static void __exit i2c_stub_exit(void)
-{
- i2c_del_adapter(&stub_adapter);
- kfree(stub_chips);
-}
-
-MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
-MODULE_DESCRIPTION("I2C stub driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_stub_init);
-module_exit(i2c_stub_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-taos-evm.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-taos-evm.c
deleted file mode 100644
index 26c352a0..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-taos-evm.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Driver for the TAOS evaluation modules
- * These devices include an I2C master which can be controlled over the
- * serial port.
- *
- * Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/serio.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-
-#define TAOS_BUFFER_SIZE 63
-
-#define TAOS_STATE_INIT 0
-#define TAOS_STATE_IDLE 1
-#define TAOS_STATE_EOFF 2
-#define TAOS_STATE_RECV 3
-
-#define TAOS_CMD_RESET 0x12
-#define TAOS_CMD_ECHO_ON '+'
-#define TAOS_CMD_ECHO_OFF '-'
-
-static DECLARE_WAIT_QUEUE_HEAD(wq);
-
-struct taos_data {
- struct i2c_adapter adapter;
- struct i2c_client *client;
- int state;
- u8 addr; /* last used address */
- unsigned char buffer[TAOS_BUFFER_SIZE];
- unsigned int pos; /* position inside the buffer */
-};
-
-/* TAOS TSL2550 EVM */
-static struct i2c_board_info tsl2550_info = {
- I2C_BOARD_INFO("tsl2550", 0x39),
-};
-
-/* Instantiate i2c devices based on the adapter name */
-static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
-{
- if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
- dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
- tsl2550_info.type, tsl2550_info.addr);
- return i2c_new_device(adapter, &tsl2550_info);
- }
-
- return NULL;
-}
-
-static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- struct serio *serio = adapter->algo_data;
- struct taos_data *taos = serio_get_drvdata(serio);
- char *p;
-
- /* Encode our transaction. "@" is for the device address, "$" for the
- SMBus command and "#" for the data. */
- p = taos->buffer;
-
- /* The device remembers the last used address, no need to send it
- again if it's the same */
- if (addr != taos->addr)
- p += sprintf(p, "@%02X", addr);
-
- switch (size) {
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_WRITE)
- sprintf(p, "$#%02X", command);
- else
- sprintf(p, "$");
- break;
- case I2C_SMBUS_BYTE_DATA:
- if (read_write == I2C_SMBUS_WRITE)
- sprintf(p, "$%02X#%02X", command, data->byte);
- else
- sprintf(p, "$%02X", command);
- break;
- default:
- dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- /* Send the transaction to the TAOS EVM */
- dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer);
- for (p = taos->buffer; *p; p++)
- serio_write(serio, *p);
-
- taos->addr = addr;
-
- /* Start the transaction and read the answer */
- taos->pos = 0;
- taos->state = TAOS_STATE_RECV;
- serio_write(serio, read_write == I2C_SMBUS_WRITE ? '>' : '<');
- wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
- msecs_to_jiffies(150));
- if (taos->state != TAOS_STATE_IDLE
- || taos->pos != 5) {
- dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n",
- taos->pos);
- return -EIO;
- }
- dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer);
-
- /* Interpret the returned string */
- p = taos->buffer + 1;
- p[3] = '\0';
- if (!strcmp(p, "NAK"))
- return -ENODEV;
-
- if (read_write == I2C_SMBUS_WRITE) {
- if (!strcmp(p, "ACK"))
- return 0;
- } else {
- if (p[0] == 'x') {
- data->byte = simple_strtol(p + 1, NULL, 16);
- return 0;
- }
- }
-
- return -EIO;
-}
-
-static u32 taos_smbus_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA;
-}
-
-static const struct i2c_algorithm taos_algorithm = {
- .smbus_xfer = taos_smbus_xfer,
- .functionality = taos_smbus_func,
-};
-
-static irqreturn_t taos_interrupt(struct serio *serio, unsigned char data,
- unsigned int flags)
-{
- struct taos_data *taos = serio_get_drvdata(serio);
-
- switch (taos->state) {
- case TAOS_STATE_INIT:
- taos->buffer[taos->pos++] = data;
- if (data == ':'
- || taos->pos == TAOS_BUFFER_SIZE - 1) {
- taos->buffer[taos->pos] = '\0';
- taos->state = TAOS_STATE_IDLE;
- wake_up_interruptible(&wq);
- }
- break;
- case TAOS_STATE_EOFF:
- taos->state = TAOS_STATE_IDLE;
- wake_up_interruptible(&wq);
- break;
- case TAOS_STATE_RECV:
- taos->buffer[taos->pos++] = data;
- if (data == ']') {
- taos->buffer[taos->pos] = '\0';
- taos->state = TAOS_STATE_IDLE;
- wake_up_interruptible(&wq);
- }
- break;
- }
-
- return IRQ_HANDLED;
-}
-
-/* Extract the adapter name from the buffer received after reset.
- The buffer is modified and a pointer inside the buffer is returned. */
-static char *taos_adapter_name(char *buffer)
-{
- char *start, *end;
-
- start = strstr(buffer, "TAOS ");
- if (!start)
- return NULL;
-
- end = strchr(start, '\r');
- if (!end)
- return NULL;
- *end = '\0';
-
- return start;
-}
-
-static int taos_connect(struct serio *serio, struct serio_driver *drv)
-{
- struct taos_data *taos;
- struct i2c_adapter *adapter;
- char *name;
- int err;
-
- taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL);
- if (!taos) {
- err = -ENOMEM;
- goto exit;
- }
- taos->state = TAOS_STATE_INIT;
- serio_set_drvdata(serio, taos);
-
- err = serio_open(serio, drv);
- if (err)
- goto exit_kfree;
-
- adapter = &taos->adapter;
- adapter->owner = THIS_MODULE;
- adapter->algo = &taos_algorithm;
- adapter->algo_data = serio;
- adapter->dev.parent = &serio->dev;
-
- /* Reset the TAOS evaluation module to identify it */
- serio_write(serio, TAOS_CMD_RESET);
- wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
- msecs_to_jiffies(2000));
-
- if (taos->state != TAOS_STATE_IDLE) {
- err = -ENODEV;
- dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, "
- "pos=%d)\n", taos->state, taos->pos);
- goto exit_close;
- }
-
- name = taos_adapter_name(taos->buffer);
- if (!name) {
- err = -ENODEV;
- dev_err(&serio->dev, "TAOS EVM identification failed\n");
- goto exit_close;
- }
- strlcpy(adapter->name, name, sizeof(adapter->name));
-
- /* Turn echo off for better performance */
- taos->state = TAOS_STATE_EOFF;
- serio_write(serio, TAOS_CMD_ECHO_OFF);
-
- wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
- msecs_to_jiffies(250));
- if (taos->state != TAOS_STATE_IDLE) {
- err = -ENODEV;
- dev_err(&serio->dev, "TAOS EVM echo off failed "
- "(state=%d)\n", taos->state);
- goto exit_close;
- }
-
- err = i2c_add_adapter(adapter);
- if (err)
- goto exit_close;
- dev_info(&serio->dev, "Connected to TAOS EVM\n");
-
- taos->client = taos_instantiate_device(adapter);
- return 0;
-
- exit_close:
- serio_close(serio);
- exit_kfree:
- serio_set_drvdata(serio, NULL);
- kfree(taos);
- exit:
- return err;
-}
-
-static void taos_disconnect(struct serio *serio)
-{
- struct taos_data *taos = serio_get_drvdata(serio);
-
- if (taos->client)
- i2c_unregister_device(taos->client);
- i2c_del_adapter(&taos->adapter);
- serio_close(serio);
- serio_set_drvdata(serio, NULL);
- kfree(taos);
-
- dev_info(&serio->dev, "Disconnected from TAOS EVM\n");
-}
-
-static struct serio_device_id taos_serio_ids[] = {
- {
- .type = SERIO_RS232,
- .proto = SERIO_TAOSEVM,
- .id = SERIO_ANY,
- .extra = SERIO_ANY,
- },
- { 0 }
-};
-MODULE_DEVICE_TABLE(serio, taos_serio_ids);
-
-static struct serio_driver taos_drv = {
- .driver = {
- .name = "taos-evm",
- },
- .description = "TAOS evaluation module driver",
- .id_table = taos_serio_ids,
- .connect = taos_connect,
- .disconnect = taos_disconnect,
- .interrupt = taos_interrupt,
-};
-
-static int __init taos_init(void)
-{
- return serio_register_driver(&taos_drv);
-}
-
-static void __exit taos_exit(void)
-{
- serio_unregister_driver(&taos_drv);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("TAOS evaluation module driver");
-MODULE_LICENSE("GPL");
-
-module_init(taos_init);
-module_exit(taos_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-tegra.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-tegra.c
deleted file mode 100644
index df19f3d5..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-tegra.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * drivers/i2c/busses/i2c-tegra.c
- *
- * Copyright (C) 2010 Google, Inc.
- * Author: Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/i2c-tegra.h>
-#include <linux/of_i2c.h>
-#include <linux/module.h>
-
-#include <asm/unaligned.h>
-
-#include <mach/clk.h>
-
-#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000))
-#define BYTES_PER_FIFO_WORD 4
-
-#define I2C_CNFG 0x000
-#define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12
-#define I2C_CNFG_PACKET_MODE_EN (1<<10)
-#define I2C_CNFG_NEW_MASTER_FSM (1<<11)
-#define I2C_STATUS 0x01C
-#define I2C_SL_CNFG 0x020
-#define I2C_SL_CNFG_NACK (1<<1)
-#define I2C_SL_CNFG_NEWSL (1<<2)
-#define I2C_SL_ADDR1 0x02c
-#define I2C_SL_ADDR2 0x030
-#define I2C_TX_FIFO 0x050
-#define I2C_RX_FIFO 0x054
-#define I2C_PACKET_TRANSFER_STATUS 0x058
-#define I2C_FIFO_CONTROL 0x05c
-#define I2C_FIFO_CONTROL_TX_FLUSH (1<<1)
-#define I2C_FIFO_CONTROL_RX_FLUSH (1<<0)
-#define I2C_FIFO_CONTROL_TX_TRIG_SHIFT 5
-#define I2C_FIFO_CONTROL_RX_TRIG_SHIFT 2
-#define I2C_FIFO_STATUS 0x060
-#define I2C_FIFO_STATUS_TX_MASK 0xF0
-#define I2C_FIFO_STATUS_TX_SHIFT 4
-#define I2C_FIFO_STATUS_RX_MASK 0x0F
-#define I2C_FIFO_STATUS_RX_SHIFT 0
-#define I2C_INT_MASK 0x064
-#define I2C_INT_STATUS 0x068
-#define I2C_INT_PACKET_XFER_COMPLETE (1<<7)
-#define I2C_INT_ALL_PACKETS_XFER_COMPLETE (1<<6)
-#define I2C_INT_TX_FIFO_OVERFLOW (1<<5)
-#define I2C_INT_RX_FIFO_UNDERFLOW (1<<4)
-#define I2C_INT_NO_ACK (1<<3)
-#define I2C_INT_ARBITRATION_LOST (1<<2)
-#define I2C_INT_TX_FIFO_DATA_REQ (1<<1)
-#define I2C_INT_RX_FIFO_DATA_REQ (1<<0)
-#define I2C_CLK_DIVISOR 0x06c
-
-#define DVC_CTRL_REG1 0x000
-#define DVC_CTRL_REG1_INTR_EN (1<<10)
-#define DVC_CTRL_REG2 0x004
-#define DVC_CTRL_REG3 0x008
-#define DVC_CTRL_REG3_SW_PROG (1<<26)
-#define DVC_CTRL_REG3_I2C_DONE_INTR_EN (1<<30)
-#define DVC_STATUS 0x00c
-#define DVC_STATUS_I2C_DONE_INTR (1<<30)
-
-#define I2C_ERR_NONE 0x00
-#define I2C_ERR_NO_ACK 0x01
-#define I2C_ERR_ARBITRATION_LOST 0x02
-#define I2C_ERR_UNKNOWN_INTERRUPT 0x04
-
-#define PACKET_HEADER0_HEADER_SIZE_SHIFT 28
-#define PACKET_HEADER0_PACKET_ID_SHIFT 16
-#define PACKET_HEADER0_CONT_ID_SHIFT 12
-#define PACKET_HEADER0_PROTOCOL_I2C (1<<4)
-
-#define I2C_HEADER_HIGHSPEED_MODE (1<<22)
-#define I2C_HEADER_CONT_ON_NAK (1<<21)
-#define I2C_HEADER_SEND_START_BYTE (1<<20)
-#define I2C_HEADER_READ (1<<19)
-#define I2C_HEADER_10BIT_ADDR (1<<18)
-#define I2C_HEADER_IE_ENABLE (1<<17)
-#define I2C_HEADER_REPEAT_START (1<<16)
-#define I2C_HEADER_MASTER_ADDR_SHIFT 12
-#define I2C_HEADER_SLAVE_ADDR_SHIFT 1
-
-/**
- * struct tegra_i2c_dev - per device i2c context
- * @dev: device reference for power management
- * @adapter: core i2c layer adapter information
- * @clk: clock reference for i2c controller
- * @i2c_clk: clock reference for i2c bus
- * @iomem: memory resource for registers
- * @base: ioremapped registers cookie
- * @cont_id: i2c controller id, used for for packet header
- * @irq: irq number of transfer complete interrupt
- * @is_dvc: identifies the DVC i2c controller, has a different register layout
- * @msg_complete: transfer completion notifier
- * @msg_err: error code for completed message
- * @msg_buf: pointer to current message data
- * @msg_buf_remaining: size of unsent data in the message buffer
- * @msg_read: identifies read transfers
- * @bus_clk_rate: current i2c bus clock rate
- * @is_suspended: prevents i2c controller accesses after suspend is called
- */
-struct tegra_i2c_dev {
- struct device *dev;
- struct i2c_adapter adapter;
- struct clk *clk;
- struct clk *i2c_clk;
- struct resource *iomem;
- void __iomem *base;
- int cont_id;
- int irq;
- bool irq_disabled;
- int is_dvc;
- struct completion msg_complete;
- int msg_err;
- u8 *msg_buf;
- size_t msg_buf_remaining;
- int msg_read;
- unsigned long bus_clk_rate;
- bool is_suspended;
-};
-
-static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg)
-{
- writel(val, i2c_dev->base + reg);
-}
-
-static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
-{
- return readl(i2c_dev->base + reg);
-}
-
-/*
- * i2c_writel and i2c_readl will offset the register if necessary to talk
- * to the I2C block inside the DVC block
- */
-static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,
- unsigned long reg)
-{
- if (i2c_dev->is_dvc)
- reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
- return reg;
-}
-
-static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
- unsigned long reg)
-{
- writel(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
-}
-
-static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
-{
- return readl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
-}
-
-static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
- unsigned long reg, int len)
-{
- writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
-}
-
-static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
- unsigned long reg, int len)
-{
- readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
-}
-
-static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
-{
- u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);
- int_mask &= ~mask;
- i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
-}
-
-static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
-{
- u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);
- int_mask |= mask;
- i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
-}
-
-static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
-{
- unsigned long timeout = jiffies + HZ;
- u32 val = i2c_readl(i2c_dev, I2C_FIFO_CONTROL);
- val |= I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH;
- i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
-
- while (i2c_readl(i2c_dev, I2C_FIFO_CONTROL) &
- (I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH)) {
- if (time_after(jiffies, timeout)) {
- dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
- return -ETIMEDOUT;
- }
- msleep(1);
- }
- return 0;
-}
-
-static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
-{
- u32 val;
- int rx_fifo_avail;
- u8 *buf = i2c_dev->msg_buf;
- size_t buf_remaining = i2c_dev->msg_buf_remaining;
- int words_to_transfer;
-
- val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
- rx_fifo_avail = (val & I2C_FIFO_STATUS_RX_MASK) >>
- I2C_FIFO_STATUS_RX_SHIFT;
-
- /* Rounds down to not include partial word at the end of buf */
- words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
- if (words_to_transfer > rx_fifo_avail)
- words_to_transfer = rx_fifo_avail;
-
- i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer);
-
- buf += words_to_transfer * BYTES_PER_FIFO_WORD;
- buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
- rx_fifo_avail -= words_to_transfer;
-
- /*
- * If there is a partial word at the end of buf, handle it manually to
- * prevent overwriting past the end of buf
- */
- if (rx_fifo_avail > 0 && buf_remaining > 0) {
- BUG_ON(buf_remaining > 3);
- val = i2c_readl(i2c_dev, I2C_RX_FIFO);
- memcpy(buf, &val, buf_remaining);
- buf_remaining = 0;
- rx_fifo_avail--;
- }
-
- BUG_ON(rx_fifo_avail > 0 && buf_remaining > 0);
- i2c_dev->msg_buf_remaining = buf_remaining;
- i2c_dev->msg_buf = buf;
- return 0;
-}
-
-static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
-{
- u32 val;
- int tx_fifo_avail;
- u8 *buf = i2c_dev->msg_buf;
- size_t buf_remaining = i2c_dev->msg_buf_remaining;
- int words_to_transfer;
-
- val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
- tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >>
- I2C_FIFO_STATUS_TX_SHIFT;
-
- /* Rounds down to not include partial word at the end of buf */
- words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
-
- /* It's very common to have < 4 bytes, so optimize that case. */
- if (words_to_transfer) {
- if (words_to_transfer > tx_fifo_avail)
- words_to_transfer = tx_fifo_avail;
-
- /*
- * Update state before writing to FIFO. If this casues us
- * to finish writing all bytes (AKA buf_remaining goes to 0) we
- * have a potential for an interrupt (PACKET_XFER_COMPLETE is
- * not maskable). We need to make sure that the isr sees
- * buf_remaining as 0 and doesn't call us back re-entrantly.
- */
- buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
- tx_fifo_avail -= words_to_transfer;
- i2c_dev->msg_buf_remaining = buf_remaining;
- i2c_dev->msg_buf = buf +
- words_to_transfer * BYTES_PER_FIFO_WORD;
- barrier();
-
- i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
-
- buf += words_to_transfer * BYTES_PER_FIFO_WORD;
- }
-
- /*
- * If there is a partial word at the end of buf, handle it manually to
- * prevent reading past the end of buf, which could cross a page
- * boundary and fault.
- */
- if (tx_fifo_avail > 0 && buf_remaining > 0) {
- BUG_ON(buf_remaining > 3);
- memcpy(&val, buf, buf_remaining);
-
- /* Again update before writing to FIFO to make sure isr sees. */
- i2c_dev->msg_buf_remaining = 0;
- i2c_dev->msg_buf = NULL;
- barrier();
-
- i2c_writel(i2c_dev, val, I2C_TX_FIFO);
- }
-
- return 0;
-}
-
-/*
- * One of the Tegra I2C blocks is inside the DVC (Digital Voltage Controller)
- * block. This block is identical to the rest of the I2C blocks, except that
- * it only supports master mode, it has registers moved around, and it needs
- * some extra init to get it into I2C mode. The register moves are handled
- * by i2c_readl and i2c_writel
- */
-static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
-{
- u32 val = 0;
- val = dvc_readl(i2c_dev, DVC_CTRL_REG3);
- val |= DVC_CTRL_REG3_SW_PROG;
- val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;
- dvc_writel(i2c_dev, val, DVC_CTRL_REG3);
-
- val = dvc_readl(i2c_dev, DVC_CTRL_REG1);
- val |= DVC_CTRL_REG1_INTR_EN;
- dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
-}
-
-static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
-{
- u32 val;
- int err = 0;
-
- clk_enable(i2c_dev->clk);
-
- tegra_periph_reset_assert(i2c_dev->clk);
- udelay(2);
- tegra_periph_reset_deassert(i2c_dev->clk);
-
- if (i2c_dev->is_dvc)
- tegra_dvc_init(i2c_dev);
-
- val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
- (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
- i2c_writel(i2c_dev, val, I2C_CNFG);
- i2c_writel(i2c_dev, 0, I2C_INT_MASK);
- clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8);
-
- if (!i2c_dev->is_dvc) {
- u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
- sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
- i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
- i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
- i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
-
- }
-
- val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
- 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;
- i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
-
- if (tegra_i2c_flush_fifos(i2c_dev))
- err = -ETIMEDOUT;
-
- clk_disable(i2c_dev->clk);
-
- if (i2c_dev->irq_disabled) {
- i2c_dev->irq_disabled = 0;
- enable_irq(i2c_dev->irq);
- }
-
- return err;
-}
-
-static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
-{
- u32 status;
- const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
- struct tegra_i2c_dev *i2c_dev = dev_id;
-
- status = i2c_readl(i2c_dev, I2C_INT_STATUS);
-
- if (status == 0) {
- dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n",
- i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
- i2c_readl(i2c_dev, I2C_STATUS),
- i2c_readl(i2c_dev, I2C_CNFG));
- i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
-
- if (!i2c_dev->irq_disabled) {
- disable_irq_nosync(i2c_dev->irq);
- i2c_dev->irq_disabled = 1;
- }
- goto err;
- }
-
- if (unlikely(status & status_err)) {
- if (status & I2C_INT_NO_ACK)
- i2c_dev->msg_err |= I2C_ERR_NO_ACK;
- if (status & I2C_INT_ARBITRATION_LOST)
- i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST;
- goto err;
- }
-
- if (i2c_dev->msg_read && (status & I2C_INT_RX_FIFO_DATA_REQ)) {
- if (i2c_dev->msg_buf_remaining)
- tegra_i2c_empty_rx_fifo(i2c_dev);
- else
- BUG();
- }
-
- if (!i2c_dev->msg_read && (status & I2C_INT_TX_FIFO_DATA_REQ)) {
- if (i2c_dev->msg_buf_remaining)
- tegra_i2c_fill_tx_fifo(i2c_dev);
- else
- tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);
- }
-
- i2c_writel(i2c_dev, status, I2C_INT_STATUS);
- if (i2c_dev->is_dvc)
- dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
-
- if (status & I2C_INT_PACKET_XFER_COMPLETE) {
- BUG_ON(i2c_dev->msg_buf_remaining);
- complete(&i2c_dev->msg_complete);
- }
- return IRQ_HANDLED;
-err:
- /* An error occurred, mask all interrupts */
- tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |
- I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
- I2C_INT_RX_FIFO_DATA_REQ);
- i2c_writel(i2c_dev, status, I2C_INT_STATUS);
- if (i2c_dev->is_dvc)
- dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
-
- complete(&i2c_dev->msg_complete);
- return IRQ_HANDLED;
-}
-
-static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
- struct i2c_msg *msg, int stop)
-{
- u32 packet_header;
- u32 int_mask;
- int ret;
-
- tegra_i2c_flush_fifos(i2c_dev);
-
- if (msg->len == 0)
- return -EINVAL;
-
- i2c_dev->msg_buf = msg->buf;
- i2c_dev->msg_buf_remaining = msg->len;
- i2c_dev->msg_err = I2C_ERR_NONE;
- i2c_dev->msg_read = (msg->flags & I2C_M_RD);
- INIT_COMPLETION(i2c_dev->msg_complete);
-
- packet_header = (0 << PACKET_HEADER0_HEADER_SIZE_SHIFT) |
- PACKET_HEADER0_PROTOCOL_I2C |
- (i2c_dev->cont_id << PACKET_HEADER0_CONT_ID_SHIFT) |
- (1 << PACKET_HEADER0_PACKET_ID_SHIFT);
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
- packet_header = msg->len - 1;
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
- packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
- packet_header |= I2C_HEADER_IE_ENABLE;
- if (!stop)
- packet_header |= I2C_HEADER_REPEAT_START;
- if (msg->flags & I2C_M_TEN)
- packet_header |= I2C_HEADER_10BIT_ADDR;
- if (msg->flags & I2C_M_IGNORE_NAK)
- packet_header |= I2C_HEADER_CONT_ON_NAK;
- if (msg->flags & I2C_M_RD)
- packet_header |= I2C_HEADER_READ;
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
- if (!(msg->flags & I2C_M_RD))
- tegra_i2c_fill_tx_fifo(i2c_dev);
-
- int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
- if (msg->flags & I2C_M_RD)
- int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
- else if (i2c_dev->msg_buf_remaining)
- int_mask |= I2C_INT_TX_FIFO_DATA_REQ;
- tegra_i2c_unmask_irq(i2c_dev, int_mask);
- dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
- i2c_readl(i2c_dev, I2C_INT_MASK));
-
- ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT);
- tegra_i2c_mask_irq(i2c_dev, int_mask);
-
- if (WARN_ON(ret == 0)) {
- dev_err(i2c_dev->dev, "i2c transfer timed out\n");
-
- tegra_i2c_init(i2c_dev);
- return -ETIMEDOUT;
- }
-
- dev_dbg(i2c_dev->dev, "transfer complete: %d %d %d\n",
- ret, completion_done(&i2c_dev->msg_complete), i2c_dev->msg_err);
-
- if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
- return 0;
-
- /*
- * NACK interrupt is generated before the I2C controller generates the
- * STOP condition on the bus. So wait for 2 clock periods before resetting
- * the controller so that STOP condition has been delivered properly.
- */
- if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
- udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
-
- tegra_i2c_init(i2c_dev);
- if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
- if (msg->flags & I2C_M_IGNORE_NAK)
- return 0;
- return -EREMOTEIO;
- }
-
- return -EIO;
-}
-
-static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
- int num)
-{
- struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
- int i;
- int ret = 0;
-
- if (i2c_dev->is_suspended)
- return -EBUSY;
-
- clk_enable(i2c_dev->clk);
- for (i = 0; i < num; i++) {
- int stop = (i == (num - 1)) ? 1 : 0;
- ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], stop);
- if (ret)
- break;
- }
- clk_disable(i2c_dev->clk);
- return ret ?: i;
-}
-
-static u32 tegra_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm tegra_i2c_algo = {
- .master_xfer = tegra_i2c_xfer,
- .functionality = tegra_i2c_func,
-};
-
-static int __devinit tegra_i2c_probe(struct platform_device *pdev)
-{
- struct tegra_i2c_dev *i2c_dev;
- struct tegra_i2c_platform_data *pdata = pdev->dev.platform_data;
- struct resource *res;
- struct resource *iomem;
- struct clk *clk;
- struct clk *i2c_clk;
- const unsigned int *prop;
- void __iomem *base;
- int irq;
- int ret = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "no mem resource\n");
- return -EINVAL;
- }
- iomem = request_mem_region(res->start, resource_size(res), pdev->name);
- if (!iomem) {
- dev_err(&pdev->dev, "I2C region already claimed\n");
- return -EBUSY;
- }
-
- base = ioremap(iomem->start, resource_size(iomem));
- if (!base) {
- dev_err(&pdev->dev, "Cannot ioremap I2C region\n");
- return -ENOMEM;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev, "no irq resource\n");
- ret = -EINVAL;
- goto err_iounmap;
- }
- irq = res->start;
-
- clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "missing controller clock");
- ret = PTR_ERR(clk);
- goto err_release_region;
- }
-
- i2c_clk = clk_get(&pdev->dev, "i2c");
- if (IS_ERR(i2c_clk)) {
- dev_err(&pdev->dev, "missing bus clock");
- ret = PTR_ERR(i2c_clk);
- goto err_clk_put;
- }
-
- i2c_dev = kzalloc(sizeof(struct tegra_i2c_dev), GFP_KERNEL);
- if (!i2c_dev) {
- ret = -ENOMEM;
- goto err_i2c_clk_put;
- }
-
- i2c_dev->base = base;
- i2c_dev->clk = clk;
- i2c_dev->i2c_clk = i2c_clk;
- i2c_dev->iomem = iomem;
- i2c_dev->adapter.algo = &tegra_i2c_algo;
- i2c_dev->irq = irq;
- i2c_dev->cont_id = pdev->id;
- i2c_dev->dev = &pdev->dev;
-
- i2c_dev->bus_clk_rate = 100000; /* default clock rate */
- if (pdata) {
- i2c_dev->bus_clk_rate = pdata->bus_clk_rate;
-
- } else if (i2c_dev->dev->of_node) { /* if there is a device tree node ... */
- prop = of_get_property(i2c_dev->dev->of_node,
- "clock-frequency", NULL);
- if (prop)
- i2c_dev->bus_clk_rate = be32_to_cpup(prop);
- }
-
- if (pdev->dev.of_node)
- i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
- "nvidia,tegra20-i2c-dvc");
- else if (pdev->id == 3)
- i2c_dev->is_dvc = 1;
- init_completion(&i2c_dev->msg_complete);
-
- platform_set_drvdata(pdev, i2c_dev);
-
- ret = tegra_i2c_init(i2c_dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to initialize i2c controller");
- goto err_free;
- }
-
- ret = request_irq(i2c_dev->irq, tegra_i2c_isr, 0, pdev->name, i2c_dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
- goto err_free;
- }
-
- clk_enable(i2c_dev->i2c_clk);
-
- i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
- i2c_dev->adapter.owner = THIS_MODULE;
- i2c_dev->adapter.class = I2C_CLASS_HWMON;
- strlcpy(i2c_dev->adapter.name, "Tegra I2C adapter",
- sizeof(i2c_dev->adapter.name));
- i2c_dev->adapter.algo = &tegra_i2c_algo;
- i2c_dev->adapter.dev.parent = &pdev->dev;
- i2c_dev->adapter.nr = pdev->id;
- i2c_dev->adapter.dev.of_node = pdev->dev.of_node;
-
- ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add I2C adapter\n");
- goto err_free_irq;
- }
-
- of_i2c_register_devices(&i2c_dev->adapter);
-
- return 0;
-err_free_irq:
- free_irq(i2c_dev->irq, i2c_dev);
-err_free:
- kfree(i2c_dev);
-err_i2c_clk_put:
- clk_put(i2c_clk);
-err_clk_put:
- clk_put(clk);
-err_release_region:
- release_mem_region(iomem->start, resource_size(iomem));
-err_iounmap:
- iounmap(base);
- return ret;
-}
-
-static int __devexit tegra_i2c_remove(struct platform_device *pdev)
-{
- struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
- i2c_del_adapter(&i2c_dev->adapter);
- free_irq(i2c_dev->irq, i2c_dev);
- clk_put(i2c_dev->i2c_clk);
- clk_put(i2c_dev->clk);
- release_mem_region(i2c_dev->iomem->start,
- resource_size(i2c_dev->iomem));
- iounmap(i2c_dev->base);
- kfree(i2c_dev);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int tegra_i2c_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-
- i2c_lock_adapter(&i2c_dev->adapter);
- i2c_dev->is_suspended = true;
- i2c_unlock_adapter(&i2c_dev->adapter);
-
- return 0;
-}
-
-static int tegra_i2c_resume(struct platform_device *pdev)
-{
- struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
- int ret;
-
- i2c_lock_adapter(&i2c_dev->adapter);
-
- ret = tegra_i2c_init(i2c_dev);
-
- if (ret) {
- i2c_unlock_adapter(&i2c_dev->adapter);
- return ret;
- }
-
- i2c_dev->is_suspended = false;
-
- i2c_unlock_adapter(&i2c_dev->adapter);
-
- return 0;
-}
-#endif
-
-#if defined(CONFIG_OF)
-/* Match table for of_platform binding */
-static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
- { .compatible = "nvidia,tegra20-i2c", },
- { .compatible = "nvidia,tegra20-i2c-dvc", },
- {},
-};
-MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
-#else
-#define tegra_i2c_of_match NULL
-#endif
-
-static struct platform_driver tegra_i2c_driver = {
- .probe = tegra_i2c_probe,
- .remove = __devexit_p(tegra_i2c_remove),
-#ifdef CONFIG_PM
- .suspend = tegra_i2c_suspend,
- .resume = tegra_i2c_resume,
-#endif
- .driver = {
- .name = "tegra-i2c",
- .owner = THIS_MODULE,
- .of_match_table = tegra_i2c_of_match,
- },
-};
-
-static int __init tegra_i2c_init_driver(void)
-{
- return platform_driver_register(&tegra_i2c_driver);
-}
-
-static void __exit tegra_i2c_exit_driver(void)
-{
- platform_driver_unregister(&tegra_i2c_driver);
-}
-
-subsys_initcall(tegra_i2c_init_driver);
-module_exit(tegra_i2c_exit_driver);
-
-MODULE_DESCRIPTION("nVidia Tegra2 I2C Bus Controller driver");
-MODULE_AUTHOR("Colin Cross");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-tiny-usb.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-tiny-usb.c
deleted file mode 100644
index f07307ff..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-tiny-usb.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * driver for the i2c-tiny-usb adapter - 1.0
- * http://www.harbaum.org/till/i2c_tiny_usb
- *
- * Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-/* include interfaces to usb layer */
-#include <linux/usb.h>
-
-/* include interface to i2c layer */
-#include <linux/i2c.h>
-
-/* commands via USB, must match command ids in the firmware */
-#define CMD_ECHO 0
-#define CMD_GET_FUNC 1
-#define CMD_SET_DELAY 2
-#define CMD_GET_STATUS 3
-
-#define CMD_I2C_IO 4
-#define CMD_I2C_IO_BEGIN (1<<0)
-#define CMD_I2C_IO_END (1<<1)
-
-/* i2c bit delay, default is 10us -> 100kHz max
- (in practice, due to additional delays in the i2c bitbanging
- code this results in a i2c clock of about 50kHz) */
-static unsigned short delay = 10;
-module_param(delay, ushort, 0);
-MODULE_PARM_DESC(delay, "bit delay in microseconds "
- "(default is 10us for 100kHz max)");
-
-static int usb_read(struct i2c_adapter *adapter, int cmd,
- int value, int index, void *data, int len);
-
-static int usb_write(struct i2c_adapter *adapter, int cmd,
- int value, int index, void *data, int len);
-
-/* ----- begin of i2c layer ---------------------------------------------- */
-
-#define STATUS_IDLE 0
-#define STATUS_ADDRESS_ACK 1
-#define STATUS_ADDRESS_NAK 2
-
-static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
-{
- unsigned char status;
- struct i2c_msg *pmsg;
- int i;
-
- dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
-
- for (i = 0 ; i < num ; i++) {
- int cmd = CMD_I2C_IO;
-
- if (i == 0)
- cmd |= CMD_I2C_IO_BEGIN;
-
- if (i == num-1)
- cmd |= CMD_I2C_IO_END;
-
- pmsg = &msgs[i];
-
- dev_dbg(&adapter->dev,
- " %d: %s (flags %d) %d bytes to 0x%02x\n",
- i, pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->flags, pmsg->len, pmsg->addr);
-
- /* and directly send the message */
- if (pmsg->flags & I2C_M_RD) {
- /* read data */
- if (usb_read(adapter, cmd,
- pmsg->flags, pmsg->addr,
- pmsg->buf, pmsg->len) != pmsg->len) {
- dev_err(&adapter->dev,
- "failure reading data\n");
- return -EREMOTEIO;
- }
- } else {
- /* write data */
- if (usb_write(adapter, cmd,
- pmsg->flags, pmsg->addr,
- pmsg->buf, pmsg->len) != pmsg->len) {
- dev_err(&adapter->dev,
- "failure writing data\n");
- return -EREMOTEIO;
- }
- }
-
- /* read status */
- if (usb_read(adapter, CMD_GET_STATUS, 0, 0, &status, 1) != 1) {
- dev_err(&adapter->dev, "failure reading status\n");
- return -EREMOTEIO;
- }
-
- dev_dbg(&adapter->dev, " status = %d\n", status);
- if (status == STATUS_ADDRESS_NAK)
- return -EREMOTEIO;
- }
-
- return i;
-}
-
-static u32 usb_func(struct i2c_adapter *adapter)
-{
- __le32 func;
-
- /* get functionality from adapter */
- if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
- sizeof(func)) {
- dev_err(&adapter->dev, "failure reading functionality\n");
- return 0;
- }
-
- return le32_to_cpu(func);
-}
-
-/* This is the actual algorithm we define */
-static const struct i2c_algorithm usb_algorithm = {
- .master_xfer = usb_xfer,
- .functionality = usb_func,
-};
-
-/* ----- end of i2c layer ------------------------------------------------ */
-
-/* ----- begin of usb layer ---------------------------------------------- */
-
-/*
- * Initially the usb i2c interface uses a vid/pid pair donated by
- * Future Technology Devices International Ltd., later a pair was
- * bought from EZPrototypes
- */
-static const struct usb_device_id i2c_tiny_usb_table[] = {
- { USB_DEVICE(0x0403, 0xc631) }, /* FTDI */
- { USB_DEVICE(0x1c40, 0x0534) }, /* EZPrototypes */
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table);
-
-/* Structure to hold all of our device specific stuff */
-struct i2c_tiny_usb {
- struct usb_device *usb_dev; /* the usb device for this device */
- struct usb_interface *interface; /* the interface for this device */
- struct i2c_adapter adapter; /* i2c related things */
-};
-
-static int usb_read(struct i2c_adapter *adapter, int cmd,
- int value, int index, void *data, int len)
-{
- struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
-
- /* do control transfer */
- return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
- cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
- USB_DIR_IN, value, index, data, len, 2000);
-}
-
-static int usb_write(struct i2c_adapter *adapter, int cmd,
- int value, int index, void *data, int len)
-{
- struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
-
- /* do control transfer */
- return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
- cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value, index, data, len, 2000);
-}
-
-static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev)
-{
- usb_put_dev(dev->usb_dev);
- kfree(dev);
-}
-
-static int i2c_tiny_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct i2c_tiny_usb *dev;
- int retval = -ENOMEM;
- u16 version;
-
- dev_dbg(&interface->dev, "probing usb device\n");
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&interface->dev, "Out of memory\n");
- goto error;
- }
-
- dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
- dev->interface = interface;
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- version = le16_to_cpu(dev->usb_dev->descriptor.bcdDevice);
- dev_info(&interface->dev,
- "version %x.%02x found at bus %03d address %03d\n",
- version >> 8, version & 0xff,
- dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
-
- /* setup i2c adapter description */
- dev->adapter.owner = THIS_MODULE;
- dev->adapter.class = I2C_CLASS_HWMON;
- dev->adapter.algo = &usb_algorithm;
- dev->adapter.algo_data = dev;
- snprintf(dev->adapter.name, sizeof(dev->adapter.name),
- "i2c-tiny-usb at bus %03d device %03d",
- dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
-
- if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) {
- dev_err(&dev->adapter.dev,
- "failure setting delay to %dus\n", delay);
- retval = -EIO;
- goto error;
- }
-
- dev->adapter.dev.parent = &dev->interface->dev;
-
- /* and finally attach to i2c layer */
- i2c_add_adapter(&dev->adapter);
-
- /* inform user about successful attachment to i2c layer */
- dev_info(&dev->adapter.dev, "connected i2c-tiny-usb device\n");
-
- return 0;
-
- error:
- if (dev)
- i2c_tiny_usb_free(dev);
-
- return retval;
-}
-
-static void i2c_tiny_usb_disconnect(struct usb_interface *interface)
-{
- struct i2c_tiny_usb *dev = usb_get_intfdata(interface);
-
- i2c_del_adapter(&dev->adapter);
- usb_set_intfdata(interface, NULL);
- i2c_tiny_usb_free(dev);
-
- dev_dbg(&interface->dev, "disconnected\n");
-}
-
-static struct usb_driver i2c_tiny_usb_driver = {
- .name = "i2c-tiny-usb",
- .probe = i2c_tiny_usb_probe,
- .disconnect = i2c_tiny_usb_disconnect,
- .id_table = i2c_tiny_usb_table,
-};
-
-module_usb_driver(i2c_tiny_usb_driver);
-
-/* ----- end of usb layer ------------------------------------------------ */
-
-MODULE_AUTHOR("Till Harbaum <Till@Harbaum.org>");
-MODULE_DESCRIPTION("i2c-tiny-usb driver v1.0");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-versatile.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-versatile.c
deleted file mode 100644
index f585aead..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-versatile.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * i2c-versatile.c
- *
- * Copyright (C) 2006 ARM Ltd.
- * written by Russell King, Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/of_i2c.h>
-
-#define I2C_CONTROL 0x00
-#define I2C_CONTROLS 0x00
-#define I2C_CONTROLC 0x04
-#define SCL (1 << 0)
-#define SDA (1 << 1)
-
-struct i2c_versatile {
- struct i2c_adapter adap;
- struct i2c_algo_bit_data algo;
- void __iomem *base;
-};
-
-static void i2c_versatile_setsda(void *data, int state)
-{
- struct i2c_versatile *i2c = data;
-
- writel(SDA, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC));
-}
-
-static void i2c_versatile_setscl(void *data, int state)
-{
- struct i2c_versatile *i2c = data;
-
- writel(SCL, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC));
-}
-
-static int i2c_versatile_getsda(void *data)
-{
- struct i2c_versatile *i2c = data;
- return !!(readl(i2c->base + I2C_CONTROL) & SDA);
-}
-
-static int i2c_versatile_getscl(void *data)
-{
- struct i2c_versatile *i2c = data;
- return !!(readl(i2c->base + I2C_CONTROL) & SCL);
-}
-
-static struct i2c_algo_bit_data i2c_versatile_algo = {
- .setsda = i2c_versatile_setsda,
- .setscl = i2c_versatile_setscl,
- .getsda = i2c_versatile_getsda,
- .getscl = i2c_versatile_getscl,
- .udelay = 30,
- .timeout = HZ,
-};
-
-static int i2c_versatile_probe(struct platform_device *dev)
-{
- struct i2c_versatile *i2c;
- struct resource *r;
- int ret;
-
- r = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!r) {
- ret = -EINVAL;
- goto err_out;
- }
-
- if (!request_mem_region(r->start, resource_size(r), "versatile-i2c")) {
- ret = -EBUSY;
- goto err_out;
- }
-
- i2c = kzalloc(sizeof(struct i2c_versatile), GFP_KERNEL);
- if (!i2c) {
- ret = -ENOMEM;
- goto err_release;
- }
-
- i2c->base = ioremap(r->start, resource_size(r));
- if (!i2c->base) {
- ret = -ENOMEM;
- goto err_free;
- }
-
- writel(SCL | SDA, i2c->base + I2C_CONTROLS);
-
- i2c->adap.owner = THIS_MODULE;
- strlcpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name));
- i2c->adap.algo_data = &i2c->algo;
- i2c->adap.dev.parent = &dev->dev;
- i2c->adap.dev.of_node = dev->dev.of_node;
- i2c->algo = i2c_versatile_algo;
- i2c->algo.data = i2c;
-
- if (dev->id >= 0) {
- /* static bus numbering */
- i2c->adap.nr = dev->id;
- ret = i2c_bit_add_numbered_bus(&i2c->adap);
- } else
- /* dynamic bus numbering */
- ret = i2c_bit_add_bus(&i2c->adap);
- if (ret >= 0) {
- platform_set_drvdata(dev, i2c);
- of_i2c_register_devices(&i2c->adap);
- return 0;
- }
-
- iounmap(i2c->base);
- err_free:
- kfree(i2c);
- err_release:
- release_mem_region(r->start, resource_size(r));
- err_out:
- return ret;
-}
-
-static int i2c_versatile_remove(struct platform_device *dev)
-{
- struct i2c_versatile *i2c = platform_get_drvdata(dev);
-
- platform_set_drvdata(dev, NULL);
-
- i2c_del_adapter(&i2c->adap);
- return 0;
-}
-
-static const struct of_device_id i2c_versatile_match[] = {
- { .compatible = "arm,versatile-i2c", },
- {},
-};
-MODULE_DEVICE_TABLE(of, i2c_versatile_match);
-
-static struct platform_driver i2c_versatile_driver = {
- .probe = i2c_versatile_probe,
- .remove = i2c_versatile_remove,
- .driver = {
- .name = "versatile-i2c",
- .owner = THIS_MODULE,
- .of_match_table = i2c_versatile_match,
- },
-};
-
-static int __init i2c_versatile_init(void)
-{
- return platform_driver_register(&i2c_versatile_driver);
-}
-
-static void __exit i2c_versatile_exit(void)
-{
- platform_driver_unregister(&i2c_versatile_driver);
-}
-
-subsys_initcall(i2c_versatile_init);
-module_exit(i2c_versatile_exit);
-
-MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:versatile-i2c");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-via.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-via.c
deleted file mode 100644
index 713d31ad..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-via.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- i2c Support for Via Technologies 82C586B South Bridge
-
- Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/io.h>
-
-/* Power management registers */
-#define PM_CFG_REVID 0x08 /* silicon revision code */
-#define PM_CFG_IOBASE0 0x20
-#define PM_CFG_IOBASE1 0x48
-
-#define I2C_DIR (pm_io_base+0x40)
-#define I2C_OUT (pm_io_base+0x42)
-#define I2C_IN (pm_io_base+0x44)
-#define I2C_SCL 0x02 /* clock bit in DIR/OUT/IN register */
-#define I2C_SDA 0x04
-
-/* io-region reservation */
-#define IOSPACE 0x06
-
-static struct pci_driver vt586b_driver;
-static u16 pm_io_base;
-
-/*
- It does not appear from the datasheet that the GPIO pins are
- open drain. So a we set a low value by setting the direction to
- output and a high value by setting the direction to input and
- relying on the required I2C pullup. The data value is initialized
- to 0 in via_init() and never changed.
-*/
-static void bit_via_setscl(void *data, int state)
-{
- outb(state ? inb(I2C_DIR) & ~I2C_SCL : inb(I2C_DIR) | I2C_SCL, I2C_DIR);
-}
-
-static void bit_via_setsda(void *data, int state)
-{
- outb(state ? inb(I2C_DIR) & ~I2C_SDA : inb(I2C_DIR) | I2C_SDA, I2C_DIR);
-}
-
-static int bit_via_getscl(void *data)
-{
- return (0 != (inb(I2C_IN) & I2C_SCL));
-}
-
-static int bit_via_getsda(void *data)
-{
- return (0 != (inb(I2C_IN) & I2C_SDA));
-}
-
-
-static struct i2c_algo_bit_data bit_data = {
- .setsda = bit_via_setsda,
- .setscl = bit_via_setscl,
- .getsda = bit_via_getsda,
- .getscl = bit_via_getscl,
- .udelay = 5,
- .timeout = HZ
-};
-
-static struct i2c_adapter vt586b_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .name = "VIA i2c",
- .algo_data = &bit_data,
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(vt586b_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, vt586b_ids);
-
-static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- u16 base;
- u8 rev;
- int res;
-
- if (pm_io_base) {
- dev_err(&dev->dev, "i2c-via: Will only support one host\n");
- return -ENODEV;
- }
-
- pci_read_config_byte(dev, PM_CFG_REVID, &rev);
-
- switch (rev) {
- case 0x00:
- base = PM_CFG_IOBASE0;
- break;
- case 0x01:
- case 0x10:
- base = PM_CFG_IOBASE1;
- break;
-
- default:
- base = PM_CFG_IOBASE1;
- /* later revision */
- }
-
- pci_read_config_word(dev, base, &pm_io_base);
- pm_io_base &= (0xff << 8);
-
- if (!request_region(I2C_DIR, IOSPACE, vt586b_driver.name)) {
- dev_err(&dev->dev, "IO 0x%x-0x%x already in use\n", I2C_DIR, I2C_DIR + IOSPACE);
- return -ENODEV;
- }
-
- outb(inb(I2C_DIR) & ~(I2C_SDA | I2C_SCL), I2C_DIR);
- outb(inb(I2C_OUT) & ~(I2C_SDA | I2C_SCL), I2C_OUT);
-
- /* set up the sysfs linkage to our parent device */
- vt586b_adapter.dev.parent = &dev->dev;
-
- res = i2c_bit_add_bus(&vt586b_adapter);
- if ( res < 0 ) {
- release_region(I2C_DIR, IOSPACE);
- pm_io_base = 0;
- return res;
- }
- return 0;
-}
-
-static void __devexit vt586b_remove(struct pci_dev *dev)
-{
- i2c_del_adapter(&vt586b_adapter);
- release_region(I2C_DIR, IOSPACE);
- pm_io_base = 0;
-}
-
-
-static struct pci_driver vt586b_driver = {
- .name = "vt586b_smbus",
- .id_table = vt586b_ids,
- .probe = vt586b_probe,
- .remove = __devexit_p(vt586b_remove),
-};
-
-static int __init i2c_vt586b_init(void)
-{
- return pci_register_driver(&vt586b_driver);
-}
-
-static void __exit i2c_vt586b_exit(void)
-{
- pci_unregister_driver(&vt586b_driver);
-}
-
-
-MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
-MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_vt586b_init);
-module_exit(i2c_vt586b_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-viapro.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-viapro.c
deleted file mode 100644
index 333011c8..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-viapro.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
- Mark D. Studebaker <mdsxyz123@yahoo.com>
- Copyright (C) 2005 - 2008 Jean Delvare <khali@linux-fr.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- Supports the following VIA south bridges:
-
- Chip name PCI ID REV I2C block
- VT82C596A 0x3050 no
- VT82C596B 0x3051 no
- VT82C686A 0x3057 0x30 no
- VT82C686B 0x3057 0x40 yes
- VT8231 0x8235 no?
- VT8233 0x3074 yes
- VT8233A 0x3147 yes?
- VT8235 0x3177 yes
- VT8237R 0x3227 yes
- VT8237A 0x3337 yes
- VT8237S 0x3372 yes
- VT8251 0x3287 yes
- CX700 0x8324 yes
- VX800/VX820 0x8353 yes
- VX855/VX875 0x8409 yes
-
- Note: we assume there can only be one device, with one SMBus interface.
-*/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-
-static struct pci_dev *vt596_pdev;
-
-#define SMBBA1 0x90
-#define SMBBA2 0x80
-#define SMBBA3 0xD0
-
-/* SMBus address offsets */
-static unsigned short vt596_smba;
-#define SMBHSTSTS (vt596_smba + 0)
-#define SMBHSTCNT (vt596_smba + 2)
-#define SMBHSTCMD (vt596_smba + 3)
-#define SMBHSTADD (vt596_smba + 4)
-#define SMBHSTDAT0 (vt596_smba + 5)
-#define SMBHSTDAT1 (vt596_smba + 6)
-#define SMBBLKDAT (vt596_smba + 7)
-
-/* PCI Address Constants */
-
-/* SMBus data in configuration space can be found in two places,
- We try to select the better one */
-
-static unsigned short SMBHSTCFG = 0xD2;
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-
-/* VT82C596 constants */
-#define VT596_QUICK 0x00
-#define VT596_BYTE 0x04
-#define VT596_BYTE_DATA 0x08
-#define VT596_WORD_DATA 0x0C
-#define VT596_PROC_CALL 0x10
-#define VT596_BLOCK_DATA 0x14
-#define VT596_I2C_BLOCK_DATA 0x34
-
-
-/* If force is set to anything different from 0, we forcibly enable the
- VT596. DANGEROUS! */
-static bool force;
-module_param(force, bool, 0);
-MODULE_PARM_DESC(force, "Forcibly enable the SMBus. DANGEROUS!");
-
-/* If force_addr is set to anything different from 0, we forcibly enable
- the VT596 at the given address. VERY DANGEROUS! */
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
- "Forcibly enable the SMBus at the given address. "
- "EXTREMELY DANGEROUS!");
-
-
-static struct pci_driver vt596_driver;
-static struct i2c_adapter vt596_adapter;
-
-#define FEATURE_I2CBLOCK (1<<0)
-static unsigned int vt596_features;
-
-#ifdef DEBUG
-static void vt596_dump_regs(const char *msg, u8 size)
-{
- dev_dbg(&vt596_adapter.dev, "%s: STS=%02x CNT=%02x CMD=%02x ADD=%02x "
- "DAT=%02x,%02x\n", msg, inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),
- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
- inb_p(SMBHSTDAT1));
-
- if (size == VT596_BLOCK_DATA
- || size == VT596_I2C_BLOCK_DATA) {
- int i;
-
- dev_dbg(&vt596_adapter.dev, "BLK=");
- for (i = 0; i < I2C_SMBUS_BLOCK_MAX / 2; i++)
- printk("%02x,", inb_p(SMBBLKDAT));
- printk("\n");
- dev_dbg(&vt596_adapter.dev, " ");
- for (; i < I2C_SMBUS_BLOCK_MAX - 1; i++)
- printk("%02x,", inb_p(SMBBLKDAT));
- printk("%02x\n", inb_p(SMBBLKDAT));
- }
-}
-#else
-static inline void vt596_dump_regs(const char *msg, u8 size) { }
-#endif
-
-/* Return -1 on error, 0 on success */
-static int vt596_transaction(u8 size)
-{
- int temp;
- int result = 0;
- int timeout = 0;
-
- vt596_dump_regs("Transaction (pre)", size);
-
- /* Make sure the SMBus host is ready to start transmitting */
- if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
- dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
- "Resetting...\n", temp);
-
- outb_p(temp, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
- dev_err(&vt596_adapter.dev, "SMBus reset failed! "
- "(0x%02x)\n", temp);
- return -EBUSY;
- }
- }
-
- /* Start the transaction by setting bit 6 */
- outb_p(0x40 | size, SMBHSTCNT);
-
- /* We will always wait for a fraction of a second */
- do {
- msleep(1);
- temp = inb_p(SMBHSTSTS);
- } while ((temp & 0x01) && (++timeout < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout == MAX_TIMEOUT) {
- result = -ETIMEDOUT;
- dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
- }
-
- if (temp & 0x10) {
- result = -EIO;
- dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
- size);
- }
-
- if (temp & 0x08) {
- result = -EIO;
- dev_err(&vt596_adapter.dev, "SMBus collision!\n");
- }
-
- if (temp & 0x04) {
- result = -ENXIO;
- dev_dbg(&vt596_adapter.dev, "No response\n");
- }
-
- /* Resetting status register */
- if (temp & 0x1F)
- outb_p(temp, SMBHSTSTS);
-
- vt596_dump_regs("Transaction (post)", size);
-
- return result;
-}
-
-/* Return negative errno on error, 0 on success */
-static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- int i;
- int status;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- size = VT596_QUICK;
- break;
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(command, SMBHSTCMD);
- size = VT596_BYTE;
- break;
- case I2C_SMBUS_BYTE_DATA:
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMBHSTDAT0);
- size = VT596_BYTE_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMBHSTDAT0);
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
- }
- size = VT596_WORD_DATA;
- break;
- case I2C_SMBUS_PROC_CALL:
- outb_p(command, SMBHSTCMD);
- outb_p(data->word & 0xff, SMBHSTDAT0);
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
- size = VT596_PROC_CALL;
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- if (!(vt596_features & FEATURE_I2CBLOCK))
- goto exit_unsupported;
- if (read_write == I2C_SMBUS_READ)
- outb_p(data->block[0], SMBHSTDAT0);
- /* Fall through */
- case I2C_SMBUS_BLOCK_DATA:
- outb_p(command, SMBHSTCMD);
- if (read_write == I2C_SMBUS_WRITE) {
- u8 len = data->block[0];
- if (len > I2C_SMBUS_BLOCK_MAX)
- len = I2C_SMBUS_BLOCK_MAX;
- outb_p(len, SMBHSTDAT0);
- inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
- for (i = 1; i <= len; i++)
- outb_p(data->block[i], SMBBLKDAT);
- }
- size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ?
- VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA;
- break;
- default:
- goto exit_unsupported;
- }
-
- outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
-
- status = vt596_transaction(size);
- if (status)
- return status;
-
- if (size == VT596_PROC_CALL)
- read_write = I2C_SMBUS_READ;
-
- if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
- return 0;
-
- switch (size) {
- case VT596_BYTE:
- case VT596_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case VT596_WORD_DATA:
- case VT596_PROC_CALL:
- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
- break;
- case VT596_I2C_BLOCK_DATA:
- case VT596_BLOCK_DATA:
- data->block[0] = inb_p(SMBHSTDAT0);
- if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
- data->block[0] = I2C_SMBUS_BLOCK_MAX;
- inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
- for (i = 1; i <= data->block[0]; i++)
- data->block[i] = inb_p(SMBBLKDAT);
- break;
- }
- return 0;
-
-exit_unsupported:
- dev_warn(&vt596_adapter.dev, "Unsupported transaction %d\n",
- size);
- return -EOPNOTSUPP;
-}
-
-static u32 vt596_func(struct i2c_adapter *adapter)
-{
- u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA;
-
- if (vt596_features & FEATURE_I2CBLOCK)
- func |= I2C_FUNC_SMBUS_I2C_BLOCK;
- return func;
-}
-
-static const struct i2c_algorithm smbus_algorithm = {
- .smbus_xfer = vt596_access,
- .functionality = vt596_func,
-};
-
-static struct i2c_adapter vt596_adapter = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &smbus_algorithm,
-};
-
-static int __devinit vt596_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- unsigned char temp;
- int error;
-
- /* Determine the address of the SMBus areas */
- if (force_addr) {
- vt596_smba = force_addr & 0xfff0;
- force = 0;
- goto found;
- }
-
- if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) ||
- !(vt596_smba & 0x0001)) {
- /* try 2nd address and config reg. for 596 */
- if (id->device == PCI_DEVICE_ID_VIA_82C596_3 &&
- !pci_read_config_word(pdev, SMBBA2, &vt596_smba) &&
- (vt596_smba & 0x0001)) {
- SMBHSTCFG = 0x84;
- } else {
- /* no matches at all */
- dev_err(&pdev->dev, "Cannot configure "
- "SMBus I/O Base address\n");
- return -ENODEV;
- }
- }
-
- vt596_smba &= 0xfff0;
- if (vt596_smba == 0) {
- dev_err(&pdev->dev, "SMBus base address "
- "uninitialized - upgrade BIOS or use "
- "force_addr=0xaddr\n");
- return -ENODEV;
- }
-
-found:
- error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
- if (error)
- return -ENODEV;
-
- if (!request_region(vt596_smba, 8, vt596_driver.name)) {
- dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
- vt596_smba);
- return -ENODEV;
- }
-
- pci_read_config_byte(pdev, SMBHSTCFG, &temp);
- /* If force_addr is set, we program the new address here. Just to make
- sure, we disable the VT596 first. */
- if (force_addr) {
- pci_write_config_byte(pdev, SMBHSTCFG, temp & 0xfe);
- pci_write_config_word(pdev, id->driver_data, vt596_smba);
- pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
- dev_warn(&pdev->dev, "WARNING: SMBus interface set to new "
- "address 0x%04x!\n", vt596_smba);
- } else if (!(temp & 0x01)) {
- if (force) {
- /* NOTE: This assumes I/O space and other allocations
- * WERE done by the Bios! Don't complain if your
- * hardware does weird things after enabling this.
- * :') Check for Bios updates before resorting to
- * this.
- */
- pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
- dev_info(&pdev->dev, "Enabling SMBus device\n");
- } else {
- dev_err(&pdev->dev, "SMBUS: Error: Host SMBus "
- "controller not enabled! - upgrade BIOS or "
- "use force=1\n");
- error = -ENODEV;
- goto release_region;
- }
- }
-
- dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
-
- switch (pdev->device) {
- case PCI_DEVICE_ID_VIA_CX700:
- case PCI_DEVICE_ID_VIA_VX800:
- case PCI_DEVICE_ID_VIA_VX855:
- case PCI_DEVICE_ID_VIA_8251:
- case PCI_DEVICE_ID_VIA_8237:
- case PCI_DEVICE_ID_VIA_8237A:
- case PCI_DEVICE_ID_VIA_8237S:
- case PCI_DEVICE_ID_VIA_8235:
- case PCI_DEVICE_ID_VIA_8233A:
- case PCI_DEVICE_ID_VIA_8233_0:
- vt596_features |= FEATURE_I2CBLOCK;
- break;
- case PCI_DEVICE_ID_VIA_82C686_4:
- /* The VT82C686B (rev 0x40) does support I2C block
- transactions, but the VT82C686A (rev 0x30) doesn't */
- if (pdev->revision >= 0x40)
- vt596_features |= FEATURE_I2CBLOCK;
- break;
- }
-
- vt596_adapter.dev.parent = &pdev->dev;
- snprintf(vt596_adapter.name, sizeof(vt596_adapter.name),
- "SMBus Via Pro adapter at %04x", vt596_smba);
-
- vt596_pdev = pci_dev_get(pdev);
- error = i2c_add_adapter(&vt596_adapter);
- if (error) {
- pci_dev_put(vt596_pdev);
- vt596_pdev = NULL;
- goto release_region;
- }
-
- /* Always return failure here. This is to allow other drivers to bind
- * to this pci device. We don't really want to have control over the
- * pci device, we only wanted to read as few register values from it.
- */
- return -ENODEV;
-
-release_region:
- release_region(vt596_smba, 8);
- return error;
-}
-
-static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),
- .driver_data = SMBBA1 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3),
- .driver_data = SMBBA1 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4),
- .driver_data = SMBBA1 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237S),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4),
- .driver_data = SMBBA1 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8251),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800),
- .driver_data = SMBBA3 },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855),
- .driver_data = SMBBA3 },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, vt596_ids);
-
-static struct pci_driver vt596_driver = {
- .name = "vt596_smbus",
- .id_table = vt596_ids,
- .probe = vt596_probe,
-};
-
-static int __init i2c_vt596_init(void)
-{
- return pci_register_driver(&vt596_driver);
-}
-
-
-static void __exit i2c_vt596_exit(void)
-{
- pci_unregister_driver(&vt596_driver);
- if (vt596_pdev != NULL) {
- i2c_del_adapter(&vt596_adapter);
- release_region(vt596_smba, 8);
- pci_dev_put(vt596_pdev);
- vt596_pdev = NULL;
- }
-}
-
-MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
- "Mark D. Studebaker <mdsxyz123@yahoo.com> and "
- "Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("vt82c596 SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_vt596_init);
-module_exit(i2c_vt596_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-xiic.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-xiic.c
deleted file mode 100644
index 2bded764..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-xiic.c
+++ /dev/null
@@ -1,812 +0,0 @@
-/*
- * i2c-xiic.c
- * Copyright (c) 2002-2007 Xilinx Inc.
- * Copyright (c) 2009-2010 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * This code was implemented by Mocean Laboratories AB when porting linux
- * to the automotive development board Russellville. The copyright holder
- * as seen in the header is Intel corporation.
- * Mocean Laboratories forked off the GNU/Linux platform work into a
- * separate company called Pelagicore AB, which committed the code to the
- * kernel.
- */
-
-/* Supports:
- * Xilinx IIC
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/i2c-xiic.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#define DRIVER_NAME "xiic-i2c"
-
-enum xilinx_i2c_state {
- STATE_DONE,
- STATE_ERROR,
- STATE_START
-};
-
-/**
- * struct xiic_i2c - Internal representation of the XIIC I2C bus
- * @base: Memory base of the HW registers
- * @wait: Wait queue for callers
- * @adap: Kernel adapter representation
- * @tx_msg: Messages from above to be sent
- * @lock: Mutual exclusion
- * @tx_pos: Current pos in TX message
- * @nmsgs: Number of messages in tx_msg
- * @state: See STATE_
- * @rx_msg: Current RX message
- * @rx_pos: Position within current RX message
- */
-struct xiic_i2c {
- void __iomem *base;
- wait_queue_head_t wait;
- struct i2c_adapter adap;
- struct i2c_msg *tx_msg;
- spinlock_t lock;
- unsigned int tx_pos;
- unsigned int nmsgs;
- enum xilinx_i2c_state state;
- struct i2c_msg *rx_msg;
- int rx_pos;
-};
-
-
-#define XIIC_MSB_OFFSET 0
-#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET)
-
-/*
- * Register offsets in bytes from RegisterBase. Three is added to the
- * base offset to access LSB (IBM style) of the word
- */
-#define XIIC_CR_REG_OFFSET (0x00+XIIC_REG_OFFSET) /* Control Register */
-#define XIIC_SR_REG_OFFSET (0x04+XIIC_REG_OFFSET) /* Status Register */
-#define XIIC_DTR_REG_OFFSET (0x08+XIIC_REG_OFFSET) /* Data Tx Register */
-#define XIIC_DRR_REG_OFFSET (0x0C+XIIC_REG_OFFSET) /* Data Rx Register */
-#define XIIC_ADR_REG_OFFSET (0x10+XIIC_REG_OFFSET) /* Address Register */
-#define XIIC_TFO_REG_OFFSET (0x14+XIIC_REG_OFFSET) /* Tx FIFO Occupancy */
-#define XIIC_RFO_REG_OFFSET (0x18+XIIC_REG_OFFSET) /* Rx FIFO Occupancy */
-#define XIIC_TBA_REG_OFFSET (0x1C+XIIC_REG_OFFSET) /* 10 Bit Address reg */
-#define XIIC_RFD_REG_OFFSET (0x20+XIIC_REG_OFFSET) /* Rx FIFO Depth reg */
-#define XIIC_GPO_REG_OFFSET (0x24+XIIC_REG_OFFSET) /* Output Register */
-
-/* Control Register masks */
-#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */
-#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */
-#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */
-#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */
-#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */
-#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */
-#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */
-
-/* Status Register masks */
-#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */
-#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */
-#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */
-#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */
-#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */
-#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */
-#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */
-#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x80 /* 1 = Tx FIFO empty */
-
-/* Interrupt Status Register masks Interrupt occurs when... */
-#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */
-#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete */
-#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */
-#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level */
-#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */
-#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */
-#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */
-#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */
-
-/* The following constants specify the depth of the FIFOs */
-#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */
-#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */
-
-/* The following constants specify groups of interrupts that are typically
- * enabled or disables at the same time
- */
-#define XIIC_TX_INTERRUPTS \
-(XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)
-
-#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
-
-/* The following constants are used with the following macros to specify the
- * operation, a read or write operation.
- */
-#define XIIC_READ_OPERATION 1
-#define XIIC_WRITE_OPERATION 0
-
-/*
- * Tx Fifo upper bit masks.
- */
-#define XIIC_TX_DYN_START_MASK 0x0100 /* 1 = Set dynamic start */
-#define XIIC_TX_DYN_STOP_MASK 0x0200 /* 1 = Set dynamic stop */
-
-/*
- * The following constants define the register offsets for the Interrupt
- * registers. There are some holes in the memory map for reserved addresses
- * to allow other registers to be added and still match the memory map of the
- * interrupt controller registers
- */
-#define XIIC_DGIER_OFFSET 0x1C /* Device Global Interrupt Enable Register */
-#define XIIC_IISR_OFFSET 0x20 /* Interrupt Status Register */
-#define XIIC_IIER_OFFSET 0x28 /* Interrupt Enable Register */
-#define XIIC_RESETR_OFFSET 0x40 /* Reset Register */
-
-#define XIIC_RESET_MASK 0xAUL
-
-/*
- * The following constant is used for the device global interrupt enable
- * register, to enable all interrupts for the device, this is the only bit
- * in the register
- */
-#define XIIC_GINTR_ENABLE_MASK 0x80000000UL
-
-#define xiic_tx_space(i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)
-#define xiic_rx_space(i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos)
-
-static void xiic_start_xfer(struct xiic_i2c *i2c);
-static void __xiic_start_xfer(struct xiic_i2c *i2c);
-
-static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value)
-{
- iowrite8(value, i2c->base + reg);
-}
-
-static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg)
-{
- return ioread8(i2c->base + reg);
-}
-
-static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value)
-{
- iowrite16(value, i2c->base + reg);
-}
-
-static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value)
-{
- iowrite32(value, i2c->base + reg);
-}
-
-static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg)
-{
- return ioread32(i2c->base + reg);
-}
-
-static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask)
-{
- u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
- xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier & ~mask);
-}
-
-static inline void xiic_irq_en(struct xiic_i2c *i2c, u32 mask)
-{
- u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
- xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier | mask);
-}
-
-static inline void xiic_irq_clr(struct xiic_i2c *i2c, u32 mask)
-{
- u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
- xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask);
-}
-
-static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask)
-{
- xiic_irq_clr(i2c, mask);
- xiic_irq_en(i2c, mask);
-}
-
-static void xiic_clear_rx_fifo(struct xiic_i2c *i2c)
-{
- u8 sr;
- for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
- !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
- sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET))
- xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
-}
-
-static void xiic_reinit(struct xiic_i2c *i2c)
-{
- xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
-
- /* Set receive Fifo depth to maximum (zero based). */
- xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1);
-
- /* Reset Tx Fifo. */
- xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
-
- /* Enable IIC Device, remove Tx Fifo reset & disable general call. */
- xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
-
- /* make sure RX fifo is empty */
- xiic_clear_rx_fifo(i2c);
-
- /* Enable interrupts */
- xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
-
- xiic_irq_clr_en(i2c, XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
-}
-
-static void xiic_deinit(struct xiic_i2c *i2c)
-{
- u8 cr;
-
- xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
-
- /* Disable IIC Device. */
- cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET);
- xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK);
-}
-
-static void xiic_read_rx(struct xiic_i2c *i2c)
-{
- u8 bytes_in_fifo;
- int i;
-
- bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
-
- dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
- ", SR: 0x%x, CR: 0x%x\n",
- __func__, bytes_in_fifo, xiic_rx_space(i2c),
- xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
- xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
-
- if (bytes_in_fifo > xiic_rx_space(i2c))
- bytes_in_fifo = xiic_rx_space(i2c);
-
- for (i = 0; i < bytes_in_fifo; i++)
- i2c->rx_msg->buf[i2c->rx_pos++] =
- xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
-
- xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET,
- (xiic_rx_space(i2c) > IIC_RX_FIFO_DEPTH) ?
- IIC_RX_FIFO_DEPTH - 1 : xiic_rx_space(i2c) - 1);
-}
-
-static int xiic_tx_fifo_space(struct xiic_i2c *i2c)
-{
- /* return the actual space left in the FIFO */
- return IIC_TX_FIFO_DEPTH - xiic_getreg8(i2c, XIIC_TFO_REG_OFFSET) - 1;
-}
-
-static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
-{
- u8 fifo_space = xiic_tx_fifo_space(i2c);
- int len = xiic_tx_space(i2c);
-
- len = (len > fifo_space) ? fifo_space : len;
-
- dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
- __func__, len, fifo_space);
-
- while (len--) {
- u16 data = i2c->tx_msg->buf[i2c->tx_pos++];
- if ((xiic_tx_space(i2c) == 0) && (i2c->nmsgs == 1)) {
- /* last message in transfer -> STOP */
- data |= XIIC_TX_DYN_STOP_MASK;
- dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
-
- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
- } else
- xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
- }
-}
-
-static void xiic_wakeup(struct xiic_i2c *i2c, int code)
-{
- i2c->tx_msg = NULL;
- i2c->rx_msg = NULL;
- i2c->nmsgs = 0;
- i2c->state = code;
- wake_up(&i2c->wait);
-}
-
-static void xiic_process(struct xiic_i2c *i2c)
-{
- u32 pend, isr, ier;
- u32 clr = 0;
-
- /* Get the interrupt Status from the IPIF. There is no clearing of
- * interrupts in the IPIF. Interrupts must be cleared at the source.
- * To find which interrupts are pending; AND interrupts pending with
- * interrupts masked.
- */
- isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
- ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
- pend = isr & ier;
-
- dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
- "pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
- __func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
- i2c->tx_msg, i2c->nmsgs);
-
- /* Do not processes a devices interrupts if the device has no
- * interrupts pending
- */
- if (!pend)
- return;
-
- /* Service requesting interrupt */
- if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
- ((pend & XIIC_INTR_TX_ERROR_MASK) &&
- !(pend & XIIC_INTR_RX_FULL_MASK))) {
- /* bus arbritration lost, or...
- * Transmit error _OR_ RX completed
- * if this happens when RX_FULL is not set
- * this is probably a TX error
- */
-
- dev_dbg(i2c->adap.dev.parent, "%s error\n", __func__);
-
- /* dynamic mode seem to suffer from problems if we just flushes
- * fifos and the next message is a TX with len 0 (only addr)
- * reset the IP instead of just flush fifos
- */
- xiic_reinit(i2c);
-
- if (i2c->tx_msg)
- xiic_wakeup(i2c, STATE_ERROR);
-
- } else if (pend & XIIC_INTR_RX_FULL_MASK) {
- /* Receive register/FIFO is full */
-
- clr = XIIC_INTR_RX_FULL_MASK;
- if (!i2c->rx_msg) {
- dev_dbg(i2c->adap.dev.parent,
- "%s unexpexted RX IRQ\n", __func__);
- xiic_clear_rx_fifo(i2c);
- goto out;
- }
-
- xiic_read_rx(i2c);
- if (xiic_rx_space(i2c) == 0) {
- /* this is the last part of the message */
- i2c->rx_msg = NULL;
-
- /* also clear TX error if there (RX complete) */
- clr |= (isr & XIIC_INTR_TX_ERROR_MASK);
-
- dev_dbg(i2c->adap.dev.parent,
- "%s end of message, nmsgs: %d\n",
- __func__, i2c->nmsgs);
-
- /* send next message if this wasn't the last,
- * otherwise the transfer will be finialise when
- * receiving the bus not busy interrupt
- */
- if (i2c->nmsgs > 1) {
- i2c->nmsgs--;
- i2c->tx_msg++;
- dev_dbg(i2c->adap.dev.parent,
- "%s will start next...\n", __func__);
-
- __xiic_start_xfer(i2c);
- }
- }
- } else if (pend & XIIC_INTR_BNB_MASK) {
- /* IIC bus has transitioned to not busy */
- clr = XIIC_INTR_BNB_MASK;
-
- /* The bus is not busy, disable BusNotBusy interrupt */
- xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
-
- if (!i2c->tx_msg)
- goto out;
-
- if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
- xiic_tx_space(i2c) == 0)
- xiic_wakeup(i2c, STATE_DONE);
- else
- xiic_wakeup(i2c, STATE_ERROR);
-
- } else if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
- /* Transmit register/FIFO is empty or ½ empty */
-
- clr = pend &
- (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK);
-
- if (!i2c->tx_msg) {
- dev_dbg(i2c->adap.dev.parent,
- "%s unexpexted TX IRQ\n", __func__);
- goto out;
- }
-
- xiic_fill_tx_fifo(i2c);
-
- /* current message sent and there is space in the fifo */
- if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
- dev_dbg(i2c->adap.dev.parent,
- "%s end of message sent, nmsgs: %d\n",
- __func__, i2c->nmsgs);
- if (i2c->nmsgs > 1) {
- i2c->nmsgs--;
- i2c->tx_msg++;
- __xiic_start_xfer(i2c);
- } else {
- xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
-
- dev_dbg(i2c->adap.dev.parent,
- "%s Got TX IRQ but no more to do...\n",
- __func__);
- }
- } else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
- /* current frame is sent and is last,
- * make sure to disable tx half
- */
- xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
- } else {
- /* got IRQ which is not acked */
- dev_err(i2c->adap.dev.parent, "%s Got unexpected IRQ\n",
- __func__);
- clr = pend;
- }
-out:
- dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
-
- xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
-}
-
-static int xiic_bus_busy(struct xiic_i2c *i2c)
-{
- u8 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
-
- return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0;
-}
-
-static int xiic_busy(struct xiic_i2c *i2c)
-{
- int tries = 3;
- int err;
-
- if (i2c->tx_msg)
- return -EBUSY;
-
- /* for instance if previous transfer was terminated due to TX error
- * it might be that the bus is on it's way to become available
- * give it at most 3 ms to wake
- */
- err = xiic_bus_busy(i2c);
- while (err && tries--) {
- mdelay(1);
- err = xiic_bus_busy(i2c);
- }
-
- return err;
-}
-
-static void xiic_start_recv(struct xiic_i2c *i2c)
-{
- u8 rx_watermark;
- struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
-
- /* Clear and enable Rx full interrupt. */
- xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
-
- /* we want to get all but last byte, because the TX_ERROR IRQ is used
- * to inidicate error ACK on the address, and negative ack on the last
- * received byte, so to not mix them receive all but last.
- * In the case where there is only one byte to receive
- * we can check if ERROR and RX full is set at the same time
- */
- rx_watermark = msg->len;
- if (rx_watermark > IIC_RX_FIFO_DEPTH)
- rx_watermark = IIC_RX_FIFO_DEPTH;
- xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
-
- if (!(msg->flags & I2C_M_NOSTART))
- /* write the address */
- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
- (msg->addr << 1) | XIIC_READ_OPERATION |
- XIIC_TX_DYN_START_MASK);
-
- xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
-
- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
- msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
- if (i2c->nmsgs == 1)
- /* very last, enable bus not busy as well */
- xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
-
- /* the message is tx:ed */
- i2c->tx_pos = msg->len;
-}
-
-static void xiic_start_send(struct xiic_i2c *i2c)
-{
- struct i2c_msg *msg = i2c->tx_msg;
-
- xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK);
-
- dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
- "ISR: 0x%x, CR: 0x%x\n",
- __func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
- xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
-
- if (!(msg->flags & I2C_M_NOSTART)) {
- /* write the address */
- u16 data = ((msg->addr << 1) & 0xfe) | XIIC_WRITE_OPERATION |
- XIIC_TX_DYN_START_MASK;
- if ((i2c->nmsgs == 1) && msg->len == 0)
- /* no data and last message -> add STOP */
- data |= XIIC_TX_DYN_STOP_MASK;
-
- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
- }
-
- xiic_fill_tx_fifo(i2c);
-
- /* Clear any pending Tx empty, Tx Error and then enable them. */
- xiic_irq_clr_en(i2c, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK |
- XIIC_INTR_BNB_MASK);
-}
-
-static irqreturn_t xiic_isr(int irq, void *dev_id)
-{
- struct xiic_i2c *i2c = dev_id;
-
- spin_lock(&i2c->lock);
- /* disable interrupts globally */
- xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
-
- dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__);
-
- xiic_process(i2c);
-
- xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
- spin_unlock(&i2c->lock);
-
- return IRQ_HANDLED;
-}
-
-static void __xiic_start_xfer(struct xiic_i2c *i2c)
-{
- int first = 1;
- int fifo_space = xiic_tx_fifo_space(i2c);
- dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
- __func__, i2c->tx_msg, fifo_space);
-
- if (!i2c->tx_msg)
- return;
-
- i2c->rx_pos = 0;
- i2c->tx_pos = 0;
- i2c->state = STATE_START;
- while ((fifo_space >= 2) && (first || (i2c->nmsgs > 1))) {
- if (!first) {
- i2c->nmsgs--;
- i2c->tx_msg++;
- i2c->tx_pos = 0;
- } else
- first = 0;
-
- if (i2c->tx_msg->flags & I2C_M_RD) {
- /* we dont date putting several reads in the FIFO */
- xiic_start_recv(i2c);
- return;
- } else {
- xiic_start_send(i2c);
- if (xiic_tx_space(i2c) != 0) {
- /* the message could not be completely sent */
- break;
- }
- }
-
- fifo_space = xiic_tx_fifo_space(i2c);
- }
-
- /* there are more messages or the current one could not be completely
- * put into the FIFO, also enable the half empty interrupt
- */
- if (i2c->nmsgs > 1 || xiic_tx_space(i2c))
- xiic_irq_clr_en(i2c, XIIC_INTR_TX_HALF_MASK);
-
-}
-
-static void xiic_start_xfer(struct xiic_i2c *i2c)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i2c->lock, flags);
- xiic_reinit(i2c);
- /* disable interrupts globally */
- xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
- spin_unlock_irqrestore(&i2c->lock, flags);
-
- __xiic_start_xfer(i2c);
- xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
-}
-
-static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct xiic_i2c *i2c = i2c_get_adapdata(adap);
- int err;
-
- dev_dbg(adap->dev.parent, "%s entry SR: 0x%x\n", __func__,
- xiic_getreg8(i2c, XIIC_SR_REG_OFFSET));
-
- err = xiic_busy(i2c);
- if (err)
- return err;
-
- i2c->tx_msg = msgs;
- i2c->nmsgs = num;
-
- xiic_start_xfer(i2c);
-
- if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
- (i2c->state == STATE_DONE), HZ))
- return (i2c->state == STATE_DONE) ? num : -EIO;
- else {
- i2c->tx_msg = NULL;
- i2c->rx_msg = NULL;
- i2c->nmsgs = 0;
- return -ETIMEDOUT;
- }
-}
-
-static u32 xiic_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm xiic_algorithm = {
- .master_xfer = xiic_xfer,
- .functionality = xiic_func,
-};
-
-static struct i2c_adapter xiic_adapter = {
- .owner = THIS_MODULE,
- .name = DRIVER_NAME,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo = &xiic_algorithm,
-};
-
-
-static int __devinit xiic_i2c_probe(struct platform_device *pdev)
-{
- struct xiic_i2c *i2c;
- struct xiic_i2c_platform_data *pdata;
- struct resource *res;
- int ret, irq;
- u8 i;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- goto resource_missing;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- goto resource_missing;
-
- pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
- if (!pdata)
- return -EINVAL;
-
- i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
- if (!i2c)
- return -ENOMEM;
-
- if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
- dev_err(&pdev->dev, "Memory region busy\n");
- ret = -EBUSY;
- goto request_mem_failed;
- }
-
- i2c->base = ioremap(res->start, resource_size(res));
- if (!i2c->base) {
- dev_err(&pdev->dev, "Unable to map registers\n");
- ret = -EIO;
- goto map_failed;
- }
-
- /* hook up driver to tree */
- platform_set_drvdata(pdev, i2c);
- i2c->adap = xiic_adapter;
- i2c_set_adapdata(&i2c->adap, i2c);
- i2c->adap.dev.parent = &pdev->dev;
-
- xiic_reinit(i2c);
-
- spin_lock_init(&i2c->lock);
- init_waitqueue_head(&i2c->wait);
- ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
- if (ret) {
- dev_err(&pdev->dev, "Cannot claim IRQ\n");
- goto request_irq_failed;
- }
-
- /* add i2c adapter to i2c tree */
- ret = i2c_add_adapter(&i2c->adap);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add adapter\n");
- goto add_adapter_failed;
- }
-
- /* add in known devices to the bus */
- for (i = 0; i < pdata->num_devices; i++)
- i2c_new_device(&i2c->adap, pdata->devices + i);
-
- return 0;
-
-add_adapter_failed:
- free_irq(irq, i2c);
-request_irq_failed:
- xiic_deinit(i2c);
- iounmap(i2c->base);
-map_failed:
- release_mem_region(res->start, resource_size(res));
-request_mem_failed:
- kfree(i2c);
-
- return ret;
-resource_missing:
- dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
- return -ENOENT;
-}
-
-static int __devexit xiic_i2c_remove(struct platform_device* pdev)
-{
- struct xiic_i2c *i2c = platform_get_drvdata(pdev);
- struct resource *res;
-
- /* remove adapter & data */
- i2c_del_adapter(&i2c->adap);
-
- xiic_deinit(i2c);
-
- platform_set_drvdata(pdev, NULL);
-
- free_irq(platform_get_irq(pdev, 0), i2c);
-
- iounmap(i2c->base);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
-
- kfree(i2c);
-
- return 0;
-}
-
-static struct platform_driver xiic_i2c_driver = {
- .probe = xiic_i2c_probe,
- .remove = __devexit_p(xiic_i2c_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = DRIVER_NAME,
- },
-};
-
-module_platform_driver(xiic_i2c_driver);
-
-MODULE_AUTHOR("info@mocean-labs.com");
-MODULE_DESCRIPTION("Xilinx I2C bus driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/i2c-xlr.c b/ANDROID_3.4.5/drivers/i2c/busses/i2c-xlr.c
deleted file mode 100644
index 96d3fabd..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/i2c-xlr.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2011, Netlogic Microsystems Inc.
- * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-
-/* XLR I2C REGISTERS */
-#define XLR_I2C_CFG 0x00
-#define XLR_I2C_CLKDIV 0x01
-#define XLR_I2C_DEVADDR 0x02
-#define XLR_I2C_ADDR 0x03
-#define XLR_I2C_DATAOUT 0x04
-#define XLR_I2C_DATAIN 0x05
-#define XLR_I2C_STATUS 0x06
-#define XLR_I2C_STARTXFR 0x07
-#define XLR_I2C_BYTECNT 0x08
-#define XLR_I2C_HDSTATIM 0x09
-
-/* XLR I2C REGISTERS FLAGS */
-#define XLR_I2C_BUS_BUSY 0x01
-#define XLR_I2C_SDOEMPTY 0x02
-#define XLR_I2C_RXRDY 0x04
-#define XLR_I2C_ACK_ERR 0x08
-#define XLR_I2C_ARB_STARTERR 0x30
-
-/* Register Values */
-#define XLR_I2C_CFG_ADDR 0xF8
-#define XLR_I2C_CFG_NOADDR 0xFA
-#define XLR_I2C_STARTXFR_ND 0x02 /* No Data */
-#define XLR_I2C_STARTXFR_RD 0x01 /* Read */
-#define XLR_I2C_STARTXFR_WR 0x00 /* Write */
-
-#define XLR_I2C_TIMEOUT 10 /* timeout per byte in msec */
-
-/*
- * On XLR/XLS, we need to use __raw_ IO to read the I2C registers
- * because they are in the big-endian MMIO area on the SoC.
- *
- * The readl/writel implementation on XLR/XLS byteswaps, because
- * those are for its little-endian PCI space (see arch/mips/Kconfig).
- */
-static inline void xlr_i2c_wreg(u32 __iomem *base, unsigned int reg, u32 val)
-{
- __raw_writel(val, base + reg);
-}
-
-static inline u32 xlr_i2c_rdreg(u32 __iomem *base, unsigned int reg)
-{
- return __raw_readl(base + reg);
-}
-
-struct xlr_i2c_private {
- struct i2c_adapter adap;
- u32 __iomem *iobase;
-};
-
-static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len,
- u8 *buf, u16 addr)
-{
- struct i2c_adapter *adap = &priv->adap;
- unsigned long timeout, stoptime, checktime;
- u32 i2c_status;
- int pos, timedout;
- u8 offset, byte;
-
- offset = buf[0];
- xlr_i2c_wreg(priv->iobase, XLR_I2C_ADDR, offset);
- xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr);
- xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, XLR_I2C_CFG_ADDR);
- xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1);
-
- timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT);
- stoptime = jiffies + timeout;
- timedout = 0;
- pos = 1;
-retry:
- if (len == 1) {
- xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR,
- XLR_I2C_STARTXFR_ND);
- } else {
- xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[pos]);
- xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR,
- XLR_I2C_STARTXFR_WR);
- }
-
- while (!timedout) {
- checktime = jiffies;
- i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS);
-
- if (i2c_status & XLR_I2C_SDOEMPTY) {
- pos++;
- /* need to do a empty dataout after the last byte */
- byte = (pos < len) ? buf[pos] : 0;
- xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, byte);
-
- /* reset timeout on successful xmit */
- stoptime = jiffies + timeout;
- }
- timedout = time_after(checktime, stoptime);
-
- if (i2c_status & XLR_I2C_ARB_STARTERR) {
- if (timedout)
- break;
- goto retry;
- }
-
- if (i2c_status & XLR_I2C_ACK_ERR)
- return -EIO;
-
- if ((i2c_status & XLR_I2C_BUS_BUSY) == 0 && pos >= len)
- return 0;
- }
- dev_err(&adap->dev, "I2C transmit timeout\n");
- return -ETIMEDOUT;
-}
-
-static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr)
-{
- struct i2c_adapter *adap = &priv->adap;
- u32 i2c_status;
- unsigned long timeout, stoptime, checktime;
- int nbytes, timedout;
- u8 byte;
-
- xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, XLR_I2C_CFG_NOADDR);
- xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len);
- xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr);
-
- timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT);
- stoptime = jiffies + timeout;
- timedout = 0;
- nbytes = 0;
-retry:
- xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, XLR_I2C_STARTXFR_RD);
-
- while (!timedout) {
- checktime = jiffies;
- i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS);
- if (i2c_status & XLR_I2C_RXRDY) {
- if (nbytes > len)
- return -EIO; /* should not happen */
-
- /* we need to do a dummy datain when nbytes == len */
- byte = xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN);
- if (nbytes < len)
- buf[nbytes] = byte;
- nbytes++;
-
- /* reset timeout on successful read */
- stoptime = jiffies + timeout;
- }
-
- timedout = time_after(checktime, stoptime);
- if (i2c_status & XLR_I2C_ARB_STARTERR) {
- if (timedout)
- break;
- goto retry;
- }
-
- if (i2c_status & XLR_I2C_ACK_ERR)
- return -EIO;
-
- if ((i2c_status & XLR_I2C_BUS_BUSY) == 0)
- return 0;
- }
-
- dev_err(&adap->dev, "I2C receive timeout\n");
- return -ETIMEDOUT;
-}
-
-static int xlr_i2c_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
-{
- struct i2c_msg *msg;
- int i;
- int ret = 0;
- struct xlr_i2c_private *priv = i2c_get_adapdata(adap);
-
- for (i = 0; ret == 0 && i < num; i++) {
- msg = &msgs[i];
- if (msg->flags & I2C_M_RD)
- ret = xlr_i2c_rx(priv, msg->len, &msg->buf[0],
- msg->addr);
- else
- ret = xlr_i2c_tx(priv, msg->len, &msg->buf[0],
- msg->addr);
- }
-
- return (ret != 0) ? ret : num;
-}
-
-static u32 xlr_func(struct i2c_adapter *adap)
-{
- /* Emulate SMBUS over I2C */
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm xlr_i2c_algo = {
- .master_xfer = xlr_i2c_xfer,
- .functionality = xlr_func,
-};
-
-static int __devinit xlr_i2c_probe(struct platform_device *pdev)
-{
- struct xlr_i2c_private *priv;
- struct resource *res;
- int ret;
-
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->iobase = devm_request_and_ioremap(&pdev->dev, res);
- if (!priv->iobase) {
- dev_err(&pdev->dev, "devm_request_and_ioremap failed\n");
- return -EBUSY;
- }
-
- priv->adap.dev.parent = &pdev->dev;
- priv->adap.owner = THIS_MODULE;
- priv->adap.algo_data = priv;
- priv->adap.algo = &xlr_i2c_algo;
- priv->adap.nr = pdev->id;
- priv->adap.class = I2C_CLASS_HWMON;
- snprintf(priv->adap.name, sizeof(priv->adap.name), "xlr-i2c");
-
- i2c_set_adapdata(&priv->adap, priv);
- ret = i2c_add_numbered_adapter(&priv->adap);
- if (ret < 0) {
- dev_err(&priv->adap.dev, "Failed to add i2c bus.\n");
- return ret;
- }
-
- platform_set_drvdata(pdev, priv);
- dev_info(&priv->adap.dev, "Added I2C Bus.\n");
- return 0;
-}
-
-static int __devexit xlr_i2c_remove(struct platform_device *pdev)
-{
- struct xlr_i2c_private *priv;
-
- priv = platform_get_drvdata(pdev);
- i2c_del_adapter(&priv->adap);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver xlr_i2c_driver = {
- .probe = xlr_i2c_probe,
- .remove = __devexit_p(xlr_i2c_remove),
- .driver = {
- .name = "xlr-i2cbus",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(xlr_i2c_driver);
-
-MODULE_AUTHOR("Ganesan Ramalingam <ganesanr@netlogicmicro.com>");
-MODULE_DESCRIPTION("XLR/XLS SoC I2C Controller driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:xlr-i2cbus");
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/scx200_acb.c b/ANDROID_3.4.5/drivers/i2c/busses/scx200_acb.c
deleted file mode 100644
index 2eacb778..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/scx200_acb.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
- National Semiconductor SCx200 ACCESS.bus support
- Also supports the AMD CS5535 and AMD CS5536
-
- Based on i2c-keywest.c which is:
- Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include <linux/scx200.h>
-
-#define NAME "scx200_acb"
-
-MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
-MODULE_ALIAS("platform:cs5535-smb");
-MODULE_LICENSE("GPL");
-
-#define MAX_DEVICES 4
-static int base[MAX_DEVICES] = { 0x820, 0x840 };
-module_param_array(base, int, NULL, 0);
-MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
-
-#define POLL_TIMEOUT (HZ/5)
-
-enum scx200_acb_state {
- state_idle,
- state_address,
- state_command,
- state_repeat_start,
- state_quick,
- state_read,
- state_write,
-};
-
-static const char *scx200_acb_state_name[] = {
- "idle",
- "address",
- "command",
- "repeat_start",
- "quick",
- "read",
- "write",
-};
-
-/* Physical interface */
-struct scx200_acb_iface {
- struct scx200_acb_iface *next;
- struct i2c_adapter adapter;
- unsigned base;
- struct mutex mutex;
-
- /* State machine data */
- enum scx200_acb_state state;
- int result;
- u8 address_byte;
- u8 command;
- u8 *ptr;
- char needs_reset;
- unsigned len;
-};
-
-/* Register Definitions */
-#define ACBSDA (iface->base + 0)
-#define ACBST (iface->base + 1)
-#define ACBST_SDAST 0x40 /* SDA Status */
-#define ACBST_BER 0x20
-#define ACBST_NEGACK 0x10 /* Negative Acknowledge */
-#define ACBST_STASTR 0x08 /* Stall After Start */
-#define ACBST_MASTER 0x02
-#define ACBCST (iface->base + 2)
-#define ACBCST_BB 0x02
-#define ACBCTL1 (iface->base + 3)
-#define ACBCTL1_STASTRE 0x80
-#define ACBCTL1_NMINTE 0x40
-#define ACBCTL1_ACK 0x10
-#define ACBCTL1_STOP 0x02
-#define ACBCTL1_START 0x01
-#define ACBADDR (iface->base + 4)
-#define ACBCTL2 (iface->base + 5)
-#define ACBCTL2_ENABLE 0x01
-
-/************************************************************************/
-
-static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
-{
- const char *errmsg;
-
- dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n",
- scx200_acb_state_name[iface->state], status);
-
- if (status & ACBST_BER) {
- errmsg = "bus error";
- goto error;
- }
- if (!(status & ACBST_MASTER)) {
- errmsg = "not master";
- goto error;
- }
- if (status & ACBST_NEGACK) {
- dev_dbg(&iface->adapter.dev, "negative ack in state %s\n",
- scx200_acb_state_name[iface->state]);
-
- iface->state = state_idle;
- iface->result = -ENXIO;
-
- outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
- outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
-
- /* Reset the status register */
- outb(0, ACBST);
- return;
- }
-
- switch (iface->state) {
- case state_idle:
- dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
- break;
-
- case state_address:
- /* Do a pointer write first */
- outb(iface->address_byte & ~1, ACBSDA);
-
- iface->state = state_command;
- break;
-
- case state_command:
- outb(iface->command, ACBSDA);
-
- if (iface->address_byte & 1)
- iface->state = state_repeat_start;
- else
- iface->state = state_write;
- break;
-
- case state_repeat_start:
- outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
- /* fallthrough */
-
- case state_quick:
- if (iface->address_byte & 1) {
- if (iface->len == 1)
- outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
- else
- outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
- outb(iface->address_byte, ACBSDA);
-
- iface->state = state_read;
- } else {
- outb(iface->address_byte, ACBSDA);
-
- iface->state = state_write;
- }
- break;
-
- case state_read:
- /* Set ACK if _next_ byte will be the last one */
- if (iface->len == 2)
- outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
- else
- outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
-
- if (iface->len == 1) {
- iface->result = 0;
- iface->state = state_idle;
- outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
- }
-
- *iface->ptr++ = inb(ACBSDA);
- --iface->len;
-
- break;
-
- case state_write:
- if (iface->len == 0) {
- iface->result = 0;
- iface->state = state_idle;
- outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
- break;
- }
-
- outb(*iface->ptr++, ACBSDA);
- --iface->len;
-
- break;
- }
-
- return;
-
- error:
- dev_err(&iface->adapter.dev,
- "%s in state %s (addr=0x%02x, len=%d, status=0x%02x)\n", errmsg,
- scx200_acb_state_name[iface->state], iface->address_byte,
- iface->len, status);
-
- iface->state = state_idle;
- iface->result = -EIO;
- iface->needs_reset = 1;
-}
-
-static void scx200_acb_poll(struct scx200_acb_iface *iface)
-{
- u8 status;
- unsigned long timeout;
-
- timeout = jiffies + POLL_TIMEOUT;
- while (1) {
- status = inb(ACBST);
-
- /* Reset the status register to avoid the hang */
- outb(0, ACBST);
-
- if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
- scx200_acb_machine(iface, status);
- return;
- }
- if (time_after(jiffies, timeout))
- break;
- cpu_relax();
- cond_resched();
- }
-
- dev_err(&iface->adapter.dev, "timeout in state %s\n",
- scx200_acb_state_name[iface->state]);
-
- iface->state = state_idle;
- iface->result = -EIO;
- iface->needs_reset = 1;
-}
-
-static void scx200_acb_reset(struct scx200_acb_iface *iface)
-{
- /* Disable the ACCESS.bus device and Configure the SCL
- frequency: 16 clock cycles */
- outb(0x70, ACBCTL2);
- /* Polling mode */
- outb(0, ACBCTL1);
- /* Disable slave address */
- outb(0, ACBADDR);
- /* Enable the ACCESS.bus device */
- outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
- /* Free STALL after START */
- outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
- /* Send a STOP */
- outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
- /* Clear BER, NEGACK and STASTR bits */
- outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
- /* Clear BB bit */
- outb(inb(ACBCST) | ACBCST_BB, ACBCST);
-}
-
-static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
- u16 address, unsigned short flags,
- char rw, u8 command, int size,
- union i2c_smbus_data *data)
-{
- struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
- int len;
- u8 *buffer;
- u16 cur_word;
- int rc;
-
- switch (size) {
- case I2C_SMBUS_QUICK:
- len = 0;
- buffer = NULL;
- break;
-
- case I2C_SMBUS_BYTE:
- len = 1;
- buffer = rw ? &data->byte : &command;
- break;
-
- case I2C_SMBUS_BYTE_DATA:
- len = 1;
- buffer = &data->byte;
- break;
-
- case I2C_SMBUS_WORD_DATA:
- len = 2;
- cur_word = cpu_to_le16(data->word);
- buffer = (u8 *)&cur_word;
- break;
-
- case I2C_SMBUS_I2C_BLOCK_DATA:
- len = data->block[0];
- if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
- return -EINVAL;
- buffer = &data->block[1];
- break;
-
- default:
- return -EINVAL;
- }
-
- dev_dbg(&adapter->dev,
- "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
- size, address, command, len, rw);
-
- if (!len && rw == I2C_SMBUS_READ) {
- dev_dbg(&adapter->dev, "zero length read\n");
- return -EINVAL;
- }
-
- mutex_lock(&iface->mutex);
-
- iface->address_byte = (address << 1) | rw;
- iface->command = command;
- iface->ptr = buffer;
- iface->len = len;
- iface->result = -EINVAL;
- iface->needs_reset = 0;
-
- outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
-
- if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
- iface->state = state_quick;
- else
- iface->state = state_address;
-
- while (iface->state != state_idle)
- scx200_acb_poll(iface);
-
- if (iface->needs_reset)
- scx200_acb_reset(iface);
-
- rc = iface->result;
-
- mutex_unlock(&iface->mutex);
-
- if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
- data->word = le16_to_cpu(cur_word);
-
-#ifdef DEBUG
- dev_dbg(&adapter->dev, "transfer done, result: %d", rc);
- if (buffer) {
- int i;
- printk(" data:");
- for (i = 0; i < len; ++i)
- printk(" %02x", buffer[i]);
- }
- printk("\n");
-#endif
-
- return rc;
-}
-
-static u32 scx200_acb_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK;
-}
-
-/* For now, we only handle combined mode (smbus) */
-static const struct i2c_algorithm scx200_acb_algorithm = {
- .smbus_xfer = scx200_acb_smbus_xfer,
- .functionality = scx200_acb_func,
-};
-
-static struct scx200_acb_iface *scx200_acb_list;
-static DEFINE_MUTEX(scx200_acb_list_mutex);
-
-static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
-{
- u8 val;
-
- /* Disable the ACCESS.bus device and Configure the SCL
- frequency: 16 clock cycles */
- outb(0x70, ACBCTL2);
-
- if (inb(ACBCTL2) != 0x70) {
- pr_debug(NAME ": ACBCTL2 readback failed\n");
- return -ENXIO;
- }
-
- outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
-
- val = inb(ACBCTL1);
- if (val) {
- pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
- val);
- return -ENXIO;
- }
-
- outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
-
- outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
-
- val = inb(ACBCTL1);
- if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
- pr_debug(NAME ": enabled, but NMINTE won't be set, "
- "ACBCTL1=0x%02x\n", val);
- return -ENXIO;
- }
-
- return 0;
-}
-
-static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text,
- struct device *dev, int index)
-{
- struct scx200_acb_iface *iface;
- struct i2c_adapter *adapter;
-
- iface = kzalloc(sizeof(*iface), GFP_KERNEL);
- if (!iface) {
- printk(KERN_ERR NAME ": can't allocate memory\n");
- return NULL;
- }
-
- adapter = &iface->adapter;
- i2c_set_adapdata(adapter, iface);
- snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
- adapter->owner = THIS_MODULE;
- adapter->algo = &scx200_acb_algorithm;
- adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- adapter->dev.parent = dev;
-
- mutex_init(&iface->mutex);
-
- return iface;
-}
-
-static int __devinit scx200_acb_create(struct scx200_acb_iface *iface)
-{
- struct i2c_adapter *adapter;
- int rc;
-
- adapter = &iface->adapter;
-
- rc = scx200_acb_probe(iface);
- if (rc) {
- printk(KERN_WARNING NAME ": probe failed\n");
- return rc;
- }
-
- scx200_acb_reset(iface);
-
- if (i2c_add_adapter(adapter) < 0) {
- printk(KERN_ERR NAME ": failed to register\n");
- return -ENODEV;
- }
-
- if (!adapter->dev.parent) {
- /* If there's no dev, we're tracking (ISA) ifaces manually */
- mutex_lock(&scx200_acb_list_mutex);
- iface->next = scx200_acb_list;
- scx200_acb_list = iface;
- mutex_unlock(&scx200_acb_list_mutex);
- }
-
- return 0;
-}
-
-static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text,
- unsigned long base, int index, struct device *dev)
-{
- struct scx200_acb_iface *iface;
- int rc;
-
- iface = scx200_create_iface(text, dev, index);
-
- if (iface == NULL)
- return NULL;
-
- if (!request_region(base, 8, iface->adapter.name)) {
- printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
- base, base + 8 - 1);
- goto errout_free;
- }
-
- iface->base = base;
- rc = scx200_acb_create(iface);
-
- if (rc == 0)
- return iface;
-
- release_region(base, 8);
- errout_free:
- kfree(iface);
- return NULL;
-}
-
-static int __devinit scx200_probe(struct platform_device *pdev)
-{
- struct scx200_acb_iface *iface;
- struct resource *res;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!res) {
- dev_err(&pdev->dev, "can't fetch device resource info\n");
- return -ENODEV;
- }
-
- iface = scx200_create_dev("CS5535", res->start, 0, &pdev->dev);
- if (!iface)
- return -EIO;
-
- dev_info(&pdev->dev, "SCx200 device '%s' registered\n",
- iface->adapter.name);
- platform_set_drvdata(pdev, iface);
-
- return 0;
-}
-
-static void __devexit scx200_cleanup_iface(struct scx200_acb_iface *iface)
-{
- i2c_del_adapter(&iface->adapter);
- release_region(iface->base, 8);
- kfree(iface);
-}
-
-static int __devexit scx200_remove(struct platform_device *pdev)
-{
- struct scx200_acb_iface *iface;
-
- iface = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
- scx200_cleanup_iface(iface);
-
- return 0;
-}
-
-static struct platform_driver scx200_pci_driver = {
- .driver = {
- .name = "cs5535-smb",
- .owner = THIS_MODULE,
- },
- .probe = scx200_probe,
- .remove = __devexit_p(scx200_remove),
-};
-
-static DEFINE_PCI_DEVICE_TABLE(scx200_isa) = {
- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
- { 0, }
-};
-
-static __init void scx200_scan_isa(void)
-{
- int i;
-
- if (!pci_dev_present(scx200_isa))
- return;
-
- for (i = 0; i < MAX_DEVICES; ++i) {
- if (base[i] == 0)
- continue;
-
- /* XXX: should we care about failures? */
- scx200_create_dev("SCx200", base[i], i, NULL);
- }
-}
-
-static int __init scx200_acb_init(void)
-{
- pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
-
- /* First scan for ISA-based devices */
- scx200_scan_isa(); /* XXX: should we care about errors? */
-
- /* If at least one bus was created, init must succeed */
- if (scx200_acb_list)
- return 0;
-
- /* No ISA devices; register the platform driver for PCI-based devices */
- return platform_driver_register(&scx200_pci_driver);
-}
-
-static void __exit scx200_acb_cleanup(void)
-{
- struct scx200_acb_iface *iface;
-
- platform_driver_unregister(&scx200_pci_driver);
-
- mutex_lock(&scx200_acb_list_mutex);
- while ((iface = scx200_acb_list) != NULL) {
- scx200_acb_list = iface->next;
- mutex_unlock(&scx200_acb_list_mutex);
-
- scx200_cleanup_iface(iface);
-
- mutex_lock(&scx200_acb_list_mutex);
- }
- mutex_unlock(&scx200_acb_list_mutex);
-}
-
-module_init(scx200_acb_init);
-module_exit(scx200_acb_cleanup);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/scx200_i2c.c b/ANDROID_3.4.5/drivers/i2c/busses/scx200_i2c.c
deleted file mode 100644
index 7ee0d502..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/scx200_i2c.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* linux/drivers/i2c/busses/scx200_i2c.c
-
- Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
- National Semiconductor SCx200 I2C bus on GPIO pins
-
- Based on i2c-velleman.c Copyright (C) 1995-96, 2000 Simon G. Vogl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/io.h>
-
-#include <linux/scx200_gpio.h>
-
-#define NAME "scx200_i2c"
-
-MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
-MODULE_LICENSE("GPL");
-
-static int scl = CONFIG_SCx200_I2C_SCL;
-static int sda = CONFIG_SCx200_I2C_SDA;
-
-module_param(scl, int, 0);
-MODULE_PARM_DESC(scl, "GPIO line for SCL");
-module_param(sda, int, 0);
-MODULE_PARM_DESC(sda, "GPIO line for SDA");
-
-static void scx200_i2c_setscl(void *data, int state)
-{
- scx200_gpio_set(scl, state);
-}
-
-static void scx200_i2c_setsda(void *data, int state)
-{
- scx200_gpio_set(sda, state);
-}
-
-static int scx200_i2c_getscl(void *data)
-{
- return scx200_gpio_get(scl);
-}
-
-static int scx200_i2c_getsda(void *data)
-{
- return scx200_gpio_get(sda);
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-
-static struct i2c_algo_bit_data scx200_i2c_data = {
- .setsda = scx200_i2c_setsda,
- .setscl = scx200_i2c_setscl,
- .getsda = scx200_i2c_getsda,
- .getscl = scx200_i2c_getscl,
- .udelay = 10,
- .timeout = HZ,
-};
-
-static struct i2c_adapter scx200_i2c_ops = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .algo_data = &scx200_i2c_data,
- .name = "NatSemi SCx200 I2C",
-};
-
-static int scx200_i2c_init(void)
-{
- pr_debug(NAME ": NatSemi SCx200 I2C Driver\n");
-
- if (!scx200_gpio_present()) {
- printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
- return -ENODEV;
- }
-
- pr_debug(NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
-
- if (scl == -1 || sda == -1 || scl == sda) {
- printk(KERN_ERR NAME ": scl and sda must be specified\n");
- return -EINVAL;
- }
-
- /* Configure GPIOs as open collector outputs */
- scx200_gpio_configure(scl, ~2, 5);
- scx200_gpio_configure(sda, ~2, 5);
-
- if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
- printk(KERN_ERR NAME ": adapter %s registration failed\n",
- scx200_i2c_ops.name);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void scx200_i2c_cleanup(void)
-{
- i2c_del_adapter(&scx200_i2c_ops);
-}
-
-module_init(scx200_i2c_init);
-module_exit(scx200_i2c_cleanup);
-
-/*
- Local variables:
- compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
- c-basic-offset: 8
- End:
-*/
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-1.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-1.c
deleted file mode 100755
index 3fd0f5a3..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-1.c
+++ /dev/null
@@ -1,1294 +0,0 @@
-/*++
- drivers/i2c/busses/wmt_i2c_bus-1.c
-
- Copyright (c) 2013 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-/* Include your headers here*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-/*
-#include <linux/i2c-id.h>
-*/
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/wmt-i2c-bus.h>
-#include <linux/slab.h>
-#include <linux/pm.h>
-#include <linux/syscore_ops.h>
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
- #define DPRINTK printk
-#else
- #define DPRINTK(x...)
-#endif
-
-#else
- #define DPRINTK printf
-
-#endif
-
-
-#define MAX_BUS_READY_CNT 50 /* jiffy*/
-#define MAX_TX_TIMEOUT 500 /* ms*/
-#define MAX_RX_TIMEOUT 500 /* ms*/
-#define CTRL_GPIO GPIO_CTRL_GP17_I2C_BYTE_ADDR
-#define PU_EN_GPIO PULL_EN_GP17_I2C_BYTE_ADDR
-#define PU_CTRL_GPIO PULL_CTRL_GP17_I2C_BYTE_ADDR
-
-#define USE_UBOOT_PARA
-
-struct wmt_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int volatile isr_nack ;
- int volatile isr_byte_end ;
- int volatile isr_timeout ;
- int volatile isr_int_pending ;
-};
-
-static int i2c_wmt_wait_bus_not_busy(void);
-static int i2c_wmt_wait_bus_release(void);
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int speed_mode = 0;
-unsigned int wmt_i2c1_speed_mode = 0;
-static unsigned int is_master = 1;/*master:1, slave:0*/
-unsigned int wmt_i2c1_is_master = 1;
-static unsigned int wmt_i2c1_power_state = 0;/*0:power on, 1:suspend, 2:shutdown*/
-EXPORT_SYMBOL(wmt_i2c1_is_master);
-
-/**/
-/* variable*/
-/*-------------------------------------------------*/
-static volatile struct wmt_i2c_s i2c ;
-
-DECLARE_WAIT_QUEUE_HEAD(i2c_wait);
-/*
-spinlock_t i2c_wmt_irqlock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_wmt_irqlock);
-static struct list_head wmt_i2c_fifohead;
-/*
-static spinlock_t i2c_fifolock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_fifolock);
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-
-static void i2c_wmt_set_mode(enum i2c_mode_e mode /*!<; //[IN] mode */)
-{
- if (is_master == 0)
- return;
- i2c.i2c_mode = mode ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- DPRINTK("I2C: set standard mode \n");
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- DPRINTK("I2C: set fast mode \n");
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
- }
-}
-
-
-static int i2c_send_request(
- struct i2c_msg *msg,
- int msg_num,
- int non_block,
- void (*callback)(void *data),
- void *data
-)
-{
- struct wmt_i2cbusfifo *i2c_fifo_head;
- struct i2c_msg *pmsg = NULL;
- int ret = 0;
- int restart = 0;
- int last = 0;
- unsigned long flags;
- int slave_addr = msg[0].addr;
-
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (wmt_i2c1_power_state == 2) {
- printk("I2C1 has been shutdown\n");
- return -EIO;
- }
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- if (non_block == 0)
- i2c.isr_int_pending = 0;
-
- i2c_fifo_head = kzalloc(sizeof(struct wmt_i2cbusfifo), GFP_ATOMIC);
- if (!i2c_fifo_head) {
- pr_err("%s: kzalloc fail\n", __func__);
- return -ENOMEM;
- }
- INIT_LIST_HEAD(&i2c_fifo_head->busfifohead);
-
- pmsg = &msg[0];
- i2c_fifo_head->msg = pmsg;
- i2c_fifo_head->msg_num = msg_num;
-
- if (list_empty(&wmt_i2c_fifohead)) {
- if (i2c_wmt_wait_bus_release()) {
- kfree(i2c_fifo_head);
- printk("i2c1 bus has been pull down by slave\n");
- return -EIO;
- }
- }
-
- spin_lock_irqsave(&i2c_fifolock, flags);
- if (list_empty(&wmt_i2c_fifohead)) {
- i2c_wmt_wait_bus_not_busy();
- pmsg = &msg[0];
- i2c_fifo_head->xfer_length = 1;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
-
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
-
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- if (pmsg->flags & I2C_M_RD) {
- i2c_fifo_head->xfer_length = 1;
- ret = i2c_wmt_read_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- } else {
- i2c_fifo_head->xfer_length = 1;
- if (pmsg->flags & I2C_M_NOSTART)
- i2c_fifo_head->restart = 1;
- else
- i2c_fifo_head->restart = 0;
- ret = i2c_wmt_write_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- }
-
- } else {
- i2c_fifo_head->xfer_length = 0;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- }
- spin_unlock_irqrestore(&i2c_fifolock, flags);
- if (non_block == 0) {
- wait_event(i2c_wait, i2c.isr_int_pending);
-#if 0
- if(wait_event_timeout(i2c_wait, i2c.isr_int_pending, HZ) == 0) {
- fifo_head = list_first_entry(&wmt_i2c_fifohead, struct wmt_i2cbusfifo, busfifohead);
- if( fifo_head ){
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- fifo_head = NULL;
- }
- i2c.regs->cr_reg = 0 ;
- i2c.regs->cr_reg |= I2C_CR_ENABLE ;
- return -ETIMEDOUT;
- }
-#endif
- ret = msg_num;
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- ret = -ETIMEDOUT ;
- }
-
- }
-
- return ret;
-
-
-}
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value;
- int ret = 0;
-
- DPRINTK("[%s]:length = %d , slave_addr = %x\n", __func__, length , slave_addr);
-
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- tcr_value = 0 ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
- return ret;
-}
-
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int ret = 0 ;
-
- DPRINTK("[%s]length = %d , slave_addr = %x\n", __func__, length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
-
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- ret = 0 ;
- return ret;
-
-}
-static int i2c_wmt_read_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete read */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result = 0 ;
-
- if (is_master == 0)
- return -ENXIO;
- if (length <= 0)
- return -1 ;
- xfer_length = 0 ;
-
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- ret = 0 ;
- for (; ;) {
- is_timeout = 0 ;
- wait_event_result = wait_event_interruptible_timeout(i2c_wait, i2c.isr_int_pending ,
- (MAX_RX_TIMEOUT * HZ / 1000)) ;
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (rx) \n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (rx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err: write software timeout error (rx) \n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- buf[xfer_length] = (i2c.regs->cdr_reg >> 8) ;
- ++xfer_length ;
- DPRINTK("i2c_test: received BYTE_END\n\r");
- }
- i2c.isr_int_pending = 0;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
- if (length > xfer_length) {
- if ((length - 1) == xfer_length) { /* next read is the last one*/
- i2c.regs->cr_reg |= (I2C_CR_TX_NEXT_NO_ACK | I2C_CR_CPU_RDY);
- DPRINTK("i2c_test: set CPU_RDY & TX_ACK. next data is last.\r\n");
- } else {
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- DPRINTK("i2c_test: more data to read. only set CPU_RDY. \r\n");
- }
- } else if (length == xfer_length) { /* end rx xfer*/
- if (last == 1) { /* stop case*/
- DPRINTK("i2c_test: read completed \r\n");
- break ;
- } else { /* restart case*/
- /* ??? how to handle the restart after read ?*/
- DPRINTK("i2c_test: RX ReStart Case \r\n") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : read known error\n\r") ;
- ret = -EIO ;
- break ;
- }
- }
-
- DPRINTK("i2c_test: read sequence completed\n\r");
- return ret ;
-}
-
-static int i2c_wmt_write_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete write */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result ;
-
- DPRINTK("length = %d , slave_addr = %x\n", length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
-
- ret = 0 ;
- for (; ;) {
-
- is_timeout = 0 ;
- /**/
- /* I2C: Wait for interrupt. if ( i2c.isr_int_pending == 1 ) ==> an interrupt exsits.*/
- /**/
- wait_event_result = wait_event_interruptible_timeout(i2c_wait, i2c.isr_int_pending , (MAX_TX_TIMEOUT * HZ / 1000)) ;
-
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (tx)\n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (tx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (tx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (tx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err : write software timeout error (tx)\n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- DPRINTK("i2c: isr end byte (tx)\n\r") ;
- ++xfer_length ;
- }
- i2c.isr_int_pending = 0 ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
-
- if ((i2c.regs->csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK) {
- DPRINTK("i2c_err : write RCV NACK error\n\r") ;
- ret = -EIO ;
- break ;
- }
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0) {
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- break ;
- }
- if (length > xfer_length) {
- i2c.regs->cdr_reg = (unsigned short) (buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
- i2c.regs->cr_reg = (I2C_CR_CPU_RDY | I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: write register data \n\r") ;
- } else if (length == xfer_length) { /* end tx xfer*/
- if (last == 1) { /* stop case*/
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: finish write \n\r") ;
- break ;
- } else { /* restart case*/
- /* handle the restart for first write then the next is read*/
- i2c.regs->cr_reg = (I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: tx restart Case \n\r") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : write unknown error\n\r") ;
- ret = -EIO ;
- break ;
- }
- } ;
-
- DPRINTK("i2c_test: write sequence completed\n\r");
-
- return ret ;
-}
-
-static int i2c_wmt_wait_bus_not_busy(void)
-{
- int ret ;
- int cnt ;
-
- ret = 0 ;
- cnt = 0 ;
- while (1) {
- if ((REG16_VAL(I2C1_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY) {
- ret = 0;
- break ;
- }
- cnt++ ;
-
- if (cnt > MAX_BUS_READY_CNT) {
- ret = (-EBUSY) ;
- printk("i2c_err : wait but not ready time-out\n\r") ;
- cnt = 0;
- break;
- }
- }
- return ret ;
-}
-
-static int i2c_wmt_wait_bus_release(void)
-{
- int val, cnt = 0;
- while(1) {
- val = REG8_VAL(__GPIO_BASE + 0x0011);
- if (0x0c == (val & 0x0c))
- return 0;
- udelay(1);
- cnt ++;
- if (cnt > 5000) {
- return -ETIMEDOUT;
- }
- }
- }
-
-static void i2c_wmt_reset(void)
-{
- unsigned short tmp ;
- if (is_master == 0)
- return;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C1_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C1 ;
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* hardware initial*/
- /**/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
-
- DPRINTK("Resetting I2C Controller Unit\n");
-
- return ;
-}
-static int wmt_i2c_transfer_msg(struct wmt_i2cbusfifo *fifo_head)
-{
- int xfer_length = fifo_head->xfer_length;
- int xfer_msgnum = fifo_head->xfer_msgnum;
- struct i2c_msg *pmsg = &fifo_head->msg[xfer_msgnum];
- int restart = fifo_head->restart;
- unsigned short tcr_value;
- unsigned short slave_addr = pmsg->addr;
- int length = pmsg->len;
- int ret = 0;
-
- if (pmsg->flags & I2C_M_RD) {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- } else {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(pmsg->buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- }
- return ret;
-}
-
-static irqreturn_t i2c_wmt_handler(
- int this_irq, /*!<; //[IN] IRQ number */
- void *dev_id /*!<; //[IN] Pointer to device ID */
-)
-{
- int wakeup ;
- unsigned short isr_status ;
- unsigned short tmp ;
- unsigned long flags;
- struct wmt_i2cbusfifo *fifo_head;
- int xfer_length = 0;
- int xfer_msgnum = 0;
- struct i2c_msg *pmsg;
- volatile unsigned short csr_reg;
-
- spin_lock_irqsave(&i2c_wmt_irqlock, flags);
- isr_status = i2c.regs->isr_reg ;
- csr_reg = i2c.regs->csr_reg;
- wakeup = 0 ;
- fifo_head = list_first_entry(&wmt_i2c_fifohead, struct wmt_i2cbusfifo, busfifohead);
-
- if (isr_status & I2C_ISR_NACK_ADDR) {
- DPRINTK("[%s]:i2c NACK\n", __func__);
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_NACK_ADDR_WRITE_CLEAR ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- }
-
- if ((isr_status & I2C_ISR_BYTE_END && ((csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK))) {
- /*
- printk("data rcv nack\n");
- */
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- } else if (isr_status & I2C_ISR_BYTE_END) {
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_byte_end = 1 ;
- xfer_length = fifo_head->xfer_length;
- xfer_msgnum = fifo_head->xfer_msgnum;
- pmsg = &fifo_head->msg[xfer_msgnum];
-
- /*read case*/
- if (pmsg->flags & I2C_M_RD) {
- pmsg->buf[xfer_length - 1] = (i2c.regs->cdr_reg >> 8) ;
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len - 1) {
- /*last msg of the current request?*/
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_TX_NEXT_NO_ACK);
- }
- /*spin_unlock(&i2c_fifolock);*/
- } else if (xfer_length == pmsg->len) {/*next msg*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else { /*data of this msg has been transfered*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*next request exist?*/
- if (list_empty(&wmt_i2c_fifohead)) {/*no more reqeust*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- } else { /*more request*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- fifo_head->xfer_length = 0;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
-
- /*
- if (fifo_head->non_block == 0) {
- printk("2 : non callback\n");
- wakeup = 1;
- } else {
- printk("2 :callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- }
-
- } else { /*write case*/
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len) {
- /*last msg of the current request?*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- }
- /*access next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else {/*this request finish*/
- /*spin_lock(&i2c_fifolock);*/
- /*next request exist?*/
- list_del(&fifo_head->busfifohead);/*del request*/
- if (list_empty(&wmt_i2c_fifohead)) {
- /*kfree(fifo_head);*/
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
-
- } else {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- /*next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*
- if (fifo_head->non_block == 0) {
- printk("4:non callback\n");
- wakeup = 1;
- } else {
- printk("4:callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- i2c.regs->cdr_reg = (unsigned short) (pmsg->buf[fifo_head->xfer_length] & I2C_CDR_DATA_WRITE_MASK);
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_ENABLE);
- }
- }
- }
-
- if (isr_status & I2C_ISR_SCL_TIME_OUT) {
- printk("[%s]I2C1 SCL timeout\n", __func__);
-#if 0
- i2c.regs->cr_reg |= BIT7;/*reset status*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR | I2C_ISR_BYTE_END_WRITE_CLEAR;
- i2c.isr_timeout = 1 ;
- wakeup = 1;
-#endif
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR ;
- }
-
-
- if (wakeup) {
- /*spin_lock_irqsave(&i2c_wmt_irqlock, flags);*/
- i2c.isr_int_pending = 1;
- /*spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);*/
- wake_up(&i2c_wait);
- } else
- DPRINTK("i2c_err : unknown I2C ISR Handle 0x%4.4X" , isr_status) ;
- spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);
- return IRQ_HANDLED;
-}
-
-static int i2c_wmt_resource_init(void)
-{
- if (is_master == 0)
- return 0;
- if (request_irq(i2c.irq_no , &i2c_wmt_handler, IRQF_DISABLED, "i2c", 0) < 0) {
- DPRINTK(KERN_INFO "I2C: Failed to register I2C irq %i\n", i2c.irq_no);
- return -ENODEV;
- }
- return 0;
-}
-
-static void i2c_wmt_resource_release(void)
-{
- if (is_master == 0)
- return;
- free_irq(i2c.irq_no, 0);
-}
-
-static struct i2c_algo_wmt_data i2c_wmt_data = {
- write_msg: i2c_wmt_write_msg,
- read_msg: i2c_wmt_read_msg,
- send_request: i2c_send_request,
- wait_bus_not_busy: i2c_wmt_wait_bus_not_busy,
- reset: i2c_wmt_reset,
- set_mode: i2c_wmt_set_mode,
- udelay: I2C_ALGO_UDELAY,
- timeout: I2C_ALGO_TIMEOUT,
-};
-
-static struct i2c_adapter i2c_wmt_ops = {
- .owner = THIS_MODULE,
- /*
- .id = I2C_ALGO_WMT,
- */
- .algo_data = &i2c_wmt_data,
- .name = "wmt_i2c_adapter1",
- .retries = I2C_ADAPTER_RETRIES,
- .nr = 1,
-};
-
-#ifdef CONFIG_PM
-static struct i2c_regs_s wmt_i2c_reg ;
-static void i2c_shutdown(void)
-{
- printk("i2c1 shutdown\n");
- wmt_i2c1_power_state = 2;
- while (!list_empty(&wmt_i2c_fifohead))
- msleep(1);
- while (1) {/*wait busy clear*/
- if ((REG16_VAL(I2C1_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY)
- break ;
- msleep(1);
- }
- return;
-}
-static int i2c_suspend(void)
-{
- printk("i2c1 suspend\n");
- wmt_i2c_reg.imr_reg = i2c.regs->imr_reg;
- wmt_i2c_reg.tr_reg = i2c.regs->tr_reg;
- wmt_i2c_reg.div_reg = i2c.regs->div_reg;
- return 0;
-}
-static void i2c_resume(void)
-{
- printk("i2c1 resume\n");
- GPIO_CTRL_GP17_I2C_BYTE_VAL &= ~(BIT2 | BIT3);
- PULL_EN_GP17_I2C_BYTE_VAL |= (BIT2 | BIT3);
- PULL_CTRL_GP17_I2C_BYTE_VAL |= (BIT2 | BIT3);
- auto_pll_divisor(DEV_I2C1, CLK_ENABLE, 0, 0);
- auto_pll_divisor(DEV_I2C1, SET_DIV, 2, 20);/*20M Hz*/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = wmt_i2c_reg.div_reg;
- i2c.regs->imr_reg = wmt_i2c_reg.imr_reg;
- i2c.regs->tr_reg = wmt_i2c_reg.tr_reg ;
- i2c.regs->cr_reg = 0x001 ;
-}
-#else
-#define i2c_suspend NULL
-#define i2c_resume NULL
-#define i2c_shutdown NULL
-#endif
-extern int wmt_i2c_add_bus(struct i2c_adapter *);
-extern int wmt_i2c_del_bus(struct i2c_adapter *);
-
-#ifdef CONFIG_PM
-static struct syscore_ops wmt_i2c_syscore_ops =
-{
- .suspend = i2c_suspend,
- .resume = i2c_resume,
- .shutdown = i2c_shutdown,
-};
-#endif
-
-static int __init i2c_adap_wmt_init(void)
-{
- unsigned short tmp ;
- char varname[] = "wmt.i2c.param";
-#ifdef CONFIG_I2C_SLAVE_WMT
- char varname1[] = "wmt.bus.i2c.slave_port";
-#endif
- unsigned char buf[80];
- int ret;
- unsigned int port_num;
- int idx = 0;
- int varlen = 80;
- unsigned int pllb_freq = 0;
- unsigned int tr_val = 0;
-
-#ifdef CONFIG_I2C_SLAVE_WMT
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname1, buf, &varlen);
-#else
- ret = 1;
-#endif
- is_master = 1;
- if (ret == 0) {
- ret = sscanf(buf, "%x", &port_num);
- while (ret) {
- if (port_num != 1)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret;
- ret = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
-#endif
- wmt_i2c1_is_master = is_master;
- if (is_master == 1) {
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname, buf, &varlen);
-#else
- ret = 1;
-#endif
-
- if (ret == 0) {
- ret = sscanf(buf, "%x:%x", &port_num, &speed_mode);
- idx += 3;
- while (ret) {
- if (ret < 2)
- speed_mode = 0;
- else {
- if (port_num != 1)
- speed_mode = 0;
- else
- break;
- }
- ret = sscanf(buf + idx, ",%x:%x", &port_num, &speed_mode);
- idx += 4;
- }
- }
- if (speed_mode > 1)
- speed_mode = 0;
- wmt_i2c1_speed_mode = speed_mode;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C1_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C1 ;
- printk("PORT 1 speed_mode = %d\n", speed_mode);
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else if (speed_mode == 1)
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
- /**/
- /* hardware initial*/
- /**/
- auto_pll_divisor(DEV_I2C1, CLK_ENABLE, 0, 0);
- pllb_freq = auto_pll_divisor(DEV_I2C1, SET_DIV, 2, 20);/*20M Hz*/
- if ((pllb_freq%(1000*2*100)) != 0)
- tr_val = pllb_freq/(1000*2*100) + 1;
- else
- tr_val = pllb_freq/(1000*2*100);
- *(volatile unsigned char *)CTRL_GPIO &= ~(BIT2 | BIT3);
- *(volatile unsigned char *)PU_EN_GPIO |= (BIT2 | BIT3);
- *(volatile unsigned char *)PU_CTRL_GPIO |= (BIT2 | BIT3);
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = 0xff00|tr_val;
- else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tr_val /= 4;
- i2c.regs->tr_reg = 0xff00|tr_val ;
- }
- }
-
-
- if (i2c_wmt_resource_init() == 0) {
- if (wmt_i2c_add_bus(&i2c_wmt_ops) < 0) {
- i2c_wmt_resource_release();
- printk(KERN_INFO "i2c: Failed to add bus\n");
- return -ENODEV;
- }
- } else
- return -ENODEV;
-
- INIT_LIST_HEAD(&wmt_i2c_fifohead);
-
-#ifdef CONFIG_PM
- register_syscore_ops(&wmt_i2c_syscore_ops);
-#endif
-
- wmt_i2c1_power_state = 0;
- printk(KERN_INFO "i2c: successfully added bus\n");
-
-#ifdef I2C_REG_TEST
- printk("i2c.regs->cr_reg= 0x%08x\n\r", i2c.regs->cr_reg);
- printk("i2c.regs->tcr_reg= 0x%08x\n\r", i2c.regs->tcr_reg);
- printk("i2c.regs->csr_reg= 0x%08x\n\r", i2c.regs->csr_reg);
- printk("i2c.regs->isr_reg= 0x%08x\n\r", i2c.regs->isr_reg);
- printk("i2c.regs->imr_reg= 0x%08x\n\r", i2c.regs->imr_reg);
- printk("i2c.regs->cdr_reg= 0x%08x\n\r", i2c.regs->cdr_reg);
- printk("i2c.regs->tr_reg= 0x%08x\n\r", i2c.regs->tr_reg);
- printk("i2c.regs->div_reg= 0x%08x\n\r", i2c.regs->div_reg);
-#endif
-
- return 0;
-}
-subsys_initcall(i2c_adap_wmt_init);
-
-static void i2c_adap_wmt_exit(void)
-{
- wmt_i2c_del_bus(&i2c_wmt_ops);
- i2c_wmt_resource_release();
-
- printk(KERN_INFO "i2c: successfully removed bus\n");
-}
-
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT I2C Adapter Driver");
-MODULE_LICENSE("GPL");
-
-module_exit(i2c_adap_wmt_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-2.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-2.c
deleted file mode 100755
index 64f5646c..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-2.c
+++ /dev/null
@@ -1,1253 +0,0 @@
-/*++
- drivers/i2c/busses/wmt-i2c-bus-2.c
-
- Copyright (c) 2013 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-/* Include your headers here*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-/*
-#include <linux/i2c-id.h>
-*/
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/wmt-i2c-bus.h>
-#include <linux/slab.h>
-#include <linux/pm.h>
-#include <linux/syscore_ops.h>
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
- #define DPRINTK printk
-#else
- #define DPRINTK(x...)
-#endif
-
-#else
- #define DPRINTK printf
-
-#endif
-
-
-#define MAX_BUS_READY_CNT 50 /* jiffy*/
-#define MAX_TX_TIMEOUT 500 /* ms*/
-#define MAX_RX_TIMEOUT 500 /* ms*/
-#define CTRL_GPIO GPIO_CTRL_GP17_I2C_BYTE_ADDR
-#define PU_EN_GPIO PULL_EN_GP17_I2C_BYTE_ADDR
-#define PU_CTRL_GPIO PULL_CTRL_GP17_I2C_BYTE_ADDR
-
-#define USE_UBOOT_PARA
-
-struct wmt_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int volatile isr_nack ;
- int volatile isr_byte_end ;
- int volatile isr_timeout ;
- int volatile isr_int_pending ;
-};
-
-static int i2c_wmt_wait_bus_not_busy(void);
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int speed_mode = 1;
-static unsigned int is_master = 1;/*master:1, slave:0*/
-unsigned int wmt_i2c2_is_master = 1;
-unsigned int wmt_i2c2_speed_mode = 0;
-static unsigned int wmt_i2c2_power_state = 0;/*0:power on, 1:suspend, 2:shutdown*/
-EXPORT_SYMBOL(wmt_i2c2_is_master);
-
-/**/
-/* variable*/
-/*-------------------------------------------------*/
-static volatile struct wmt_i2c_s i2c ;
-
-DECLARE_WAIT_QUEUE_HEAD(i2c2_wait);
-/*
-spinlock_t i2c2_wmt_irqlock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c2_wmt_irqlock);
-static struct list_head wmt_i2c_fifohead;
-/*
-static spinlock_t i2c_fifolock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_fifolock);
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-
-static void i2c_wmt_set_mode(enum i2c_mode_e mode /*!<; //[IN] mode */)
-{
- if (is_master == 0)
- return;
- i2c.i2c_mode = mode ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- DPRINTK("I2C: set standard mode \n");
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- DPRINTK("I2C: set fast mode \n");
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
- }
-}
-
-
-static int i2c_send_request(
- struct i2c_msg *msg,
- int msg_num,
- int non_block,
- void (*callback)(void *data),
- void *data
-)
-{
- struct wmt_i2cbusfifo *i2c_fifo_head;
- struct i2c_msg *pmsg = NULL;
- int ret = 0;
- int restart = 0;
- int last = 0;
- unsigned long flags;
- int slave_addr = msg[0].addr;
-
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
- if (wmt_i2c2_power_state == 2) {
- printk("I2C2 has been shutdown\n");
- return -EIO;
- }
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c_fifo_head = kzalloc(sizeof(struct wmt_i2cbusfifo), GFP_ATOMIC);
- INIT_LIST_HEAD(&i2c_fifo_head->busfifohead);
-
- pmsg = &msg[0];
- i2c_fifo_head->msg = pmsg;
- i2c_fifo_head->msg_num = msg_num;
-
- spin_lock_irqsave(&i2c_fifolock, flags);
- if (list_empty(&wmt_i2c_fifohead)) {
- i2c_wmt_wait_bus_not_busy();
- pmsg = &msg[0];
- i2c_fifo_head->xfer_length = 1;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
-
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
-
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- if (pmsg->flags & I2C_M_RD) {
- i2c_fifo_head->xfer_length = 1;
- ret = i2c_wmt_read_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- } else {
- i2c_fifo_head->xfer_length = 1;
- if (pmsg->flags & I2C_M_NOSTART)
- i2c_fifo_head->restart = 1;
- else
- i2c_fifo_head->restart = 0;
- ret = i2c_wmt_write_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- }
-
- } else {
- i2c_fifo_head->xfer_length = 0;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- }
- spin_unlock_irqrestore(&i2c_fifolock, flags);
- if (non_block == 0) {
- wait_event(i2c2_wait, i2c.isr_int_pending);
- ret = msg_num;
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- ret = -ETIMEDOUT ;
- }
-
- }
-
- return ret;
-
-
-}
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value;
- int ret = 0;
-
- DPRINTK("[%s]:length = %d , slave_addr = %x\n", __func__, length , slave_addr);
-
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- tcr_value = 0 ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
- return ret;
-}
-
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int ret = 0 ;
-
- DPRINTK("[%s]length = %d , slave_addr = %x\n", __func__, length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
-
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- ret = 0 ;
- return ret;
-
-}
-static int i2c_wmt_read_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete read */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result = 0 ;
-
- if (is_master == 0)
- return -ENXIO;
- if (length <= 0)
- return -1 ;
- xfer_length = 0 ;
-
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- ret = 0 ;
- for (; ;) {
- is_timeout = 0 ;
- wait_event_result = wait_event_interruptible_timeout(i2c2_wait, i2c.isr_int_pending ,
- (MAX_RX_TIMEOUT * HZ / 1000)) ;
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (rx) \n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (rx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err: write software timeout error (rx) \n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- buf[xfer_length] = (i2c.regs->cdr_reg >> 8) ;
- ++xfer_length ;
- DPRINTK("i2c_test: received BYTE_END\n\r");
- }
- i2c.isr_int_pending = 0;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
- if (length > xfer_length) {
- if ((length - 1) == xfer_length) { /* next read is the last one*/
- i2c.regs->cr_reg |= (I2C_CR_TX_NEXT_NO_ACK | I2C_CR_CPU_RDY);
- DPRINTK("i2c_test: set CPU_RDY & TX_ACK. next data is last.\r\n");
- } else {
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- DPRINTK("i2c_test: more data to read. only set CPU_RDY. \r\n");
- }
- } else if (length == xfer_length) { /* end rx xfer*/
- if (last == 1) { /* stop case*/
- DPRINTK("i2c_test: read completed \r\n");
- break ;
- } else { /* restart case*/
- /* ??? how to handle the restart after read ?*/
- DPRINTK("i2c_test: RX ReStart Case \r\n") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : read known error\n\r") ;
- ret = -EIO ;
- break ;
- }
- }
-
- DPRINTK("i2c_test: read sequence completed\n\r");
- return ret ;
-}
-
-static int i2c_wmt_write_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete write */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result ;
-
- DPRINTK("length = %d , slave_addr = %x\n", length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
-
- ret = 0 ;
- for (; ;) {
-
- is_timeout = 0 ;
- /**/
- /* I2C: Wait for interrupt. if ( i2c.isr_int_pending == 1 ) ==> an interrupt exsits.*/
- /**/
- wait_event_result = wait_event_interruptible_timeout(i2c2_wait, i2c.isr_int_pending , (MAX_TX_TIMEOUT * HZ / 1000)) ;
-
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (tx)\n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (tx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (tx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (tx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err : write software timeout error (tx)\n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- DPRINTK("i2c: isr end byte (tx)\n\r") ;
- ++xfer_length ;
- }
- i2c.isr_int_pending = 0 ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
-
- if ((i2c.regs->csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK) {
- DPRINTK("i2c_err : write RCV NACK error\n\r") ;
- ret = -EIO ;
- break ;
- }
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0) {
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- break ;
- }
- if (length > xfer_length) {
- i2c.regs->cdr_reg = (unsigned short) (buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
- i2c.regs->cr_reg = (I2C_CR_CPU_RDY | I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: write register data \n\r") ;
- } else if (length == xfer_length) { /* end tx xfer*/
- if (last == 1) { /* stop case*/
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: finish write \n\r") ;
- break ;
- } else { /* restart case*/
- /* handle the restart for first write then the next is read*/
- i2c.regs->cr_reg = (I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: tx restart Case \n\r") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : write unknown error\n\r") ;
- ret = -EIO ;
- break ;
- }
- } ;
-
- DPRINTK("i2c_test: write sequence completed\n\r");
-
- return ret ;
-}
-
-static int i2c_wmt_wait_bus_not_busy(void)
-{
- int ret ;
- int cnt ;
-
- ret = 0 ;
- cnt = 0 ;
- while (1) {
- if ((REG16_VAL(I2C2_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY) {
- ret = 0;
- break ;
- }
- cnt++ ;
-
- if (cnt > MAX_BUS_READY_CNT) {
- ret = (-EBUSY) ;
- printk("i2c_err 2: wait but not ready time-out\n\r") ;
- cnt = 0;
- break;
- }
- }
- return ret ;
-}
-
-static void i2c_wmt_reset(void)
-{
- unsigned short tmp ;
- if (is_master == 0)
- return;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C2_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C2 ;
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* hardware initial*/
- /**/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
-
- DPRINTK("Resetting I2C Controller Unit\n");
-
- return ;
-}
-static int wmt_i2c_transfer_msg(struct wmt_i2cbusfifo *fifo_head)
-{
- int xfer_length = fifo_head->xfer_length;
- int xfer_msgnum = fifo_head->xfer_msgnum;
- struct i2c_msg *pmsg = &fifo_head->msg[xfer_msgnum];
- int restart = fifo_head->restart;
- unsigned short tcr_value;
- unsigned short slave_addr = pmsg->addr;
- int length = pmsg->len;
- int ret = 0;
-
- if (pmsg->flags & I2C_M_RD) {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- } else {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(pmsg->buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- }
- return ret;
-}
-
-static irqreturn_t i2c_wmt_handler(
- int this_irq, /*!<; //[IN] IRQ number */
- void *dev_id /*!<; //[IN] Pointer to device ID */
-)
-{
- int wakeup ;
- unsigned short isr_status ;
- unsigned short tmp ;
- unsigned long flags;
- struct wmt_i2cbusfifo *fifo_head;
- int xfer_length = 0;
- int xfer_msgnum = 0;
- struct i2c_msg *pmsg;
- volatile unsigned short csr_reg;
-
- spin_lock_irqsave(&i2c2_wmt_irqlock, flags);
- isr_status = i2c.regs->isr_reg ;
- csr_reg = i2c.regs->csr_reg;
- wakeup = 0 ;
- fifo_head = list_first_entry(&wmt_i2c_fifohead, struct wmt_i2cbusfifo, busfifohead);
-
- if (isr_status & I2C_ISR_NACK_ADDR) {
- DPRINTK("[%s]:i2c NACK\n", __func__);
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_NACK_ADDR_WRITE_CLEAR ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- }
-
- if ((isr_status & I2C_ISR_BYTE_END && ((csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK))) {
- /*
- printk("data rcv nack\n");
- */
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- } else if (isr_status & I2C_ISR_BYTE_END) {
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_byte_end = 1 ;
- xfer_length = fifo_head->xfer_length;
- xfer_msgnum = fifo_head->xfer_msgnum;
- pmsg = &fifo_head->msg[xfer_msgnum];
-
- /*read case*/
- if (pmsg->flags & I2C_M_RD) {
- pmsg->buf[xfer_length - 1] = (i2c.regs->cdr_reg >> 8) ;
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len - 1) {
- /*last msg of the current request?*/
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_TX_NEXT_NO_ACK);
- }
- /*spin_unlock(&i2c_fifolock);*/
- } else if (xfer_length == pmsg->len) {/*next msg*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else { /*data of this msg has been transfered*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*next request exist?*/
- if (list_empty(&wmt_i2c_fifohead)) {/*no more reqeust*/
- /*kfree(fifo_head);*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- } else { /*more request*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- fifo_head->xfer_length = 0;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
-
- /*
- if (fifo_head->non_block == 0) {
- printk("2 : non callback\n");
- wakeup = 1;
- } else {
- printk("2 :callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- }
-
- } else { /*write case*/
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len) {
- /*last msg of the current request?*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- }
- /*access next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else {/*this request finish*/
- /*spin_lock(&i2c_fifolock);*/
- /*next request exist?*/
- list_del(&fifo_head->busfifohead);/*del request*/
- if (list_empty(&wmt_i2c_fifohead)) {
- /*kfree(fifo_head);*/
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
-
- } else {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- /*next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*
- if (fifo_head->non_block == 0) {
- printk("4:non callback\n");
- wakeup = 1;
- } else {
- printk("4:callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- i2c.regs->cdr_reg = (unsigned short) (pmsg->buf[fifo_head->xfer_length] & I2C_CDR_DATA_WRITE_MASK);
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_ENABLE);
- }
- }
- }
-
- if (isr_status & I2C_ISR_SCL_TIME_OUT) {
- DPRINTK("[%s]SCL timeout\n", __func__);
-#if 0
- i2c.regs->cr_reg |= BIT7;/*reset status*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR | I2C_ISR_BYTE_END_WRITE_CLEAR;
- i2c.isr_timeout = 1 ;
- wakeup = 1;
-#endif
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR ;
- }
-
-
- if (wakeup) {
- /*spin_lock_irqsave(&i2c_wmt_irqlock, flags);*/
- i2c.isr_int_pending = 1;
- /*spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);*/
- wake_up(&i2c2_wait);
- } else
- DPRINTK("i2c_err : unknown I2C ISR Handle 0x%4.4X" , isr_status) ;
- spin_unlock_irqrestore(&i2c2_wmt_irqlock, flags);
- return IRQ_HANDLED;
-}
-
-static int i2c_wmt_resource_init(void)
-{
- if (is_master == 0)
- return 0;
- if (request_irq(i2c.irq_no , &i2c_wmt_handler, IRQF_DISABLED, "i2c", 0) < 0) {
- DPRINTK(KERN_INFO "I2C: Failed to register I2C irq %i\n", i2c.irq_no);
- return -ENODEV;
- }
- return 0;
-}
-
-static void i2c_wmt_resource_release(void)
-{
- if (is_master == 0)
- return;
- free_irq(i2c.irq_no, 0);
-}
-
-static struct i2c_algo_wmt_data i2c_wmt_data = {
- write_msg: i2c_wmt_write_msg,
- read_msg: i2c_wmt_read_msg,
- send_request: i2c_send_request,
- wait_bus_not_busy: i2c_wmt_wait_bus_not_busy,
- reset: i2c_wmt_reset,
- set_mode: i2c_wmt_set_mode,
- udelay: I2C_ALGO_UDELAY,
- timeout: I2C_ALGO_TIMEOUT,
-};
-
-static struct i2c_adapter i2c_wmt_ops = {
- .owner = THIS_MODULE,
- /*
- .id = I2C_ALGO_WMT,
- */
- .algo_data = &i2c_wmt_data,
- .name = "wmt_i2c2_adapter",
- .retries = I2C_ADAPTER_RETRIES,
- .nr = 2,
-};
-
-#ifdef CONFIG_PM
-static struct i2c_regs_s wmt_i2c_reg ;
-static void i2c_shutdown(void)
-{
- printk("i2c2 shutdown\n");
- wmt_i2c2_power_state = 2;
- while (!list_empty(&wmt_i2c_fifohead))
- msleep(1);
- while (1) {/*wait busy clear*/
- if ((REG16_VAL(I2C2_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY)
- break ;
- msleep(1);
- }
- return;
-}
-static int i2c_suspend(void)
-{
- printk("i2c2 suspend\n");
- wmt_i2c_reg.imr_reg = i2c.regs->imr_reg;
- wmt_i2c_reg.tr_reg = i2c.regs->tr_reg;
- wmt_i2c_reg.div_reg = i2c.regs->div_reg;
- return 0;
-}
-static void i2c_resume(void)
-{
- printk("i2c2 resume\n");
- GPIO_CTRL_GP17_I2C_BYTE_VAL &= ~(BIT4 | BIT5);
- PULL_EN_GP17_I2C_BYTE_VAL |= (BIT4 | BIT5);
- PULL_CTRL_GP17_I2C_BYTE_VAL |= (BIT4 | BIT5);
- auto_pll_divisor(DEV_I2C2, CLK_ENABLE, 0, 0);
- auto_pll_divisor(DEV_I2C2, SET_DIV, 2, 20);/*20M Hz*/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = wmt_i2c_reg.div_reg;
- i2c.regs->imr_reg = wmt_i2c_reg.imr_reg;
- i2c.regs->tr_reg = wmt_i2c_reg.tr_reg ;
- i2c.regs->cr_reg = 0x001 ;
-}
-#else
-#define i2c_suspend NULL
-#define i2c_resume NULL
-#define i2c_shutdown NULL
-#endif
-extern int wmt_i2c_add_bus(struct i2c_adapter *);
-extern int wmt_i2c_del_bus(struct i2c_adapter *);
-
-#ifdef CONFIG_PM
-static struct syscore_ops wmt_i2c_syscore_ops = {
- .suspend = i2c_suspend,
- .resume = i2c_resume,
- .shutdown = i2c_shutdown,
-};
-#endif
-
-static int __init i2c_adap_wmt_init(void)
-{
- unsigned short tmp ;
- char varname[] = "wmt.i2c.param";
-#ifdef CONFIG_I2C_SLAVE_WMT
- char varname1[] = "wmt.bus.i2c.slave_port";
-#endif
- unsigned char buf[80];
- int ret;
- unsigned int port_num;
- int idx = 0;
- int varlen = 80;
- unsigned int pllb_freq = 0;
- unsigned int tr_val = 0;
-
-#ifdef CONFIG_I2C_SLAVE_WMT
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname1, buf, &varlen);
-#else
- ret = 1;
-#endif
- is_master = 1;
- if (ret == 0) {
- ret = sscanf(buf, "%x", &port_num);
- while (ret) {
- if (port_num != 0)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret;
- ret = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
-#endif
- wmt_i2c2_is_master = is_master;
- if (is_master == 1) {
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname, buf, &varlen);
-#else
- ret = 1;
-#endif
-
- if (ret == 0) {
- ret = sscanf(buf, "%x:%x", &port_num, &speed_mode);
- idx += 3;
- while (ret) {
- if (ret < 2)
- speed_mode = 0;
- else {
- if (port_num != 2)
- speed_mode = 0;
- else
- break;
- }
- ret = sscanf(buf + idx, ",%x:%x", &port_num, &speed_mode);
- idx += 4;
- }
- }
- if (speed_mode > 1)
- speed_mode = 0;
- wmt_i2c2_speed_mode = speed_mode;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C2_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C2 ;
-
- printk("PORT 2 speed_mode = %d\n", speed_mode);
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else if (speed_mode == 1)
- i2c.i2c_mode = I2C_FAST_MODE ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
- /**/
- /* hardware initial*/
- /**/
- auto_pll_divisor(DEV_I2C2, CLK_ENABLE, 0, 0);
- pllb_freq = auto_pll_divisor(DEV_I2C2, SET_DIV, 2, 20);/*20M Hz*/
- if ((pllb_freq%(1000*2*100)) != 0)
- tr_val = pllb_freq/(1000*2*100) + 1;
- else
- tr_val = pllb_freq/(1000*2*100);
- *(volatile unsigned char *)CTRL_GPIO &= ~(BIT4 | BIT5);
- *(volatile unsigned char *)PU_EN_GPIO |= (BIT4 | BIT5);
- *(volatile unsigned char *)PU_CTRL_GPIO |= (BIT4 | BIT5);
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = 0xff00|tr_val;
- else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tr_val /= 4;
- i2c.regs->tr_reg = 0xff00|tr_val ;
- }
- }
-
-
- if (i2c_wmt_resource_init() == 0) {
- if (wmt_i2c_add_bus(&i2c_wmt_ops) < 0) {
- i2c_wmt_resource_release();
- printk(KERN_INFO "i2c: Failed to add bus\n");
- return -ENODEV;
- }
- } else
- return -ENODEV;
-
- INIT_LIST_HEAD(&wmt_i2c_fifohead);
-
-#ifdef CONFIG_PM
- register_syscore_ops(&wmt_i2c_syscore_ops);
-#endif
-
- printk(KERN_INFO "i2c: successfully added bus\n");
-
-#ifdef I2C_REG_TEST
- printk("i2c.regs->cr_reg= 0x%08x\n\r", i2c.regs->cr_reg);
- printk("i2c.regs->tcr_reg= 0x%08x\n\r", i2c.regs->tcr_reg);
- printk("i2c.regs->csr_reg= 0x%08x\n\r", i2c.regs->csr_reg);
- printk("i2c.regs->isr_reg= 0x%08x\n\r", i2c.regs->isr_reg);
- printk("i2c.regs->imr_reg= 0x%08x\n\r", i2c.regs->imr_reg);
- printk("i2c.regs->cdr_reg= 0x%08x\n\r", i2c.regs->cdr_reg);
- printk("i2c.regs->tr_reg= 0x%08x\n\r", i2c.regs->tr_reg);
- printk("i2c.regs->div_reg= 0x%08x\n\r", i2c.regs->div_reg);
-#endif
-
- return 0;
-}
-subsys_initcall(i2c_adap_wmt_init);
-
-static void i2c_adap_wmt_exit(void)
-{
- wmt_i2c_del_bus(&i2c_wmt_ops);
- i2c_wmt_resource_release();
-
- printk(KERN_INFO "i2c: successfully removed bus\n");
-}
-
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT I2C Adapter Driver");
-MODULE_LICENSE("GPL");
-
-module_exit(i2c_adap_wmt_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-3.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-3.c
deleted file mode 100755
index b362a156..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-3.c
+++ /dev/null
@@ -1,1256 +0,0 @@
-/*++
- drivers/i2c/busses/wmt-i2c-bus-3.c
-
- Copyright (c) 2013 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-/* Include your headers here*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-/*
-#include <linux/i2c-id.h>
-*/
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/wmt-i2c-bus.h>
-#include <linux/slab.h>
-#include <linux/pm.h>
-#include <linux/syscore_ops.h>
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
- #define DPRINTK printk
-#else
- #define DPRINTK(x...)
-#endif
-
-#else
- #define DPRINTK printf
-
-#endif
-
-
-#define MAX_BUS_READY_CNT 50 /* jiffy*/
-#define MAX_TX_TIMEOUT 500 /* ms*/
-#define MAX_RX_TIMEOUT 500 /* ms*/
-#define CTRL_GPIO GPIO_CTRL_GP23_I2C3_BYTE_ADDR
-#define PU_EN_GPIO PULL_EN_GP23_I2C3_BYTE_ADDR
-#define PU_CTRL_GPIO PULL_CTRL_GP23_I2C3_BYTE_ADDR
-
-#define USE_UBOOT_PARA
-
-struct wmt_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int volatile isr_nack ;
- int volatile isr_byte_end ;
- int volatile isr_timeout ;
- int volatile isr_int_pending ;
-};
-
-static int i2c_wmt_wait_bus_not_busy(void);
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int speed_mode = 1;
-static unsigned int is_master = 1;/*master:1, slave:0*/
-unsigned int wmt_i2c3_is_master = 1;
-unsigned int wmt_i2c3_speed_mode = 0;
-static unsigned int wmt_i2c3_power_state = 0;/*0:power on, 1:suspend, 2:shutdown*/
-EXPORT_SYMBOL(wmt_i2c3_is_master);
-
-/**/
-/* variable*/
-/*-------------------------------------------------*/
-static volatile struct wmt_i2c_s i2c ;
-
-DECLARE_WAIT_QUEUE_HEAD(i2c3_wait);
-/*
-spinlock_t i2c3_wmt_irqlock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c3_wmt_irqlock);
-static struct list_head wmt_i2c_fifohead;
-/*
-static spinlock_t i2c_fifolock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_fifolock);
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-
-static void i2c_wmt_set_mode(enum i2c_mode_e mode /*!<; //[IN] mode */)
-{
- if (is_master == 0)
- return;
- i2c.i2c_mode = mode ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- DPRINTK("I2C: set standard mode \n");
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- DPRINTK("I2C: set fast mode \n");
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
- }
-}
-
-
-static int i2c_send_request(
- struct i2c_msg *msg,
- int msg_num,
- int non_block,
- void (*callback)(void *data),
- void *data
-)
-{
- struct wmt_i2cbusfifo *i2c_fifo_head;
- struct i2c_msg *pmsg = NULL;
- int ret = 0;
- int restart = 0;
- int last = 0;
- unsigned long flags;
- int slave_addr = msg[0].addr;
-
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
- if (wmt_i2c3_power_state == 2) {
- printk("I2C3 has been shutdown\n");
- return -EIO;
- }
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c_fifo_head = kzalloc(sizeof(struct wmt_i2cbusfifo), GFP_ATOMIC);
- INIT_LIST_HEAD(&i2c_fifo_head->busfifohead);
-
- pmsg = &msg[0];
- i2c_fifo_head->msg = pmsg;
- i2c_fifo_head->msg_num = msg_num;
-
- spin_lock_irqsave(&i2c_fifolock, flags);
- if (list_empty(&wmt_i2c_fifohead)) {
- i2c_wmt_wait_bus_not_busy();
- pmsg = &msg[0];
- i2c_fifo_head->xfer_length = 1;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
-
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
-
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- if (pmsg->flags & I2C_M_RD) {
- i2c_fifo_head->xfer_length = 1;
- ret = i2c_wmt_read_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- } else {
- i2c_fifo_head->xfer_length = 1;
- if (pmsg->flags & I2C_M_NOSTART)
- i2c_fifo_head->restart = 1;
- else
- i2c_fifo_head->restart = 0;
- ret = i2c_wmt_write_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- }
-
- } else {
- i2c_fifo_head->xfer_length = 0;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- }
- spin_unlock_irqrestore(&i2c_fifolock, flags);
- if (non_block == 0) {
- wait_event(i2c3_wait, i2c.isr_int_pending);
- ret = msg_num;
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- ret = -ETIMEDOUT ;
- }
-
- }
-
- return ret;
-
-
-}
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value;
- int ret = 0;
-
- DPRINTK("[%s]:length = %d , slave_addr = %x\n", __func__, length , slave_addr);
-
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- tcr_value = 0 ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
- return ret;
-}
-
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int ret = 0 ;
-
- DPRINTK("[%s]length = %d , slave_addr = %x\n", __func__, length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
-
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- ret = 0 ;
- return ret;
-
-}
-static int i2c_wmt_read_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete read */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result = 0 ;
-
- if (is_master == 0)
- return -ENXIO;
- if (length <= 0)
- return -1 ;
- xfer_length = 0 ;
-
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- ret = 0 ;
- for (; ;) {
- is_timeout = 0 ;
- wait_event_result = wait_event_interruptible_timeout(i2c3_wait, i2c.isr_int_pending ,
- (MAX_RX_TIMEOUT * HZ / 1000)) ;
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (rx) \n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (rx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err: write software timeout error (rx) \n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- buf[xfer_length] = (i2c.regs->cdr_reg >> 8) ;
- ++xfer_length ;
- DPRINTK("i2c_test: received BYTE_END\n\r");
- }
- i2c.isr_int_pending = 0;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
- if (length > xfer_length) {
- if ((length - 1) == xfer_length) { /* next read is the last one*/
- i2c.regs->cr_reg |= (I2C_CR_TX_NEXT_NO_ACK | I2C_CR_CPU_RDY);
- DPRINTK("i2c_test: set CPU_RDY & TX_ACK. next data is last.\r\n");
- } else {
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- DPRINTK("i2c_test: more data to read. only set CPU_RDY. \r\n");
- }
- } else if (length == xfer_length) { /* end rx xfer*/
- if (last == 1) { /* stop case*/
- DPRINTK("i2c_test: read completed \r\n");
- break ;
- } else { /* restart case*/
- /* ??? how to handle the restart after read ?*/
- DPRINTK("i2c_test: RX ReStart Case \r\n") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : read known error\n\r") ;
- ret = -EIO ;
- break ;
- }
- }
-
- DPRINTK("i2c_test: read sequence completed\n\r");
- return ret ;
-}
-
-static int i2c_wmt_write_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete write */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result ;
-
- DPRINTK("length = %d , slave_addr = %x\n", length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
-
- ret = 0 ;
- for (; ;) {
-
- is_timeout = 0 ;
- /**/
- /* I2C: Wait for interrupt. if ( i2c.isr_int_pending == 1 ) ==> an interrupt exsits.*/
- /**/
- wait_event_result = wait_event_interruptible_timeout(i2c3_wait, i2c.isr_int_pending , (MAX_TX_TIMEOUT * HZ / 1000)) ;
-
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (tx)\n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (tx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (tx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (tx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err : write software timeout error (tx)\n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- DPRINTK("i2c: isr end byte (tx)\n\r") ;
- ++xfer_length ;
- }
- i2c.isr_int_pending = 0 ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
-
- if ((i2c.regs->csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK) {
- DPRINTK("i2c_err : write RCV NACK error\n\r") ;
- ret = -EIO ;
- break ;
- }
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0) {
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- break ;
- }
- if (length > xfer_length) {
- i2c.regs->cdr_reg = (unsigned short) (buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
- i2c.regs->cr_reg = (I2C_CR_CPU_RDY | I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: write register data \n\r") ;
- } else if (length == xfer_length) { /* end tx xfer*/
- if (last == 1) { /* stop case*/
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: finish write \n\r") ;
- break ;
- } else { /* restart case*/
- /* handle the restart for first write then the next is read*/
- i2c.regs->cr_reg = (I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: tx restart Case \n\r") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : write unknown error\n\r") ;
- ret = -EIO ;
- break ;
- }
- } ;
-
- DPRINTK("i2c_test: write sequence completed\n\r");
-
- return ret ;
-}
-
-static int i2c_wmt_wait_bus_not_busy(void)
-{
- int ret ;
- int cnt ;
-
- ret = 0 ;
- cnt = 0 ;
- while (1) {
- if ((REG16_VAL(I2C3_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY) {
- ret = 0;
- break ;
- }
- cnt++ ;
-
- if (cnt > MAX_BUS_READY_CNT) {
- ret = (-EBUSY) ;
- printk("i2c_err 3: wait but not ready time-out\n\r") ;
- cnt = 0;
- break;
- }
- }
- return ret ;
-}
-
-static void i2c_wmt_reset(void)
-{
- unsigned short tmp ;
- if (is_master == 0)
- return;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C3_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C3 ;
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* hardware initial*/
- /**/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
-
- DPRINTK("Resetting I2C Controller Unit\n");
-
- return ;
-}
-static int wmt_i2c_transfer_msg(struct wmt_i2cbusfifo *fifo_head)
-{
- int xfer_length = fifo_head->xfer_length;
- int xfer_msgnum = fifo_head->xfer_msgnum;
- struct i2c_msg *pmsg = &fifo_head->msg[xfer_msgnum];
- int restart = fifo_head->restart;
- unsigned short tcr_value;
- unsigned short slave_addr = pmsg->addr;
- int length = pmsg->len;
- int ret = 0;
-
- if (pmsg->flags & I2C_M_RD) {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- } else {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(pmsg->buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- }
- return ret;
-}
-
-static irqreturn_t i2c_wmt_handler(
- int this_irq, /*!<; //[IN] IRQ number */
- void *dev_id /*!<; //[IN] Pointer to device ID */
-)
-{
- int wakeup ;
- unsigned short isr_status ;
- unsigned short tmp ;
- unsigned long flags;
- struct wmt_i2cbusfifo *fifo_head;
- int xfer_length = 0;
- int xfer_msgnum = 0;
- struct i2c_msg *pmsg;
- volatile unsigned short csr_reg;
-
- spin_lock_irqsave(&i2c3_wmt_irqlock, flags);
- isr_status = i2c.regs->isr_reg ;
- csr_reg = i2c.regs->csr_reg;
- wakeup = 0 ;
- fifo_head = list_first_entry(&wmt_i2c_fifohead, struct wmt_i2cbusfifo, busfifohead);
-
- if (isr_status & I2C_ISR_NACK_ADDR) {
- DPRINTK("[%s]:i2c NACK\n", __func__);
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_NACK_ADDR_WRITE_CLEAR ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- }
-
- if ((isr_status & I2C_ISR_BYTE_END && ((csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK))) {
- /*
- printk("data rcv nack\n");
- */
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- } else if (isr_status & I2C_ISR_BYTE_END) {
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_byte_end = 1 ;
- xfer_length = fifo_head->xfer_length;
- xfer_msgnum = fifo_head->xfer_msgnum;
- pmsg = &fifo_head->msg[xfer_msgnum];
-
- /*read case*/
- if (pmsg->flags & I2C_M_RD) {
- pmsg->buf[xfer_length - 1] = (i2c.regs->cdr_reg >> 8) ;
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len - 1) {
- /*last msg of the current request?*/
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_TX_NEXT_NO_ACK);
- }
- /*spin_unlock(&i2c_fifolock);*/
- } else if (xfer_length == pmsg->len) {/*next msg*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else { /*data of this msg has been transfered*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*next request exist?*/
- if (list_empty(&wmt_i2c_fifohead)) {/*no more reqeust*/
- /*kfree(fifo_head);*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- } else { /*more request*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- fifo_head->xfer_length = 0;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
-
- /*
- if (fifo_head->non_block == 0) {
- printk("2 : non callback\n");
- wakeup = 1;
- } else {
- printk("2 :callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- }
-
- } else { /*write case*/
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len) {
- /*last msg of the current request?*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- }
- /*access next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else {/*this request finish*/
- /*spin_lock(&i2c_fifolock);*/
- /*next request exist?*/
- list_del(&fifo_head->busfifohead);/*del request*/
- if (list_empty(&wmt_i2c_fifohead)) {
- /*kfree(fifo_head);*/
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
-
- } else {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- /*next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*
- if (fifo_head->non_block == 0) {
- printk("4:non callback\n");
- wakeup = 1;
- } else {
- printk("4:callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- i2c.regs->cdr_reg = (unsigned short) (pmsg->buf[fifo_head->xfer_length] & I2C_CDR_DATA_WRITE_MASK);
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_ENABLE);
- }
- }
- }
-
- if (isr_status & I2C_ISR_SCL_TIME_OUT) {
- DPRINTK("[%s]SCL timeout\n", __func__);
-#if 0
- i2c.regs->cr_reg |= BIT7;/*reset status*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR | I2C_ISR_BYTE_END_WRITE_CLEAR;
- i2c.isr_timeout = 1 ;
- wakeup = 1;
-#endif
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR ;
- }
-
-
- if (wakeup) {
- /*spin_lock_irqsave(&i2c_wmt_irqlock, flags);*/
- i2c.isr_int_pending = 1;
- /*spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);*/
- wake_up(&i2c3_wait);
- } else
- DPRINTK("i2c_err : unknown I2C ISR Handle 0x%4.4X" , isr_status) ;
- spin_unlock_irqrestore(&i2c3_wmt_irqlock, flags);
- return IRQ_HANDLED;
-}
-
-static int i2c_wmt_resource_init(void)
-{
- if (is_master == 0)
- return 0;
- if (request_irq(i2c.irq_no , &i2c_wmt_handler, IRQF_DISABLED, "i2c", 0) < 0) {
- DPRINTK(KERN_INFO "I2C: Failed to register I2C irq %i\n", i2c.irq_no);
- return -ENODEV;
- }
- return 0;
-}
-
-static void i2c_wmt_resource_release(void)
-{
- if (is_master == 0)
- return;
- free_irq(i2c.irq_no, 0);
-}
-
-static struct i2c_algo_wmt_data i2c_wmt_data = {
- write_msg: i2c_wmt_write_msg,
- read_msg: i2c_wmt_read_msg,
- send_request: i2c_send_request,
- wait_bus_not_busy: i2c_wmt_wait_bus_not_busy,
- reset: i2c_wmt_reset,
- set_mode: i2c_wmt_set_mode,
- udelay: I2C_ALGO_UDELAY,
- timeout: I2C_ALGO_TIMEOUT,
-};
-
-static struct i2c_adapter i2c_wmt_ops = {
- .owner = THIS_MODULE,
- /*
- .id = I2C_ALGO_WMT,
- */
- .algo_data = &i2c_wmt_data,
- .name = "wmt_i2c3_adapter",
- .retries = I2C_ADAPTER_RETRIES,
- .nr = 3,
-};
-
-#ifdef CONFIG_PM
-static struct i2c_regs_s wmt_i2c_reg ;
-static void i2c_shutdown(void)
-{
- printk("i2c3 shutdown\n");
- wmt_i2c3_power_state = 2;
- while (!list_empty(&wmt_i2c_fifohead))
- msleep(1);
- while (1) {/*wait busy clear*/
- if ((REG16_VAL(I2C3_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY)
- break ;
- msleep(1);
- }
- return;
-}
-static int i2c_suspend(void)
-{
- printk("i2c3 suspend\n");
- wmt_i2c_reg.imr_reg = i2c.regs->imr_reg;
- wmt_i2c_reg.tr_reg = i2c.regs->tr_reg;
- wmt_i2c_reg.div_reg = i2c.regs->div_reg;
- return 0;
-}
-static void i2c_resume(void)
-{
- printk("i2c3 resume\n");
- GPIO_CTRL_GP23_I2C3_BYTE_VAL &= ~(BIT0 | BIT1);
- PULL_EN_GP23_I2C3_BYTE_VAL |= (BIT0 | BIT1);
- PULL_CTRL_GP23_I2C3_BYTE_VAL |= (BIT0 | BIT1);
- PIN_SHARING_SEL_4BYTE_VAL &= ~BIT28;
- auto_pll_divisor(DEV_I2C3, CLK_ENABLE, 0, 0);
- auto_pll_divisor(DEV_I2C3, SET_DIV, 2, 20);/*20M Hz*/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = wmt_i2c_reg.div_reg;
- i2c.regs->imr_reg = wmt_i2c_reg.imr_reg;
- i2c.regs->tr_reg = wmt_i2c_reg.tr_reg ;
- i2c.regs->cr_reg = 0x001 ;
-}
-#else
-#define i2c_suspend NULL
-#define i2c_resume NULL
-#define i2c_shutdown NULL
-#endif
-extern int wmt_i2c_add_bus(struct i2c_adapter *);
-extern int wmt_i2c_del_bus(struct i2c_adapter *);
-
-#ifdef CONFIG_PM
-static struct syscore_ops wmt_i2c_syscore_ops = {
- .suspend = i2c_suspend,
- .resume = i2c_resume,
- .shutdown = i2c_shutdown,
-};
-#endif
-
-static int __init i2c_adap_wmt_init(void)
-{
- unsigned short tmp ;
- char varname[] = "wmt.i2c.param";
-#ifdef CONFIG_I2C_SLAVE_WMT
- char varname1[] = "wmt.bus.i2c.slave_port";
-#endif
- unsigned char buf[80];
- int ret;
- unsigned int port_num;
- int idx = 0;
- int varlen = 80;
- unsigned int pllb_freq = 0;
- unsigned int tr_val = 0;
-
-#ifdef CONFIG_I2C_SLAVE_WMT
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname1, buf, &varlen);
-#else
- ret = 1;
-#endif
- is_master = 1;
- if (ret == 0) {
- ret = sscanf(buf, "%x", &port_num);
- while (ret) {
- if (port_num != 0)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret;
- ret = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
-#endif
- wmt_i2c3_is_master = is_master;
- if (is_master == 1) {
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname, buf, &varlen);
-#else
- ret = 1;
-#endif
-
- if (ret == 0) {
- ret = sscanf(buf, "%x:%x", &port_num, &speed_mode);
- idx += 3;
- while (ret) {
- if (ret < 2)
- speed_mode = 0;
- else {
- if (port_num != 3)
- speed_mode = 0;
- else
- break;
- }
- ret = sscanf(buf + idx, ",%x:%x", &port_num, &speed_mode);
- idx += 4;
- }
- }
- if (speed_mode > 1)
- speed_mode = 0;
- wmt_i2c3_speed_mode = speed_mode;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C3_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C3 ;
-
- printk("PORT 3 speed_mode = %d\n", speed_mode);
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else if (speed_mode == 1)
- i2c.i2c_mode = I2C_FAST_MODE ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
- /**/
- /* hardware initial*/
- /**/
- auto_pll_divisor(DEV_I2C3, CLK_ENABLE, 0, 0);
- pllb_freq = auto_pll_divisor(DEV_I2C3, SET_DIV, 2, 20);/*20M Hz*/
- printk("pllb_freq = %d\n", pllb_freq);
- if ((pllb_freq%(1000*2*100)) != 0)
- tr_val = pllb_freq/(1000*2*100) + 1;
- else
- tr_val = pllb_freq/(1000*2*100);
- *(volatile unsigned char *)CTRL_GPIO &= ~(BIT0 | BIT1);
- *(volatile unsigned char *)PU_EN_GPIO |= (BIT0 | BIT1);
- *(volatile unsigned char *)PU_CTRL_GPIO |= (BIT0 | BIT1);
- PIN_SHARING_SEL_4BYTE_VAL &= ~BIT28;
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = 0xff00|tr_val;
- else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tr_val /= 4;
- i2c.regs->tr_reg = 0xff00|tr_val ;
- }
- }
-
-
- if (i2c_wmt_resource_init() == 0) {
- if (wmt_i2c_add_bus(&i2c_wmt_ops) < 0) {
- i2c_wmt_resource_release();
- printk(KERN_INFO "i2c: Failed to add bus\n");
- return -ENODEV;
- }
- } else
- return -ENODEV;
-
- INIT_LIST_HEAD(&wmt_i2c_fifohead);
-
-#ifdef CONFIG_PM
- register_syscore_ops(&wmt_i2c_syscore_ops);
-#endif
-
- printk(KERN_INFO "i2c: successfully added bus\n");
-
-#ifdef I2C_REG_TEST
- printk("i2c.regs->cr_reg= 0x%08x\n\r", i2c.regs->cr_reg);
- printk("i2c.regs->tcr_reg= 0x%08x\n\r", i2c.regs->tcr_reg);
- printk("i2c.regs->csr_reg= 0x%08x\n\r", i2c.regs->csr_reg);
- printk("i2c.regs->isr_reg= 0x%08x\n\r", i2c.regs->isr_reg);
- printk("i2c.regs->imr_reg= 0x%08x\n\r", i2c.regs->imr_reg);
- printk("i2c.regs->cdr_reg= 0x%08x\n\r", i2c.regs->cdr_reg);
- printk("i2c.regs->tr_reg= 0x%08x\n\r", i2c.regs->tr_reg);
- printk("i2c.regs->div_reg= 0x%08x\n\r", i2c.regs->div_reg);
-#endif
-
- return 0;
-}
-subsys_initcall(i2c_adap_wmt_init);
-
-static void i2c_adap_wmt_exit(void)
-{
- wmt_i2c_del_bus(&i2c_wmt_ops);
- i2c_wmt_resource_release();
-
- printk(KERN_INFO "i2c: successfully removed bus\n");
-}
-
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT I2C Adapter Driver");
-MODULE_LICENSE("GPL");
-
-module_exit(i2c_adap_wmt_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-4.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-4.c
deleted file mode 100755
index 72e6531d..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus-4.c
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*++
- drivers/i2c/busses/wmt_i2c_bus-4.c
-
- Copyright (c) 2013 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-/* Include your headers here*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-/*
-#include <linux/i2c-id.h>
-*/
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/wmt-i2c-bus.h>
-#include <linux/slab.h>
-#include <linux/pm.h>
-#include <linux/syscore_ops.h>
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
- #define DPRINTK printk
-#else
- #define DPRINTK(x...)
-#endif
-
-#else
- #define DPRINTK printf
-
-#endif
-
-
-#define MAX_BUS_READY_CNT 50 /* jiffy*/
-#define MAX_TX_TIMEOUT 500 /* ms*/
-#define MAX_RX_TIMEOUT 500 /* ms*/
-
-#define USE_UBOOT_PARA
-
-struct wmt_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int volatile isr_nack ;
- int volatile isr_byte_end ;
- int volatile isr_timeout ;
- int volatile isr_int_pending ;
-};
-
-static int i2c_wmt_wait_bus_not_busy(void);
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int speed_mode = 0;
-unsigned int wmt_i2c4_speed_mode = 0;
-static unsigned int is_master = 1;/*master:1, slave:0*/
-unsigned int wmt_i2c4_is_master = 1;
-static unsigned int wmt_i2c4_power_state = 0;/*0:power on, 1:suspend, 2:shutdown*/
-EXPORT_SYMBOL(wmt_i2c4_is_master);
-
-/**/
-/* variable*/
-/*-------------------------------------------------*/
-static volatile struct wmt_i2c_s i2c ;
-
-DECLARE_WAIT_QUEUE_HEAD(i2c4_wait);
-/*
-spinlock_t i2c_wmt_irqlock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_wmt_irqlock);
-static struct list_head wmt_i2c_fifohead;
-/*
-static spinlock_t i2c_fifolock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_fifolock);
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-
-static void i2c_gpio_init(void)
-{
- GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~BIT4;
- GPIO_CTRL_GP11_I2S_BYTE_VAL &= ~BIT2;
-
- PULL_EN_GP10_I2S_BYTE_VAL |= BIT4;
- PULL_EN_GP11_I2S_BYTE_VAL |= BIT2;
-
- PULL_CTRL_GP10_I2S_BYTE_VAL |= BIT4;
- PULL_CTRL_GP11_I2S_BYTE_VAL |= BIT2;
-
- PIN_SHARING_SEL_4BYTE_VAL |= BIT21 | BIT22 | BIT13 | BIT14;
-}
-
-static void i2c_wmt_set_mode(enum i2c_mode_e mode /*!<; //[IN] mode */)
-{
- if (is_master == 0)
- return;
- i2c.i2c_mode = mode ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- DPRINTK("I2C: set standard mode \n");
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- DPRINTK("I2C: set fast mode \n");
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
- }
-}
-
-
-static int i2c_send_request(
- struct i2c_msg *msg,
- int msg_num,
- int non_block,
- void (*callback)(void *data),
- void *data
-)
-{
- struct wmt_i2cbusfifo *i2c_fifo_head;
- struct i2c_msg *pmsg = NULL;
- int ret = 0;
- int restart = 0;
- int last = 0;
- unsigned long flags;
- int slave_addr = msg[0].addr;
-
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (wmt_i2c4_power_state == 2) {
- printk("I2C4 has been shutdown\n");
- return -EIO;
- }
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- if (non_block == 0)
- i2c.isr_int_pending = 0;
-
- i2c_fifo_head = kzalloc(sizeof(struct wmt_i2cbusfifo), GFP_ATOMIC);
- INIT_LIST_HEAD(&i2c_fifo_head->busfifohead);
-
- pmsg = &msg[0];
- i2c_fifo_head->msg = pmsg;
- i2c_fifo_head->msg_num = msg_num;
-
- spin_lock_irqsave(&i2c_fifolock, flags);
- if (list_empty(&wmt_i2c_fifohead)) {
- i2c_wmt_wait_bus_not_busy();
- pmsg = &msg[0];
- i2c_fifo_head->xfer_length = 1;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
-
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
-
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- if (pmsg->flags & I2C_M_RD) {
- i2c_fifo_head->xfer_length = 1;
- ret = i2c_wmt_read_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- } else {
- i2c_fifo_head->xfer_length = 1;
- if (pmsg->flags & I2C_M_NOSTART)
- i2c_fifo_head->restart = 1;
- else
- i2c_fifo_head->restart = 0;
- ret = i2c_wmt_write_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- }
-
- } else {
- i2c_fifo_head->xfer_length = 0;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- }
- spin_unlock_irqrestore(&i2c_fifolock, flags);
- if (non_block == 0) {
- wait_event(i2c4_wait, i2c.isr_int_pending);
- ret = msg_num;
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- ret = -ETIMEDOUT ;
- }
-
- }
-
- return ret;
-
-
-}
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value;
- int ret = 0;
-
- DPRINTK("[%s]:length = %d , slave_addr = %x\n", __func__, length , slave_addr);
-
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- tcr_value = 0 ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
- return ret;
-}
-
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int ret = 0 ;
-
- DPRINTK("[%s]length = %d , slave_addr = %x\n", __func__, length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
-
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- ret = 0 ;
- return ret;
-
-}
-static int i2c_wmt_read_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete read */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result = 0 ;
-
- if (is_master == 0)
- return -ENXIO;
- if (length <= 0)
- return -1 ;
- xfer_length = 0 ;
-
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- ret = 0 ;
- for (; ;) {
- is_timeout = 0 ;
- wait_event_result = wait_event_interruptible_timeout(i2c4_wait, i2c.isr_int_pending ,
- (MAX_RX_TIMEOUT * HZ / 1000)) ;
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (rx) \n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (rx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err: write software timeout error (rx) \n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- buf[xfer_length] = (i2c.regs->cdr_reg >> 8) ;
- ++xfer_length ;
- DPRINTK("i2c_test: received BYTE_END\n\r");
- }
- i2c.isr_int_pending = 0;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
- if (length > xfer_length) {
- if ((length - 1) == xfer_length) { /* next read is the last one*/
- i2c.regs->cr_reg |= (I2C_CR_TX_NEXT_NO_ACK | I2C_CR_CPU_RDY);
- DPRINTK("i2c_test: set CPU_RDY & TX_ACK. next data is last.\r\n");
- } else {
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- DPRINTK("i2c_test: more data to read. only set CPU_RDY. \r\n");
- }
- } else if (length == xfer_length) { /* end rx xfer*/
- if (last == 1) { /* stop case*/
- DPRINTK("i2c_test: read completed \r\n");
- break ;
- } else { /* restart case*/
- /* ??? how to handle the restart after read ?*/
- DPRINTK("i2c_test: RX ReStart Case \r\n") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : read known error\n\r") ;
- ret = -EIO ;
- break ;
- }
- }
-
- DPRINTK("i2c_test: read sequence completed\n\r");
- return ret ;
-}
-
-static int i2c_wmt_write_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete write */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result ;
-
- DPRINTK("length = %d , slave_addr = %x\n", length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
-
- ret = 0 ;
- for (; ;) {
-
- is_timeout = 0 ;
- /**/
- /* I2C: Wait for interrupt. if ( i2c.isr_int_pending == 1 ) ==> an interrupt exsits.*/
- /**/
- wait_event_result = wait_event_interruptible_timeout(i2c4_wait, i2c.isr_int_pending , (MAX_TX_TIMEOUT * HZ / 1000)) ;
-
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (tx)\n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (tx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (tx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (tx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err : write software timeout error (tx)\n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- DPRINTK("i2c: isr end byte (tx)\n\r") ;
- ++xfer_length ;
- }
- i2c.isr_int_pending = 0 ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
-
- if ((i2c.regs->csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK) {
- DPRINTK("i2c_err : write RCV NACK error\n\r") ;
- ret = -EIO ;
- break ;
- }
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0) {
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- break ;
- }
- if (length > xfer_length) {
- i2c.regs->cdr_reg = (unsigned short) (buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
- i2c.regs->cr_reg = (I2C_CR_CPU_RDY | I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: write register data \n\r") ;
- } else if (length == xfer_length) { /* end tx xfer*/
- if (last == 1) { /* stop case*/
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: finish write \n\r") ;
- break ;
- } else { /* restart case*/
- /* handle the restart for first write then the next is read*/
- i2c.regs->cr_reg = (I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: tx restart Case \n\r") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : write unknown error\n\r") ;
- ret = -EIO ;
- break ;
- }
- } ;
-
- DPRINTK("i2c_test: write sequence completed\n\r");
-
- return ret ;
-}
-
-static int i2c_wmt_wait_bus_not_busy(void)
-{
- int ret ;
- int cnt ;
-
- ret = 0 ;
- cnt = 0 ;
- while (1) {
- if ((REG16_VAL(I2C4_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY) {
- ret = 0;
- break ;
- }
- cnt++ ;
-
- if (cnt > MAX_BUS_READY_CNT) {
- ret = (-EBUSY) ;
- printk("i2c_err : wait but not ready time-out\n\r") ;
- cnt = 0;
- break;
- }
- }
- return ret ;
-}
-
-static void i2c_wmt_reset(void)
-{
- unsigned short tmp ;
- if (is_master == 0)
- return;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C4_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C4 ;
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* hardware initial*/
- /**/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
-
- DPRINTK("Resetting I2C Controller Unit\n");
-
- return ;
-}
-static int wmt_i2c_transfer_msg(struct wmt_i2cbusfifo *fifo_head)
-{
- int xfer_length = fifo_head->xfer_length;
- int xfer_msgnum = fifo_head->xfer_msgnum;
- struct i2c_msg *pmsg = &fifo_head->msg[xfer_msgnum];
- int restart = fifo_head->restart;
- unsigned short tcr_value;
- unsigned short slave_addr = pmsg->addr;
- int length = pmsg->len;
- int ret = 0;
-
- if (pmsg->flags & I2C_M_RD) {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- } else {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(pmsg->buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- }
- return ret;
-}
-
-static irqreturn_t i2c_wmt_handler(
- int this_irq, /*!<; //[IN] IRQ number */
- void *dev_id /*!<; //[IN] Pointer to device ID */
-)
-{
- int wakeup ;
- unsigned short isr_status ;
- unsigned short tmp ;
- unsigned long flags;
- struct wmt_i2cbusfifo *fifo_head;
- int xfer_length = 0;
- int xfer_msgnum = 0;
- struct i2c_msg *pmsg;
- volatile unsigned short csr_reg;
-
- spin_lock_irqsave(&i2c_wmt_irqlock, flags);
- isr_status = i2c.regs->isr_reg ;
- csr_reg = i2c.regs->csr_reg;
- wakeup = 0 ;
- fifo_head = list_first_entry(&wmt_i2c_fifohead, struct wmt_i2cbusfifo, busfifohead);
-
- if (isr_status & I2C_ISR_NACK_ADDR) {
- DPRINTK("[%s]:i2c NACK\n", __func__);
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_NACK_ADDR_WRITE_CLEAR ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- }
-
- if ((isr_status & I2C_ISR_BYTE_END && ((csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK))) {
- /*
- printk("data rcv nack\n");
- */
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- } else if (isr_status & I2C_ISR_BYTE_END) {
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_byte_end = 1 ;
- xfer_length = fifo_head->xfer_length;
- xfer_msgnum = fifo_head->xfer_msgnum;
- pmsg = &fifo_head->msg[xfer_msgnum];
-
- /*read case*/
- if (pmsg->flags & I2C_M_RD) {
- pmsg->buf[xfer_length - 1] = (i2c.regs->cdr_reg >> 8) ;
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len - 1) {
- /*last msg of the current request?*/
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_TX_NEXT_NO_ACK);
- }
- /*spin_unlock(&i2c_fifolock);*/
- } else if (xfer_length == pmsg->len) {/*next msg*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else { /*data of this msg has been transfered*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*next request exist?*/
- if (list_empty(&wmt_i2c_fifohead)) {/*no more reqeust*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- } else { /*more request*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- fifo_head->xfer_length = 0;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
-
- /*
- if (fifo_head->non_block == 0) {
- printk("2 : non callback\n");
- wakeup = 1;
- } else {
- printk("2 :callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- }
-
- } else { /*write case*/
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len) {
- /*last msg of the current request?*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- }
- /*access next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else {/*this request finish*/
- /*spin_lock(&i2c_fifolock);*/
- /*next request exist?*/
- list_del(&fifo_head->busfifohead);/*del request*/
- if (list_empty(&wmt_i2c_fifohead)) {
- /*kfree(fifo_head);*/
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
-
- } else {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- /*next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*
- if (fifo_head->non_block == 0) {
- printk("4:non callback\n");
- wakeup = 1;
- } else {
- printk("4:callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- i2c.regs->cdr_reg = (unsigned short) (pmsg->buf[fifo_head->xfer_length] & I2C_CDR_DATA_WRITE_MASK);
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_ENABLE);
- }
- }
- }
-
- if (isr_status & I2C_ISR_SCL_TIME_OUT) {
- DPRINTK("[%s]SCL timeout\n", __func__);
-#if 0
- i2c.regs->cr_reg |= BIT7;/*reset status*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR | I2C_ISR_BYTE_END_WRITE_CLEAR;
- i2c.isr_timeout = 1 ;
- wakeup = 1;
-#endif
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR ;
- }
-
-
- if (wakeup) {
- /*spin_lock_irqsave(&i2c_wmt_irqlock, flags);*/
- i2c.isr_int_pending = 1;
- /*spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);*/
- wake_up(&i2c4_wait);
- } else
- DPRINTK("i2c_err : unknown I2C ISR Handle 0x%4.4X" , isr_status) ;
- spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);
- return IRQ_HANDLED;
-}
-
-static int i2c_wmt_resource_init(void)
-{
- if (is_master == 0)
- return 0;
- if (request_irq(i2c.irq_no , &i2c_wmt_handler, IRQF_DISABLED, "i2c", 0) < 0) {
- DPRINTK(KERN_INFO "I2C: Failed to register I2C irq %i\n", i2c.irq_no);
- return -ENODEV;
- }
- return 0;
-}
-
-static void i2c_wmt_resource_release(void)
-{
- if (is_master == 0)
- return;
- free_irq(i2c.irq_no, 0);
-}
-
-static struct i2c_algo_wmt_data i2c_wmt_data = {
- write_msg: i2c_wmt_write_msg,
- read_msg: i2c_wmt_read_msg,
- send_request: i2c_send_request,
- wait_bus_not_busy: i2c_wmt_wait_bus_not_busy,
- reset: i2c_wmt_reset,
- set_mode: i2c_wmt_set_mode,
- udelay: I2C_ALGO_UDELAY,
- timeout: I2C_ALGO_TIMEOUT,
-};
-
-static struct i2c_adapter i2c_wmt_ops = {
- .owner = THIS_MODULE,
- /*
- .id = I2C_ALGO_WMT,
- */
- .algo_data = &i2c_wmt_data,
- .name = "wmt_i2c4_adapter",
- .retries = I2C_ADAPTER_RETRIES,
- .nr = 4,
-};
-
-#ifdef CONFIG_PM
-static struct i2c_regs_s wmt_i2c_reg ;
-static void i2c_shutdown(void)
-{
- printk("i2c4 shutdown\n");
- wmt_i2c4_power_state = 2;
- while (!list_empty(&wmt_i2c_fifohead))
- msleep(1);
- while (1) {/*wait busy clear*/
- if ((REG16_VAL(I2C4_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY)
- break ;
- msleep(1);
- }
- return;
-}
-static int i2c_suspend(void)
-{
- printk("i2c4 suspend\n");
- wmt_i2c_reg.imr_reg = i2c.regs->imr_reg;
- wmt_i2c_reg.tr_reg = i2c.regs->tr_reg;
- wmt_i2c_reg.div_reg = i2c.regs->div_reg;
- return 0;
-}
-static void i2c_resume(void)
-{
- printk("i2c4 resume\n");
- /*
- GPIO_CTRL_GP17_I2C_BYTE_VAL &= ~(BIT2 | BIT3);
- PULL_EN_GP17_I2C_BYTE_VAL |= (BIT2 | BIT3);
- PULL_CTRL_GP17_I2C_BYTE_VAL |= (BIT2 | BIT3);
- */
- i2c_gpio_init();
- auto_pll_divisor(DEV_I2C4, CLK_ENABLE, 0, 0);
- auto_pll_divisor(DEV_I2C4, SET_DIV, 2, 20);/*20M Hz*/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = wmt_i2c_reg.div_reg;
- i2c.regs->imr_reg = wmt_i2c_reg.imr_reg;
- i2c.regs->tr_reg = wmt_i2c_reg.tr_reg ;
- i2c.regs->cr_reg = 0x001 ;
-}
-#else
-#define i2c_suspend NULL
-#define i2c_resume NULL
-#define i2c_shutdown NULL
-#endif
-extern int wmt_i2c_add_bus(struct i2c_adapter *);
-extern int wmt_i2c_del_bus(struct i2c_adapter *);
-
-#ifdef CONFIG_PM
-static struct syscore_ops wmt_i2c_syscore_ops =
-{
- .suspend = i2c_suspend,
- .resume = i2c_resume,
- .shutdown = i2c_shutdown,
-};
-#endif
-
-static int __init i2c_adap_wmt_init(void)
-{
- unsigned short tmp ;
- char varname[] = "wmt.i2c.param";
-#ifdef CONFIG_I2C_SLAVE_WMT
- char varname1[] = "wmt.bus.i2c.slave_port";
-#endif
- unsigned char buf[80];
- int ret;
- unsigned int port_num;
- int idx = 0;
- int varlen = 80;
- /*since i2c4 is share pin, it turn on while uboot parameter define i2c4 mode*/
- int i2c_turn_on = 0;
- unsigned int pllb_freq = 0;
- unsigned int tr_val = 0;
-
-#ifdef CONFIG_I2C_SLAVE_WMT
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname1, buf, &varlen);
-#else
- ret = 1;
-#endif
- is_master = 1;
- if (ret == 0) {
- ret = sscanf(buf, "%x", &port_num);
- while (ret) {
- if (port_num != 4)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret;
- ret = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
-#endif
- wmt_i2c4_is_master = is_master;
- if (is_master == 1) {
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname, buf, &varlen);
-#else
- ret = 1;
-#endif
-
- if (ret == 0) {
- ret = sscanf(buf, "%x:%x", &port_num, &speed_mode);
- idx += 3;
- while (ret) {
- if (ret < 2)
- speed_mode = 0;
- else {
- if (port_num != 4)
- speed_mode = 0;
- else {
- i2c_turn_on = 1;
- break;
- }
- }
- ret = sscanf(buf + idx, ",%x:%x", &port_num, &speed_mode);
- idx += 4;
- }
- }
- if (i2c_turn_on == 0) {
- printk("I2C4 turn off\n");
- return -EIO;
- }
- if (speed_mode > 1)
- speed_mode = 0;
- wmt_i2c4_speed_mode = speed_mode;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C4_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C4 ;
- printk("PORT 4 speed_mode = %d\n", speed_mode);
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else if (speed_mode == 1)
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
- /**/
- /* hardware initial*/
- /**/
- auto_pll_divisor(DEV_I2C4, CLK_ENABLE, 0, 0);
- pllb_freq = auto_pll_divisor(DEV_I2C4, SET_DIV, 2, 20);/*20M Hz*/
- i2c_gpio_init();
- printk("pllb_freq = %d\n", pllb_freq);
- if ((pllb_freq%(1000*2*100)) != 0)
- tr_val = pllb_freq/(1000*2*100) + 1;
- else
- tr_val = pllb_freq/(1000*2*100);
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = 0xff00|tr_val;
- else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tr_val /= 4;
- i2c.regs->tr_reg = 0xff00|tr_val ;
- }
- }
-
-
- if (i2c_wmt_resource_init() == 0) {
- if (wmt_i2c_add_bus(&i2c_wmt_ops) < 0) {
- i2c_wmt_resource_release();
- printk(KERN_INFO "i2c: Failed to add bus\n");
- return -ENODEV;
- }
- } else
- return -ENODEV;
-
- INIT_LIST_HEAD(&wmt_i2c_fifohead);
-
-#ifdef CONFIG_PM
- register_syscore_ops(&wmt_i2c_syscore_ops);
-#endif
-
- wmt_i2c4_power_state = 0;
- printk(KERN_INFO "i2c: successfully added bus\n");
-
-#ifdef I2C_REG_TEST
- printk("i2c.regs->cr_reg= 0x%08x\n\r", i2c.regs->cr_reg);
- printk("i2c.regs->tcr_reg= 0x%08x\n\r", i2c.regs->tcr_reg);
- printk("i2c.regs->csr_reg= 0x%08x\n\r", i2c.regs->csr_reg);
- printk("i2c.regs->isr_reg= 0x%08x\n\r", i2c.regs->isr_reg);
- printk("i2c.regs->imr_reg= 0x%08x\n\r", i2c.regs->imr_reg);
- printk("i2c.regs->cdr_reg= 0x%08x\n\r", i2c.regs->cdr_reg);
- printk("i2c.regs->tr_reg= 0x%08x\n\r", i2c.regs->tr_reg);
- printk("i2c.regs->div_reg= 0x%08x\n\r", i2c.regs->div_reg);
-#endif
-
- return 0;
-}
-subsys_initcall(i2c_adap_wmt_init);
-
-static void i2c_adap_wmt_exit(void)
-{
- wmt_i2c_del_bus(&i2c_wmt_ops);
- i2c_wmt_resource_release();
-
- printk(KERN_INFO "i2c: successfully removed bus\n");
-}
-
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT I2C Adapter Driver");
-MODULE_LICENSE("GPL");
-
-module_exit(i2c_adap_wmt_exit);
-
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus.c
deleted file mode 100755
index ecfda642..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-bus.c
+++ /dev/null
@@ -1,1254 +0,0 @@
-/*++
- drivers/i2c/busses/wmt-i2c-bus.c
-
- Copyright (c) 2013 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-/* Include your headers here*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/i2c.h>
-/*
-#include <linux/i2c-id.h>
-*/
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/wmt-i2c-bus.h>
-#include <linux/slab.h>
-#include <linux/pm.h>
-#include <linux/syscore_ops.h>
-
-#ifdef __KERNEL__
-
-#ifdef DEBUG
- #define DPRINTK printk
-#else
- #define DPRINTK(x...)
-#endif
-
-#else
- #define DPRINTK printf
-
-#endif
-
-
-#define MAX_BUS_READY_CNT 50 /* jiffy*/
-#define MAX_TX_TIMEOUT 500 /* ms*/
-#define MAX_RX_TIMEOUT 500 /* ms*/
-#define CTRL_GPIO GPIO_CTRL_GP17_I2C_BYTE_ADDR
-#define PU_EN_GPIO PULL_EN_GP17_I2C_BYTE_ADDR
-#define PU_CTRL_GPIO PULL_CTRL_GP17_I2C_BYTE_ADDR
-
-#define USE_UBOOT_PARA
-
-struct wmt_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int volatile isr_nack ;
- int volatile isr_byte_end ;
- int volatile isr_timeout ;
- int volatile isr_int_pending ;
-};
-
-static int i2c_wmt_wait_bus_not_busy(void);
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int speed_mode = 0;
-static unsigned int is_master = 1;/*master:1, slave:0*/
-unsigned int wmt_i2c0_is_master = 1;
-unsigned int wmt_i2c0_speed_mode = 0;
-static unsigned int wmt_i2c0_power_state = 0;/*0:power on, 1:suspend, 2:shutdown*/
-EXPORT_SYMBOL(wmt_i2c0_is_master);
-
-/**/
-/* variable*/
-/*-------------------------------------------------*/
-static volatile struct wmt_i2c_s i2c ;
-
-DECLARE_WAIT_QUEUE_HEAD(i2c1_wait);
-/*
-spinlock_t i2c1_wmt_irqlock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c1_wmt_irqlock);
-static struct list_head wmt_i2c_fifohead;
-/*
-static spinlock_t i2c_fifolock = SPIN_LOCK_UNLOCKED;
-*/
-static DEFINE_SPINLOCK(i2c_fifolock);
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-);
-
-static void i2c_wmt_set_mode(enum i2c_mode_e mode /*!<; //[IN] mode */)
-{
- if (is_master == 0)
- return;
- i2c.i2c_mode = mode ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- DPRINTK("I2C: set standard mode \n");
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- DPRINTK("I2C: set fast mode \n");
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
- }
-}
-
-
-static int i2c_send_request(
- struct i2c_msg *msg,
- int msg_num,
- int non_block,
- void (*callback)(void *data),
- void *data
-)
-{
- struct wmt_i2cbusfifo *i2c_fifo_head;
- struct i2c_msg *pmsg = NULL;
- int ret = 0;
- int restart = 0;
- int last = 0;
- unsigned long flags;
- int slave_addr = msg[0].addr;
-
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
- if (wmt_i2c0_power_state == 2) {
- printk("I2C0 has been shutdown\n");
- return -EIO;
- }
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c_fifo_head = kzalloc(sizeof(struct wmt_i2cbusfifo), GFP_ATOMIC);
- INIT_LIST_HEAD(&i2c_fifo_head->busfifohead);
-
- pmsg = &msg[0];
- i2c_fifo_head->msg = pmsg;
- i2c_fifo_head->msg_num = msg_num;
-
- spin_lock_irqsave(&i2c_fifolock, flags);
- if (list_empty(&wmt_i2c_fifohead)) {
- i2c_wmt_wait_bus_not_busy();
- pmsg = &msg[0];
- i2c_fifo_head->xfer_length = 1;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
-
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
-
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- if (pmsg->flags & I2C_M_RD) {
- i2c_fifo_head->xfer_length = 1;
- ret = i2c_wmt_read_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- } else {
- i2c_fifo_head->xfer_length = 1;
- if (pmsg->flags & I2C_M_NOSTART)
- i2c_fifo_head->restart = 1;
- else
- i2c_fifo_head->restart = 0;
- ret = i2c_wmt_write_buf(pmsg->addr, pmsg->buf, pmsg->len, restart, last);
- }
-
- } else {
- i2c_fifo_head->xfer_length = 0;
- i2c_fifo_head->xfer_msgnum = 0;
- i2c_fifo_head->restart = 0;
- i2c_fifo_head->non_block = non_block;
- if (non_block == 1) {
- i2c_fifo_head->callback = callback;
- i2c_fifo_head->data = data;
- } else {
- i2c_fifo_head->callback = 0;
- i2c_fifo_head->data = 0;
- }
- list_add_tail(&i2c_fifo_head->busfifohead, &wmt_i2c_fifohead);
- }
- spin_unlock_irqrestore(&i2c_fifolock, flags);
- if (non_block == 0) {
- wait_event(i2c1_wait, i2c.isr_int_pending);
- ret = msg_num;
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- ret = -ETIMEDOUT ;
- }
-
- }
-
- return ret;
-
-
-}
-static int i2c_wmt_read_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value;
- int ret = 0;
-
- DPRINTK("[%s]:length = %d , slave_addr = %x\n", __func__, length , slave_addr);
-
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (length <=0)
- return -1;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- tcr_value = 0 ;
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
- return ret;
-}
-
-static int i2c_wmt_write_buf(
- unsigned int slave_addr,
- char *buf,
- unsigned int length,
- int restart,
- int last
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int ret = 0 ;
-
- DPRINTK("[%s]length = %d , slave_addr = %x\n", __func__, length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
-
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- ret = 0 ;
- return ret;
-
-}
-static int i2c_wmt_read_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete read */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result = 0 ;
-
- if (is_master == 0)
- return -ENXIO;
- if (length <= 0)
- return -1 ;
- xfer_length = 0 ;
-
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- ret = 0 ;
- for (; ;) {
- is_timeout = 0 ;
- wait_event_result = wait_event_interruptible_timeout(i2c1_wait, i2c.isr_int_pending ,
- (MAX_RX_TIMEOUT * HZ / 1000)) ;
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (rx) \n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (rx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (rx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (rx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err: write software timeout error (rx) \n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- buf[xfer_length] = (i2c.regs->cdr_reg >> 8) ;
- ++xfer_length ;
- DPRINTK("i2c_test: received BYTE_END\n\r");
- }
- i2c.isr_int_pending = 0;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
- if (length > xfer_length) {
- if ((length - 1) == xfer_length) { /* next read is the last one*/
- i2c.regs->cr_reg |= (I2C_CR_TX_NEXT_NO_ACK | I2C_CR_CPU_RDY);
- DPRINTK("i2c_test: set CPU_RDY & TX_ACK. next data is last.\r\n");
- } else {
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- DPRINTK("i2c_test: more data to read. only set CPU_RDY. \r\n");
- }
- } else if (length == xfer_length) { /* end rx xfer*/
- if (last == 1) { /* stop case*/
- DPRINTK("i2c_test: read completed \r\n");
- break ;
- } else { /* restart case*/
- /* ??? how to handle the restart after read ?*/
- DPRINTK("i2c_test: RX ReStart Case \r\n") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : read known error\n\r") ;
- ret = -EIO ;
- break ;
- }
- }
-
- DPRINTK("i2c_test: read sequence completed\n\r");
- return ret ;
-}
-
-static int i2c_wmt_write_msg(
- unsigned int slave_addr, /*!<; //[IN] Salve address */
- char *buf, /*!<; //[OUT] Pointer to data */
- unsigned int length, /*!<; //Data length */
- int restart, /*!<; //Need to restart after a complete write */
- int last /*!<; //Last read */
-)
-{
- unsigned short tcr_value ;
- unsigned int xfer_length ;
- int is_timeout ;
- int ret = 0 ;
- int wait_event_result ;
-
- DPRINTK("length = %d , slave_addr = %x\n", length , slave_addr);
- if (slave_addr == WMT_I2C_API_I2C_ADDR)
- return ret ;
-
- if (is_master == 0)
- return -ENXIO;
-
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length < 0)
- return -1 ;
- xfer_length = 0 ; /* for array index and also for checking counting*/
- if (restart == 0)
- ret = i2c_wmt_wait_bus_not_busy() ;
- if (ret < 0)
- return ret ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
-
- ret = 0 ;
- for (; ;) {
-
- is_timeout = 0 ;
- /**/
- /* I2C: Wait for interrupt. if ( i2c.isr_int_pending == 1 ) ==> an interrupt exsits.*/
- /**/
- wait_event_result = wait_event_interruptible_timeout(i2c1_wait, i2c.isr_int_pending , (MAX_TX_TIMEOUT * HZ / 1000)) ;
-
- if (likely(wait_event_result > 0)) {
- DPRINTK("I2C: wait interrupted (tx)\n");
- ret = 0 ;
- } else if (likely(i2c.isr_int_pending == 0)) {
- DPRINTK("I2C: wait timeout (tx) \n");
- is_timeout = 1 ;
- ret = -ETIMEDOUT ;
- }
-
- /**/
- /* fail case*/
- /**/
- if (i2c.isr_nack == 1) {
- DPRINTK("i2c_err : write NACK error (tx) \n\r") ;
- ret = -EIO ;
- break ;
- }
- if (i2c.isr_timeout == 1) {
- DPRINTK("i2c_err : write SCL timeout error (tx)\n\r") ;
- msleep(10);
- ret = -ETIMEDOUT ;
- break ;
- }
- if (is_timeout == 1) {
- DPRINTK("i2c_err : write software timeout error (tx)\n\r") ;
- ret = -ETIMEDOUT ;
- break ;
- }
-
- /**/
- /* pass case*/
- /**/
- if (i2c.isr_byte_end == 1) {
- DPRINTK("i2c: isr end byte (tx)\n\r") ;
- ++xfer_length ;
- }
- i2c.isr_int_pending = 0 ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
-
-
- if ((i2c.regs->csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK) {
- DPRINTK("i2c_err : write RCV NACK error\n\r") ;
- ret = -EIO ;
- break ;
- }
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0) {
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- break ;
- }
- if (length > xfer_length) {
- i2c.regs->cdr_reg = (unsigned short) (buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
- i2c.regs->cr_reg = (I2C_CR_CPU_RDY | I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: write register data \n\r") ;
- } else if (length == xfer_length) { /* end tx xfer*/
- if (last == 1) { /* stop case*/
- i2c.regs->cr_reg = (I2C_CR_TX_END|I2C_CR_CPU_RDY|I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: finish write \n\r") ;
- break ;
- } else { /* restart case*/
- /* handle the restart for first write then the next is read*/
- i2c.regs->cr_reg = (I2C_CR_ENABLE) ;
- DPRINTK("i2c_test: tx restart Case \n\r") ;
- break ;
- }
- } else {
- DPRINTK("i2c_err : write unknown error\n\r") ;
- ret = -EIO ;
- break ;
- }
- } ;
-
- DPRINTK("i2c_test: write sequence completed\n\r");
-
- return ret ;
-}
-
-static int i2c_wmt_wait_bus_not_busy(void)
-{
- int ret ;
- int cnt ;
-
- ret = 0 ;
- cnt = 0 ;
- while (1) {
- if ((REG16_VAL(I2C_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY) {
- ret = 0;
- break ;
- }
- cnt++ ;
-
- if (cnt > MAX_BUS_READY_CNT) {
- ret = (-EBUSY) ;
- printk("i2c_err 0: wait but not ready time-out\n\r") ;
- cnt = 0;
- break; //add by rambo d10 always has it 2013-4-14
- }
- }
- return ret ;
-}
-
-static void i2c_wmt_reset(void)
-{
- unsigned short tmp ;
- if (is_master == 0)
- return;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C0_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C0 ;
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else
- i2c.i2c_mode = I2C_FAST_MODE ;
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
-
- /**/
- /* hardware initial*/
- /**/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = I2C_TR_STD_VALUE ; /* 0x8041*/
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- i2c.regs->tr_reg = I2C_TR_FAST_VALUE ; /* 0x8011*/
-
- DPRINTK("Resetting I2C Controller Unit\n");
-
- return ;
-}
-static int wmt_i2c_transfer_msg(struct wmt_i2cbusfifo *fifo_head)
-{
- int xfer_length = fifo_head->xfer_length;
- int xfer_msgnum = fifo_head->xfer_msgnum;
- struct i2c_msg *pmsg = &fifo_head->msg[xfer_msgnum];
- int restart = fifo_head->restart;
- unsigned short tcr_value;
- unsigned short slave_addr = pmsg->addr;
- int length = pmsg->len;
- int ret = 0;
-
- if (pmsg->flags & I2C_M_RD) {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg &= ~(I2C_CR_TX_NEXT_NO_ACK); /*clear NEXT_NO_ACK*/
- if (restart == 0)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
-
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- } else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_READ |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- }
- if (length == 1)
- i2c.regs->cr_reg |= I2C_CR_TX_NEXT_NO_ACK; /*only 8-bit to read*/
-
- i2c.regs->tcr_reg = tcr_value ;
-
- /*repeat start case*/
- if (restart == 1)
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- } else {
- if (restart == 0)
- i2c_wmt_wait_bus_not_busy();
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- /*i2c.isr_int_pending = 0;*/
-
- /**/
- /* special case allow length:0, for i2c_smbus_xfer*/
- /**/
- if (length == 0)
- i2c.regs->cdr_reg = 0 ;
- else
- i2c.regs->cdr_reg = (unsigned short)(pmsg->buf[xfer_length] & I2C_CDR_DATA_WRITE_MASK) ;
-
- if (restart == 0) {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END); /*clear Tx end*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY); /*release SCL*/
- }
-
- /**/
- /* I2C: Set transfer mode [standard/fast]*/
- /**/
- tcr_value = 0 ;
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- tcr_value = (unsigned short)(I2C_TCR_STANDARD_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
- else if (i2c.i2c_mode == I2C_FAST_MODE)
- tcr_value = (unsigned short)(I2C_TCR_FAST_MODE|I2C_TCR_MASTER_WRITE |\
- (slave_addr & I2C_TCR_SLAVE_ADDR_MASK)) ;
-
- i2c.regs->tcr_reg = tcr_value ;
-
- if (restart == 1)
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY ;
- }
- return ret;
-}
-
-static irqreturn_t i2c_wmt_handler(
- int this_irq, /*!<; //[IN] IRQ number */
- void *dev_id /*!<; //[IN] Pointer to device ID */
-)
-{
- int wakeup ;
- unsigned short isr_status ;
- unsigned short tmp ;
- unsigned long flags;
- struct wmt_i2cbusfifo *fifo_head;
- int xfer_length = 0;
- int xfer_msgnum = 0;
- struct i2c_msg *pmsg;
- volatile unsigned short csr_reg;
-
- spin_lock_irqsave(&i2c1_wmt_irqlock, flags);
- isr_status = i2c.regs->isr_reg ;
- csr_reg = i2c.regs->csr_reg;
- wakeup = 0 ;
- fifo_head = list_first_entry(&wmt_i2c_fifohead, struct wmt_i2cbusfifo, busfifohead);
-
- if (isr_status & I2C_ISR_NACK_ADDR) {
- DPRINTK("[%s]:i2c NACK\n", __func__);
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_NACK_ADDR_WRITE_CLEAR ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- }
-
- if ((isr_status & I2C_ISR_BYTE_END && ((csr_reg & I2C_CSR_RCV_ACK_MASK) == I2C_CSR_RCV_NOT_ACK))) {
- /*
- printk("data rcv nack\n");
- */
- list_del(&fifo_head->busfifohead);/*del request*/
- kfree(fifo_head);
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_nack = 1 ;
- wakeup = 1 ;
- } else if (isr_status & I2C_ISR_BYTE_END) {
- i2c.regs->isr_reg = I2C_ISR_BYTE_END_WRITE_CLEAR ;
- i2c.isr_byte_end = 1 ;
- xfer_length = fifo_head->xfer_length;
- xfer_msgnum = fifo_head->xfer_msgnum;
- pmsg = &fifo_head->msg[xfer_msgnum];
-
- /*read case*/
- if (pmsg->flags & I2C_M_RD) {
- pmsg->buf[xfer_length - 1] = (i2c.regs->cdr_reg >> 8) ;
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len - 1) {
- /*last msg of the current request?*/
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- /*
- ++fifo_head->xfer_msgnum;
- */
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_TX_NEXT_NO_ACK);
- }
- /*spin_unlock(&i2c_fifolock);*/
- } else if (xfer_length == pmsg->len) {/*next msg*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else { /*data of this msg has been transfered*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*next request exist?*/
- if (list_empty(&wmt_i2c_fifohead)) {/*no more reqeust*/
- /*kfree(fifo_head);*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- } else { /*more request*/
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- fifo_head->xfer_length = 0;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
-
- /*
- if (fifo_head->non_block == 0) {
- printk("2 : non callback\n");
- wakeup = 1;
- } else {
- printk("2 :callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= I2C_CR_CPU_RDY;
- }
-
- } else { /*write case*/
- /*the last data in current msg?*/
- if (xfer_length == pmsg->len) {
- /*last msg of the current request?*/
- if (xfer_msgnum < fifo_head->msg_num - 1) {
- /*spin_lock(&i2c_fifolock);*/
- if (pmsg->flags & I2C_M_NOSTART) {
- ++fifo_head->xfer_length;
- fifo_head->restart = 1;
- } else {
- ++fifo_head->xfer_length;
- fifo_head->restart = 0;
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- }
- /*access next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
-
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- } else {/*this request finish*/
- /*spin_lock(&i2c_fifolock);*/
- /*next request exist?*/
- list_del(&fifo_head->busfifohead);/*del request*/
- if (list_empty(&wmt_i2c_fifohead)) {
- /*kfree(fifo_head);*/
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
-
- } else {
- i2c.regs->cr_reg &= ~(I2C_CR_TX_END);
- udelay(2);
- i2c.regs->cr_reg |= (I2C_CR_TX_END);
- if (fifo_head->non_block == 0) {
- wakeup = 1;
- } else {
- fifo_head->callback(fifo_head->data);
- }
- kfree(fifo_head);
- fifo_head = list_first_entry(&wmt_i2c_fifohead,
- struct wmt_i2cbusfifo, busfifohead);
- /*
- if (fifo_head->non_block == 0)
- wakeup = 1;
- */
-
- /*next msg*/
- fifo_head->xfer_length = 0;
- ++fifo_head->xfer_msgnum;
- wmt_i2c_transfer_msg(fifo_head);
- ++fifo_head->xfer_length;
- /*
- if (fifo_head->non_block == 0) {
- printk("4:non callback\n");
- wakeup = 1;
- } else {
- printk("4:callback\n");
- fifo_head->callback(fifo_head->data);
- }
- */
- }
- /*spin_unlock(&i2c_fifolock);*/
- }
- } else {/*next data*/
- i2c.regs->cdr_reg = (unsigned short) (pmsg->buf[fifo_head->xfer_length] & I2C_CDR_DATA_WRITE_MASK);
- /*spin_lock(&i2c_fifolock);*/
- ++fifo_head->xfer_length;
- /*spin_unlock(&i2c_fifolock);*/
- i2c.regs->cr_reg |= (I2C_CR_CPU_RDY | I2C_CR_ENABLE);
- }
- }
- }
-
- if (isr_status & I2C_ISR_SCL_TIME_OUT) {
- DPRINTK("[%s]SCL timeout\n", __func__);
-#if 0
- i2c.regs->cr_reg |= BIT7;/*reset status*/
- /*spin_lock(&i2c_fifolock);*/
- list_del(&fifo_head->busfifohead);/*del request*/
- /*spin_unlock(&i2c_fifolock);*/
- xfer_length = 0;
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR | I2C_ISR_BYTE_END_WRITE_CLEAR;
- i2c.isr_timeout = 1 ;
- wakeup = 1;
-#endif
- i2c.regs->isr_reg = I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR ;
- }
-
-
- if (wakeup) {
- /*spin_lock_irqsave(&i2c_wmt_irqlock, flags);*/
- i2c.isr_int_pending = 1;
- /*spin_unlock_irqrestore(&i2c_wmt_irqlock, flags);*/
- wake_up(&i2c1_wait);
- } else
- DPRINTK("i2c_err : unknown I2C ISR Handle 0x%4.4X" , isr_status) ;
- spin_unlock_irqrestore(&i2c1_wmt_irqlock, flags);
- return IRQ_HANDLED;
-}
-
-static int i2c_wmt_resource_init(void)
-{
- if (is_master == 0)
- return 0;
- if (request_irq(i2c.irq_no , &i2c_wmt_handler, IRQF_DISABLED, "i2c", 0) < 0) {
- DPRINTK(KERN_INFO "I2C: Failed to register I2C irq %i\n", i2c.irq_no);
- return -ENODEV;
- }
- return 0;
-}
-
-static void i2c_wmt_resource_release(void)
-{
- if (is_master == 0)
- return;
- free_irq(i2c.irq_no, 0);
-}
-
-static struct i2c_algo_wmt_data i2c_wmt_data = {
- write_msg: i2c_wmt_write_msg,
- read_msg: i2c_wmt_read_msg,
- send_request: i2c_send_request,
- wait_bus_not_busy: i2c_wmt_wait_bus_not_busy,
- reset: i2c_wmt_reset,
- set_mode: i2c_wmt_set_mode,
- udelay: I2C_ALGO_UDELAY,
- timeout: I2C_ALGO_TIMEOUT,
-};
-
-static struct i2c_adapter i2c_wmt_ops = {
- .owner = THIS_MODULE,
- /*
- .id = I2C_ALGO_WMT,
- */
- .algo_data = &i2c_wmt_data,
- .name = "wmt_i2c_adapter",
- .retries = I2C_ADAPTER_RETRIES,
- .nr = 0,
-};
-
-#ifdef CONFIG_PM
-static struct i2c_regs_s wmt_i2c_reg ;
-static void i2c_shutdown(void)
-{
- printk("i2c0 shutdown\n");
- wmt_i2c0_power_state = 2;
- while (!list_empty(&wmt_i2c_fifohead))
- msleep(1);
- while (1) {/*wait busy clear*/
- if ((REG16_VAL(I2C_CSR_ADDR) & I2C_STATUS_MASK) == I2C_READY)
- break ;
- msleep(1);
- }
- return;
-}
-static int i2c_suspend(void)
-{
- printk("i2c0 suspend\n");
- wmt_i2c_reg.imr_reg = i2c.regs->imr_reg;
- wmt_i2c_reg.tr_reg = i2c.regs->tr_reg;
- wmt_i2c_reg.div_reg = i2c.regs->div_reg;
- return 0;
-}
-static void i2c_resume(void)
-{
- printk("i2c0 resume\n");
- GPIO_CTRL_GP17_I2C_BYTE_VAL &= ~(BIT0 | BIT1);
- PULL_EN_GP17_I2C_BYTE_VAL |= (BIT0 | BIT1);
- PULL_CTRL_GP17_I2C_BYTE_VAL |= (BIT0 | BIT1);
- auto_pll_divisor(DEV_I2C0, CLK_ENABLE, 0, 0);
- auto_pll_divisor(DEV_I2C0, SET_DIV, 2, 20);/*20M Hz*/
-
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = wmt_i2c_reg.div_reg;
- i2c.regs->imr_reg = wmt_i2c_reg.imr_reg;
- i2c.regs->tr_reg = wmt_i2c_reg.tr_reg ;
- i2c.regs->cr_reg = 0x001 ;
-}
-#else
-#define i2c_suspend NULL
-#define i2c_resume NULL
-#define i2c_shutdown NULL
-#endif
-extern int wmt_i2c_add_bus(struct i2c_adapter *);
-extern int wmt_i2c_del_bus(struct i2c_adapter *);
-
-#ifdef CONFIG_PM
-static struct syscore_ops wmt_i2c_syscore_ops =
-{
- .suspend = i2c_suspend,
- .resume = i2c_resume,
- .shutdown = i2c_shutdown,
-};
-#endif
-
-static int __init i2c_adap_wmt_init(void)
-{
- unsigned short tmp ;
- char varname[] = "wmt.i2c.param";
-#ifdef CONFIG_I2C_SLAVE_WMT
- char varname1[] = "wmt.bus.i2c.slave_port";
-#endif
- unsigned char buf[80];
- int ret;
- unsigned int port_num;
- int idx = 0;
- int varlen = 80;
- unsigned int pllb_freq = 0;
- unsigned int tr_val = 0;
-
-#ifdef CONFIG_I2C_SLAVE_WMT
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname1, buf, &varlen);
-#else
- ret = 1;
-#endif
- is_master = 1;
- if (ret == 0) {
- ret = sscanf(buf, "%x", &port_num);
- while (ret) {
- if (port_num != 0)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret;
- ret = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
-#endif
- wmt_i2c0_is_master = is_master;
- if (is_master == 1) {
-#ifdef USE_UBOOT_PARA
- ret = wmt_getsyspara(varname, buf, &varlen);
-#else
- ret = 1;
-#endif
-
- if (ret == 0) {
- ret = sscanf(buf, "%x:%x", &port_num, &speed_mode);
- idx += 3;
- while (ret) {
- if (ret < 2)
- speed_mode = 0;
- else {
- if (port_num != 0)
- speed_mode = 0;
- else
- break;
- }
- ret = sscanf(buf + idx, ",%x:%x", &port_num, &speed_mode);
- idx += 4;
- }
- }
- if (speed_mode > 1)
- speed_mode = 0;
- wmt_i2c0_speed_mode = speed_mode;
-
- /**/
- /* software initial*/
- /**/
- i2c.regs = (struct i2c_regs_s *)I2C0_BASE_ADDR ;
- i2c.irq_no = IRQ_I2C0 ;
-
- printk("PORT 0 speed_mode = %d\n", speed_mode);
- if (speed_mode == 0)
- i2c.i2c_mode = I2C_STANDARD_MODE ;
- else if (speed_mode == 1)
- i2c.i2c_mode = I2C_FAST_MODE ;
-
- i2c.isr_nack = 0 ;
- i2c.isr_byte_end = 0 ;
- i2c.isr_timeout = 0 ;
- i2c.isr_int_pending = 0;
- /**/
- /* hardware initial*/
- /**/
- auto_pll_divisor(DEV_I2C0, CLK_ENABLE, 0, 0);
- pllb_freq = auto_pll_divisor(DEV_I2C0, SET_DIV, 2, 20);/*20M Hz*/
- if ((pllb_freq%(1000*2*100)) != 0)
- tr_val = pllb_freq/(1000*2*100) + 1;
- else
- tr_val = pllb_freq/(1000*2*100);
- *(volatile unsigned char *)CTRL_GPIO &= ~(BIT0 | BIT1);
- *(volatile unsigned char *)PU_EN_GPIO |= (BIT0 | BIT1);
- *(volatile unsigned char *)PU_CTRL_GPIO |= (BIT0 | BIT1);
- i2c.regs->cr_reg = 0 ;
- i2c.regs->div_reg = APB_96M_I2C_DIV ;
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
- i2c.regs->imr_reg = I2C_IMR_ALL_ENABLE ; /* 0x0007*/
-
- i2c.regs->cr_reg = I2C_CR_ENABLE ;
- tmp = i2c.regs->csr_reg ; /* read clear*/
- i2c.regs->isr_reg = I2C_ISR_ALL_WRITE_CLEAR ; /* 0x0007*/
-
- if (i2c.i2c_mode == I2C_STANDARD_MODE)
- i2c.regs->tr_reg = 0xff00|tr_val;
- else if (i2c.i2c_mode == I2C_FAST_MODE) {
- tr_val /= 4;
- i2c.regs->tr_reg = 0xff00|tr_val ;
- }
- }
-
-
- if (i2c_wmt_resource_init() == 0) {
- if (wmt_i2c_add_bus(&i2c_wmt_ops) < 0) {
- i2c_wmt_resource_release();
- printk(KERN_INFO "i2c: Failed to add bus\n");
- return -ENODEV;
- }
- } else
- return -ENODEV;
-
- INIT_LIST_HEAD(&wmt_i2c_fifohead);
-
-#ifdef CONFIG_PM
- printk("register i2c0 syscore ops\n");
- register_syscore_ops(&wmt_i2c_syscore_ops);
-#endif
- wmt_i2c0_power_state = 0;
- printk(KERN_INFO "i2c: successfully added bus\n");
-
-#ifdef I2C_REG_TEST
- printk("i2c.regs->cr_reg= 0x%08x\n\r", i2c.regs->cr_reg);
- printk("i2c.regs->tcr_reg= 0x%08x\n\r", i2c.regs->tcr_reg);
- printk("i2c.regs->csr_reg= 0x%08x\n\r", i2c.regs->csr_reg);
- printk("i2c.regs->isr_reg= 0x%08x\n\r", i2c.regs->isr_reg);
- printk("i2c.regs->imr_reg= 0x%08x\n\r", i2c.regs->imr_reg);
- printk("i2c.regs->cdr_reg= 0x%08x\n\r", i2c.regs->cdr_reg);
- printk("i2c.regs->tr_reg= 0x%08x\n\r", i2c.regs->tr_reg);
- printk("i2c.regs->div_reg= 0x%08x\n\r", i2c.regs->div_reg);
-#endif
-
- return 0;
-}
-subsys_initcall(i2c_adap_wmt_init);
-
-static void i2c_adap_wmt_exit(void)
-{
- wmt_i2c_del_bus(&i2c_wmt_ops);
- i2c_wmt_resource_release();
-
- printk(KERN_INFO "i2c: successfully removed bus\n");
-}
-
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT I2C Adapter Driver");
-MODULE_LICENSE("GPL");
-
-module_exit(i2c_adap_wmt_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus-1.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus-1.c
deleted file mode 100755
index 90b49ea8..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus-1.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*++
- drivers/i2c/busses/wmt-i2c-slave-bus-1.c
-
- Copyright (c) 2008 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
-
- History:
- 2010/03/15 First Version
---*/
-
-#include <linux/config.h>
-#define WMT_I2C1_SLAVE_C
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/errno.h>
-#include <asm/uaccess.h>
-#include <linux/kdev_t.h>
-#include <linux/cdev.h>
-#include <asm/semaphore.h>
-#include <linux/proc_fs.h>
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include "./wmt-i2c-slave-bus.h"
-/*#define DEBUG*/
-#ifdef DEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
-
-#define DEVICE_NAME "WMT_I2C_SLAVE-1"
-#define PMC_ClOCK_ENABLE_LOWER 0xd8130250
-#define CTRL_GPIO21 0xD8110055
-#define PU_EN_GPIO21 0xD8110495
-#define PU_CTRL_GPIO21 0xD81104D5
-
-#define DISABLE_I2C_SLAVE BIT15
-
-struct i2c_slave_msg {
- __u16 addr; /* slave address */
- __u16 flags;
-#define I2C_M_RD 0x01
- __u16 len; /* data length */
- __u8 *buf; /* pointer to data */
-};
-
-struct slave_i2c_dev_s {
- /* module parameters */
- char *buf;
-
- /* char dev struct */
- struct cdev cdev;
- struct class *class_slave_i2c;
-};
-
-
-struct wmt_slave_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int isr_nack ;
- int isr_byte_end ;
- int isr_timeout ;
- int isr_int_pending ;
- struct compat_semaphore tx_sem;
- struct compat_semaphore rx_sem;
-};
-
-static struct i2c_regs_s regs_backup;
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int is_master = 1;/*master:1, slave:0*/
-
-static DEFINE_SPINLOCK(slave_i2c_lock);
-
-static int slave_i2c_dev_major = SLAVE_I2C_MAJOR;
-static int slave_i2c_dev_minor = 1;
-static int slave_i2c_dev_nr = 1;
-static struct slave_i2c_dev_s slave_i2c_dev;
-
-static struct wmt_slave_i2c_s slave_i2c_port;
-
-static unsigned char slave_i2c_addr = 0x31;
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *slave_i2c_proc;
-
-static int slave_i2c_reg_read(char *buf, char **start, off_t offset, int len)
-{
- char *p = buf;
- p += sprintf(p, "reg : value\n");
- p += sprintf(p, "cr : 0x%.4x\n", slave_i2c_port.regs->cr_reg);
- p += sprintf(p, "tcr : 0x%.4x\n", slave_i2c_port.regs->tcr_reg);
- p += sprintf(p, "csr : 0x%.4x\n", slave_i2c_port.regs->csr_reg);
- p += sprintf(p, "isr : 0x%.4x\n", slave_i2c_port.regs->isr_reg);
- p += sprintf(p, "imr : 0x%.4x\n", slave_i2c_port.regs->imr_reg);
- p += sprintf(p, "cdr : 0x%.4x\n", slave_i2c_port.regs->cdr_reg);
- p += sprintf(p, "tr : 0x%.4x\n", slave_i2c_port.regs->tr_reg);
- p += sprintf(p, "scr : 0x%.4x\n", slave_i2c_port.regs->scr_reg);
- p += sprintf(p, "cssr : 0x%.4x\n", slave_i2c_port.regs->cssr_reg);
- p += sprintf(p, "simr : 0x%.4x\n", slave_i2c_port.regs->simr_reg);
- p += sprintf(p, "sisr : 0x%.4x\n", slave_i2c_port.regs->sisr_reg);
- p += sprintf(p, "csdr : 0x%.4x\n", slave_i2c_port.regs->csdr_reg);
- p += sprintf(p, "str : 0x%.4x\n", slave_i2c_port.regs->str_reg);
- return p - buf;
-}
-
-static int slave_i2c_addr_read(char *buf, char **start, off_t offset, int len)
-{
- char *p = buf;
- p += sprintf(p, "i2c-slave address : 0x%.2x\n", slave_i2c_addr);
- return p - buf;
-}
-
-#endif
-
-static irqreturn_t slave_i2c_isr(
- int irq, /*!<; // IRQ number */
- void *dev, /*!<; // Private paramater(i.e. pointer of spi port) */
- struct pt_regs *regs /*!<; // interrupt register */
-)
-{
- unsigned short isr_status = slave_i2c_port.regs->sisr_reg;
- unsigned short ssr_status = slave_i2c_port.regs->cssr_reg;
- DPRINTK("slave_i2c isr sisr = %x\n", isr_status);
- DPRINTK("slave_i2c isr cssr = %x\n", ssr_status);
- if (isr_status & I2C_SISR_DAT_REQ) {
- slave_i2c_port.regs->sisr_reg |= I2C_SISR_DAT_REQ_WRITE_CLEAR;
- slave_i2c_port.isr_nack = ssr_status & I2C_SRCV_NACK_MASK;
- compat_up(&slave_i2c_port.tx_sem);
- } else if (isr_status & I2C_SISR_BYTE_END) {
- slave_i2c_port.regs->sisr_reg |= I2C_SISR_BYTE_END_WRITE_CLEAR;
- slave_i2c_port.isr_byte_end = 1;
- slave_i2c_port.isr_nack = ssr_status & I2C_SRCV_NACK_MASK;
- compat_up(&slave_i2c_port.rx_sem);
- } else if (isr_status & I2C_SISR_SCL_TIME_OUT) {
- slave_i2c_port.regs->sisr_reg |= I2C_SISR_SCL_TIME_OUT_WRITE_CLEAR;
- slave_i2c_port.isr_timeout = 1 ;
- }
- return IRQ_HANDLED;
-}
-
-static int wmt_slave_i2c_read_data(unsigned short addr , unsigned char *buf, int size, int flags)
-{
- int ret = 0;
- int xfer_len = 0;
- int sleep_count = 1;
- DPRINTK("ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
- while (xfer_len < size) {
- compat_down_interruptible(&slave_i2c_port.rx_sem);
- buf[xfer_len] = ((slave_i2c_port.regs->csdr_reg & I2C_SLAVE_READ_DATA_MASK) >> I2C_SLAVE_READ_DATA_SHIFT);
- DPRINTK("data = %x\n", buf[xfer_len]);
- xfer_len++;
- }
- ret = xfer_len;
- while (slave_i2c_port.regs->cssr_reg & I2C_SLAVE_ACTIVE) {
- if (compat_sema_count(&slave_i2c_port.rx_sem) > 0) {/*receive data was longer than request*/
- ret = -1;
- break;
- }
- msleep(sleep_count);
- if (sleep_count < 16)
- sleep_count *= 2;
- }
- DPRINTK("ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
-
- return ret;
-}
-
-static int wmt_slave_i2c_write_data(unsigned short addr, unsigned char *buf, int size, int flags)
-{
- int ret = 0;
- int xfer_len = 0;
- int sleep_count = 1;
- DPRINTK("tx ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
- while (xfer_len < size) {
- compat_down_interruptible(&slave_i2c_port.tx_sem);
- slave_i2c_port.regs->csdr_reg = buf[xfer_len];
- DPRINTK("data = %x\n", buf[xfer_len]);
- ++xfer_len;
- }
- ret = xfer_len;
- while (slave_i2c_port.regs->cssr_reg & I2C_SLAVE_ACTIVE) {
- msleep(sleep_count);
- if (sleep_count < 16)
- sleep_count *= 2;
- }
- DPRINTK("2.tx ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
- return ret;
-}
-
-static int slave_i2c_do_xfer(unsigned short addr, unsigned char *buf, int size, int flags)
-{
- int ret;
- if (flags & I2C_M_RD)
- ret = wmt_slave_i2c_read_data(addr , buf, size, flags);
- else
- ret = wmt_slave_i2c_write_data(addr , buf, size, flags);
- return ret;
-}
-
-int wmt_i2cslave_transfer1(struct i2c_slave_msg slave_msg)
-{
- int flags = slave_msg.flags;
- unsigned char *buf = slave_msg.buf;
- unsigned short addr = slave_msg.addr;
- int size = slave_msg.len;
- int xfer_len;
- if (is_master == 1)
- return 0;
- spin_lock(&slave_i2c_lock);
- xfer_len = slave_i2c_do_xfer(addr, buf, size, flags);
- spin_unlock(&slave_i2c_lock);
- return xfer_len;
-}
-EXPORT_SYMBOL(wmt_i2cslave_transfer1);
-
-void wmt_i2cslave_setaddr1(struct i2c_slave_msg msg)
-{
- if (is_master == 1)
- return;
- spin_lock(&slave_i2c_lock);
-
- slave_i2c_addr = msg.addr;
-
- if (msg.addr & DISABLE_I2C_SLAVE)
- slave_i2c_port.regs->cr_reg &= ~I2C_CR_ENABLE;
- else {
- slave_i2c_port.regs->cr_reg = 0;
- slave_i2c_port.regs->scr_reg = 0;
- slave_i2c_port.regs->cr_reg = (I2C_SLAV_MODE_SEL|I2C_CR_ENABLE);
- slave_i2c_port.regs->sisr_reg = I2C_SISR_ALL_WRITE_CLEAR;
-
- if (slave_i2c_port.i2c_mode == I2C_STANDARD_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else if (slave_i2c_port.i2c_mode == I2C_FAST_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else
- slave_i2c_port.regs->scr_reg = (slave_i2c_addr|I2C_SLAVE_HS_MODE);
-
- slave_i2c_port.regs->simr_reg = I2C_SIMR_ALL_ENABLE;
- }
- spin_unlock(&slave_i2c_lock);
-}
-EXPORT_SYMBOL(wmt_i2cslave_setaddr1);
-
-static ssize_t slave_i2c_read(
- struct file *filp,
- char __user *buf,
- size_t count,
- loff_t *f_pos
-)
-{
- int ret = 0;
- struct i2c_slave_msg slave_msg;
- if (is_master == 1)
- return ret;
- slave_msg.buf = (char *)kmalloc(count * sizeof(unsigned char), GFP_KERNEL);
- slave_msg.flags = 0;
- slave_msg.flags |= I2C_M_RD;
- slave_msg.len = count;
- slave_msg.addr = slave_i2c_addr;
- ret = wmt_i2cslave_transfer1(slave_msg);
- if (copy_to_user(buf, slave_msg.buf, count)) {
- kfree(slave_msg.buf);
- return -EFAULT;
- }
- return ret;
-}
-
-static ssize_t slave_i2c_write(
- struct file *filp,
- const char __user *buf,
- size_t count,
- loff_t *f_pos
-)
-{
- int ret = 0;
- struct i2c_slave_msg slave_msg;
- if (is_master == 1)
- return ret;
- slave_msg.buf = (char *)kmalloc(count * sizeof(unsigned char), GFP_KERNEL);
- slave_msg.flags = 0;
- slave_msg.flags &= ~I2C_M_RD;
- slave_msg.len = count;
- slave_msg.addr = slave_i2c_addr;
- if (copy_from_user(slave_msg.buf, buf, count)) {
- kfree(slave_msg.buf);
- return -EFAULT;
- }
- ret = wmt_i2cslave_transfer1(slave_msg);
- return ret; /* return Write out data size*/
-}
-
-static int slave_i2c_open(
- struct inode *inode,
- struct file *filp
-)
-{
- struct slave_i2c_dev_s *dev;
- char name[40];
- int minor_no;
-
- dev = container_of(inode->i_cdev, struct slave_i2c_dev_s, cdev);
- filp->private_data = dev;
- minor_no = iminor(inode); /* get */
-
- /* Create user name*/
- memset(name, 0x0, 8);
- sprintf(name, "slave-i2c%d", minor_no);
- return 0;
-}
-
-static int slave_i2c_release(
- struct inode *inode,
- struct file *filp
-)
-{
- struct slave_i2c_dev_s *dev;
- int minor_no;
-
- dev = container_of(inode->i_cdev, struct slave_i2c_dev_s, cdev);
- minor_no = iminor(inode);
-
- return 0;
-}
-
-static int slave_i2c_ioctl(
- struct inode *inode,
- struct file *filp,
- unsigned int cmd,
- unsigned long arg
-)
-{
- int ret = 0;
- struct i2c_slave_msg slave_msg[1];
- unsigned char *data_ptr;
- unsigned char __user *usr_ptr;
- switch (cmd) {
- case IOCTL_DO_TRANSFER:
- if (copy_from_user(slave_msg, (struct i2c_slave_msg *)arg,
- sizeof(struct i2c_slave_msg)))
- return -EFAULT;
-
- data_ptr = (unsigned char *)kmalloc(slave_msg->len*sizeof(unsigned char), GFP_KERNEL);
- usr_ptr = (unsigned char __user *)slave_msg->buf;
-
- if (copy_from_user(data_ptr, (unsigned char *)slave_msg->buf,
- slave_msg->len*sizeof(unsigned char))) {
- kfree(data_ptr);
- return -EFAULT;
- }
- slave_msg->buf = data_ptr;
-
- ret = wmt_i2cslave_transfer1((struct i2c_slave_msg)*slave_msg);
-
- if (slave_msg->flags & I2C_M_RD) {
- if (copy_to_user(
- usr_ptr,
- data_ptr,
- slave_msg->len))
- ret = -EFAULT;
- }
-
- kfree(data_ptr);
- break;
- case IOCTL_SET_ADDR:
- if (copy_from_user(slave_msg, (struct i2c_slave_msg *)arg,
- sizeof(struct i2c_slave_msg)))
- return -EFAULT;
- wmt_i2cslave_setaddr1((struct i2c_slave_msg) *slave_msg);
- break;
- case IOCTL_QUERY_DATA:
- break;
- case IOCTL_SET_SPEED_MODE:
- break;
- default:
- break;
- }
- return ret;
-}
-
-/*!*************************************************************************
- driver file operations struct define
-****************************************************************************/
-static struct file_operations i2c_slave_fops = {
- .owner = THIS_MODULE,
- .open = slave_i2c_open,
- .read = slave_i2c_read,
- .write = slave_i2c_write,
- .ioctl = slave_i2c_ioctl,
- .release = slave_i2c_release,
-};
-
-static int slave_i2c_probe(
- struct device *dev
-)
-{
- int ret = 0;
- dev_t dev_no;
- struct cdev *cdev;
- char name[40];
- char buf[80];
- unsigned int port_num;
- int idx = 0;
- char varname1[] = "wmt.bus.i2c.slave_port";
- int ret_val = 0;
- int varlen = 80;
- memset(name, 0, 40);
-
- dev_no = MKDEV(slave_i2c_dev_major, slave_i2c_dev_minor);
-
- sprintf(name, "wmt_i2cslave%d",slave_i2c_dev_minor);
- cdev = &slave_i2c_dev.cdev;
- cdev_init(cdev, &i2c_slave_fops);
- ret = cdev_add(cdev, dev_no, 8);
- slave_i2c_dev.class_slave_i2c = class_create(THIS_MODULE, "wmt_i2cslave1");
- device_create(slave_i2c_dev.class_slave_i2c, NULL ,
- MKDEV(slave_i2c_dev_major,slave_i2c_dev_minor),
- NULL, name);
- if (ret) {
- printk(KERN_ALERT "*E* register char dev \n");
- return ret;
- }
-
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *res;
-
- slave_i2c_proc = proc_mkdir("driver/wmt_i2cslave1", NULL);
- /*
- slave_i2c_proc->owner = THIS_MODULE;
- */
- res = create_proc_entry("registers", 0, slave_i2c_proc);
- if (res) {
- res->read_proc = slave_i2c_reg_read;
- }
-
- res = create_proc_entry("address", 0, slave_i2c_proc);
- if (res) {
- res->read_proc = slave_i2c_addr_read;
- }
-#endif
- slave_i2c_port.regs = (struct i2c_regs_s *)I2C1_BASE_ADDR;
- slave_i2c_port.irq_no = IRQ_I2C1;
- slave_i2c_port.i2c_mode = I2C_STANDARD_MODE;
- slave_i2c_port.isr_nack = 0;
- slave_i2c_port.isr_byte_end = 0;
- slave_i2c_port.isr_timeout = 0;
- slave_i2c_port.isr_int_pending = 0;
- compat_sema_init(&slave_i2c_port.tx_sem, 0);
- compat_sema_init(&slave_i2c_port.rx_sem, 0);
- ret_val = wmt_getsyspara(varname1, buf, &varlen);
- is_master = 1;
- if (ret_val == 0) {
- ret_val = sscanf(buf, "%x", &port_num);
- while (ret_val) {
- if (port_num != 1)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret_val;
- ret_val = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
- /**/
- /* hardware initial*/
- /**/
- if (is_master == 0) {
- *(volatile unsigned int *)PMC_ClOCK_ENABLE_LOWER |= (BIT0);
- *(volatile unsigned int *)CTRL_GPIO21 &= ~(BIT2 | BIT3);
- *(volatile unsigned int *)PU_EN_GPIO21 |= (BIT2 | BIT3);
- *(volatile unsigned int *)PU_CTRL_GPIO21 |= (BIT2 | BIT3);
-
- /*set i2c slave register*/
- slave_i2c_port.regs->cr_reg = 0;
- slave_i2c_port.regs->scr_reg = 0;
- slave_i2c_port.regs->cr_reg = (I2C_SLAV_MODE_SEL|I2C_CR_ENABLE);
- slave_i2c_port.regs->sisr_reg = I2C_SISR_ALL_WRITE_CLEAR;
-
- if (slave_i2c_port.i2c_mode == I2C_STANDARD_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else if (slave_i2c_port.i2c_mode == I2C_FAST_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else
- slave_i2c_port.regs->scr_reg = (slave_i2c_addr|I2C_SLAVE_HS_MODE);
-
- slave_i2c_port.regs->simr_reg = I2C_SIMR_ALL_ENABLE;
-
- slave_i2c_port.regs->cr_reg &= ~I2C_CR_ENABLE;
-
- if (request_irq(slave_i2c_port.irq_no , &slave_i2c_isr, IRQF_DISABLED, "i2c-slave", 0) < 0) {
- DPRINTK(KERN_INFO "I2C-SLAVE: Failed to register I2C-SLAVE irq %i\n", slave_i2c_port.irq_no);
- return -ENODEV;
- }
- }
-
- return ret;
-}
-
-static int slave_i2c_remove(
- struct device *dev /*!<; // please add parameters description her*/
-)
-{
- struct cdev *cdev;
-
- cdev = &slave_i2c_dev.cdev;
- cdev_del(cdev);
-
- return 0;
-} /* End of spi_remove() */
-
-static void slave_i2c_backup(void)
-{
- regs_backup.cr_reg = slave_i2c_port.regs->cr_reg;
- regs_backup.tcr_reg = slave_i2c_port.regs->tcr_reg;
- regs_backup.scr_reg = slave_i2c_port.regs->scr_reg;
- regs_backup.simr_reg = slave_i2c_port.regs->simr_reg;
- regs_backup.str_reg = slave_i2c_port.regs->str_reg;
-
-}
-
-static void slave_i2c_restore(void)
-{
- slave_i2c_port.regs->cr_reg = 0;
- slave_i2c_port.regs->cr_reg = regs_backup.cr_reg;
- slave_i2c_port.regs->tcr_reg = regs_backup.tcr_reg;
- slave_i2c_port.regs->scr_reg = regs_backup.scr_reg;
- slave_i2c_port.regs->simr_reg = regs_backup.simr_reg;
- slave_i2c_port.regs->str_reg = regs_backup.str_reg;
-}
-
-static int slave_i2c_suspend(
- struct device *dev, /*!<; // please add parameters description her*/
- pm_message_t state /*!<; // please add parameters description her*/
-)
-{
- if (is_master == 1)
- return 0;
- slave_i2c_backup();
- compat_sema_init(&slave_i2c_port.tx_sem, 0);
- compat_sema_init(&slave_i2c_port.rx_sem, 0);
- return 0;
-}
-
-
-static int slave_i2c_resume(
- struct device *dev
-)
-{
- if (is_master == 1)
- return 0;
- *(volatile unsigned int *)PMC_ClOCK_ENABLE_LOWER |= (BIT0);
- *(volatile unsigned int *)CTRL_GPIO21 &= ~(BIT2 | BIT3);
- *(volatile unsigned int *)PU_EN_GPIO21 |= (BIT2 | BIT3);
- *(volatile unsigned int *)PU_CTRL_GPIO21 |= (BIT2 | BIT3);
- slave_i2c_restore();
- return 0;
-}
-
-/*!*************************************************************************
- device driver struct define
-****************************************************************************/
-static struct device_driver slave_i2c_driver = {
- .name = "wmt_i2c_slave_1", /* This name should equal to platform device name.*/
- .bus = &platform_bus_type,
- .probe = slave_i2c_probe,
- .remove = slave_i2c_remove,
- .suspend = slave_i2c_suspend,
- .resume = slave_i2c_resume
-};
-
-static void slave_i2c_platform_release(
- struct device *device
-)
-{
-}
-
-/*!*************************************************************************
- platform device struct define
-****************************************************************************/
-
-static struct platform_device slave_i2c_device = {
- .name = "wmt_i2c_slave_1",
- .id = 1,
- .dev = { .release = slave_i2c_platform_release,
- },
- .num_resources = 0,
- .resource = NULL,
-};
-
-static int slave_i2c_init(void)
-{
- int ret;
- dev_t dev_no;
- char dev_name[40];
- memset(dev_name, 0, 40);
- sprintf(dev_name, "wmt_i2c_slave%d", slave_i2c_device.id);
-
- if (slave_i2c_dev_major) {
- dev_no = MKDEV(slave_i2c_dev_major, slave_i2c_dev_minor);
- ret = register_chrdev_region(dev_no, slave_i2c_dev_nr, dev_name);
- } else {
- ret = alloc_chrdev_region(&dev_no, slave_i2c_dev_minor, slave_i2c_dev_nr, dev_name);
- slave_i2c_dev_major = MAJOR(dev_no);
- }
-
- if (ret < 0) {
- printk(KERN_ALERT "*E* can't get major %d\n", slave_i2c_dev_major);
- return ret;
- }
-
- platform_device_register(&slave_i2c_device);
- ret = driver_register(&slave_i2c_driver);
-
- return ret;
-}
-
-module_init(slave_i2c_init);
-
-static void slave_i2c_exit(void)
-{
- dev_t dev_no;
-
- driver_unregister(&slave_i2c_driver);
- platform_device_unregister(&slave_i2c_device);
- dev_no = MKDEV(slave_i2c_dev_major, slave_i2c_dev_minor);
- unregister_chrdev_region(dev_no, slave_i2c_dev_nr);
-
- return;
-}
-
-module_exit(slave_i2c_exit);
-
-MODULE_AUTHOR("WMT SW Team");
-MODULE_DESCRIPTION("WMT_slave_i2c device driver");
-MODULE_LICENSE("GPL");
-#undef WMT_I2C_SLAVE_C
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.c b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.c
deleted file mode 100755
index 547e5ad0..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.c
+++ /dev/null
@@ -1,662 +0,0 @@
-/*++
- drivers/i2c/busses/wmt-i2c-slave-bus.c
-
- Copyright (c) 2008 WonderMedia Technologies, Inc.
-
- This program is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software Foundation,
- either version 2 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see <http://www.gnu.org/licenses/>.
-
- WonderMedia Technologies, Inc.
- 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
-
- History:
- 2010/03/11 First Version
---*/
-
-#include <linux/config.h>
-#define WMT_I2C_SLAVE_C
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/errno.h>
-#include <asm/uaccess.h>
-#include <linux/kdev_t.h>
-#include <linux/cdev.h>
-#include <asm/semaphore.h>
-#include <linux/proc_fs.h>
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include "./wmt-i2c-slave-bus.h"
-/*#define DEBUG*/
-#ifdef DEBUG
-
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
-
-#define DEVICE_NAME "WMT_I2C_SLAVE-0"
-#define PMC_ClOCK_ENABLE_LOWER 0xd8130250
-#define CTRL_GPIO21 0xD8110055
-#define PU_EN_GPIO21 0xD8110495
-#define PU_CTRL_GPIO21 0xD81104D5
-
-#define DISABLE_I2C_SLAVE BIT15
-
-struct i2c_slave_msg {
- __u16 addr; /* slave address */
- __u16 flags;
-#define I2C_M_RD 0x01
- __u16 len; /* data length */
- __u8 *buf; /* pointer to data */
-};
-
-struct slave_i2c_dev_s {
- /* module parameters */
- char *buf;
-
- /* char dev struct */
- struct cdev cdev;
- struct class *class_slave_i2c;
-};
-
-
-struct wmt_slave_i2c_s {
- struct i2c_regs_s *regs;
- int irq_no ;
- enum i2c_mode_e i2c_mode ;
- int isr_nack ;
- int isr_byte_end ;
- int isr_timeout ;
- int isr_int_pending ;
- struct compat_semaphore tx_sem;
- struct compat_semaphore rx_sem;
-};
-
-static struct i2c_regs_s regs_backup;
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-static unsigned int is_master = 1;/*master:1, slave:0*/
-
-static DEFINE_SPINLOCK(slave_i2c_lock);
-
-static int slave_i2c_dev_major = SLAVE_I2C_MAJOR;
-static int slave_i2c_dev_minor;
-static int slave_i2c_dev_nr = 1;
-static struct slave_i2c_dev_s slave_i2c_dev;
-
-static struct wmt_slave_i2c_s slave_i2c_port;
-
-static unsigned char slave_i2c_addr = 0x31;
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *slave_i2c_proc;
-
-static int slave_i2c_reg_read(char *buf, char **start, off_t offset, int len)
-{
- char *p = buf;
- p += sprintf(p, "reg : value\n");
- p += sprintf(p, "cr : 0x%.4x\n", slave_i2c_port.regs->cr_reg);
- p += sprintf(p, "tcr : 0x%.4x\n", slave_i2c_port.regs->tcr_reg);
- p += sprintf(p, "csr : 0x%.4x\n", slave_i2c_port.regs->csr_reg);
- p += sprintf(p, "isr : 0x%.4x\n", slave_i2c_port.regs->isr_reg);
- p += sprintf(p, "imr : 0x%.4x\n", slave_i2c_port.regs->imr_reg);
- p += sprintf(p, "cdr : 0x%.4x\n", slave_i2c_port.regs->cdr_reg);
- p += sprintf(p, "tr : 0x%.4x\n", slave_i2c_port.regs->tr_reg);
- p += sprintf(p, "scr : 0x%.4x\n", slave_i2c_port.regs->scr_reg);
- p += sprintf(p, "cssr : 0x%.4x\n", slave_i2c_port.regs->cssr_reg);
- p += sprintf(p, "simr : 0x%.4x\n", slave_i2c_port.regs->simr_reg);
- p += sprintf(p, "sisr : 0x%.4x\n", slave_i2c_port.regs->sisr_reg);
- p += sprintf(p, "csdr : 0x%.4x\n", slave_i2c_port.regs->csdr_reg);
- p += sprintf(p, "str : 0x%.4x\n", slave_i2c_port.regs->str_reg);
- return p - buf;
-}
-
-static int slave_i2c_addr_read(char *buf, char **start, off_t offset, int len)
-{
- char *p = buf;
- p += sprintf(p, "i2c-slave address : 0x%.2x\n", slave_i2c_addr);
- return p - buf;
-}
-
-#endif
-
-static irqreturn_t slave_i2c_isr(
- int irq, /*!<; // IRQ number */
- void *dev, /*!<; // Private paramater(i.e. pointer of spi port) */
- struct pt_regs *regs /*!<; // interrupt register */
-)
-{
- unsigned short isr_status = slave_i2c_port.regs->sisr_reg;
- unsigned short ssr_status = slave_i2c_port.regs->cssr_reg;
- DPRINTK("slave_i2c isr sisr = %x\n", isr_status);
- DPRINTK("slave_i2c isr cssr = %x\n", ssr_status);
- if (isr_status & I2C_SISR_DAT_REQ) {
- slave_i2c_port.regs->sisr_reg |= I2C_SISR_DAT_REQ_WRITE_CLEAR;
- slave_i2c_port.isr_nack = ssr_status & I2C_SRCV_NACK_MASK;
- compat_up(&slave_i2c_port.tx_sem);
- } else if (isr_status & I2C_SISR_BYTE_END) {
- slave_i2c_port.regs->sisr_reg |= I2C_SISR_BYTE_END_WRITE_CLEAR;
- slave_i2c_port.isr_byte_end = 1;
- slave_i2c_port.isr_nack = ssr_status & I2C_SRCV_NACK_MASK;
- compat_up(&slave_i2c_port.rx_sem);
- } else if (isr_status & I2C_SISR_SCL_TIME_OUT) {
- slave_i2c_port.regs->sisr_reg |= I2C_SISR_SCL_TIME_OUT_WRITE_CLEAR;
- slave_i2c_port.isr_timeout = 1 ;
- }
- return IRQ_HANDLED;
-}
-
-static int wmt_slave_i2c_read_data(unsigned short addr , unsigned char *buf, int size, int flags)
-{
- int ret = 0;
- int xfer_len = 0;
- int sleep_count = 1;
- DPRINTK("ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
- while (xfer_len < size) {
- compat_down_interruptible(&slave_i2c_port.rx_sem);
- buf[xfer_len] = ((slave_i2c_port.regs->csdr_reg & I2C_SLAVE_READ_DATA_MASK) >> I2C_SLAVE_READ_DATA_SHIFT);
- DPRINTK("data = %x\n", buf[xfer_len]);
- xfer_len++;
- }
- ret = xfer_len;
- while (slave_i2c_port.regs->cssr_reg & I2C_SLAVE_ACTIVE) {
- if (compat_sema_count(&slave_i2c_port.rx_sem) > 0) {/*receive data was longer than request*/
- ret = -1;
- break;
- }
- msleep(sleep_count);
- if (sleep_count < 16)
- sleep_count *= 2;
- }
- DPRINTK("ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
-
- return ret;
-}
-
-static int wmt_slave_i2c_write_data(unsigned short addr, unsigned char *buf, int size, int flags)
-{
- int ret = 0;
- int xfer_len = 0;
- int sleep_count = 1;
- DPRINTK("tx ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
- while (xfer_len < size) {
- compat_down_interruptible(&slave_i2c_port.tx_sem);
- slave_i2c_port.regs->csdr_reg = buf[xfer_len];
- DPRINTK("data = %x\n", buf[xfer_len]);
- ++xfer_len;
- }
- ret = xfer_len;
- while (slave_i2c_port.regs->cssr_reg & I2C_SLAVE_ACTIVE) {
- msleep(sleep_count);
- if (sleep_count < 16)
- sleep_count *= 2;
- }
- DPRINTK("2.tx ssr = %x, isr = %x\n", slave_i2c_port.regs->cssr_reg, slave_i2c_port.regs->sisr_reg);
- return ret;
-}
-
-static int slave_i2c_do_xfer(unsigned short addr, unsigned char *buf, int size, int flags)
-{
- int ret;
- if (flags & I2C_M_RD)
- ret = wmt_slave_i2c_read_data(addr , buf, size, flags);
- else
- ret = wmt_slave_i2c_write_data(addr , buf, size, flags);
- return ret;
-}
-
-int wmt_i2cslave_transfer0(struct i2c_slave_msg slave_msg)
-{
- int flags = slave_msg.flags;
- unsigned char *buf = slave_msg.buf;
- unsigned short addr = slave_msg.addr;
- int size = slave_msg.len;
- int xfer_len;
- if (is_master == 1)
- return 0;
- spin_lock(&slave_i2c_lock);
- xfer_len = slave_i2c_do_xfer(addr, buf, size, flags);
- spin_unlock(&slave_i2c_lock);
- return xfer_len;
-}
-EXPORT_SYMBOL(wmt_i2cslave_transfer0);
-
-void wmt_i2cslave_setaddr0(struct i2c_slave_msg msg)
-{
- if (is_master == 1)
- return;
- spin_lock(&slave_i2c_lock);
-
- slave_i2c_addr = msg.addr;
-
- if (msg.addr & DISABLE_I2C_SLAVE)
- slave_i2c_port.regs->cr_reg &= ~I2C_CR_ENABLE;
- else {
- slave_i2c_port.regs->cr_reg = 0;
- slave_i2c_port.regs->scr_reg = 0;
- slave_i2c_port.regs->cr_reg = (I2C_SLAV_MODE_SEL|I2C_CR_ENABLE);
- slave_i2c_port.regs->sisr_reg = I2C_SISR_ALL_WRITE_CLEAR;
-
- if (slave_i2c_port.i2c_mode == I2C_STANDARD_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else if (slave_i2c_port.i2c_mode == I2C_FAST_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else
- slave_i2c_port.regs->scr_reg = (slave_i2c_addr|I2C_SLAVE_HS_MODE);
-
- slave_i2c_port.regs->simr_reg = I2C_SIMR_ALL_ENABLE;
- }
- spin_unlock(&slave_i2c_lock);
-}
-EXPORT_SYMBOL(wmt_i2cslave_setaddr0);
-
-static ssize_t slave_i2c_read(
- struct file *filp,
- char __user *buf,
- size_t count,
- loff_t *f_pos
-)
-{
- int ret = 0;
- struct i2c_slave_msg slave_msg;
- if (is_master == 1)
- return ret;
- slave_msg.buf = (char *)kmalloc(count * sizeof(unsigned char), GFP_KERNEL);
- slave_msg.flags = 0;
- slave_msg.flags |= I2C_M_RD;
- slave_msg.len = count;
- slave_msg.addr = slave_i2c_addr;
- ret = wmt_i2cslave_transfer0(slave_msg);
- if (copy_to_user(buf, slave_msg.buf, count)) {
- kfree(slave_msg.buf);
- return -EFAULT;
- }
- return ret;
-}
-
-static ssize_t slave_i2c_write(
- struct file *filp,
- const char __user *buf,
- size_t count,
- loff_t *f_pos
-)
-{
- int ret = 0;
- struct i2c_slave_msg slave_msg;
- if (is_master == 1)
- return ret;
- slave_msg.buf = (char *)kmalloc(count * sizeof(unsigned char), GFP_KERNEL);
- slave_msg.flags = 0;
- slave_msg.flags &= ~I2C_M_RD;
- slave_msg.len = count;
- slave_msg.addr = slave_i2c_addr;
- if (copy_from_user(slave_msg.buf, buf, count)) {
- kfree(slave_msg.buf);
- return -EFAULT;
- }
- ret = wmt_i2cslave_transfer0(slave_msg);
- return ret; /* return Write out data size*/
-}
-
-static int slave_i2c_open(
- struct inode *inode,
- struct file *filp
-)
-{
- struct slave_i2c_dev_s *dev;
- char name[40];
- int minor_no;
-
- dev = container_of(inode->i_cdev, struct slave_i2c_dev_s, cdev);
- filp->private_data = dev;
- minor_no = iminor(inode); /* get */
-
- /* Create user name*/
- memset(name, 0x0, 8);
- sprintf(name, "slave-i2c%d", minor_no);
- return 0;
-}
-
-static int slave_i2c_release(
- struct inode *inode,
- struct file *filp
-)
-{
- struct slave_i2c_dev_s *dev;
- int minor_no;
-
- dev = container_of(inode->i_cdev, struct slave_i2c_dev_s, cdev);
- minor_no = iminor(inode);
-
- return 0;
-}
-
-static int slave_i2c_ioctl(
- struct inode *inode,
- struct file *filp,
- unsigned int cmd,
- unsigned long arg
-)
-{
- int ret = 0;
- struct i2c_slave_msg slave_msg[1];
- unsigned char *data_ptr;
- unsigned char __user *usr_ptr;
- switch (cmd) {
- case IOCTL_DO_TRANSFER:
- if (copy_from_user(slave_msg, (struct i2c_slave_msg *)arg,
- sizeof(struct i2c_slave_msg)))
- return -EFAULT;
-
- data_ptr = (unsigned char *)kmalloc(slave_msg->len*sizeof(unsigned char), GFP_KERNEL);
- usr_ptr = (unsigned char __user *)slave_msg->buf;
-
- if (copy_from_user(data_ptr, (unsigned char *)slave_msg->buf,
- slave_msg->len*sizeof(unsigned char))) {
- kfree(data_ptr);
- return -EFAULT;
- }
- slave_msg->buf = data_ptr;
-
- ret = wmt_i2cslave_transfer0((struct i2c_slave_msg)*slave_msg);
-
- if (slave_msg->flags & I2C_M_RD) {
- if (copy_to_user(
- usr_ptr,
- data_ptr,
- slave_msg->len))
- ret = -EFAULT;
- }
-
- kfree(data_ptr);
- break;
- case IOCTL_SET_ADDR:
- if (copy_from_user(slave_msg, (struct i2c_slave_msg *)arg,
- sizeof(struct i2c_slave_msg)))
- return -EFAULT;
- wmt_i2cslave_setaddr0((struct i2c_slave_msg) *slave_msg);
- break;
- case IOCTL_QUERY_DATA:
- break;
- case IOCTL_SET_SPEED_MODE:
- break;
- default:
- break;
- }
- return ret;
-}
-
-/*!*************************************************************************
- driver file operations struct define
-****************************************************************************/
-static struct file_operations i2c_slave_fops = {
- .owner = THIS_MODULE,
- .open = slave_i2c_open,
- .read = slave_i2c_read,
- .write = slave_i2c_write,
- .ioctl = slave_i2c_ioctl,
- .release = slave_i2c_release,
-};
-
-static int slave_i2c_probe(
- struct device *dev
-)
-{
- int ret = 0;
- dev_t dev_no;
- struct cdev *cdev;
- char name[40];
- char buf[80];
- unsigned int port_num;
- int idx = 0;
- char varname1[] = "wmt.bus.i2c.slave_port";
- int ret_val = 0;
- int varlen = 80;
- memset(name, 0, 40);
-
- dev_no = MKDEV(slave_i2c_dev_major, slave_i2c_dev_minor);
-
- sprintf(name, "wmt_i2cslave%d",slave_i2c_dev_minor);
- cdev = &slave_i2c_dev.cdev;
- cdev_init(cdev, &i2c_slave_fops);
- ret = cdev_add(cdev, dev_no, 8);
- slave_i2c_dev.class_slave_i2c = class_create(THIS_MODULE, "wmt_i2cslave");
- device_create(slave_i2c_dev.class_slave_i2c, NULL ,
- MKDEV(slave_i2c_dev_major,slave_i2c_dev_minor),
- NULL, name);
- if (ret) {
- printk(KERN_ALERT "*E* register char dev \n");
- return ret;
- }
-
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *res;
-
- slave_i2c_proc = proc_mkdir("driver/wmt_i2cslave0", NULL);
- /*
- slave_i2c_proc->owner = THIS_MODULE;
- */
- res = create_proc_entry("registers", 0, slave_i2c_proc);
- if (res) {
- res->read_proc = slave_i2c_reg_read;
- }
-
- res = create_proc_entry("address", 0, slave_i2c_proc);
- if (res) {
- res->read_proc = slave_i2c_addr_read;
- }
-#endif
- slave_i2c_port.regs = (struct i2c_regs_s *)I2C0_BASE_ADDR;
- slave_i2c_port.irq_no = IRQ_I2C0;
- slave_i2c_port.i2c_mode = I2C_STANDARD_MODE;
- slave_i2c_port.isr_nack = 0;
- slave_i2c_port.isr_byte_end = 0;
- slave_i2c_port.isr_timeout = 0;
- slave_i2c_port.isr_int_pending = 0;
- compat_sema_init(&slave_i2c_port.tx_sem, 0);
- compat_sema_init(&slave_i2c_port.rx_sem, 0);
- ret_val = wmt_getsyspara(varname1, buf, &varlen);
- is_master = 1;
- if (ret_val == 0) {
- ret_val = sscanf(buf, "%x", &port_num);
- while (ret_val) {
- if (port_num != 0)
- is_master = 1;
- else {
- is_master = 0;
- break;
- }
- idx += ret_val;
- ret_val = sscanf(buf + idx, ",%x", &port_num);
- }
- } else
- is_master = 1;
- /**/
- /* hardware initial*/
- /**/
- if (is_master == 0) {
- *(volatile unsigned int *)PMC_ClOCK_ENABLE_LOWER |= (BIT5);
- *(volatile unsigned int *)CTRL_GPIO21 &= ~(BIT0 | BIT1);
- *(volatile unsigned int *)PU_EN_GPIO21 |= (BIT0 | BIT1);
- *(volatile unsigned int *)PU_CTRL_GPIO21 |= (BIT0 | BIT1);
-
- /*set i2c slave register*/
- slave_i2c_port.regs->cr_reg = 0;
- slave_i2c_port.regs->scr_reg = 0;
- slave_i2c_port.regs->cr_reg = (I2C_SLAV_MODE_SEL|I2C_CR_ENABLE);
- slave_i2c_port.regs->sisr_reg = I2C_SISR_ALL_WRITE_CLEAR;
-
- if (slave_i2c_port.i2c_mode == I2C_STANDARD_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else if (slave_i2c_port.i2c_mode == I2C_FAST_MODE)
- slave_i2c_port.regs->scr_reg = slave_i2c_addr;
- else
- slave_i2c_port.regs->scr_reg = (slave_i2c_addr|I2C_SLAVE_HS_MODE);
-
- slave_i2c_port.regs->simr_reg = I2C_SIMR_ALL_ENABLE;
-
- slave_i2c_port.regs->cr_reg &= ~I2C_CR_ENABLE;
-
- if (request_irq(slave_i2c_port.irq_no , &slave_i2c_isr, IRQF_DISABLED, "i2c-slave", 0) < 0) {
- DPRINTK(KERN_INFO "I2C-SLAVE: Failed to register I2C-SLAVE irq %i\n", slave_i2c_port.irq_no);
- return -ENODEV;
- }
- }
-
- return ret;
-}
-
-static int slave_i2c_remove(
- struct device *dev /*!<; // please add parameters description her*/
-)
-{
- struct cdev *cdev;
-
- cdev = &slave_i2c_dev.cdev;
- cdev_del(cdev);
-
- return 0;
-} /* End of spi_remove() */
-
-static void slave_i2c_backup(void)
-{
- regs_backup.cr_reg = slave_i2c_port.regs->cr_reg;
- regs_backup.tcr_reg = slave_i2c_port.regs->tcr_reg;
- regs_backup.scr_reg = slave_i2c_port.regs->scr_reg;
- regs_backup.simr_reg = slave_i2c_port.regs->simr_reg;
- regs_backup.str_reg = slave_i2c_port.regs->str_reg;
-
-}
-
-static void slave_i2c_restore(void)
-{
- slave_i2c_port.regs->cr_reg = 0;
- slave_i2c_port.regs->cr_reg = regs_backup.cr_reg;
- slave_i2c_port.regs->tcr_reg = regs_backup.tcr_reg;
- slave_i2c_port.regs->scr_reg = regs_backup.scr_reg;
- slave_i2c_port.regs->simr_reg = regs_backup.simr_reg;
- slave_i2c_port.regs->str_reg = regs_backup.str_reg;
-}
-
-static int slave_i2c_suspend(
- struct device *dev, /*!<; // please add parameters description her*/
- pm_message_t state /*!<; // please add parameters description her*/
-)
-{
- if (is_master == 1)
- return 0;
- slave_i2c_backup();
- compat_sema_init(&slave_i2c_port.tx_sem, 0);
- compat_sema_init(&slave_i2c_port.rx_sem, 0);
- return 0;
-}
-
-
-static int slave_i2c_resume(
- struct device *dev
-)
-{
- if (is_master == 1)
- return 0;
- *(volatile unsigned int *)PMC_ClOCK_ENABLE_LOWER |= (BIT5);
- *(volatile unsigned int *)CTRL_GPIO21 &= ~(BIT0 | BIT1);
- *(volatile unsigned int *)PU_EN_GPIO21 |= (BIT0 | BIT1);
- *(volatile unsigned int *)PU_CTRL_GPIO21 |= (BIT0 | BIT1);
- slave_i2c_restore();
- return 0;
-}
-
-/*!*************************************************************************
- device driver struct define
-****************************************************************************/
-static struct device_driver slave_i2c_driver = {
- .name = "wmt_i2c_slave_0", /* This name should equal to platform device name.*/
- .bus = &platform_bus_type,
- .probe = slave_i2c_probe,
- .remove = slave_i2c_remove,
- .suspend = slave_i2c_suspend,
- .resume = slave_i2c_resume
-};
-
-static void slave_i2c_platform_release(
- struct device *device
-)
-{
-}
-
-/*!*************************************************************************
- platform device struct define
-****************************************************************************/
-
-static struct platform_device slave_i2c_device = {
- .name = "wmt_i2c_slave_0",
- .id = 0,
- .dev = { .release = slave_i2c_platform_release,
- },
- .num_resources = 0,
- .resource = NULL,
-};
-
-static int slave_i2c_init(void)
-{
- int ret;
- dev_t dev_no;
- char dev_name[40];
- memset(dev_name, 0, 40);
- sprintf(dev_name, "wmt_i2c_slave%d", slave_i2c_device.id);
-
- if (slave_i2c_dev_major) {
- dev_no = MKDEV(slave_i2c_dev_major, slave_i2c_dev_minor);
- ret = register_chrdev_region(dev_no, slave_i2c_dev_nr, dev_name);
- } else {
- ret = alloc_chrdev_region(&dev_no, slave_i2c_dev_minor, slave_i2c_dev_nr, dev_name);
- slave_i2c_dev_major = MAJOR(dev_no);
- }
-
- if (ret < 0) {
- printk(KERN_ALERT "*E* can't get major %d\n", slave_i2c_dev_major);
- return ret;
- }
-
- platform_device_register(&slave_i2c_device);
- ret = driver_register(&slave_i2c_driver);
-
- return ret;
-}
-
-module_init(slave_i2c_init);
-
-static void slave_i2c_exit(void)
-{
- dev_t dev_no;
-
- driver_unregister(&slave_i2c_driver);
- platform_device_unregister(&slave_i2c_device);
- dev_no = MKDEV(slave_i2c_dev_major, slave_i2c_dev_minor);
- unregister_chrdev_region(dev_no, slave_i2c_dev_nr);
-
- return;
-}
-
-module_exit(slave_i2c_exit);
-
-MODULE_AUTHOR("WMT SW Team");
-MODULE_DESCRIPTION("WMT_slave_i2c device driver");
-MODULE_LICENSE("GPL");
-#undef WMT_I2C_SLAVE_C
diff --git a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.h b/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.h
deleted file mode 100755
index 485823db..00000000
--- a/ANDROID_3.4.5/drivers/i2c/busses/wmt-i2c-slave-bus.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*++
-Copyright (c) 2010 WonderMedia Technologies, Inc.
-
-This program is free software: you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation, either version 2 of the License, or (at your option) any later
-version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU General Public License for more details. You
-should have received a copy of the GNU General Public License along with this
-program. If not, see http://www.gnu.org/licenses/>.
-
-WonderMedia Technologies, Inc.
-10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-
-#define SLAVE_I2C_MAJOR 191
-
-#define IOCTL_DO_TRANSFER 0xBF01
-#define IOCTL_SET_ADDR 0xBF02
-#define IOCTL_QUERY_DATA 0xBF03
-#define IOCTL_SET_SPEED_MODE 0xBF04
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-api.c b/ANDROID_3.4.5/drivers/i2c/i2c-api.c
deleted file mode 100755
index d01335bb..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-api.c
+++ /dev/null
@@ -1,216 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#define I2C_API_FAKE_ADDR 0x7f
-#define I2C_MINORS 256
-
-struct i2c_api {
- struct list_head list;
- struct i2c_client *client;
-};
-
-static LIST_HEAD(i2c_api_list);
-static DEFINE_SPINLOCK(i2c_api_list_lock);
-
-static struct i2c_api *get_i2c_api(int bus_id)
-{
- struct i2c_api *i2c_api;
-
- spin_lock(&i2c_api_list_lock);
- list_for_each_entry(i2c_api, &i2c_api_list, list) {
- if (i2c_api->client->adapter->nr == bus_id)
- goto found;
- }
- i2c_api = NULL;
-
-found:
- spin_unlock(&i2c_api_list_lock);
- return i2c_api;
-}
-
-static struct i2c_api *add_i2c_api(struct i2c_client *client)
-{
- struct i2c_api *i2c_api;
-
- if (client->adapter->nr >= I2C_MINORS) {
- printk(KERN_ERR "i2c_api: Out of device minors (%d)\n",
- client->adapter->nr);
- return NULL;
- }
-
- i2c_api = kzalloc(sizeof(*i2c_api), GFP_KERNEL);
- if (!i2c_api)
- return NULL;
- i2c_api->client = client;
-
- spin_lock(&i2c_api_list_lock);
- list_add_tail(&i2c_api->list, &i2c_api_list);
- spin_unlock(&i2c_api_list_lock);
- return i2c_api;
-}
-
-static void del_i2c_api(struct i2c_api *i2c_api)
-{
- spin_lock(&i2c_api_list_lock);
- list_del(&i2c_api->list);
- spin_unlock(&i2c_api_list_lock);
- kfree(i2c_api);
-}
-
-static int i2c_api_do_xfer(int bus_id, char chip_addr, char sub_addr, int mode,
- char *buf, unsigned int size)
-{
-/** you could define more transfer mode here, implement it following. */
-#define I2C_API_XFER_MODE_SEND 0x0 /* standard send */
-#define I2C_API_XFER_MODE_RECV 0x1 /* standard receive */
-#define I2C_API_XFER_MODE_SEND_NO_SUBADDR 0x2 /* send without sub-address */
-#define I2C_API_XFER_MODE_RECV_NO_SUBADDR 0x3 /* receive without sub-address */
-
- int ret = 0;
- char *tmp;
- struct i2c_api *i2c_api = get_i2c_api(bus_id);
-
- if (!i2c_api)
- return -ENODEV;
-
- i2c_api->client->addr = chip_addr;
- switch (mode) {
- case I2C_API_XFER_MODE_SEND:
- tmp = kmalloc(size + 1,GFP_KERNEL);
- if (tmp == NULL)
- return -ENOMEM;
- tmp[0] = sub_addr;
- memcpy(&tmp[1], buf, size);
- ret = i2c_master_send(i2c_api->client, tmp, size + 1);
- ret = (ret == size + 1) ? size : ret;
- kfree(tmp);
- break;
-
- case I2C_API_XFER_MODE_RECV:
- ret = i2c_master_send(i2c_api->client, &sub_addr, 1);
- if (ret < 0)
- return ret;
- ret = i2c_master_recv(i2c_api->client, buf, size);
- break;
-
- case I2C_API_XFER_MODE_SEND_NO_SUBADDR:
- ret = i2c_master_send(i2c_api->client, buf, size);
- break;
-
- case I2C_API_XFER_MODE_RECV_NO_SUBADDR:
- ret = i2c_master_recv(i2c_api->client, buf, size);
- break;
-
- default:
- return -EINVAL;
- }
- return ret;
-}
-
-int i2c_api_do_send(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size)
-{
- return i2c_api_do_xfer(bus_id, chip_addr, sub_addr, I2C_API_XFER_MODE_SEND, buf, size);
-}
-
-int i2c_api_do_recv(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size)
-{
- return i2c_api_do_xfer(bus_id, chip_addr, sub_addr, I2C_API_XFER_MODE_RECV, buf, size);
-}
-
-int i2c_api_do_send_without_subaddr(int bus_id, char chip_addr, char *buf, unsigned int size)
-{
- return i2c_api_do_xfer(bus_id, chip_addr, 0, I2C_API_XFER_MODE_SEND_NO_SUBADDR, buf, size);
-}
-
-int i2c_api_do_recv_without_subaddr(int bus_id, char chip_addr, char *buf, unsigned int size)
-{
- return i2c_api_do_xfer(bus_id, chip_addr, 0, I2C_API_XFER_MODE_RECV_NO_SUBADDR, buf, size);
-}
-
-int i2c_api_attach(struct i2c_adapter *adap)
-{
- struct i2c_board_info info;
- struct i2c_client *client;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "i2c_api", I2C_NAME_SIZE);
- info.addr = I2C_API_FAKE_ADDR;
- client = i2c_new_device(adap, &info);
- if (client)
- add_i2c_api(client);
- printk(KERN_INFO "i2c_api_attach adap[%d]\n", adap->nr);
- return 0;
-}
-
-int i2c_api_detach(struct i2c_adapter *adap)
-{
- struct i2c_api *i2c_api;
-
- i2c_api = get_i2c_api(adap->nr);
- if (i2c_api)
- del_i2c_api(i2c_api);
- return 0;
-}
-
-static const unsigned short normal_addr[] = { I2C_API_FAKE_ADDR, I2C_CLIENT_END };
-static const unsigned short ignore[] = { I2C_CLIENT_END };
-/*static struct i2c_client_address_data addr_data =
-{
- .normal_i2c = normal_addr,
- .probe = ignore,
- .ignore = ignore,
- .forces = NULL,
-};*/
-
-static const struct i2c_device_id id[] = {
- {"I2C-API", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, id);
-
-static struct i2c_driver i2c_api_driver = {
- .id_table = id,
- .attach_adapter = i2c_api_attach,
- .detach_adapter = i2c_api_detach,
- .command = NULL,
- .driver = {
- .name = "I2C-API",
- .owner = THIS_MODULE,
- },
- //.address_data = &addr_data,
-};
-
-static int __init i2c_api_init(void)
-{
- int ret = i2c_add_driver(&i2c_api_driver);
-
- if (ret) {
- printk(KERN_ERR "[%s] Driver registration failed, module not inserted.\n", __func__);
- return ret;
- }
-
- return 0 ;
-}
-
-static void __exit i2c_api_exit(void)
-{
- i2c_del_driver(&i2c_api_driver);
-}
-
-MODULE_AUTHOR("Loon, <Loonzhong@wondermedia.com.cn>");
-MODULE_DESCRIPTION("I2C i2c_api Driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_api_init);
-module_exit(i2c_api_exit);
-
-EXPORT_SYMBOL_GPL(i2c_api_do_send);
-EXPORT_SYMBOL_GPL(i2c_api_do_recv);
-EXPORT_SYMBOL_GPL(i2c_api_do_send_without_subaddr);
-EXPORT_SYMBOL_GPL(i2c_api_do_recv_without_subaddr);
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-boardinfo.c b/ANDROID_3.4.5/drivers/i2c/i2c-boardinfo.c
deleted file mode 100644
index f24cc64e..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-boardinfo.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * i2c-boardinfo.c - collect pre-declarations of I2C devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/rwsem.h>
-
-#include "i2c-core.h"
-
-
-/* These symbols are exported ONLY FOR the i2c core.
- * No other users will be supported.
- */
-DECLARE_RWSEM(__i2c_board_lock);
-EXPORT_SYMBOL_GPL(__i2c_board_lock);
-
-LIST_HEAD(__i2c_board_list);
-EXPORT_SYMBOL_GPL(__i2c_board_list);
-
-int __i2c_first_dynamic_bus_num;
-EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
-
-
-/**
- * i2c_register_board_info - statically declare I2C devices
- * @busnum: identifies the bus to which these devices belong
- * @info: vector of i2c device descriptors
- * @len: how many descriptors in the vector; may be zero to reserve
- * the specified bus number.
- *
- * Systems using the Linux I2C driver stack can declare tables of board info
- * while they initialize. This should be done in board-specific init code
- * near arch_initcall() time, or equivalent, before any I2C adapter driver is
- * registered. For example, mainboard init code could define several devices,
- * as could the init code for each daughtercard in a board stack.
- *
- * The I2C devices will be created later, after the adapter for the relevant
- * bus has been registered. After that moment, standard driver model tools
- * are used to bind "new style" I2C drivers to the devices. The bus number
- * for any device declared using this routine is not available for dynamic
- * allocation.
- *
- * The board info passed can safely be __initdata, but be careful of embedded
- * pointers (for platform_data, functions, etc) since that won't be copied.
- */
-int __init
-i2c_register_board_info(int busnum,
- struct i2c_board_info const *info, unsigned len)
-{
- int status;
-
- down_write(&__i2c_board_lock);
-
- /* dynamic bus numbers will be assigned after the last static one */
- if (busnum >= __i2c_first_dynamic_bus_num)
- __i2c_first_dynamic_bus_num = busnum + 1;
-
- for (status = 0; len; len--, info++) {
- struct i2c_devinfo *devinfo;
-
- devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
- if (!devinfo) {
- pr_debug("i2c-core: can't register boardinfo!\n");
- status = -ENOMEM;
- break;
- }
-
- devinfo->busnum = busnum;
- devinfo->board_info = *info;
- list_add_tail(&devinfo->list, &__i2c_board_list);
- }
-
- up_write(&__i2c_board_lock);
-
- return status;
-}
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-core.c b/ANDROID_3.4.5/drivers/i2c/i2c-core.c
deleted file mode 100644
index feb7dc35..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-core.c
+++ /dev/null
@@ -1,2136 +0,0 @@
-/* i2c-core.c - a device driver for the iic-bus interface */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 1995-99 Simon G. Vogl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA. */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
- All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
- SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
- Jean Delvare <khali@linux-fr.org>
- Mux support by Rodolfo Giometti <giometti@enneenne.com> and
- Michael Lawnick <michael.lawnick.ext@nsn.com> */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/idr.h>
-#include <linux/mutex.h>
-#include <linux/of_device.h>
-#include <linux/completion.h>
-#include <linux/hardirq.h>
-#include <linux/irqflags.h>
-#include <linux/rwsem.h>
-#include <linux/pm_runtime.h>
-#include <asm/uaccess.h>
-
-#include "i2c-core.h"
-
-
-/* core_lock protects i2c_adapter_idr, and guarantees
- that device detection, deletion of detected devices, and attach_adapter
- and detach_adapter calls are serialized */
-static DEFINE_MUTEX(core_lock);
-static DEFINE_IDR(i2c_adapter_idr);
-
-static struct device_type i2c_client_type;
-static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
-
-/* ------------------------------------------------------------------------- */
-
-static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
- const struct i2c_client *client)
-{
- while (id->name[0]) {
- if (strcmp(client->name, id->name) == 0)
- return id;
- id++;
- }
- return NULL;
-}
-
-static int i2c_device_match(struct device *dev, struct device_driver *drv)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
-
- if (!client)
- return 0;
-
- /* Attempt an OF style match */
- if (of_driver_match_device(dev, drv))
- return 1;
-
- driver = to_i2c_driver(drv);
- /* match on an id table if there is one */
- if (driver->id_table)
- return i2c_match_id(driver->id_table, client) != NULL;
-
- return 0;
-}
-
-#ifdef CONFIG_HOTPLUG
-
-/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
-static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct i2c_client *client = to_i2c_client(dev);
-
- if (add_uevent_var(env, "MODALIAS=%s%s",
- I2C_MODULE_PREFIX, client->name))
- return -ENOMEM;
- dev_dbg(dev, "uevent\n");
- return 0;
-}
-
-#else
-#define i2c_device_uevent NULL
-#endif /* CONFIG_HOTPLUG */
-
-static int i2c_device_probe(struct device *dev)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
- int status;
-
- if (!client)
- return 0;
-
- driver = to_i2c_driver(dev->driver);
- if (!driver->probe || !driver->id_table)
- return -ENODEV;
- client->driver = driver;
- if (!device_can_wakeup(&client->dev))
- device_init_wakeup(&client->dev,
- client->flags & I2C_CLIENT_WAKE);
- dev_dbg(dev, "probe\n");
-
- status = driver->probe(client, i2c_match_id(driver->id_table, client));
- if (status) {
- client->driver = NULL;
- i2c_set_clientdata(client, NULL);
- }
- return status;
-}
-
-static int i2c_device_remove(struct device *dev)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
- int status;
-
- if (!client || !dev->driver)
- return 0;
-
- driver = to_i2c_driver(dev->driver);
- if (driver->remove) {
- dev_dbg(dev, "remove\n");
- status = driver->remove(client);
- } else {
- dev->driver = NULL;
- status = 0;
- }
- if (status == 0) {
- client->driver = NULL;
- i2c_set_clientdata(client, NULL);
- }
- return status;
-}
-
-static void i2c_device_shutdown(struct device *dev)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
-
- if (!client || !dev->driver)
- return;
- driver = to_i2c_driver(dev->driver);
- if (driver->shutdown)
- driver->shutdown(client);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int i2c_legacy_suspend(struct device *dev, pm_message_t mesg)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
-
- if (!client || !dev->driver)
- return 0;
- driver = to_i2c_driver(dev->driver);
- if (!driver->suspend)
- return 0;
- return driver->suspend(client, mesg);
-}
-
-static int i2c_legacy_resume(struct device *dev)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
-
- if (!client || !dev->driver)
- return 0;
- driver = to_i2c_driver(dev->driver);
- if (!driver->resume)
- return 0;
- return driver->resume(client);
-}
-
-static int i2c_device_pm_suspend(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_suspend(dev);
- else
- return i2c_legacy_suspend(dev, PMSG_SUSPEND);
-}
-
-static int i2c_device_pm_resume(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_resume(dev);
- else
- return i2c_legacy_resume(dev);
-}
-
-static int i2c_device_pm_freeze(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_freeze(dev);
- else
- return i2c_legacy_suspend(dev, PMSG_FREEZE);
-}
-
-static int i2c_device_pm_thaw(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_thaw(dev);
- else
- return i2c_legacy_resume(dev);
-}
-
-static int i2c_device_pm_poweroff(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_poweroff(dev);
- else
- return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
-}
-
-static int i2c_device_pm_restore(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_restore(dev);
- else
- return i2c_legacy_resume(dev);
-}
-#else /* !CONFIG_PM_SLEEP */
-#define i2c_device_pm_suspend NULL
-#define i2c_device_pm_resume NULL
-#define i2c_device_pm_freeze NULL
-#define i2c_device_pm_thaw NULL
-#define i2c_device_pm_poweroff NULL
-#define i2c_device_pm_restore NULL
-#endif /* !CONFIG_PM_SLEEP */
-
-static void i2c_client_dev_release(struct device *dev)
-{
- kfree(to_i2c_client(dev));
-}
-
-static ssize_t
-show_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", dev->type == &i2c_client_type ?
- to_i2c_client(dev)->name : to_i2c_adapter(dev)->name);
-}
-
-static ssize_t
-show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
-}
-
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
-
-static struct attribute *i2c_dev_attrs[] = {
- &dev_attr_name.attr,
- /* modalias helps coldplug: modprobe $(cat .../modalias) */
- &dev_attr_modalias.attr,
- NULL
-};
-
-static struct attribute_group i2c_dev_attr_group = {
- .attrs = i2c_dev_attrs,
-};
-
-static const struct attribute_group *i2c_dev_attr_groups[] = {
- &i2c_dev_attr_group,
- NULL
-};
-
-static const struct dev_pm_ops i2c_device_pm_ops = {
- .suspend = i2c_device_pm_suspend,
- .resume = i2c_device_pm_resume,
- .freeze = i2c_device_pm_freeze,
- .thaw = i2c_device_pm_thaw,
- .poweroff = i2c_device_pm_poweroff,
- .restore = i2c_device_pm_restore,
- SET_RUNTIME_PM_OPS(
- pm_generic_runtime_suspend,
- pm_generic_runtime_resume,
- pm_generic_runtime_idle
- )
-};
-
-struct bus_type i2c_bus_type = {
- .name = "i2c",
- .match = i2c_device_match,
- .probe = i2c_device_probe,
- .remove = i2c_device_remove,
- .shutdown = i2c_device_shutdown,
- .pm = &i2c_device_pm_ops,
-};
-EXPORT_SYMBOL_GPL(i2c_bus_type);
-
-static struct device_type i2c_client_type = {
- .groups = i2c_dev_attr_groups,
- .uevent = i2c_device_uevent,
- .release = i2c_client_dev_release,
-};
-
-
-/**
- * i2c_verify_client - return parameter as i2c_client, or NULL
- * @dev: device, probably from some driver model iterator
- *
- * When traversing the driver model tree, perhaps using driver model
- * iterators like @device_for_each_child(), you can't assume very much
- * about the nodes you find. Use this function to avoid oopses caused
- * by wrongly treating some non-I2C device as an i2c_client.
- */
-struct i2c_client *i2c_verify_client(struct device *dev)
-{
- return (dev->type == &i2c_client_type)
- ? to_i2c_client(dev)
- : NULL;
-}
-EXPORT_SYMBOL(i2c_verify_client);
-
-
-/* This is a permissive address validity check, I2C address map constraints
- * are purposely not enforced, except for the general call address. */
-static int i2c_check_client_addr_validity(const struct i2c_client *client)
-{
- if (client->flags & I2C_CLIENT_TEN) {
- /* 10-bit address, all values are valid */
- if (client->addr > 0x3ff)
- return -EINVAL;
- } else {
- /* 7-bit address, reject the general call address */
- if (client->addr == 0x00 || client->addr > 0x7f)
- return -EINVAL;
- }
- return 0;
-}
-
-/* And this is a strict address validity check, used when probing. If a
- * device uses a reserved address, then it shouldn't be probed. 7-bit
- * addressing is assumed, 10-bit address devices are rare and should be
- * explicitly enumerated. */
-static int i2c_check_addr_validity(unsigned short addr)
-{
- /*
- * Reserved addresses per I2C specification:
- * 0x00 General call address / START byte
- * 0x01 CBUS address
- * 0x02 Reserved for different bus format
- * 0x03 Reserved for future purposes
- * 0x04-0x07 Hs-mode master code
- * 0x78-0x7b 10-bit slave addressing
- * 0x7c-0x7f Reserved for future purposes
- */
- if (addr < 0x08 || addr > 0x77)
- return -EINVAL;
- return 0;
-}
-
-static int __i2c_check_addr_busy(struct device *dev, void *addrp)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- int addr = *(int *)addrp;
-
- if (client && client->addr == addr)
- return -EBUSY;
- return 0;
-}
-
-/* walk up mux tree */
-static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
- int result;
-
- result = device_for_each_child(&adapter->dev, &addr,
- __i2c_check_addr_busy);
-
- if (!result && parent)
- result = i2c_check_mux_parents(parent, addr);
-
- return result;
-}
-
-/* recurse down mux tree */
-static int i2c_check_mux_children(struct device *dev, void *addrp)
-{
- int result;
-
- if (dev->type == &i2c_adapter_type)
- result = device_for_each_child(dev, addrp,
- i2c_check_mux_children);
- else
- result = __i2c_check_addr_busy(dev, addrp);
-
- return result;
-}
-
-static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
- int result = 0;
-
- if (parent)
- result = i2c_check_mux_parents(parent, addr);
-
- if (!result)
- result = device_for_each_child(&adapter->dev, &addr,
- i2c_check_mux_children);
-
- return result;
-}
-
-/**
- * i2c_lock_adapter - Get exclusive access to an I2C bus segment
- * @adapter: Target I2C bus segment
- */
-void i2c_lock_adapter(struct i2c_adapter *adapter)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
-
- if (parent)
- i2c_lock_adapter(parent);
- else
- rt_mutex_lock(&adapter->bus_lock);
-}
-EXPORT_SYMBOL_GPL(i2c_lock_adapter);
-
-/**
- * i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment
- * @adapter: Target I2C bus segment
- */
-static int i2c_trylock_adapter(struct i2c_adapter *adapter)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
-
- if (parent)
- return i2c_trylock_adapter(parent);
- else
- return rt_mutex_trylock(&adapter->bus_lock);
-}
-
-/**
- * i2c_unlock_adapter - Release exclusive access to an I2C bus segment
- * @adapter: Target I2C bus segment
- */
-void i2c_unlock_adapter(struct i2c_adapter *adapter)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
-
- if (parent)
- i2c_unlock_adapter(parent);
- else
- rt_mutex_unlock(&adapter->bus_lock);
-}
-EXPORT_SYMBOL_GPL(i2c_unlock_adapter);
-
-/**
- * i2c_new_device - instantiate an i2c device
- * @adap: the adapter managing the device
- * @info: describes one I2C device; bus_num is ignored
- * Context: can sleep
- *
- * Create an i2c device. Binding is handled through driver model
- * probe()/remove() methods. A driver may be bound to this device when we
- * return from this function, or any later moment (e.g. maybe hotplugging will
- * load the driver module). This call is not appropriate for use by mainboard
- * initialization logic, which usually runs during an arch_initcall() long
- * before any i2c_adapter could exist.
- *
- * This returns the new i2c client, which may be saved for later use with
- * i2c_unregister_device(); or NULL to indicate an error.
- */
-struct i2c_client *
-i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
-{
- struct i2c_client *client;
- int status;
-
- client = kzalloc(sizeof *client, GFP_KERNEL);
- if (!client)
- return NULL;
-
- client->adapter = adap;
-
- client->dev.platform_data = info->platform_data;
-
- if (info->archdata)
- client->dev.archdata = *info->archdata;
-
- client->flags = info->flags;
- client->addr = info->addr;
- client->irq = info->irq;
-
- strlcpy(client->name, info->type, sizeof(client->name));
-
- /* Check for address validity */
- status = i2c_check_client_addr_validity(client);
- if (status) {
- dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",
- client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);
- goto out_err_silent;
- }
-
- /* Check for address business */
- status = i2c_check_addr_busy(adap, client->addr);
- if (status)
- goto out_err;
-
- client->dev.parent = &client->adapter->dev;
- client->dev.bus = &i2c_bus_type;
- client->dev.type = &i2c_client_type;
- client->dev.of_node = info->of_node;
-
- /* For 10-bit clients, add an arbitrary offset to avoid collisions */
- dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
- client->addr | ((client->flags & I2C_CLIENT_TEN)
- ? 0xa000 : 0));
- status = device_register(&client->dev);
- if (status)
- goto out_err;
-
- dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
- client->name, dev_name(&client->dev));
-
- return client;
-
-out_err:
- dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
- "(%d)\n", client->name, client->addr, status);
-out_err_silent:
- kfree(client);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(i2c_new_device);
-
-
-/**
- * i2c_unregister_device - reverse effect of i2c_new_device()
- * @client: value returned from i2c_new_device()
- * Context: can sleep
- */
-void i2c_unregister_device(struct i2c_client *client)
-{
- device_unregister(&client->dev);
-}
-EXPORT_SYMBOL_GPL(i2c_unregister_device);
-
-
-static const struct i2c_device_id dummy_id[] = {
- { "dummy", 0 },
- { },
-};
-
-static int dummy_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- return 0;
-}
-
-static int dummy_remove(struct i2c_client *client)
-{
- return 0;
-}
-
-static struct i2c_driver dummy_driver = {
- .driver.name = "dummy",
- .probe = dummy_probe,
- .remove = dummy_remove,
- .id_table = dummy_id,
-};
-
-/**
- * i2c_new_dummy - return a new i2c device bound to a dummy driver
- * @adapter: the adapter managing the device
- * @address: seven bit address to be used
- * Context: can sleep
- *
- * This returns an I2C client bound to the "dummy" driver, intended for use
- * with devices that consume multiple addresses. Examples of such chips
- * include various EEPROMS (like 24c04 and 24c08 models).
- *
- * These dummy devices have two main uses. First, most I2C and SMBus calls
- * except i2c_transfer() need a client handle; the dummy will be that handle.
- * And second, this prevents the specified address from being bound to a
- * different driver.
- *
- * This returns the new i2c client, which should be saved for later use with
- * i2c_unregister_device(); or NULL to indicate an error.
- */
-struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
-{
- struct i2c_board_info info = {
- I2C_BOARD_INFO("dummy", address),
- };
-
- return i2c_new_device(adapter, &info);
-}
-EXPORT_SYMBOL_GPL(i2c_new_dummy);
-
-/* ------------------------------------------------------------------------- */
-
-/* I2C bus adapters -- one roots each I2C or SMBUS segment */
-
-static void i2c_adapter_dev_release(struct device *dev)
-{
- struct i2c_adapter *adap = to_i2c_adapter(dev);
- complete(&adap->dev_released);
-}
-
-/*
- * Let users instantiate I2C devices through sysfs. This can be used when
- * platform initialization code doesn't contain the proper data for
- * whatever reason. Also useful for drivers that do device detection and
- * detection fails, either because the device uses an unexpected address,
- * or this is a compatible device with different ID register values.
- *
- * Parameter checking may look overzealous, but we really don't want
- * the user to provide incorrect parameters.
- */
-static ssize_t
-i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_adapter *adap = to_i2c_adapter(dev);
- struct i2c_board_info info;
- struct i2c_client *client;
- char *blank, end;
- int res;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
-
- blank = strchr(buf, ' ');
- if (!blank) {
- dev_err(dev, "%s: Missing parameters\n", "new_device");
- return -EINVAL;
- }
- if (blank - buf > I2C_NAME_SIZE - 1) {
- dev_err(dev, "%s: Invalid device name\n", "new_device");
- return -EINVAL;
- }
- memcpy(info.type, buf, blank - buf);
-
- /* Parse remaining parameters, reject extra parameters */
- res = sscanf(++blank, "%hi%c", &info.addr, &end);
- if (res < 1) {
- dev_err(dev, "%s: Can't parse I2C address\n", "new_device");
- return -EINVAL;
- }
- if (res > 1 && end != '\n') {
- dev_err(dev, "%s: Extra parameters\n", "new_device");
- return -EINVAL;
- }
-
- client = i2c_new_device(adap, &info);
- if (!client)
- return -EINVAL;
-
- /* Keep track of the added device */
- mutex_lock(&adap->userspace_clients_lock);
- list_add_tail(&client->detected, &adap->userspace_clients);
- mutex_unlock(&adap->userspace_clients_lock);
- dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
- info.type, info.addr);
-
- return count;
-}
-
-/*
- * And of course let the users delete the devices they instantiated, if
- * they got it wrong. This interface can only be used to delete devices
- * instantiated by i2c_sysfs_new_device above. This guarantees that we
- * don't delete devices to which some kernel code still has references.
- *
- * Parameter checking may look overzealous, but we really don't want
- * the user to delete the wrong device.
- */
-static ssize_t
-i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_adapter *adap = to_i2c_adapter(dev);
- struct i2c_client *client, *next;
- unsigned short addr;
- char end;
- int res;
-
- /* Parse parameters, reject extra parameters */
- res = sscanf(buf, "%hi%c", &addr, &end);
- if (res < 1) {
- dev_err(dev, "%s: Can't parse I2C address\n", "delete_device");
- return -EINVAL;
- }
- if (res > 1 && end != '\n') {
- dev_err(dev, "%s: Extra parameters\n", "delete_device");
- return -EINVAL;
- }
-
- /* Make sure the device was added through sysfs */
- res = -ENOENT;
- mutex_lock(&adap->userspace_clients_lock);
- list_for_each_entry_safe(client, next, &adap->userspace_clients,
- detected) {
- if (client->addr == addr) {
- dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
- "delete_device", client->name, client->addr);
-
- list_del(&client->detected);
- i2c_unregister_device(client);
- res = count;
- break;
- }
- }
- mutex_unlock(&adap->userspace_clients_lock);
-
- if (res < 0)
- dev_err(dev, "%s: Can't find device in list\n",
- "delete_device");
- return res;
-}
-
-static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);
-static DEVICE_ATTR(delete_device, S_IWUSR, NULL, i2c_sysfs_delete_device);
-
-static struct attribute *i2c_adapter_attrs[] = {
- &dev_attr_name.attr,
- &dev_attr_new_device.attr,
- &dev_attr_delete_device.attr,
- NULL
-};
-
-static struct attribute_group i2c_adapter_attr_group = {
- .attrs = i2c_adapter_attrs,
-};
-
-static const struct attribute_group *i2c_adapter_attr_groups[] = {
- &i2c_adapter_attr_group,
- NULL
-};
-
-struct device_type i2c_adapter_type = {
- .groups = i2c_adapter_attr_groups,
- .release = i2c_adapter_dev_release,
-};
-EXPORT_SYMBOL_GPL(i2c_adapter_type);
-
-#ifdef CONFIG_I2C_COMPAT
-static struct class_compat *i2c_adapter_compat_class;
-#endif
-
-static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
-{
- struct i2c_devinfo *devinfo;
-
- down_read(&__i2c_board_lock);
- list_for_each_entry(devinfo, &__i2c_board_list, list) {
- if (devinfo->busnum == adapter->nr
- && !i2c_new_device(adapter,
- &devinfo->board_info))
- dev_err(&adapter->dev,
- "Can't create device at 0x%02x\n",
- devinfo->board_info.addr);
- }
- up_read(&__i2c_board_lock);
-}
-
-static int i2c_do_add_adapter(struct i2c_driver *driver,
- struct i2c_adapter *adap)
-{
- /* Detect supported devices on that bus, and instantiate them */
- i2c_detect(adap, driver);
-
- /* Let legacy drivers scan this bus for matching devices */
- if (driver->attach_adapter) {
- dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
- driver->driver.name);
- dev_warn(&adap->dev, "Please use another way to instantiate "
- "your i2c_client\n");
- /* We ignore the return code; if it fails, too bad */
- driver->attach_adapter(adap);
- }
- return 0;
-}
-
-static int __process_new_adapter(struct device_driver *d, void *data)
-{
- return i2c_do_add_adapter(to_i2c_driver(d), data);
-}
-
-static int i2c_register_adapter(struct i2c_adapter *adap)
-{
- int res = 0;
-
- /* Can't register until after driver model init */
- if (unlikely(WARN_ON(!i2c_bus_type.p))) {
- res = -EAGAIN;
- goto out_list;
- }
-
- /* Sanity checks */
- if (unlikely(adap->name[0] == '\0')) {
- pr_err("i2c-core: Attempt to register an adapter with "
- "no name!\n");
- return -EINVAL;
- }
- if (unlikely(!adap->algo)) {
- pr_err("i2c-core: Attempt to register adapter '%s' with "
- "no algo!\n", adap->name);
- return -EINVAL;
- }
-
- rt_mutex_init(&adap->bus_lock);
- mutex_init(&adap->userspace_clients_lock);
- INIT_LIST_HEAD(&adap->userspace_clients);
-
- /* Set default timeout to 1 second if not already set */
- if (adap->timeout == 0)
- adap->timeout = HZ;
-
- dev_set_name(&adap->dev, "i2c-%d", adap->nr);
- adap->dev.bus = &i2c_bus_type;
- adap->dev.type = &i2c_adapter_type;
- res = device_register(&adap->dev);
- if (res)
- goto out_list;
-
- dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
-
-#ifdef CONFIG_I2C_COMPAT
- res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,
- adap->dev.parent);
- if (res)
- dev_warn(&adap->dev,
- "Failed to create compatibility class link\n");
-#endif
-
- /* create pre-declared device nodes */
- if (adap->nr < __i2c_first_dynamic_bus_num)
- i2c_scan_static_board_info(adap);
-
- /* Notify drivers */
- mutex_lock(&core_lock);
- bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
- mutex_unlock(&core_lock);
-
- return 0;
-
-out_list:
- mutex_lock(&core_lock);
- idr_remove(&i2c_adapter_idr, adap->nr);
- mutex_unlock(&core_lock);
- return res;
-}
-
-/**
- * i2c_add_adapter - declare i2c adapter, use dynamic bus number
- * @adapter: the adapter to add
- * Context: can sleep
- *
- * This routine is used to declare an I2C adapter when its bus number
- * doesn't matter. Examples: for I2C adapters dynamically added by
- * USB links or PCI plugin cards.
- *
- * When this returns zero, a new bus number was allocated and stored
- * in adap->nr, and the specified adapter became available for clients.
- * Otherwise, a negative errno value is returned.
- */
-int i2c_add_adapter(struct i2c_adapter *adapter)
-{
- int id, res = 0;
-
-retry:
- if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
- return -ENOMEM;
-
- mutex_lock(&core_lock);
- /* "above" here means "above or equal to", sigh */
- res = idr_get_new_above(&i2c_adapter_idr, adapter,
- __i2c_first_dynamic_bus_num, &id);
- mutex_unlock(&core_lock);
-
- if (res < 0) {
- if (res == -EAGAIN)
- goto retry;
- return res;
- }
-
- adapter->nr = id;
- return i2c_register_adapter(adapter);
-}
-EXPORT_SYMBOL(i2c_add_adapter);
-
-/**
- * i2c_add_numbered_adapter - declare i2c adapter, use static bus number
- * @adap: the adapter to register (with adap->nr initialized)
- * Context: can sleep
- *
- * This routine is used to declare an I2C adapter when its bus number
- * matters. For example, use it for I2C adapters from system-on-chip CPUs,
- * or otherwise built in to the system's mainboard, and where i2c_board_info
- * is used to properly configure I2C devices.
- *
- * If the requested bus number is set to -1, then this function will behave
- * identically to i2c_add_adapter, and will dynamically assign a bus number.
- *
- * If no devices have pre-been declared for this bus, then be sure to
- * register the adapter before any dynamically allocated ones. Otherwise
- * the required bus ID may not be available.
- *
- * When this returns zero, the specified adapter became available for
- * clients using the bus number provided in adap->nr. Also, the table
- * of I2C devices pre-declared using i2c_register_board_info() is scanned,
- * and the appropriate driver model device nodes are created. Otherwise, a
- * negative errno value is returned.
- */
-int i2c_add_numbered_adapter(struct i2c_adapter *adap)
-{
- int id;
- int status;
-
- if (adap->nr == -1) /* -1 means dynamically assign bus id */
- return i2c_add_adapter(adap);
- if (adap->nr & ~MAX_ID_MASK)
- return -EINVAL;
-
-retry:
- if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
- return -ENOMEM;
-
- mutex_lock(&core_lock);
- /* "above" here means "above or equal to", sigh;
- * we need the "equal to" result to force the result
- */
- status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);
- if (status == 0 && id != adap->nr) {
- status = -EBUSY;
- idr_remove(&i2c_adapter_idr, id);
- }
- mutex_unlock(&core_lock);
- if (status == -EAGAIN)
- goto retry;
-
- if (status == 0)
- status = i2c_register_adapter(adap);
- return status;
-}
-EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
-
-static int i2c_do_del_adapter(struct i2c_driver *driver,
- struct i2c_adapter *adapter)
-{
- struct i2c_client *client, *_n;
- int res;
-
- /* Remove the devices we created ourselves as the result of hardware
- * probing (using a driver's detect method) */
- list_for_each_entry_safe(client, _n, &driver->clients, detected) {
- if (client->adapter == adapter) {
- dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
- client->name, client->addr);
- list_del(&client->detected);
- i2c_unregister_device(client);
- }
- }
-
- if (!driver->detach_adapter)
- return 0;
- dev_warn(&adapter->dev, "%s: detach_adapter method is deprecated\n",
- driver->driver.name);
- res = driver->detach_adapter(adapter);
- if (res)
- dev_err(&adapter->dev, "detach_adapter failed (%d) "
- "for driver [%s]\n", res, driver->driver.name);
- return res;
-}
-
-static int __unregister_client(struct device *dev, void *dummy)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- if (client && strcmp(client->name, "dummy"))
- i2c_unregister_device(client);
- return 0;
-}
-
-static int __unregister_dummy(struct device *dev, void *dummy)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- if (client)
- i2c_unregister_device(client);
- return 0;
-}
-
-static int __process_removed_adapter(struct device_driver *d, void *data)
-{
- return i2c_do_del_adapter(to_i2c_driver(d), data);
-}
-
-/**
- * i2c_del_adapter - unregister I2C adapter
- * @adap: the adapter being unregistered
- * Context: can sleep
- *
- * This unregisters an I2C adapter which was previously registered
- * by @i2c_add_adapter or @i2c_add_numbered_adapter.
- */
-int i2c_del_adapter(struct i2c_adapter *adap)
-{
- int res = 0;
- struct i2c_adapter *found;
- struct i2c_client *client, *next;
-
- /* First make sure that this adapter was ever added */
- mutex_lock(&core_lock);
- found = idr_find(&i2c_adapter_idr, adap->nr);
- mutex_unlock(&core_lock);
- if (found != adap) {
- pr_debug("i2c-core: attempting to delete unregistered "
- "adapter [%s]\n", adap->name);
- return -EINVAL;
- }
-
- /* Tell drivers about this removal */
- mutex_lock(&core_lock);
- res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
- __process_removed_adapter);
- mutex_unlock(&core_lock);
- if (res)
- return res;
-
- /* Remove devices instantiated from sysfs */
- mutex_lock(&adap->userspace_clients_lock);
- list_for_each_entry_safe(client, next, &adap->userspace_clients,
- detected) {
- dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
- client->addr);
- list_del(&client->detected);
- i2c_unregister_device(client);
- }
- mutex_unlock(&adap->userspace_clients_lock);
-
- /* Detach any active clients. This can't fail, thus we do not
- * check the returned value. This is a two-pass process, because
- * we can't remove the dummy devices during the first pass: they
- * could have been instantiated by real devices wishing to clean
- * them up properly, so we give them a chance to do that first. */
- res = device_for_each_child(&adap->dev, NULL, __unregister_client);
- res = device_for_each_child(&adap->dev, NULL, __unregister_dummy);
-
-#ifdef CONFIG_I2C_COMPAT
- class_compat_remove_link(i2c_adapter_compat_class, &adap->dev,
- adap->dev.parent);
-#endif
-
- /* device name is gone after device_unregister */
- dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
-
- /* clean up the sysfs representation */
- init_completion(&adap->dev_released);
- device_unregister(&adap->dev);
-
- /* wait for sysfs to drop all references */
- wait_for_completion(&adap->dev_released);
-
- /* free bus id */
- mutex_lock(&core_lock);
- idr_remove(&i2c_adapter_idr, adap->nr);
- mutex_unlock(&core_lock);
-
- /* Clear the device structure in case this adapter is ever going to be
- added again */
- memset(&adap->dev, 0, sizeof(adap->dev));
-
- return 0;
-}
-EXPORT_SYMBOL(i2c_del_adapter);
-
-
-/* ------------------------------------------------------------------------- */
-
-int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
-{
- int res;
-
- mutex_lock(&core_lock);
- res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn);
- mutex_unlock(&core_lock);
-
- return res;
-}
-EXPORT_SYMBOL_GPL(i2c_for_each_dev);
-
-static int __process_new_driver(struct device *dev, void *data)
-{
- if (dev->type != &i2c_adapter_type)
- return 0;
- return i2c_do_add_adapter(data, to_i2c_adapter(dev));
-}
-
-/*
- * An i2c_driver is used with one or more i2c_client (device) nodes to access
- * i2c slave chips, on a bus instance associated with some i2c_adapter.
- */
-
-int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
-{
- int res;
-
- /* Can't register until after driver model init */
- if (unlikely(WARN_ON(!i2c_bus_type.p)))
- return -EAGAIN;
-
- /* add the driver to the list of i2c drivers in the driver core */
- driver->driver.owner = owner;
- driver->driver.bus = &i2c_bus_type;
-
- /* When registration returns, the driver core
- * will have called probe() for all matching-but-unbound devices.
- */
- res = driver_register(&driver->driver);
- if (res)
- return res;
-
- /* Drivers should switch to dev_pm_ops instead. */
- if (driver->suspend)
- pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
- driver->driver.name);
- if (driver->resume)
- pr_warn("i2c-core: driver [%s] using legacy resume method\n",
- driver->driver.name);
-
- pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
-
- INIT_LIST_HEAD(&driver->clients);
- /* Walk the adapters that are already present */
- i2c_for_each_dev(driver, __process_new_driver);
-
- return 0;
-}
-EXPORT_SYMBOL(i2c_register_driver);
-
-static int __process_removed_driver(struct device *dev, void *data)
-{
- if (dev->type != &i2c_adapter_type)
- return 0;
- return i2c_do_del_adapter(data, to_i2c_adapter(dev));
-}
-
-/**
- * i2c_del_driver - unregister I2C driver
- * @driver: the driver being unregistered
- * Context: can sleep
- */
-void i2c_del_driver(struct i2c_driver *driver)
-{
- i2c_for_each_dev(driver, __process_removed_driver);
-
- driver_unregister(&driver->driver);
- pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
-}
-EXPORT_SYMBOL(i2c_del_driver);
-
-/* ------------------------------------------------------------------------- */
-
-/**
- * i2c_use_client - increments the reference count of the i2c client structure
- * @client: the client being referenced
- *
- * Each live reference to a client should be refcounted. The driver model does
- * that automatically as part of driver binding, so that most drivers don't
- * need to do this explicitly: they hold a reference until they're unbound
- * from the device.
- *
- * A pointer to the client with the incremented reference counter is returned.
- */
-struct i2c_client *i2c_use_client(struct i2c_client *client)
-{
- if (client && get_device(&client->dev))
- return client;
- return NULL;
-}
-EXPORT_SYMBOL(i2c_use_client);
-
-/**
- * i2c_release_client - release a use of the i2c client structure
- * @client: the client being no longer referenced
- *
- * Must be called when a user of a client is finished with it.
- */
-void i2c_release_client(struct i2c_client *client)
-{
- if (client)
- put_device(&client->dev);
-}
-EXPORT_SYMBOL(i2c_release_client);
-
-struct i2c_cmd_arg {
- unsigned cmd;
- void *arg;
-};
-
-static int i2c_cmd(struct device *dev, void *_arg)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_cmd_arg *arg = _arg;
-
- if (client && client->driver && client->driver->command)
- client->driver->command(client, arg->cmd, arg->arg);
- return 0;
-}
-
-void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
-{
- struct i2c_cmd_arg cmd_arg;
-
- cmd_arg.cmd = cmd;
- cmd_arg.arg = arg;
- device_for_each_child(&adap->dev, &cmd_arg, i2c_cmd);
-}
-EXPORT_SYMBOL(i2c_clients_command);
-
-static int __init i2c_init(void)
-{
- int retval;
-
- retval = bus_register(&i2c_bus_type);
- if (retval)
- return retval;
-#ifdef CONFIG_I2C_COMPAT
- i2c_adapter_compat_class = class_compat_register("i2c-adapter");
- if (!i2c_adapter_compat_class) {
- retval = -ENOMEM;
- goto bus_err;
- }
-#endif
- retval = i2c_add_driver(&dummy_driver);
- if (retval)
- goto class_err;
- return 0;
-
-class_err:
-#ifdef CONFIG_I2C_COMPAT
- class_compat_unregister(i2c_adapter_compat_class);
-bus_err:
-#endif
- bus_unregister(&i2c_bus_type);
- return retval;
-}
-
-static void __exit i2c_exit(void)
-{
- i2c_del_driver(&dummy_driver);
-#ifdef CONFIG_I2C_COMPAT
- class_compat_unregister(i2c_adapter_compat_class);
-#endif
- bus_unregister(&i2c_bus_type);
-}
-
-/* We must initialize early, because some subsystems register i2c drivers
- * in subsys_initcall() code, but are linked (and initialized) before i2c.
- */
-postcore_initcall(i2c_init);
-module_exit(i2c_exit);
-
-/* ----------------------------------------------------
- * the functional interface to the i2c busses.
- * ----------------------------------------------------
- */
-
-/**
- * i2c_transfer - execute a single or combined I2C message
- * @adap: Handle to I2C bus
- * @msgs: One or more messages to execute before STOP is issued to
- * terminate the operation; each message begins with a START.
- * @num: Number of messages to be executed.
- *
- * Returns negative errno, else the number of messages executed.
- *
- * Note that there is no requirement that each message be sent to
- * the same slave address, although that is the most common model.
- */
-int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- unsigned long orig_jiffies;
- int ret, try;
-
- /* REVISIT the fault reporting model here is weak:
- *
- * - When we get an error after receiving N bytes from a slave,
- * there is no way to report "N".
- *
- * - When we get a NAK after transmitting N bytes to a slave,
- * there is no way to report "N" ... or to let the master
- * continue executing the rest of this combined message, if
- * that's the appropriate response.
- *
- * - When for example "num" is two and we successfully complete
- * the first message but get an error part way through the
- * second, it's unclear whether that should be reported as
- * one (discarding status on the second message) or errno
- * (discarding status on the first one).
- */
-
- if (adap->algo->master_xfer) {
-#ifdef DEBUG
- for (ret = 0; ret < num; ret++) {
- dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
- "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
- ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
- (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
- }
-#endif
-
- if (in_atomic() || irqs_disabled()) {
- ret = i2c_trylock_adapter(adap);
- if (!ret)
- /* I2C activity is ongoing. */
- return -EAGAIN;
- } else {
- i2c_lock_adapter(adap);
- }
-
- /* Retry automatically on arbitration loss */
- orig_jiffies = jiffies;
- for (ret = 0, try = 0; try <= adap->retries; try++) {
- ret = adap->algo->master_xfer(adap, msgs, num);
- if (ret != -EAGAIN)
- break;
- if (time_after(jiffies, orig_jiffies + adap->timeout))
- break;
- }
- i2c_unlock_adapter(adap);
-
- return ret;
- } else {
- dev_dbg(&adap->dev, "I2C level transfers not supported\n");
- return -EOPNOTSUPP;
- }
-}
-EXPORT_SYMBOL(i2c_transfer);
-
-/**
- * i2c_master_send - issue a single I2C message in master transmit mode
- * @client: Handle to slave device
- * @buf: Data that will be written to the slave
- * @count: How many bytes to write, must be less than 64k since msg.len is u16
- *
- * Returns negative errno, or else the number of bytes written.
- */
-int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
-{
- int ret;
- struct i2c_adapter *adap = client->adapter;
- struct i2c_msg msg;
-
- msg.addr = client->addr;
- msg.flags = client->flags & I2C_M_TEN;
- msg.len = count;
- msg.buf = (char *)buf;
-
- ret = i2c_transfer(adap, &msg, 1);
-
- /*
- * If everything went ok (i.e. 1 msg transmitted), return #bytes
- * transmitted, else error code.
- */
- return (ret == 1) ? count : ret;
-}
-EXPORT_SYMBOL(i2c_master_send);
-
-/**
- * i2c_master_recv - issue a single I2C message in master receive mode
- * @client: Handle to slave device
- * @buf: Where to store data read from slave
- * @count: How many bytes to read, must be less than 64k since msg.len is u16
- *
- * Returns negative errno, or else the number of bytes read.
- */
-int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
-{
- struct i2c_adapter *adap = client->adapter;
- struct i2c_msg msg;
- int ret;
-
- msg.addr = client->addr;
- msg.flags = client->flags & I2C_M_TEN;
- msg.flags |= I2C_M_RD;
- msg.len = count;
- msg.buf = buf;
-
- ret = i2c_transfer(adap, &msg, 1);
-
- /*
- * If everything went ok (i.e. 1 msg received), return #bytes received,
- * else error code.
- */
- return (ret == 1) ? count : ret;
-}
-EXPORT_SYMBOL(i2c_master_recv);
-
-/* ----------------------------------------------------
- * the i2c address scanning function
- * Will not work for 10-bit addresses!
- * ----------------------------------------------------
- */
-
-/*
- * Legacy default probe function, mostly relevant for SMBus. The default
- * probe method is a quick write, but it is known to corrupt the 24RF08
- * EEPROMs due to a state machine bug, and could also irreversibly
- * write-protect some EEPROMs, so for address ranges 0x30-0x37 and 0x50-0x5f,
- * we use a short byte read instead. Also, some bus drivers don't implement
- * quick write, so we fallback to a byte read in that case too.
- * On x86, there is another special case for FSC hardware monitoring chips,
- * which want regular byte reads (address 0x73.) Fortunately, these are the
- * only known chips using this I2C address on PC hardware.
- * Returns 1 if probe succeeded, 0 if not.
- */
-static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
-{
- int err;
- union i2c_smbus_data dummy;
-
-#ifdef CONFIG_X86
- if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON)
- && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA))
- err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
- I2C_SMBUS_BYTE_DATA, &dummy);
- else
-#endif
- if (!((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50)
- && i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
- err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
- I2C_SMBUS_QUICK, NULL);
- else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE))
- err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
- I2C_SMBUS_BYTE, &dummy);
- else {
- dev_warn(&adap->dev, "No suitable probing method supported\n");
- err = -EOPNOTSUPP;
- }
-
- return err >= 0;
-}
-
-static int i2c_detect_address(struct i2c_client *temp_client,
- struct i2c_driver *driver)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter = temp_client->adapter;
- int addr = temp_client->addr;
- int err;
-
- /* Make sure the address is valid */
- err = i2c_check_addr_validity(addr);
- if (err) {
- dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
- addr);
- return err;
- }
-
- /* Skip if already in use */
- if (i2c_check_addr_busy(adapter, addr))
- return 0;
-
- /* Make sure there is something at this address */
- if (!i2c_default_probe(adapter, addr))
- return 0;
-
- /* Finally call the custom detection function */
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = addr;
- err = driver->detect(temp_client, &info);
- if (err) {
- /* -ENODEV is returned if the detection fails. We catch it
- here as this isn't an error. */
- return err == -ENODEV ? 0 : err;
- }
-
- /* Consistency check */
- if (info.type[0] == '\0') {
- dev_err(&adapter->dev, "%s detection function provided "
- "no name for 0x%x\n", driver->driver.name,
- addr);
- } else {
- struct i2c_client *client;
-
- /* Detection succeeded, instantiate the device */
- dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
- info.type, info.addr);
- client = i2c_new_device(adapter, &info);
- if (client)
- list_add_tail(&client->detected, &driver->clients);
- else
- dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
- info.type, info.addr);
- }
- return 0;
-}
-
-static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
-{
- const unsigned short *address_list;
- struct i2c_client *temp_client;
- int i, err = 0;
- int adap_id = i2c_adapter_id(adapter);
-
- address_list = driver->address_list;
- if (!driver->detect || !address_list)
- return 0;
-
- /* Stop here if the classes do not match */
- if (!(adapter->class & driver->class))
- return 0;
-
- /* Set up a temporary client to help detect callback */
- temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!temp_client)
- return -ENOMEM;
- temp_client->adapter = adapter;
-
- for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
- dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
- "addr 0x%02x\n", adap_id, address_list[i]);
- temp_client->addr = address_list[i];
- err = i2c_detect_address(temp_client, driver);
- if (unlikely(err))
- break;
- }
-
- kfree(temp_client);
- return err;
-}
-
-int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr)
-{
- return i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
- I2C_SMBUS_QUICK, NULL) >= 0;
-}
-EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read);
-
-struct i2c_client *
-i2c_new_probed_device(struct i2c_adapter *adap,
- struct i2c_board_info *info,
- unsigned short const *addr_list,
- int (*probe)(struct i2c_adapter *, unsigned short addr))
-{
- int i;
-
- if (!probe)
- probe = i2c_default_probe;
-
- for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
- /* Check address validity */
- if (i2c_check_addr_validity(addr_list[i]) < 0) {
- dev_warn(&adap->dev, "Invalid 7-bit address "
- "0x%02x\n", addr_list[i]);
- continue;
- }
-
- /* Check address availability */
- if (i2c_check_addr_busy(adap, addr_list[i])) {
- dev_dbg(&adap->dev, "Address 0x%02x already in "
- "use, not probing\n", addr_list[i]);
- continue;
- }
-
- /* Test address responsiveness */
- if (probe(adap, addr_list[i]))
- break;
- }
-
- if (addr_list[i] == I2C_CLIENT_END) {
- dev_dbg(&adap->dev, "Probing failed, no device found\n");
- return NULL;
- }
-
- info->addr = addr_list[i];
- return i2c_new_device(adap, info);
-}
-EXPORT_SYMBOL_GPL(i2c_new_probed_device);
-
-struct i2c_adapter *i2c_get_adapter(int nr)
-{
- struct i2c_adapter *adapter;
-
- mutex_lock(&core_lock);
- adapter = idr_find(&i2c_adapter_idr, nr);
- if (adapter && !try_module_get(adapter->owner))
- adapter = NULL;
-
- mutex_unlock(&core_lock);
- return adapter;
-}
-EXPORT_SYMBOL(i2c_get_adapter);
-
-void i2c_put_adapter(struct i2c_adapter *adap)
-{
- module_put(adap->owner);
-}
-EXPORT_SYMBOL(i2c_put_adapter);
-
-/* The SMBus parts */
-
-#define POLY (0x1070U << 3)
-static u8 crc8(u16 data)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- if (data & 0x8000)
- data = data ^ POLY;
- data = data << 1;
- }
- return (u8)(data >> 8);
-}
-
-/* Incremental CRC8 over count bytes in the array pointed to by p */
-static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- crc = crc8((crc ^ p[i]) << 8);
- return crc;
-}
-
-/* Assume a 7-bit address, which is reasonable for SMBus */
-static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)
-{
- /* The address will be sent first */
- u8 addr = (msg->addr << 1) | !!(msg->flags & I2C_M_RD);
- pec = i2c_smbus_pec(pec, &addr, 1);
-
- /* The data buffer follows */
- return i2c_smbus_pec(pec, msg->buf, msg->len);
-}
-
-/* Used for write only transactions */
-static inline void i2c_smbus_add_pec(struct i2c_msg *msg)
-{
- msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg);
- msg->len++;
-}
-
-/* Return <0 on CRC error
- If there was a write before this read (most cases) we need to take the
- partial CRC from the write part into account.
- Note that this function does modify the message (we need to decrease the
- message length to hide the CRC byte from the caller). */
-static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
-{
- u8 rpec = msg->buf[--msg->len];
- cpec = i2c_smbus_msg_pec(cpec, msg);
-
- if (rpec != cpec) {
- pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
- rpec, cpec);
- return -EBADMSG;
- }
- return 0;
-}
-
-/**
- * i2c_smbus_read_byte - SMBus "receive byte" protocol
- * @client: Handle to slave device
- *
- * This executes the SMBus "receive byte" protocol, returning negative errno
- * else the byte received from the device.
- */
-s32 i2c_smbus_read_byte(const struct i2c_client *client)
-{
- union i2c_smbus_data data;
- int status;
-
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_READ, 0,
- I2C_SMBUS_BYTE, &data);
- return (status < 0) ? status : data.byte;
-}
-EXPORT_SYMBOL(i2c_smbus_read_byte);
-
-/**
- * i2c_smbus_write_byte - SMBus "send byte" protocol
- * @client: Handle to slave device
- * @value: Byte to be sent
- *
- * This executes the SMBus "send byte" protocol, returning negative errno
- * else zero on success.
- */
-s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value)
-{
- return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
-}
-EXPORT_SYMBOL(i2c_smbus_write_byte);
-
-/**
- * i2c_smbus_read_byte_data - SMBus "read byte" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- *
- * This executes the SMBus "read byte" protocol, returning negative errno
- * else a data byte received from the device.
- */
-s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)
-{
- union i2c_smbus_data data;
- int status;
-
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_READ, command,
- I2C_SMBUS_BYTE_DATA, &data);
- return (status < 0) ? status : data.byte;
-}
-EXPORT_SYMBOL(i2c_smbus_read_byte_data);
-
-/**
- * i2c_smbus_write_byte_data - SMBus "write byte" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- * @value: Byte being written
- *
- * This executes the SMBus "write byte" protocol, returning negative errno
- * else zero on success.
- */
-s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command,
- u8 value)
-{
- union i2c_smbus_data data;
- data.byte = value;
- return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_BYTE_DATA, &data);
-}
-EXPORT_SYMBOL(i2c_smbus_write_byte_data);
-
-/**
- * i2c_smbus_read_word_data - SMBus "read word" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- *
- * This executes the SMBus "read word" protocol, returning negative errno
- * else a 16-bit unsigned "word" received from the device.
- */
-s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)
-{
- union i2c_smbus_data data;
- int status;
-
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_READ, command,
- I2C_SMBUS_WORD_DATA, &data);
- return (status < 0) ? status : data.word;
-}
-EXPORT_SYMBOL(i2c_smbus_read_word_data);
-
-/**
- * i2c_smbus_write_word_data - SMBus "write word" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- * @value: 16-bit "word" being written
- *
- * This executes the SMBus "write word" protocol, returning negative errno
- * else zero on success.
- */
-s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command,
- u16 value)
-{
- union i2c_smbus_data data;
- data.word = value;
- return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_WORD_DATA, &data);
-}
-EXPORT_SYMBOL(i2c_smbus_write_word_data);
-
-/**
- * i2c_smbus_process_call - SMBus "process call" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- * @value: 16-bit "word" being written
- *
- * This executes the SMBus "process call" protocol, returning negative errno
- * else a 16-bit unsigned "word" received from the device.
- */
-s32 i2c_smbus_process_call(const struct i2c_client *client, u8 command,
- u16 value)
-{
- union i2c_smbus_data data;
- int status;
- data.word = value;
-
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_PROC_CALL, &data);
- return (status < 0) ? status : data.word;
-}
-EXPORT_SYMBOL(i2c_smbus_process_call);
-
-/**
- * i2c_smbus_read_block_data - SMBus "block read" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- * @values: Byte array into which data will be read; big enough to hold
- * the data returned by the slave. SMBus allows at most 32 bytes.
- *
- * This executes the SMBus "block read" protocol, returning negative errno
- * else the number of data bytes in the slave's response.
- *
- * Note that using this function requires that the client's adapter support
- * the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality. Not all adapter drivers
- * support this; its emulation through I2C messaging relies on a specific
- * mechanism (I2C_M_RECV_LEN) which may not be implemented.
- */
-s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command,
- u8 *values)
-{
- union i2c_smbus_data data;
- int status;
-
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_READ, command,
- I2C_SMBUS_BLOCK_DATA, &data);
- if (status)
- return status;
-
- memcpy(values, &data.block[1], data.block[0]);
- return data.block[0];
-}
-EXPORT_SYMBOL(i2c_smbus_read_block_data);
-
-/**
- * i2c_smbus_write_block_data - SMBus "block write" protocol
- * @client: Handle to slave device
- * @command: Byte interpreted by slave
- * @length: Size of data block; SMBus allows at most 32 bytes
- * @values: Byte array which will be written.
- *
- * This executes the SMBus "block write" protocol, returning negative errno
- * else zero on success.
- */
-s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command,
- u8 length, const u8 *values)
-{
- union i2c_smbus_data data;
-
- if (length > I2C_SMBUS_BLOCK_MAX)
- length = I2C_SMBUS_BLOCK_MAX;
- data.block[0] = length;
- memcpy(&data.block[1], values, length);
- return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_BLOCK_DATA, &data);
-}
-EXPORT_SYMBOL(i2c_smbus_write_block_data);
-
-/* Returns the number of read bytes */
-s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command,
- u8 length, u8 *values)
-{
- union i2c_smbus_data data;
- int status;
-
- if (length > I2C_SMBUS_BLOCK_MAX)
- length = I2C_SMBUS_BLOCK_MAX;
- data.block[0] = length;
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_READ, command,
- I2C_SMBUS_I2C_BLOCK_DATA, &data);
- if (status < 0)
- return status;
-
- memcpy(values, &data.block[1], data.block[0]);
- return data.block[0];
-}
-EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
-
-s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command,
- u8 length, const u8 *values)
-{
- union i2c_smbus_data data;
-
- if (length > I2C_SMBUS_BLOCK_MAX)
- length = I2C_SMBUS_BLOCK_MAX;
- data.block[0] = length;
- memcpy(data.block + 1, values, length);
- return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_I2C_BLOCK_DATA, &data);
-}
-EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
-
-/* Simulate a SMBus command using the i2c protocol
- No checking of parameters is done! */
-static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
- unsigned short flags,
- char read_write, u8 command, int size,
- union i2c_smbus_data *data)
-{
- /* So we need to generate a series of msgs. In the case of writing, we
- need to use only one message; when reading, we need two. We initialize
- most things with sane defaults, to keep the code below somewhat
- simpler. */
- unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
- unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
- int num = read_write == I2C_SMBUS_READ ? 2 : 1;
- struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
- { addr, flags | I2C_M_RD, 0, msgbuf1 }
- };
- int i;
- u8 partial_pec = 0;
- int status;
-
- msgbuf0[0] = command;
- switch (size) {
- case I2C_SMBUS_QUICK:
- msg[0].len = 0;
- /* Special case: The read/write field is used as data */
- msg[0].flags = flags | (read_write == I2C_SMBUS_READ ?
- I2C_M_RD : 0);
- num = 1;
- break;
- case I2C_SMBUS_BYTE:
- if (read_write == I2C_SMBUS_READ) {
- /* Special case: only a read! */
- msg[0].flags = I2C_M_RD | flags;
- num = 1;
- }
- break;
- case I2C_SMBUS_BYTE_DATA:
- if (read_write == I2C_SMBUS_READ)
- msg[1].len = 1;
- else {
- msg[0].len = 2;
- msgbuf0[1] = data->byte;
- }
- break;
- case I2C_SMBUS_WORD_DATA:
- if (read_write == I2C_SMBUS_READ)
- msg[1].len = 2;
- else {
- msg[0].len = 3;
- msgbuf0[1] = data->word & 0xff;
- msgbuf0[2] = data->word >> 8;
- }
- break;
- case I2C_SMBUS_PROC_CALL:
- num = 2; /* Special case */
- read_write = I2C_SMBUS_READ;
- msg[0].len = 3;
- msg[1].len = 2;
- msgbuf0[1] = data->word & 0xff;
- msgbuf0[2] = data->word >> 8;
- break;
- case I2C_SMBUS_BLOCK_DATA:
- if (read_write == I2C_SMBUS_READ) {
- msg[1].flags |= I2C_M_RECV_LEN;
- msg[1].len = 1; /* block length will be added by
- the underlying bus driver */
- } else {
- msg[0].len = data->block[0] + 2;
- if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
- dev_err(&adapter->dev,
- "Invalid block write size %d\n",
- data->block[0]);
- return -EINVAL;
- }
- for (i = 1; i < msg[0].len; i++)
- msgbuf0[i] = data->block[i-1];
- }
- break;
- case I2C_SMBUS_BLOCK_PROC_CALL:
- num = 2; /* Another special case */
- read_write = I2C_SMBUS_READ;
- if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
- dev_err(&adapter->dev,
- "Invalid block write size %d\n",
- data->block[0]);
- return -EINVAL;
- }
- msg[0].len = data->block[0] + 2;
- for (i = 1; i < msg[0].len; i++)
- msgbuf0[i] = data->block[i-1];
- msg[1].flags |= I2C_M_RECV_LEN;
- msg[1].len = 1; /* block length will be added by
- the underlying bus driver */
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- if (read_write == I2C_SMBUS_READ) {
- msg[1].len = data->block[0];
- } else {
- msg[0].len = data->block[0] + 1;
- if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
- dev_err(&adapter->dev,
- "Invalid block write size %d\n",
- data->block[0]);
- return -EINVAL;
- }
- for (i = 1; i <= data->block[0]; i++)
- msgbuf0[i] = data->block[i];
- }
- break;
- default:
- dev_err(&adapter->dev, "Unsupported transaction %d\n", size);
- return -EOPNOTSUPP;
- }
-
- i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK
- && size != I2C_SMBUS_I2C_BLOCK_DATA);
- if (i) {
- /* Compute PEC if first message is a write */
- if (!(msg[0].flags & I2C_M_RD)) {
- if (num == 1) /* Write only */
- i2c_smbus_add_pec(&msg[0]);
- else /* Write followed by read */
- partial_pec = i2c_smbus_msg_pec(0, &msg[0]);
- }
- /* Ask for PEC if last message is a read */
- if (msg[num-1].flags & I2C_M_RD)
- msg[num-1].len++;
- }
-
- status = i2c_transfer(adapter, msg, num);
- if (status < 0)
- return status;
-
- /* Check PEC if last message is a read */
- if (i && (msg[num-1].flags & I2C_M_RD)) {
- status = i2c_smbus_check_pec(partial_pec, &msg[num-1]);
- if (status < 0)
- return status;
- }
-
- if (read_write == I2C_SMBUS_READ)
- switch (size) {
- case I2C_SMBUS_BYTE:
- data->byte = msgbuf0[0];
- break;
- case I2C_SMBUS_BYTE_DATA:
- data->byte = msgbuf1[0];
- break;
- case I2C_SMBUS_WORD_DATA:
- case I2C_SMBUS_PROC_CALL:
- data->word = msgbuf1[0] | (msgbuf1[1] << 8);
- break;
- case I2C_SMBUS_I2C_BLOCK_DATA:
- for (i = 0; i < data->block[0]; i++)
- data->block[i+1] = msgbuf1[i];
- break;
- case I2C_SMBUS_BLOCK_DATA:
- case I2C_SMBUS_BLOCK_PROC_CALL:
- for (i = 0; i < msgbuf1[0] + 1; i++)
- data->block[i] = msgbuf1[i];
- break;
- }
- return 0;
-}
-
-/**
- * i2c_smbus_xfer - execute SMBus protocol operations
- * @adapter: Handle to I2C bus
- * @addr: Address of SMBus slave on that bus
- * @flags: I2C_CLIENT_* flags (usually zero or I2C_CLIENT_PEC)
- * @read_write: I2C_SMBUS_READ or I2C_SMBUS_WRITE
- * @command: Byte interpreted by slave, for protocols which use such bytes
- * @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL
- * @data: Data to be read or written
- *
- * This executes an SMBus protocol operation, and returns a negative
- * errno code else zero on success.
- */
-s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
- char read_write, u8 command, int protocol,
- union i2c_smbus_data *data)
-{
- unsigned long orig_jiffies;
- int try;
- s32 res;
-
- flags &= I2C_M_TEN | I2C_CLIENT_PEC;
-
- if (adapter->algo->smbus_xfer) {
- i2c_lock_adapter(adapter);
-
- /* Retry automatically on arbitration loss */
- orig_jiffies = jiffies;
- for (res = 0, try = 0; try <= adapter->retries; try++) {
- res = adapter->algo->smbus_xfer(adapter, addr, flags,
- read_write, command,
- protocol, data);
- if (res != -EAGAIN)
- break;
- if (time_after(jiffies,
- orig_jiffies + adapter->timeout))
- break;
- }
- i2c_unlock_adapter(adapter);
- } else
- res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
- command, protocol, data);
-
- return res;
-}
-EXPORT_SYMBOL(i2c_smbus_xfer);
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus main module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-core.h b/ANDROID_3.4.5/drivers/i2c/i2c-core.h
deleted file mode 100644
index 18a8fd21..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-core.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * i2c-core.h - interfaces internal to the I2C framework
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-#include <linux/rwsem.h>
-
-struct i2c_devinfo {
- struct list_head list;
- int busnum;
- struct i2c_board_info board_info;
-};
-
-/* board_lock protects board_list and first_dynamic_bus_num.
- * only i2c core components are allowed to use these symbols.
- */
-extern struct rw_semaphore __i2c_board_lock;
-extern struct list_head __i2c_board_list;
-extern int __i2c_first_dynamic_bus_num;
-
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-dev.c b/ANDROID_3.4.5/drivers/i2c/i2c-dev.c
deleted file mode 100644
index 45048323..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-dev.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- i2c-dev.c - i2c-bus driver, char device interface
-
- Copyright (C) 1995-97 Simon G. Vogl
- Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
- Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301 USA.
-*/
-
-/* Note that this is a complete rewrite of Simon Vogl's i2c-dev module.
- But I have used so much of his original code and ideas that it seems
- only fair to recognize him as co-author -- Frodo */
-
-/* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk@telos.de> */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/notifier.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
-#include <linux/jiffies.h>
-#include <linux/uaccess.h>
-
-/*
- * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a
- * slave (i2c_client) with which messages will be exchanged. It's coupled
- * with a character special file which is accessed by user mode drivers.
- *
- * The list of i2c_dev structures is parallel to the i2c_adapter lists
- * maintained by the driver model, and is updated using bus notifications.
- */
-struct i2c_dev {
- struct list_head list;
- struct i2c_adapter *adap;
- struct device *dev;
-};
-
-#define I2C_MINORS 256
-static LIST_HEAD(i2c_dev_list);
-static DEFINE_SPINLOCK(i2c_dev_list_lock);
-
-static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
-{
- struct i2c_dev *i2c_dev;
-
- spin_lock(&i2c_dev_list_lock);
- list_for_each_entry(i2c_dev, &i2c_dev_list, list) {
- if (i2c_dev->adap->nr == index)
- goto found;
- }
- i2c_dev = NULL;
-found:
- spin_unlock(&i2c_dev_list_lock);
- return i2c_dev;
-}
-
-static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
-{
- struct i2c_dev *i2c_dev;
-
- if (adap->nr >= I2C_MINORS) {
- printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n",
- adap->nr);
- return ERR_PTR(-ENODEV);
- }
-
- i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
- if (!i2c_dev)
- return ERR_PTR(-ENOMEM);
- i2c_dev->adap = adap;
-
- spin_lock(&i2c_dev_list_lock);
- list_add_tail(&i2c_dev->list, &i2c_dev_list);
- spin_unlock(&i2c_dev_list_lock);
- return i2c_dev;
-}
-
-static void return_i2c_dev(struct i2c_dev *i2c_dev)
-{
- spin_lock(&i2c_dev_list_lock);
- list_del(&i2c_dev->list);
- spin_unlock(&i2c_dev_list_lock);
- kfree(i2c_dev);
-}
-
-static ssize_t show_adapter_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt));
-
- if (!i2c_dev)
- return -ENODEV;
- return sprintf(buf, "%s\n", i2c_dev->adap->name);
-}
-static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * After opening an instance of this character special file, a file
- * descriptor starts out associated only with an i2c_adapter (and bus).
- *
- * Using the I2C_RDWR ioctl(), you can then *immediately* issue i2c_msg
- * traffic to any devices on the bus used by that adapter. That's because
- * the i2c_msg vectors embed all the addressing information they need, and
- * are submitted directly to an i2c_adapter. However, SMBus-only adapters
- * don't support that interface.
- *
- * To use read()/write() system calls on that file descriptor, or to use
- * SMBus interfaces (and work with SMBus-only hosts!), you must first issue
- * an I2C_SLAVE (or I2C_SLAVE_FORCE) ioctl. That configures an anonymous
- * (never registered) i2c_client so it holds the addressing information
- * needed by those system calls and by this SMBus interface.
- */
-
-static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
- loff_t *offset)
-{
- char *tmp;
- int ret;
-
- struct i2c_client *client = file->private_data;
-
- if (count > 8192)
- count = 8192;
-
- tmp = kmalloc(count, GFP_KERNEL);
- if (tmp == NULL)
- return -ENOMEM;
-
- pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
- iminor(file->f_path.dentry->d_inode), count);
-
- ret = i2c_master_recv(client, tmp, count);
- if (ret >= 0)
- ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
- kfree(tmp);
- return ret;
-}
-
-static ssize_t i2cdev_write(struct file *file, const char __user *buf,
- size_t count, loff_t *offset)
-{
- int ret;
- char *tmp;
- struct i2c_client *client = file->private_data;
-
- if (count > 8192)
- count = 8192;
-
- tmp = memdup_user(buf, count);
- if (IS_ERR(tmp))
- return PTR_ERR(tmp);
-
- pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
- iminor(file->f_path.dentry->d_inode), count);
-
- ret = i2c_master_send(client, tmp, count);
- kfree(tmp);
- return ret;
-}
-
-static int i2cdev_check(struct device *dev, void *addrp)
-{
- struct i2c_client *client = i2c_verify_client(dev);
-
- if (!client || client->addr != *(unsigned int *)addrp)
- return 0;
-
- return dev->driver ? -EBUSY : 0;
-}
-
-/* walk up mux tree */
-static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
- int result;
-
- result = device_for_each_child(&adapter->dev, &addr, i2cdev_check);
- if (!result && parent)
- result = i2cdev_check_mux_parents(parent, addr);
-
- return result;
-}
-
-/* recurse down mux tree */
-static int i2cdev_check_mux_children(struct device *dev, void *addrp)
-{
- int result;
-
- if (dev->type == &i2c_adapter_type)
- result = device_for_each_child(dev, addrp,
- i2cdev_check_mux_children);
- else
- result = i2cdev_check(dev, addrp);
-
- return result;
-}
-
-/* This address checking function differs from the one in i2c-core
- in that it considers an address with a registered device, but no
- driver bound to it, as NOT busy. */
-static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
-{
- struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
- int result = 0;
-
- if (parent)
- result = i2cdev_check_mux_parents(parent, addr);
-
- if (!result)
- result = device_for_each_child(&adapter->dev, &addr,
- i2cdev_check_mux_children);
-
- return result;
-}
-
-static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
- unsigned long arg)
-{
- struct i2c_rdwr_ioctl_data rdwr_arg;
- struct i2c_msg *rdwr_pa;
- u8 __user **data_ptrs;
- int i, res;
-
- if (copy_from_user(&rdwr_arg,
- (struct i2c_rdwr_ioctl_data __user *)arg,
- sizeof(rdwr_arg)))
- return -EFAULT;
-
- /* Put an arbitrary limit on the number of messages that can
- * be sent at once */
- if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
- return -EINVAL;
-
- rdwr_pa = memdup_user(rdwr_arg.msgs,
- rdwr_arg.nmsgs * sizeof(struct i2c_msg));
- if (IS_ERR(rdwr_pa))
- return PTR_ERR(rdwr_pa);
-
- data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
- if (data_ptrs == NULL) {
- kfree(rdwr_pa);
- return -ENOMEM;
- }
-
- res = 0;
- for (i = 0; i < rdwr_arg.nmsgs; i++) {
- /* Limit the size of the message to a sane amount;
- * and don't let length change either. */
- if ((rdwr_pa[i].len > 8192) ||
- (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
- res = -EINVAL;
- break;
- }
- data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
- rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
- if (IS_ERR(rdwr_pa[i].buf)) {
- res = PTR_ERR(rdwr_pa[i].buf);
- break;
- }
- }
- if (res < 0) {
- int j;
- for (j = 0; j < i; ++j)
- kfree(rdwr_pa[j].buf);
- kfree(data_ptrs);
- kfree(rdwr_pa);
- return res;
- }
-
- res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
- while (i-- > 0) {
- if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
- if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
- rdwr_pa[i].len))
- res = -EFAULT;
- }
- kfree(rdwr_pa[i].buf);
- }
- kfree(data_ptrs);
- kfree(rdwr_pa);
- return res;
-}
-
-static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
- unsigned long arg)
-{
- struct i2c_smbus_ioctl_data data_arg;
- union i2c_smbus_data temp;
- int datasize, res;
-
- if (copy_from_user(&data_arg,
- (struct i2c_smbus_ioctl_data __user *) arg,
- sizeof(struct i2c_smbus_ioctl_data)))
- return -EFAULT;
- if ((data_arg.size != I2C_SMBUS_BYTE) &&
- (data_arg.size != I2C_SMBUS_QUICK) &&
- (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
- (data_arg.size != I2C_SMBUS_WORD_DATA) &&
- (data_arg.size != I2C_SMBUS_PROC_CALL) &&
- (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
- (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
- (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
- (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
- dev_dbg(&client->adapter->dev,
- "size out of range (%x) in ioctl I2C_SMBUS.\n",
- data_arg.size);
- return -EINVAL;
- }
- /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
- so the check is valid if size==I2C_SMBUS_QUICK too. */
- if ((data_arg.read_write != I2C_SMBUS_READ) &&
- (data_arg.read_write != I2C_SMBUS_WRITE)) {
- dev_dbg(&client->adapter->dev,
- "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
- data_arg.read_write);
- return -EINVAL;
- }
-
- /* Note that command values are always valid! */
-
- if ((data_arg.size == I2C_SMBUS_QUICK) ||
- ((data_arg.size == I2C_SMBUS_BYTE) &&
- (data_arg.read_write == I2C_SMBUS_WRITE)))
- /* These are special: we do not use data */
- return i2c_smbus_xfer(client->adapter, client->addr,
- client->flags, data_arg.read_write,
- data_arg.command, data_arg.size, NULL);
-
- if (data_arg.data == NULL) {
- dev_dbg(&client->adapter->dev,
- "data is NULL pointer in ioctl I2C_SMBUS.\n");
- return -EINVAL;
- }
-
- if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
- (data_arg.size == I2C_SMBUS_BYTE))
- datasize = sizeof(data_arg.data->byte);
- else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
- (data_arg.size == I2C_SMBUS_PROC_CALL))
- datasize = sizeof(data_arg.data->word);
- else /* size == smbus block, i2c block, or block proc. call */
- datasize = sizeof(data_arg.data->block);
-
- if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
- (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
- (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
- (data_arg.read_write == I2C_SMBUS_WRITE)) {
- if (copy_from_user(&temp, data_arg.data, datasize))
- return -EFAULT;
- }
- if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
- /* Convert old I2C block commands to the new
- convention. This preserves binary compatibility. */
- data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
- if (data_arg.read_write == I2C_SMBUS_READ)
- temp.block[0] = I2C_SMBUS_BLOCK_MAX;
- }
- res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- data_arg.read_write, data_arg.command, data_arg.size, &temp);
- if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
- (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
- (data_arg.read_write == I2C_SMBUS_READ))) {
- if (copy_to_user(data_arg.data, &temp, datasize))
- return -EFAULT;
- }
- return res;
-}
-
-static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct i2c_client *client = file->private_data;
- unsigned long funcs;
-
- dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
- cmd, arg);
-
- switch (cmd) {
- case I2C_SLAVE:
- case I2C_SLAVE_FORCE:
- /* NOTE: devices set up to work with "new style" drivers
- * can't use I2C_SLAVE, even when the device node is not
- * bound to a driver. Only I2C_SLAVE_FORCE will work.
- *
- * Setting the PEC flag here won't affect kernel drivers,
- * which will be using the i2c_client node registered with
- * the driver model core. Likewise, when that client has
- * the PEC flag already set, the i2c-dev driver won't see
- * (or use) this setting.
- */
- if ((arg > 0x3ff) ||
- (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
- return -EINVAL;
- if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
- return -EBUSY;
- /* REVISIT: address could become busy later */
- client->addr = arg;
- return 0;
- case I2C_TENBIT:
- if (arg)
- client->flags |= I2C_M_TEN;
- else
- client->flags &= ~I2C_M_TEN;
- return 0;
- case I2C_PEC:
- if (arg)
- client->flags |= I2C_CLIENT_PEC;
- else
- client->flags &= ~I2C_CLIENT_PEC;
- return 0;
- case I2C_FUNCS:
- funcs = i2c_get_functionality(client->adapter);
- return put_user(funcs, (unsigned long __user *)arg);
-
- case I2C_RDWR:
- return i2cdev_ioctl_rdrw(client, arg);
-
- case I2C_SMBUS:
- return i2cdev_ioctl_smbus(client, arg);
-
- case I2C_RETRIES:
- client->adapter->retries = arg;
- break;
- case I2C_TIMEOUT:
- /* For historical reasons, user-space sets the timeout
- * value in units of 10 ms.
- */
- client->adapter->timeout = msecs_to_jiffies(arg * 10);
- break;
- default:
- /* NOTE: returning a fault code here could cause trouble
- * in buggy userspace code. Some old kernel bugs returned
- * zero in this case, and userspace code might accidentally
- * have depended on that bug.
- */
- return -ENOTTY;
- }
- return 0;
-}
-
-static int i2cdev_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- struct i2c_client *client;
- struct i2c_adapter *adap;
- struct i2c_dev *i2c_dev;
-
- i2c_dev = i2c_dev_get_by_minor(minor);
- if (!i2c_dev)
- return -ENODEV;
-
- adap = i2c_get_adapter(i2c_dev->adap->nr);
- if (!adap)
- return -ENODEV;
-
- /* This creates an anonymous i2c_client, which may later be
- * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
- *
- * This client is ** NEVER REGISTERED ** with the driver model
- * or I2C core code!! It just holds private copies of addressing
- * information and maybe a PEC flag.
- */
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (!client) {
- i2c_put_adapter(adap);
- return -ENOMEM;
- }
- snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
-
- client->adapter = adap;
- file->private_data = client;
-
- return 0;
-}
-
-static int i2cdev_release(struct inode *inode, struct file *file)
-{
- struct i2c_client *client = file->private_data;
-
- i2c_put_adapter(client->adapter);
- kfree(client);
- file->private_data = NULL;
-
- return 0;
-}
-
-static const struct file_operations i2cdev_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = i2cdev_read,
- .write = i2cdev_write,
- .unlocked_ioctl = i2cdev_ioctl,
- .open = i2cdev_open,
- .release = i2cdev_release,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static struct class *i2c_dev_class;
-
-static int i2cdev_attach_adapter(struct device *dev, void *dummy)
-{
- struct i2c_adapter *adap;
- struct i2c_dev *i2c_dev;
- int res;
-
- if (dev->type != &i2c_adapter_type)
- return 0;
- adap = to_i2c_adapter(dev);
-
- i2c_dev = get_free_i2c_dev(adap);
- if (IS_ERR(i2c_dev))
- return PTR_ERR(i2c_dev);
-
- /* register this i2c device with the driver core */
- i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
- MKDEV(I2C_MAJOR, adap->nr), NULL,
- "i2c-%d", adap->nr);
- if (IS_ERR(i2c_dev->dev)) {
- res = PTR_ERR(i2c_dev->dev);
- goto error;
- }
- res = device_create_file(i2c_dev->dev, &dev_attr_name);
- if (res)
- goto error_destroy;
-
- pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
- adap->name, adap->nr);
- return 0;
-error_destroy:
- device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
-error:
- return_i2c_dev(i2c_dev);
- return res;
-}
-
-static int i2cdev_detach_adapter(struct device *dev, void *dummy)
-{
- struct i2c_adapter *adap;
- struct i2c_dev *i2c_dev;
-
- if (dev->type != &i2c_adapter_type)
- return 0;
- adap = to_i2c_adapter(dev);
-
- i2c_dev = i2c_dev_get_by_minor(adap->nr);
- if (!i2c_dev) /* attach_adapter must have failed */
- return 0;
-
- device_remove_file(i2c_dev->dev, &dev_attr_name);
- return_i2c_dev(i2c_dev);
- device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
-
- pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
- return 0;
-}
-
-static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
- void *data)
-{
- struct device *dev = data;
-
- switch (action) {
- case BUS_NOTIFY_ADD_DEVICE:
- return i2cdev_attach_adapter(dev, NULL);
- case BUS_NOTIFY_DEL_DEVICE:
- return i2cdev_detach_adapter(dev, NULL);
- }
-
- return 0;
-}
-
-static struct notifier_block i2cdev_notifier = {
- .notifier_call = i2cdev_notifier_call,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * module load/unload record keeping
- */
-
-static int __init i2c_dev_init(void)
-{
- int res;
-
- printk(KERN_INFO "i2c /dev entries driver\n");
-
- res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
- if (res)
- goto out;
-
- i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
- if (IS_ERR(i2c_dev_class)) {
- res = PTR_ERR(i2c_dev_class);
- goto out_unreg_chrdev;
- }
-
- /* Keep track of adapters which will be added or removed later */
- res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
- if (res)
- goto out_unreg_class;
-
- /* Bind to already existing adapters right away */
- i2c_for_each_dev(NULL, i2cdev_attach_adapter);
-
- return 0;
-
-out_unreg_class:
- class_destroy(i2c_dev_class);
-out_unreg_chrdev:
- unregister_chrdev(I2C_MAJOR, "i2c");
-out:
- printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
- return res;
-}
-
-static void __exit i2c_dev_exit(void)
-{
- bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier);
- i2c_for_each_dev(NULL, i2cdev_detach_adapter);
- class_destroy(i2c_dev_class);
- unregister_chrdev(I2C_MAJOR, "i2c");
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
- "Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C /dev entries driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_dev_init);
-module_exit(i2c_dev_exit);
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-mux.c b/ANDROID_3.4.5/drivers/i2c/i2c-mux.c
deleted file mode 100644
index d7a4833b..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-mux.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Multiplexed I2C bus driver.
- *
- * Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
- * Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
- * Copyright (c) 2009-2010 NSN GmbH & Co KG <michael.lawnick.ext@nsn.com>
- *
- * Simplifies access to complex multiplexed I2C bus topologies, by presenting
- * each multiplexed bus segment as an additional I2C adapter.
- * Supports multi-level mux'ing (mux behind a mux).
- *
- * Based on:
- * i2c-virt.c from Kumar Gala <galak@kernel.crashing.org>
- * i2c-virtual.c from Ken Harrenstien, Copyright (c) 2004 Google, Inc.
- * i2c-virtual.c from Brian Kuschak <bkuschak@yahoo.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/i2c-mux.h>
-
-/* multiplexer per channel data */
-struct i2c_mux_priv {
- struct i2c_adapter adap;
- struct i2c_algorithm algo;
-
- struct i2c_adapter *parent;
- void *mux_dev; /* the mux chip/device */
- u32 chan_id; /* the channel id */
-
- int (*select)(struct i2c_adapter *, void *mux_dev, u32 chan_id);
- int (*deselect)(struct i2c_adapter *, void *mux_dev, u32 chan_id);
-};
-
-static int i2c_mux_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg msgs[], int num)
-{
- struct i2c_mux_priv *priv = adap->algo_data;
- struct i2c_adapter *parent = priv->parent;
- int ret;
-
- /* Switch to the right mux port and perform the transfer. */
-
- ret = priv->select(parent, priv->mux_dev, priv->chan_id);
- if (ret >= 0)
- ret = parent->algo->master_xfer(parent, msgs, num);
- if (priv->deselect)
- priv->deselect(parent, priv->mux_dev, priv->chan_id);
-
- return ret;
-}
-
-static int i2c_mux_smbus_xfer(struct i2c_adapter *adap,
- u16 addr, unsigned short flags,
- char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- struct i2c_mux_priv *priv = adap->algo_data;
- struct i2c_adapter *parent = priv->parent;
- int ret;
-
- /* Select the right mux port and perform the transfer. */
-
- ret = priv->select(parent, priv->mux_dev, priv->chan_id);
- if (ret >= 0)
- ret = parent->algo->smbus_xfer(parent, addr, flags,
- read_write, command, size, data);
- if (priv->deselect)
- priv->deselect(parent, priv->mux_dev, priv->chan_id);
-
- return ret;
-}
-
-/* Return the parent's functionality */
-static u32 i2c_mux_functionality(struct i2c_adapter *adap)
-{
- struct i2c_mux_priv *priv = adap->algo_data;
- struct i2c_adapter *parent = priv->parent;
-
- return parent->algo->functionality(parent);
-}
-
-struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
- void *mux_dev, u32 force_nr, u32 chan_id,
- int (*select) (struct i2c_adapter *,
- void *, u32),
- int (*deselect) (struct i2c_adapter *,
- void *, u32))
-{
- struct i2c_mux_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(struct i2c_mux_priv), GFP_KERNEL);
- if (!priv)
- return NULL;
-
- /* Set up private adapter data */
- priv->parent = parent;
- priv->mux_dev = mux_dev;
- priv->chan_id = chan_id;
- priv->select = select;
- priv->deselect = deselect;
-
- /* Need to do algo dynamically because we don't know ahead
- * of time what sort of physical adapter we'll be dealing with.
- */
- if (parent->algo->master_xfer)
- priv->algo.master_xfer = i2c_mux_master_xfer;
- if (parent->algo->smbus_xfer)
- priv->algo.smbus_xfer = i2c_mux_smbus_xfer;
- priv->algo.functionality = i2c_mux_functionality;
-
- /* Now fill out new adapter structure */
- snprintf(priv->adap.name, sizeof(priv->adap.name),
- "i2c-%d-mux (chan_id %d)", i2c_adapter_id(parent), chan_id);
- priv->adap.owner = THIS_MODULE;
- priv->adap.algo = &priv->algo;
- priv->adap.algo_data = priv;
- priv->adap.dev.parent = &parent->dev;
-
- if (force_nr) {
- priv->adap.nr = force_nr;
- ret = i2c_add_numbered_adapter(&priv->adap);
- } else {
- ret = i2c_add_adapter(&priv->adap);
- }
- if (ret < 0) {
- dev_err(&parent->dev,
- "failed to add mux-adapter (error=%d)\n",
- ret);
- kfree(priv);
- return NULL;
- }
-
- dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
- i2c_adapter_id(&priv->adap));
-
- return &priv->adap;
-}
-EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
-
-int i2c_del_mux_adapter(struct i2c_adapter *adap)
-{
- struct i2c_mux_priv *priv = adap->algo_data;
- int ret;
-
- ret = i2c_del_adapter(adap);
- if (ret < 0)
- return ret;
- kfree(priv);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(i2c_del_mux_adapter);
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("I2C driver for multiplexed I2C busses");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/i2c/i2c-smbus.c b/ANDROID_3.4.5/drivers/i2c/i2c-smbus.c
deleted file mode 100644
index 9836d08f..00000000
--- a/ANDROID_3.4.5/drivers/i2c/i2c-smbus.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * i2c-smbus.c - SMBus extensions to the I2C protocol
- *
- * Copyright (C) 2008 David Brownell
- * Copyright (C) 2010 Jean Delvare <khali@linux-fr.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/i2c.h>
-#include <linux/i2c-smbus.h>
-#include <linux/slab.h>
-
-struct i2c_smbus_alert {
- unsigned int alert_edge_triggered:1;
- int irq;
- struct work_struct alert;
- struct i2c_client *ara; /* Alert response address */
-};
-
-struct alert_data {
- unsigned short addr;
- u8 flag:1;
-};
-
-/* If this is the alerting device, notify its driver */
-static int smbus_do_alert(struct device *dev, void *addrp)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct alert_data *data = addrp;
-
- if (!client || client->addr != data->addr)
- return 0;
- if (client->flags & I2C_CLIENT_TEN)
- return 0;
-
- /*
- * Drivers should either disable alerts, or provide at least
- * a minimal handler. Lock so client->driver won't change.
- */
- device_lock(dev);
- if (client->driver) {
- if (client->driver->alert)
- client->driver->alert(client, data->flag);
- else
- dev_warn(&client->dev, "no driver alert()!\n");
- } else
- dev_dbg(&client->dev, "alert with no driver\n");
- device_unlock(dev);
-
- /* Stop iterating after we find the device */
- return -EBUSY;
-}
-
-/*
- * The alert IRQ handler needs to hand work off to a task which can issue
- * SMBus calls, because those sleeping calls can't be made in IRQ context.
- */
-static void smbus_alert(struct work_struct *work)
-{
- struct i2c_smbus_alert *alert;
- struct i2c_client *ara;
- unsigned short prev_addr = 0; /* Not a valid address */
-
- alert = container_of(work, struct i2c_smbus_alert, alert);
- ara = alert->ara;
-
- for (;;) {
- s32 status;
- struct alert_data data;
-
- /*
- * Devices with pending alerts reply in address order, low
- * to high, because of slave transmit arbitration. After
- * responding, an SMBus device stops asserting SMBALERT#.
- *
- * Note that SMBus 2.0 reserves 10-bit addresess for future
- * use. We neither handle them, nor try to use PEC here.
- */
- status = i2c_smbus_read_byte(ara);
- if (status < 0)
- break;
-
- data.flag = status & 1;
- data.addr = status >> 1;
-
- if (data.addr == prev_addr) {
- dev_warn(&ara->dev, "Duplicate SMBALERT# from dev "
- "0x%02x, skipping\n", data.addr);
- break;
- }
- dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n",
- data.addr, data.flag);
-
- /* Notify driver for the device which issued the alert */
- device_for_each_child(&ara->adapter->dev, &data,
- smbus_do_alert);
- prev_addr = data.addr;
- }
-
- /* We handled all alerts; re-enable level-triggered IRQs */
- if (!alert->alert_edge_triggered)
- enable_irq(alert->irq);
-}
-
-static irqreturn_t smbalert_irq(int irq, void *d)
-{
- struct i2c_smbus_alert *alert = d;
-
- /* Disable level-triggered IRQs until we handle them */
- if (!alert->alert_edge_triggered)
- disable_irq_nosync(irq);
-
- schedule_work(&alert->alert);
- return IRQ_HANDLED;
-}
-
-/* Setup SMBALERT# infrastructure */
-static int smbalert_probe(struct i2c_client *ara,
- const struct i2c_device_id *id)
-{
- struct i2c_smbus_alert_setup *setup = ara->dev.platform_data;
- struct i2c_smbus_alert *alert;
- struct i2c_adapter *adapter = ara->adapter;
- int res;
-
- alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL);
- if (!alert)
- return -ENOMEM;
-
- alert->alert_edge_triggered = setup->alert_edge_triggered;
- alert->irq = setup->irq;
- INIT_WORK(&alert->alert, smbus_alert);
- alert->ara = ara;
-
- if (setup->irq > 0) {
- res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq,
- 0, "smbus_alert", alert);
- if (res) {
- kfree(alert);
- return res;
- }
- }
-
- i2c_set_clientdata(ara, alert);
- dev_info(&adapter->dev, "supports SMBALERT#, %s trigger\n",
- setup->alert_edge_triggered ? "edge" : "level");
-
- return 0;
-}
-
-/* IRQ resource is managed so it is freed automatically */
-static int smbalert_remove(struct i2c_client *ara)
-{
- struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
-
- cancel_work_sync(&alert->alert);
-
- kfree(alert);
- return 0;
-}
-
-static const struct i2c_device_id smbalert_ids[] = {
- { "smbus_alert", 0 },
- { /* LIST END */ }
-};
-MODULE_DEVICE_TABLE(i2c, smbalert_ids);
-
-static struct i2c_driver smbalert_driver = {
- .driver = {
- .name = "smbus_alert",
- },
- .probe = smbalert_probe,
- .remove = smbalert_remove,
- .id_table = smbalert_ids,
-};
-
-/**
- * i2c_setup_smbus_alert - Setup SMBus alert support
- * @adapter: the target adapter
- * @setup: setup data for the SMBus alert handler
- * Context: can sleep
- *
- * Setup handling of the SMBus alert protocol on a given I2C bus segment.
- *
- * Handling can be done either through our IRQ handler, or by the
- * adapter (from its handler, periodic polling, or whatever).
- *
- * NOTE that if we manage the IRQ, we *MUST* know if it's level or
- * edge triggered in order to hand it to the workqueue correctly.
- * If triggering the alert seems to wedge the system, you probably
- * should have said it's level triggered.
- *
- * This returns the ara client, which should be saved for later use with
- * i2c_handle_smbus_alert() and ultimately i2c_unregister_device(); or NULL
- * to indicate an error.
- */
-struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter,
- struct i2c_smbus_alert_setup *setup)
-{
- struct i2c_board_info ara_board_info = {
- I2C_BOARD_INFO("smbus_alert", 0x0c),
- .platform_data = setup,
- };
-
- return i2c_new_device(adapter, &ara_board_info);
-}
-EXPORT_SYMBOL_GPL(i2c_setup_smbus_alert);
-
-/**
- * i2c_handle_smbus_alert - Handle an SMBus alert
- * @ara: the ARA client on the relevant adapter
- * Context: can't sleep
- *
- * Helper function to be called from an I2C bus driver's interrupt
- * handler. It will schedule the alert work, in turn calling the
- * corresponding I2C device driver's alert function.
- *
- * It is assumed that ara is a valid i2c client previously returned by
- * i2c_setup_smbus_alert().
- */
-int i2c_handle_smbus_alert(struct i2c_client *ara)
-{
- struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
-
- return schedule_work(&alert->alert);
-}
-EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert);
-
-static int __init i2c_smbus_init(void)
-{
- return i2c_add_driver(&smbalert_driver);
-}
-
-static void __exit i2c_smbus_exit(void)
-{
- i2c_del_driver(&smbalert_driver);
-}
-
-module_init(i2c_smbus_init);
-module_exit(i2c_smbus_exit);
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("SMBus protocol extensions support");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/i2c/muxes/Kconfig b/ANDROID_3.4.5/drivers/i2c/muxes/Kconfig
deleted file mode 100644
index 90b7a016..00000000
--- a/ANDROID_3.4.5/drivers/i2c/muxes/Kconfig
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Multiplexer I2C chip drivers configuration
-#
-
-menu "Multiplexer I2C Chip support"
- depends on I2C_MUX
-
-config I2C_MUX_GPIO
- tristate "GPIO-based I2C multiplexer"
- depends on GENERIC_GPIO
- help
- If you say yes to this option, support will be included for a
- GPIO based I2C multiplexer. This driver provides access to
- I2C busses connected through a MUX, which is controlled
- through GPIO pins.
-
- This driver can also be built as a module. If so, the module
- will be called gpio-i2cmux.
-
-config I2C_MUX_PCA9541
- tristate "NXP PCA9541 I2C Master Selector"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for the NXP PCA9541
- I2C Master Selector.
-
- This driver can also be built as a module. If so, the module
- will be called pca9541.
-
-config I2C_MUX_PCA954x
- tristate "Philips PCA954x I2C Mux/switches"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for the Philips PCA954x
- I2C mux/switch devices.
-
- This driver can also be built as a module. If so, the module
- will be called pca954x.
-
-endmenu
diff --git a/ANDROID_3.4.5/drivers/i2c/muxes/Makefile b/ANDROID_3.4.5/drivers/i2c/muxes/Makefile
deleted file mode 100644
index 4640436e..00000000
--- a/ANDROID_3.4.5/drivers/i2c/muxes/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for multiplexer I2C chip drivers.
-
-obj-$(CONFIG_I2C_MUX_GPIO) += gpio-i2cmux.o
-obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o
-obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o
-
-ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/ANDROID_3.4.5/drivers/i2c/muxes/gpio-i2cmux.c b/ANDROID_3.4.5/drivers/i2c/muxes/gpio-i2cmux.c
deleted file mode 100644
index e5fa695e..00000000
--- a/ANDROID_3.4.5/drivers/i2c/muxes/gpio-i2cmux.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * I2C multiplexer using GPIO API
- *
- * Peter Korsgaard <peter.korsgaard@barco.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c-mux.h>
-#include <linux/gpio-i2cmux.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-
-struct gpiomux {
- struct i2c_adapter *parent;
- struct i2c_adapter **adap; /* child busses */
- struct gpio_i2cmux_platform_data data;
-};
-
-static void gpiomux_set(const struct gpiomux *mux, unsigned val)
-{
- int i;
-
- for (i = 0; i < mux->data.n_gpios; i++)
- gpio_set_value(mux->data.gpios[i], val & (1 << i));
-}
-
-static int gpiomux_select(struct i2c_adapter *adap, void *data, u32 chan)
-{
- struct gpiomux *mux = data;
-
- gpiomux_set(mux, mux->data.values[chan]);
-
- return 0;
-}
-
-static int gpiomux_deselect(struct i2c_adapter *adap, void *data, u32 chan)
-{
- struct gpiomux *mux = data;
-
- gpiomux_set(mux, mux->data.idle);
-
- return 0;
-}
-
-static int __devinit gpiomux_probe(struct platform_device *pdev)
-{
- struct gpiomux *mux;
- struct gpio_i2cmux_platform_data *pdata;
- struct i2c_adapter *parent;
- int (*deselect) (struct i2c_adapter *, void *, u32);
- unsigned initial_state;
- int i, ret;
-
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "Missing platform data\n");
- return -ENODEV;
- }
-
- parent = i2c_get_adapter(pdata->parent);
- if (!parent) {
- dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
- pdata->parent);
- return -ENODEV;
- }
-
- mux = kzalloc(sizeof(*mux), GFP_KERNEL);
- if (!mux) {
- ret = -ENOMEM;
- goto alloc_failed;
- }
-
- mux->parent = parent;
- mux->data = *pdata;
- mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
- GFP_KERNEL);
- if (!mux->adap) {
- ret = -ENOMEM;
- goto alloc_failed2;
- }
-
- if (pdata->idle != GPIO_I2CMUX_NO_IDLE) {
- initial_state = pdata->idle;
- deselect = gpiomux_deselect;
- } else {
- initial_state = pdata->values[0];
- deselect = NULL;
- }
-
- for (i = 0; i < pdata->n_gpios; i++) {
- ret = gpio_request(pdata->gpios[i], "gpio-i2cmux");
- if (ret)
- goto err_request_gpio;
- gpio_direction_output(pdata->gpios[i],
- initial_state & (1 << i));
- }
-
- for (i = 0; i < pdata->n_values; i++) {
- u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
-
- mux->adap[i] = i2c_add_mux_adapter(parent, mux, nr, i,
- gpiomux_select, deselect);
- if (!mux->adap[i]) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
- goto add_adapter_failed;
- }
- }
-
- dev_info(&pdev->dev, "%d port mux on %s adapter\n",
- pdata->n_values, parent->name);
-
- platform_set_drvdata(pdev, mux);
-
- return 0;
-
-add_adapter_failed:
- for (; i > 0; i--)
- i2c_del_mux_adapter(mux->adap[i - 1]);
- i = pdata->n_gpios;
-err_request_gpio:
- for (; i > 0; i--)
- gpio_free(pdata->gpios[i - 1]);
- kfree(mux->adap);
-alloc_failed2:
- kfree(mux);
-alloc_failed:
- i2c_put_adapter(parent);
-
- return ret;
-}
-
-static int __devexit gpiomux_remove(struct platform_device *pdev)
-{
- struct gpiomux *mux = platform_get_drvdata(pdev);
- int i;
-
- for (i = 0; i < mux->data.n_values; i++)
- i2c_del_mux_adapter(mux->adap[i]);
-
- for (i = 0; i < mux->data.n_gpios; i++)
- gpio_free(mux->data.gpios[i]);
-
- platform_set_drvdata(pdev, NULL);
- i2c_put_adapter(mux->parent);
- kfree(mux->adap);
- kfree(mux);
-
- return 0;
-}
-
-static struct platform_driver gpiomux_driver = {
- .probe = gpiomux_probe,
- .remove = __devexit_p(gpiomux_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = "gpio-i2cmux",
- },
-};
-
-module_platform_driver(gpiomux_driver);
-
-MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver");
-MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:gpio-i2cmux");
diff --git a/ANDROID_3.4.5/drivers/i2c/muxes/pca9541.c b/ANDROID_3.4.5/drivers/i2c/muxes/pca9541.c
deleted file mode 100644
index e0df9b6c..00000000
--- a/ANDROID_3.4.5/drivers/i2c/muxes/pca9541.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * I2C multiplexer driver for PCA9541 bus master selector
- *
- * Copyright (c) 2010 Ericsson AB.
- *
- * Author: Guenter Roeck <guenter.roeck@ericsson.com>
- *
- * Derived from:
- * pca954x.c
- *
- * Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
- * Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/i2c-mux.h>
-
-#include <linux/i2c/pca954x.h>
-
-/*
- * The PCA9541 is a bus master selector. It supports two I2C masters connected
- * to a single slave bus.
- *
- * Before each bus transaction, a master has to acquire bus ownership. After the
- * transaction is complete, bus ownership has to be released. This fits well
- * into the I2C multiplexer framework, which provides select and release
- * functions for this purpose. For this reason, this driver is modeled as
- * single-channel I2C bus multiplexer.
- *
- * This driver assumes that the two bus masters are controlled by two different
- * hosts. If a single host controls both masters, platform code has to ensure
- * that only one of the masters is instantiated at any given time.
- */
-
-#define PCA9541_CONTROL 0x01
-#define PCA9541_ISTAT 0x02
-
-#define PCA9541_CTL_MYBUS (1 << 0)
-#define PCA9541_CTL_NMYBUS (1 << 1)
-#define PCA9541_CTL_BUSON (1 << 2)
-#define PCA9541_CTL_NBUSON (1 << 3)
-#define PCA9541_CTL_BUSINIT (1 << 4)
-#define PCA9541_CTL_TESTON (1 << 6)
-#define PCA9541_CTL_NTESTON (1 << 7)
-
-#define PCA9541_ISTAT_INTIN (1 << 0)
-#define PCA9541_ISTAT_BUSINIT (1 << 1)
-#define PCA9541_ISTAT_BUSOK (1 << 2)
-#define PCA9541_ISTAT_BUSLOST (1 << 3)
-#define PCA9541_ISTAT_MYTEST (1 << 6)
-#define PCA9541_ISTAT_NMYTEST (1 << 7)
-
-#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
-#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
-#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
-#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON)
-
-/* arbitration timeouts, in jiffies */
-#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */
-#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */
-
-/* arbitration retry delays, in us */
-#define SELECT_DELAY_SHORT 50
-#define SELECT_DELAY_LONG 1000
-
-struct pca9541 {
- struct i2c_adapter *mux_adap;
- unsigned long select_timeout;
- unsigned long arb_timeout;
-};
-
-static const struct i2c_device_id pca9541_id[] = {
- {"pca9541", 0},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, pca9541_id);
-
-/*
- * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
- * as they will try to lock the adapter a second time.
- */
-static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
-{
- struct i2c_adapter *adap = client->adapter;
- int ret;
-
- if (adap->algo->master_xfer) {
- struct i2c_msg msg;
- char buf[2];
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 2;
- buf[0] = command;
- buf[1] = val;
- msg.buf = buf;
- ret = adap->algo->master_xfer(adap, &msg, 1);
- } else {
- union i2c_smbus_data data;
-
- data.byte = val;
- ret = adap->algo->smbus_xfer(adap, client->addr,
- client->flags,
- I2C_SMBUS_WRITE,
- command,
- I2C_SMBUS_BYTE_DATA, &data);
- }
-
- return ret;
-}
-
-/*
- * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
- * as they will try to lock adapter a second time.
- */
-static int pca9541_reg_read(struct i2c_client *client, u8 command)
-{
- struct i2c_adapter *adap = client->adapter;
- int ret;
- u8 val;
-
- if (adap->algo->master_xfer) {
- struct i2c_msg msg[2] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = &command
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = 1,
- .buf = &val
- }
- };
- ret = adap->algo->master_xfer(adap, msg, 2);
- if (ret == 2)
- ret = val;
- else if (ret >= 0)
- ret = -EIO;
- } else {
- union i2c_smbus_data data;
-
- ret = adap->algo->smbus_xfer(adap, client->addr,
- client->flags,
- I2C_SMBUS_READ,
- command,
- I2C_SMBUS_BYTE_DATA, &data);
- if (!ret)
- ret = data.byte;
- }
- return ret;
-}
-
-/*
- * Arbitration management functions
- */
-
-/* Release bus. Also reset NTESTON and BUSINIT if it was set. */
-static void pca9541_release_bus(struct i2c_client *client)
-{
- int reg;
-
- reg = pca9541_reg_read(client, PCA9541_CONTROL);
- if (reg >= 0 && !busoff(reg) && mybus(reg))
- pca9541_reg_write(client, PCA9541_CONTROL,
- (reg & PCA9541_CTL_NBUSON) >> 1);
-}
-
-/*
- * Arbitration is defined as a two-step process. A bus master can only activate
- * the slave bus if it owns it; otherwise it has to request ownership first.
- * This multi-step process ensures that access contention is resolved
- * gracefully.
- *
- * Bus Ownership Other master Action
- * state requested access
- * ----------------------------------------------------
- * off - yes wait for arbitration timeout or
- * for other master to drop request
- * off no no take ownership
- * off yes no turn on bus
- * on yes - done
- * on no - wait for arbitration timeout or
- * for other master to release bus
- *
- * The main contention point occurs if the slave bus is off and both masters
- * request ownership at the same time. In this case, one master will turn on
- * the slave bus, believing that it owns it. The other master will request
- * bus ownership. Result is that the bus is turned on, and master which did
- * _not_ own the slave bus before ends up owning it.
- */
-
-/* Control commands per PCA9541 datasheet */
-static const u8 pca9541_control[16] = {
- 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1
-};
-
-/*
- * Channel arbitration
- *
- * Return values:
- * <0: error
- * 0 : bus not acquired
- * 1 : bus acquired
- */
-static int pca9541_arbitrate(struct i2c_client *client)
-{
- struct pca9541 *data = i2c_get_clientdata(client);
- int reg;
-
- reg = pca9541_reg_read(client, PCA9541_CONTROL);
- if (reg < 0)
- return reg;
-
- if (busoff(reg)) {
- int istat;
- /*
- * Bus is off. Request ownership or turn it on unless
- * other master requested ownership.
- */
- istat = pca9541_reg_read(client, PCA9541_ISTAT);
- if (!(istat & PCA9541_ISTAT_NMYTEST)
- || time_is_before_eq_jiffies(data->arb_timeout)) {
- /*
- * Other master did not request ownership,
- * or arbitration timeout expired. Take the bus.
- */
- pca9541_reg_write(client,
- PCA9541_CONTROL,
- pca9541_control[reg & 0x0f]
- | PCA9541_CTL_NTESTON);
- data->select_timeout = SELECT_DELAY_SHORT;
- } else {
- /*
- * Other master requested ownership.
- * Set extra long timeout to give it time to acquire it.
- */
- data->select_timeout = SELECT_DELAY_LONG * 2;
- }
- } else if (mybus(reg)) {
- /*
- * Bus is on, and we own it. We are done with acquisition.
- * Reset NTESTON and BUSINIT, then return success.
- */
- if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
- pca9541_reg_write(client,
- PCA9541_CONTROL,
- reg & ~(PCA9541_CTL_NTESTON
- | PCA9541_CTL_BUSINIT));
- return 1;
- } else {
- /*
- * Other master owns the bus.
- * If arbitration timeout has expired, force ownership.
- * Otherwise request it.
- */
- data->select_timeout = SELECT_DELAY_LONG;
- if (time_is_before_eq_jiffies(data->arb_timeout)) {
- /* Time is up, take the bus and reset it. */
- pca9541_reg_write(client,
- PCA9541_CONTROL,
- pca9541_control[reg & 0x0f]
- | PCA9541_CTL_BUSINIT
- | PCA9541_CTL_NTESTON);
- } else {
- /* Request bus ownership if needed */
- if (!(reg & PCA9541_CTL_NTESTON))
- pca9541_reg_write(client,
- PCA9541_CONTROL,
- reg | PCA9541_CTL_NTESTON);
- }
- }
- return 0;
-}
-
-static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
-{
- struct pca9541 *data = i2c_get_clientdata(client);
- int ret;
- unsigned long timeout = jiffies + ARB2_TIMEOUT;
- /* give up after this time */
-
- data->arb_timeout = jiffies + ARB_TIMEOUT;
- /* force bus ownership after this time */
-
- do {
- ret = pca9541_arbitrate(client);
- if (ret)
- return ret < 0 ? ret : 0;
-
- if (data->select_timeout == SELECT_DELAY_SHORT)
- udelay(data->select_timeout);
- else
- msleep(data->select_timeout / 1000);
- } while (time_is_after_eq_jiffies(timeout));
-
- return -ETIMEDOUT;
-}
-
-static int pca9541_release_chan(struct i2c_adapter *adap,
- void *client, u32 chan)
-{
- pca9541_release_bus(client);
- return 0;
-}
-
-/*
- * I2C init/probing/exit functions
- */
-static int pca9541_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adap = client->adapter;
- struct pca954x_platform_data *pdata = client->dev.platform_data;
- struct pca9541 *data;
- int force;
- int ret = -ENODEV;
-
- if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
- goto err;
-
- data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto err;
- }
-
- i2c_set_clientdata(client, data);
-
- /*
- * I2C accesses are unprotected here.
- * We have to lock the adapter before releasing the bus.
- */
- i2c_lock_adapter(adap);
- pca9541_release_bus(client);
- i2c_unlock_adapter(adap);
-
- /* Create mux adapter */
-
- force = 0;
- if (pdata)
- force = pdata->modes[0].adap_id;
- data->mux_adap = i2c_add_mux_adapter(adap, client, force, 0,
- pca9541_select_chan,
- pca9541_release_chan);
-
- if (data->mux_adap == NULL) {
- dev_err(&client->dev, "failed to register master selector\n");
- goto exit_free;
- }
-
- dev_info(&client->dev, "registered master selector for I2C %s\n",
- client->name);
-
- return 0;
-
-exit_free:
- kfree(data);
-err:
- return ret;
-}
-
-static int pca9541_remove(struct i2c_client *client)
-{
- struct pca9541 *data = i2c_get_clientdata(client);
-
- i2c_del_mux_adapter(data->mux_adap);
-
- kfree(data);
- return 0;
-}
-
-static struct i2c_driver pca9541_driver = {
- .driver = {
- .name = "pca9541",
- .owner = THIS_MODULE,
- },
- .probe = pca9541_probe,
- .remove = pca9541_remove,
- .id_table = pca9541_id,
-};
-
-module_i2c_driver(pca9541_driver);
-
-MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
-MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/i2c/muxes/pca954x.c b/ANDROID_3.4.5/drivers/i2c/muxes/pca954x.c
deleted file mode 100644
index 0e37ef27..00000000
--- a/ANDROID_3.4.5/drivers/i2c/muxes/pca954x.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * I2C multiplexer
- *
- * Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
- * Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
- *
- * This module supports the PCA954x series of I2C multiplexer/switch chips
- * made by Philips Semiconductors.
- * This includes the:
- * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547
- * and PCA9548.
- *
- * These chips are all controlled via the I2C bus itself, and all have a
- * single 8-bit register. The upstream "parent" bus fans out to two,
- * four, or eight downstream busses or channels; which of these
- * are selected is determined by the chip type and register contents. A
- * mux can select only one sub-bus at a time; a switch can select any
- * combination simultaneously.
- *
- * Based on:
- * pca954x.c from Kumar Gala <galak@kernel.crashing.org>
- * Copyright (C) 2006
- *
- * Based on:
- * pca954x.c from Ken Harrenstien
- * Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
- *
- * Based on:
- * i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
- * and
- * pca9540.c from Jean Delvare <khali@linux-fr.org>.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/i2c-mux.h>
-
-#include <linux/i2c/pca954x.h>
-
-#define PCA954X_MAX_NCHANS 8
-
-enum pca_type {
- pca_9540,
- pca_9542,
- pca_9543,
- pca_9544,
- pca_9545,
- pca_9546,
- pca_9547,
- pca_9548,
-};
-
-struct pca954x {
- enum pca_type type;
- struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS];
-
- u8 last_chan; /* last register value */
-};
-
-struct chip_desc {
- u8 nchans;
- u8 enable; /* used for muxes only */
- enum muxtype {
- pca954x_ismux = 0,
- pca954x_isswi
- } muxtype;
-};
-
-/* Provide specs for the PCA954x types we know about */
-static const struct chip_desc chips[] = {
- [pca_9540] = {
- .nchans = 2,
- .enable = 0x4,
- .muxtype = pca954x_ismux,
- },
- [pca_9543] = {
- .nchans = 2,
- .muxtype = pca954x_isswi,
- },
- [pca_9544] = {
- .nchans = 4,
- .enable = 0x4,
- .muxtype = pca954x_ismux,
- },
- [pca_9545] = {
- .nchans = 4,
- .muxtype = pca954x_isswi,
- },
- [pca_9547] = {
- .nchans = 8,
- .enable = 0x8,
- .muxtype = pca954x_ismux,
- },
- [pca_9548] = {
- .nchans = 8,
- .muxtype = pca954x_isswi,
- },
-};
-
-static const struct i2c_device_id pca954x_id[] = {
- { "pca9540", pca_9540 },
- { "pca9542", pca_9540 },
- { "pca9543", pca_9543 },
- { "pca9544", pca_9544 },
- { "pca9545", pca_9545 },
- { "pca9546", pca_9545 },
- { "pca9547", pca_9547 },
- { "pca9548", pca_9548 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, pca954x_id);
-
-/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
- for this as they will try to lock adapter a second time */
-static int pca954x_reg_write(struct i2c_adapter *adap,
- struct i2c_client *client, u8 val)
-{
- int ret = -ENODEV;
-
- if (adap->algo->master_xfer) {
- struct i2c_msg msg;
- char buf[1];
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 1;
- buf[0] = val;
- msg.buf = buf;
- ret = adap->algo->master_xfer(adap, &msg, 1);
- } else {
- union i2c_smbus_data data;
- ret = adap->algo->smbus_xfer(adap, client->addr,
- client->flags,
- I2C_SMBUS_WRITE,
- val, I2C_SMBUS_BYTE, &data);
- }
-
- return ret;
-}
-
-static int pca954x_select_chan(struct i2c_adapter *adap,
- void *client, u32 chan)
-{
- struct pca954x *data = i2c_get_clientdata(client);
- const struct chip_desc *chip = &chips[data->type];
- u8 regval;
- int ret = 0;
-
- /* we make switches look like muxes, not sure how to be smarter */
- if (chip->muxtype == pca954x_ismux)
- regval = chan | chip->enable;
- else
- regval = 1 << chan;
-
- /* Only select the channel if its different from the last channel */
- if (data->last_chan != regval) {
- ret = pca954x_reg_write(adap, client, regval);
- data->last_chan = regval;
- }
-
- return ret;
-}
-
-static int pca954x_deselect_mux(struct i2c_adapter *adap,
- void *client, u32 chan)
-{
- struct pca954x *data = i2c_get_clientdata(client);
-
- /* Deselect active channel */
- data->last_chan = 0;
- return pca954x_reg_write(adap, client, data->last_chan);
-}
-
-/*
- * I2C init/probing/exit functions
- */
-static int pca954x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
- struct pca954x_platform_data *pdata = client->dev.platform_data;
- int num, force;
- struct pca954x *data;
- int ret = -ENODEV;
-
- if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
- goto err;
-
- data = kzalloc(sizeof(struct pca954x), GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto err;
- }
-
- i2c_set_clientdata(client, data);
-
- /* Write the mux register at addr to verify
- * that the mux is in fact present. This also
- * initializes the mux to disconnected state.
- */
- if (i2c_smbus_write_byte(client, 0) < 0) {
- dev_warn(&client->dev, "probe failed\n");
- goto exit_free;
- }
-
- data->type = id->driver_data;
- data->last_chan = 0; /* force the first selection */
-
- /* Now create an adapter for each channel */
- for (num = 0; num < chips[data->type].nchans; num++) {
- force = 0; /* dynamic adap number */
- if (pdata) {
- if (num < pdata->num_modes)
- /* force static number */
- force = pdata->modes[num].adap_id;
- else
- /* discard unconfigured channels */
- break;
- }
-
- data->virt_adaps[num] =
- i2c_add_mux_adapter(adap, client,
- force, num, pca954x_select_chan,
- (pdata && pdata->modes[num].deselect_on_exit)
- ? pca954x_deselect_mux : NULL);
-
- if (data->virt_adaps[num] == NULL) {
- ret = -ENODEV;
- dev_err(&client->dev,
- "failed to register multiplexed adapter"
- " %d as bus %d\n", num, force);
- goto virt_reg_failed;
- }
- }
-
- dev_info(&client->dev,
- "registered %d multiplexed busses for I2C %s %s\n",
- num, chips[data->type].muxtype == pca954x_ismux
- ? "mux" : "switch", client->name);
-
- return 0;
-
-virt_reg_failed:
- for (num--; num >= 0; num--)
- i2c_del_mux_adapter(data->virt_adaps[num]);
-exit_free:
- kfree(data);
-err:
- return ret;
-}
-
-static int pca954x_remove(struct i2c_client *client)
-{
- struct pca954x *data = i2c_get_clientdata(client);
- const struct chip_desc *chip = &chips[data->type];
- int i, err;
-
- for (i = 0; i < chip->nchans; ++i)
- if (data->virt_adaps[i]) {
- err = i2c_del_mux_adapter(data->virt_adaps[i]);
- if (err)
- return err;
- data->virt_adaps[i] = NULL;
- }
-
- kfree(data);
- return 0;
-}
-
-static struct i2c_driver pca954x_driver = {
- .driver = {
- .name = "pca954x",
- .owner = THIS_MODULE,
- },
- .probe = pca954x_probe,
- .remove = pca954x_remove,
- .id_table = pca954x_id,
-};
-
-module_i2c_driver(pca954x_driver);
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("PCA954x I2C mux/switch driver");
-MODULE_LICENSE("GPL v2");