提交 8d41f0e8 编写于 作者: L Linus Torvalds

Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: (44 commits)
  i2c-s3c2410: Fix bug in releasing driver
  i2c-s3c2410: Fix I2C SDA to SCL setup time
  i2c: New i2c-tiny-usb bus driver
  i2c: Documentation update
  i2c: SPIN_LOCK_UNLOCKED cleanup
  i2c: Obsolete i2c-ixp2000, i2c-ixp4xx and scx200_i2c
  i2c: New Simtec I2C bus driver
  i2c: Bitbanging I2C bus driver using the GPIO API
  Use menuconfig objects - I2C
  i2c: Restore i2c_smbus_read_block_data
  i2c-pxa: Clean transaction stop
  i2c-algo-bit: Improve debugging
  i2c-algo-bit: Implement a 50/50 SCL duty cycle
  i2c-omap: Switch to static adapter numbering
  i2c: Blackfin Two Wire Interface driver
  i2c-algo-sgi: Comment and whitespace cleanups
  i2c: Make i2c_del_driver a void function
  i2c: Move i2c-isa-only exported symbol declarations
  i2c: Document i2c_new_device()
  i2c: Add i2c_new_probed_device()
  ...

Fixed trivial conflict in Documentation/feature-removal-schedule.txt manually.
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
...@@ -190,18 +190,10 @@ Who: Jean Delvare <khali@linux-fr.org> ...@@ -190,18 +190,10 @@ Who: Jean Delvare <khali@linux-fr.org>
--------------------------- ---------------------------
What: i2c_adapter.dev What: i2c_adapter.list
i2c_adapter.list
When: July 2007 When: July 2007
Why: Superfluous, given i2c_adapter.class_dev: Why: Superfluous, this list duplicates the one maintained by the driver
* The "dev" was a stand-in for the physical device node that legacy core.
drivers would not have; but now it's almost always present. Any
remaining legacy drivers must upgrade (they now trigger warnings).
* The "list" duplicates class device children.
The delay in removing this is so upgraded lm_sensors and libsensors
can get deployed. (Removal causes minor changes in the sysfs layout,
notably the location of the adapter type name and parenting the i2c
client hardware directly from their controller.)
Who: Jean Delvare <khali@linux-fr.org>, Who: Jean Delvare <khali@linux-fr.org>,
David Brownell <dbrownell@users.sourceforge.net> David Brownell <dbrownell@users.sourceforge.net>
...@@ -331,3 +323,10 @@ Who: Cornelia Huck <cornelia.huck@de.ibm.com> ...@@ -331,3 +323,10 @@ Who: Cornelia Huck <cornelia.huck@de.ibm.com>
--------------------------- ---------------------------
What: i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
When: September 2007
Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific
I2C-over-GPIO drivers.
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
...@@ -9,6 +9,8 @@ Supported adapters: ...@@ -9,6 +9,8 @@ Supported adapters:
* nForce4 MCP-04 10de:0034 * nForce4 MCP-04 10de:0034
* nForce4 MCP51 10de:0264 * nForce4 MCP51 10de:0264
* nForce4 MCP55 10de:0368 * nForce4 MCP55 10de:0368
* nForce4 MCP61 10de:03EB
* nForce4 MCP65 10de:0446
Datasheet: not publicly available, but seems to be similar to the Datasheet: not publicly available, but seems to be similar to the
AMD-8111 SMBus 2.0 adapter. AMD-8111 SMBus 2.0 adapter.
......
Revision 6, 2005-11-20 Revision 7, 2007-04-19
Jean Delvare <khali@linux-fr.org> Jean Delvare <khali@linux-fr.org>
Greg KH <greg@kroah.com> Greg KH <greg@kroah.com>
...@@ -20,6 +20,10 @@ yours for best results. ...@@ -20,6 +20,10 @@ yours for best results.
Technical changes: Technical changes:
* [Driver type] Any driver that was relying on i2c-isa has to be
converted to a proper isa, platform or pci driver. This is not
covered by this guide.
* [Includes] Get rid of "version.h" and <linux/i2c-proc.h>. * [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
Includes typically look like that: Includes typically look like that:
#include <linux/module.h> #include <linux/module.h>
...@@ -27,12 +31,10 @@ Technical changes: ...@@ -27,12 +31,10 @@ Technical changes:
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-isa.h> /* for ISA drivers */
#include <linux/hwmon.h> /* for hardware monitoring drivers */ #include <linux/hwmon.h> /* for hardware monitoring drivers */
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h> /* if you need VRM support */ #include <linux/hwmon-vid.h> /* if you need VRM support */
#include <linux/err.h> /* for class registration */ #include <linux/err.h> /* for class registration */
#include <asm/io.h> /* if you have I/O operations */
Please respect this inclusion order. Some extra headers may be Please respect this inclusion order. Some extra headers may be
required for a given driver (e.g. "lm75.h"). required for a given driver (e.g. "lm75.h").
...@@ -69,20 +71,16 @@ Technical changes: ...@@ -69,20 +71,16 @@ Technical changes:
sensors mailing list <lm-sensors@lm-sensors.org> by providing a sensors mailing list <lm-sensors@lm-sensors.org> by providing a
patch to the Documentation/hwmon/sysfs-interface file. patch to the Documentation/hwmon/sysfs-interface file.
* [Attach] For I2C drivers, the attach function should make sure * [Attach] The attach function should make sure that the adapter's
that the adapter's class has I2C_CLASS_HWMON (or whatever class is class has I2C_CLASS_HWMON (or whatever class is suitable for your
suitable for your driver), using the following construct: driver), using the following construct:
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
ISA-only drivers of course don't need this.
Call i2c_probe() instead of i2c_detect(). Call i2c_probe() instead of i2c_detect().
* [Detect] As mentioned earlier, the flags parameter is gone. * [Detect] As mentioned earlier, the flags parameter is gone.
The type_name and client_name strings are replaced by a single The type_name and client_name strings are replaced by a single
name string, which will be filled with a lowercase, short string. name string, which will be filled with a lowercase, short string.
In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
useless. Same for isa-only drivers, as the test would always be
true. Only hybrid drivers (which are quite rare) still need it.
The labels used for error paths are reduced to the number needed. The labels used for error paths are reduced to the number needed.
It is advised that the labels are given descriptive names such as It is advised that the labels are given descriptive names such as
exit and exit_free. Don't forget to properly set err before exit and exit_free. Don't forget to properly set err before
......
...@@ -4,17 +4,23 @@ I2C and SMBus ...@@ -4,17 +4,23 @@ I2C and SMBus
============= =============
I2C (pronounce: I squared C) is a protocol developed by Philips. It is a I2C (pronounce: I squared C) is a protocol developed by Philips. It is a
slow two-wire protocol (10-400 kHz), but it suffices for many types of slow two-wire protocol (variable speed, up to 400 kHz), with a high speed
devices. extension (3.4 MHz). It provides an inexpensive bus for connecting many
types of devices with infrequent or low bandwidth communications needs.
I2C is widely used with embedded systems. Some systems use variants that
don't meet branding requirements, and so are not advertised as being I2C.
SMBus (System Management Bus) is a subset of the I2C protocol. Many SMBus (System Management Bus) is based on the I2C protocol, and is mostly
modern mainboards have a System Management Bus. There are a lot of a subset of I2C protocols and signaling. Many I2C devices will work on an
devices which can be connected to a SMBus; the most notable are modern SMBus, but some SMBus protocols add semantics beyond what is required to
memory chips with EEPROM memories and chips for hardware monitoring. achieve I2C branding. Modern PC mainboards rely on SMBus. The most common
devices connected through SMBus are RAM modules configured using I2C EEPROMs,
and hardware monitoring chips.
Because the SMBus is just a special case of the generalized I2C bus, we Because the SMBus is mostly a subset of the generalized I2C bus, we can
can simulate the SMBus protocol on plain I2C busses. The reverse is use its protocols on many I2C systems. However, there are systems that don't
regretfully impossible. meet both SMBus and I2C electrical constraints; and others which can't
implement all the common SMBus protocol semantics or messages.
Terminology Terminology
...@@ -29,6 +35,7 @@ When we talk about I2C, we use the following terms: ...@@ -29,6 +35,7 @@ When we talk about I2C, we use the following terms:
An Algorithm driver contains general code that can be used for a whole class An Algorithm driver contains general code that can be used for a whole class
of I2C adapters. Each specific adapter driver depends on one algorithm of I2C adapters. Each specific adapter driver depends on one algorithm
driver. driver.
A Driver driver (yes, this sounds ridiculous, sorry) contains the general A Driver driver (yes, this sounds ridiculous, sorry) contains the general
code to access some type of device. Each detected device gets its own code to access some type of device. Each detected device gets its own
data in the Client structure. Usually, Driver and Client are more closely data in the Client structure. Usually, Driver and Client are more closely
...@@ -40,6 +47,10 @@ a separate Adapter and Algorithm driver), and drivers for your I2C devices ...@@ -40,6 +47,10 @@ a separate Adapter and Algorithm driver), and drivers for your I2C devices
in this package. See the lm_sensors project http://www.lm-sensors.nu in this package. See the lm_sensors project http://www.lm-sensors.nu
for device drivers. for device drivers.
At this time, Linux only operates I2C (or SMBus) in master mode; you can't
use these APIs to make a Linux system behave as a slave/device, either to
speak a custom protocol or to emulate some other device.
Included Bus Drivers Included Bus Drivers
==================== ====================
......
此差异已折叠。
...@@ -733,6 +733,13 @@ M: tigran@aivazian.fsnet.co.uk ...@@ -733,6 +733,13 @@ M: tigran@aivazian.fsnet.co.uk
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
BLACKFIN I2C TWI DRIVER
P: Sonic Zhang
M: sonic.zhang@analog.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org/
S: Supported
BLOCK LAYER BLOCK LAYER
P: Jens Axboe P: Jens Axboe
M: axboe@kernel.dk M: axboe@kernel.dk
...@@ -1459,6 +1466,11 @@ L: linux-scsi@vger.kernel.org ...@@ -1459,6 +1466,11 @@ L: linux-scsi@vger.kernel.org
W: http://www.icp-vortex.com/ W: http://www.icp-vortex.com/
S: Supported S: Supported
GENERIC GPIO I2C DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS
P: Krzysztof Halasa P: Krzysztof Halasa
M: khc@pm.waw.pl M: khc@pm.waw.pl
...@@ -1631,6 +1643,13 @@ L: i2c@lm-sensors.org ...@@ -1631,6 +1643,13 @@ L: i2c@lm-sensors.org
T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/ T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
S: Maintained S: Maintained
I2C-TINY-USB DRIVER
P: Till Harbaum
M: till@harbaum.org
L: i2c@lm-sensors.org
T: http://www.harbaum.org/till/i2c_tiny_usb
S: Maintained
i386 BOOT CODE i386 BOOT CODE
P: Riley H. Williams P: Riley H. Williams
M: Riley@Williams.Name M: Riley@Williams.Name
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/i2c.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/machdep.h> #include <asm/machdep.h>
......
...@@ -58,7 +58,7 @@ obj-$(CONFIG_GAMEPORT) += input/gameport/ ...@@ -58,7 +58,7 @@ obj-$(CONFIG_GAMEPORT) += input/gameport/
obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_INPUT) += input/
obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_I2O) += message/
obj-$(CONFIG_RTC_LIB) += rtc/ obj-$(CONFIG_RTC_LIB) += rtc/
obj-$(CONFIG_I2C) += i2c/ obj-y += i2c/
obj-$(CONFIG_W1) += w1/ obj-$(CONFIG_W1) += w1/
obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_HWMON) += hwmon/
obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_PHONE) += telephony/
......
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
# I2C subsystem configuration # I2C subsystem configuration
# #
menu "I2C support" menuconfig I2C
config I2C
tristate "I2C support" tristate "I2C support"
---help--- ---help---
I2C (pronounce: I-square-C) is a slow serial bus protocol used in I2C (pronounce: I-square-C) is a slow serial bus protocol used in
...@@ -22,9 +20,14 @@ config I2C ...@@ -22,9 +20,14 @@ config I2C
This I2C support can also be built as a module. If so, the module This I2C support can also be built as a module. If so, the module
will be called i2c-core. will be called i2c-core.
if I2C
config I2C_BOARDINFO
boolean
default y
config I2C_CHARDEV config I2C_CHARDEV
tristate "I2C device interface" tristate "I2C device interface"
depends on I2C
help help
Say Y here to use i2c-* device files, usually found in the /dev 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 directory on your system. They make it possible to have user-space
...@@ -40,7 +43,6 @@ source drivers/i2c/chips/Kconfig ...@@ -40,7 +43,6 @@ source drivers/i2c/chips/Kconfig
config I2C_DEBUG_CORE config I2C_DEBUG_CORE
bool "I2C Core debugging messages" bool "I2C Core debugging messages"
depends on I2C
help help
Say Y here if you want the I2C core to produce a bunch of debug 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 messages to the system log. Select this if you are having a
...@@ -48,7 +50,6 @@ config I2C_DEBUG_CORE ...@@ -48,7 +50,6 @@ config I2C_DEBUG_CORE
config I2C_DEBUG_ALGO config I2C_DEBUG_ALGO
bool "I2C Algorithm debugging messages" bool "I2C Algorithm debugging messages"
depends on I2C
help help
Say Y here if you want the I2C algorithm drivers to produce a bunch 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 of debug messages to the system log. Select this if you are having
...@@ -57,7 +58,6 @@ config I2C_DEBUG_ALGO ...@@ -57,7 +58,6 @@ config I2C_DEBUG_ALGO
config I2C_DEBUG_BUS config I2C_DEBUG_BUS
bool "I2C Bus debugging messages" bool "I2C Bus debugging messages"
depends on I2C
help help
Say Y here if you want the I2C bus drivers to produce a bunch of 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 debug messages to the system log. Select this if you are having
...@@ -66,12 +66,10 @@ config I2C_DEBUG_BUS ...@@ -66,12 +66,10 @@ config I2C_DEBUG_BUS
config I2C_DEBUG_CHIP config I2C_DEBUG_CHIP
bool "I2C Chip debugging messages" bool "I2C Chip debugging messages"
depends on I2C
help help
Say Y here if you want the I2C chip drivers to produce a bunch of Say Y here if you want the I2C chip drivers to produce a bunch of
debug messages to the system log. Select this if you are having 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 a problem with I2C support and want to see more of what is going
on. on.
endmenu endif # I2C
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Makefile for the i2c core. # Makefile for the i2c core.
# #
obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
obj-y += busses/ chips/ algos/ obj-y += busses/ chips/ algos/
......
...@@ -3,11 +3,9 @@ ...@@ -3,11 +3,9 @@
# #
menu "I2C Algorithms" menu "I2C Algorithms"
depends on I2C
config I2C_ALGOBIT config I2C_ALGOBIT
tristate "I2C bit-banging interfaces" tristate "I2C bit-banging interfaces"
depends on I2C
help help
This allows you to use a range of I2C adapters called bit-banging This allows you to use a range of I2C adapters called bit-banging
adapters. Say Y if you own an I2C adapter belonging to this class adapters. Say Y if you own an I2C adapter belonging to this class
...@@ -18,7 +16,6 @@ config I2C_ALGOBIT ...@@ -18,7 +16,6 @@ config I2C_ALGOBIT
config I2C_ALGOPCF config I2C_ALGOPCF
tristate "I2C PCF 8584 interfaces" tristate "I2C PCF 8584 interfaces"
depends on I2C
help help
This allows you to use a range of I2C adapters called PCF adapters. This allows you to use a range of I2C adapters called PCF adapters.
Say Y if you own an I2C adapter belonging to this class and then say Say Y if you own an I2C adapter belonging to this class and then say
...@@ -29,7 +26,6 @@ config I2C_ALGOPCF ...@@ -29,7 +26,6 @@ config I2C_ALGOPCF
config I2C_ALGOPCA config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces" tristate "I2C PCA 9564 interfaces"
depends on I2C
help help
This allows you to use a range of I2C adapters called PCA adapters. This allows you to use a range of I2C adapters called PCA adapters.
Say Y if you own an I2C adapter belonging to this class and then say Say Y if you own an I2C adapter belonging to this class and then say
...@@ -40,11 +36,11 @@ config I2C_ALGOPCA ...@@ -40,11 +36,11 @@ config I2C_ALGOPCA
config I2C_ALGO8XX config I2C_ALGO8XX
tristate "MPC8xx CPM I2C interface" tristate "MPC8xx CPM I2C interface"
depends on 8xx && I2C depends on 8xx
config I2C_ALGO_SGI config I2C_ALGO_SGI
tristate "I2C SGI interfaces" tristate "I2C SGI interfaces"
depends on I2C && (SGI_IP22 || SGI_IP32 || X86_VISWS) depends on SGI_IP22 || SGI_IP32 || X86_VISWS
help help
Supports the SGI interfaces like the ones found on SGI Indy VINO Supports the SGI interfaces like the ones found on SGI Indy VINO
or SGI O2 MACE. or SGI O2 MACE.
......
...@@ -33,19 +33,30 @@ ...@@ -33,19 +33,30 @@
/* ----- global defines ----------------------------------------------- */ /* ----- global defines ----------------------------------------------- */
#define DEB(x) if (i2c_debug>=1) x;
#define DEB2(x) if (i2c_debug>=2) x;
#define DEBSTAT(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 */
#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 --------------------------------------------- */ /* ----- global variables --------------------------------------------- */
/* module parameters:
*/
static int i2c_debug;
static int bit_test; /* see if the line-setting functions work */ static int bit_test; /* see if the line-setting functions work */
module_param(bit_test, bool, 0);
MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is 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: --------------- */ /* --- setting states on the bus with the right timing: --------------- */
...@@ -57,19 +68,19 @@ static int bit_test; /* see if the line-setting functions work */ ...@@ -57,19 +68,19 @@ static int bit_test; /* see if the line-setting functions work */
static inline void sdalo(struct i2c_algo_bit_data *adap) static inline void sdalo(struct i2c_algo_bit_data *adap)
{ {
setsda(adap,0); setsda(adap,0);
udelay(adap->udelay); udelay((adap->udelay + 1) / 2);
} }
static inline void sdahi(struct i2c_algo_bit_data *adap) static inline void sdahi(struct i2c_algo_bit_data *adap)
{ {
setsda(adap,1); setsda(adap,1);
udelay(adap->udelay); udelay((adap->udelay + 1) / 2);
} }
static inline void scllo(struct i2c_algo_bit_data *adap) static inline void scllo(struct i2c_algo_bit_data *adap)
{ {
setscl(adap,0); setscl(adap,0);
udelay(adap->udelay); udelay(adap->udelay / 2);
} }
/* /*
...@@ -98,7 +109,11 @@ static int sclhi(struct i2c_algo_bit_data *adap) ...@@ -98,7 +109,11 @@ static int sclhi(struct i2c_algo_bit_data *adap)
} }
cond_resched(); cond_resched();
} }
DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); #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: done:
udelay(adap->udelay); udelay(adap->udelay);
...@@ -110,30 +125,29 @@ static int sclhi(struct i2c_algo_bit_data *adap) ...@@ -110,30 +125,29 @@ static int sclhi(struct i2c_algo_bit_data *adap)
static void i2c_start(struct i2c_algo_bit_data *adap) static void i2c_start(struct i2c_algo_bit_data *adap)
{ {
/* assert: scl, sda are high */ /* assert: scl, sda are high */
DEBPROTO(printk("S ")); setsda(adap, 0);
sdalo(adap); udelay(adap->udelay);
scllo(adap); scllo(adap);
} }
static void i2c_repstart(struct i2c_algo_bit_data *adap) static void i2c_repstart(struct i2c_algo_bit_data *adap)
{ {
/* scl, sda may not be high */ /* assert: scl is low */
DEBPROTO(printk(" Sr ")); sdahi(adap);
setsda(adap,1);
sclhi(adap); sclhi(adap);
setsda(adap, 0);
sdalo(adap); udelay(adap->udelay);
scllo(adap); scllo(adap);
} }
static void i2c_stop(struct i2c_algo_bit_data *adap) static void i2c_stop(struct i2c_algo_bit_data *adap)
{ {
DEBPROTO(printk("P\n"));
/* assert: scl is low */ /* assert: scl is low */
sdalo(adap); sdalo(adap);
sclhi(adap); sclhi(adap);
sdahi(adap); setsda(adap, 1);
udelay(adap->udelay);
} }
...@@ -145,7 +159,7 @@ static void i2c_stop(struct i2c_algo_bit_data *adap) ...@@ -145,7 +159,7 @@ static void i2c_stop(struct i2c_algo_bit_data *adap)
* 0 if the device did not ack * 0 if the device did not ack
* -ETIMEDOUT if an error occurred (while raising the scl line) * -ETIMEDOUT if an error occurred (while raising the scl line)
*/ */
static int i2c_outb(struct i2c_adapter *i2c_adap, char c) static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
{ {
int i; int i;
int sb; int sb;
...@@ -154,34 +168,32 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) ...@@ -154,34 +168,32 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
/* assert: scl is low */ /* assert: scl is low */
for ( i=7 ; i>=0 ; i-- ) { for ( i=7 ; i>=0 ; i-- ) {
sb = c & ( 1 << i ); sb = (c >> i) & 1;
setsda(adap,sb); setsda(adap,sb);
udelay(adap->udelay); udelay((adap->udelay + 1) / 2);
DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
if (sclhi(adap)<0) { /* timed out */ if (sclhi(adap)<0) { /* timed out */
sdahi(adap); /* we don't want to block the net */ bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i)); "timeout at bit #%d\n", (int)c, i);
return -ETIMEDOUT; return -ETIMEDOUT;
}; };
/* do arbitration here: /* do arbitration here:
* if ( sb && ! getsda(adap) ) -> ouch! Get out of here. * if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
*/ */
setscl(adap, 0 ); scllo(adap);
udelay(adap->udelay);
} }
sdahi(adap); sdahi(adap);
if (sclhi(adap)<0){ /* timeout */ if (sclhi(adap)<0){ /* timeout */
DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff)); bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
return -ETIMEDOUT; "timeout at ack\n", (int)c);
return -ETIMEDOUT;
}; };
/* read ack: SDA should be pulled down by slave */ /* read ack: SDA should be pulled down by slave */
ack=getsda(adap); /* ack: sda is pulled low ->success. */ ack = !getsda(adap); /* ack: sda is pulled low -> success */
DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack)); bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
ack ? "A" : "NA");
DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) );
DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") );
scllo(adap); scllo(adap);
return 0==ack; /* return 1 if device acked */ return ack;
/* assert: scl is low (sda undef) */ /* assert: scl is low (sda undef) */
} }
...@@ -198,19 +210,18 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) ...@@ -198,19 +210,18 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
sdahi(adap); sdahi(adap);
for (i=0;i<8;i++) { for (i=0;i<8;i++) {
if (sclhi(adap)<0) { /* timeout */ if (sclhi(adap)<0) { /* timeout */
DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i)); bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
"#%d\n", 7 - i);
return -ETIMEDOUT; return -ETIMEDOUT;
}; };
indata *= 2; indata *= 2;
if ( getsda(adap) ) if ( getsda(adap) )
indata |= 0x01; indata |= 0x01;
scllo(adap); setscl(adap, 0);
udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
} }
/* assert: scl is low */ /* assert: scl is low */
DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff)); return indata;
DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff));
return (int) (indata & 0xff);
} }
/* /*
...@@ -221,73 +232,67 @@ static int test_bus(struct i2c_algo_bit_data *adap, char* name) { ...@@ -221,73 +232,67 @@ static int test_bus(struct i2c_algo_bit_data *adap, char* name) {
int scl,sda; int scl,sda;
if (adap->getscl==NULL) if (adap->getscl==NULL)
printk(KERN_INFO "i2c-algo-bit.o: Testing SDA only, " pr_info("%s: Testing SDA only, SCL is not readable\n", name);
"SCL is not readable.\n");
sda=getsda(adap); sda=getsda(adap);
scl=(adap->getscl==NULL?1:getscl(adap)); scl=(adap->getscl==NULL?1:getscl(adap));
printk(KERN_DEBUG "i2c-algo-bit.o: (0) scl=%d, sda=%d\n",scl,sda);
if (!scl || !sda ) { if (!scl || !sda ) {
printk(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name); printk(KERN_WARNING "%s: bus seems to be busy\n", name);
goto bailout; goto bailout;
} }
sdalo(adap); sdalo(adap);
sda=getsda(adap); sda=getsda(adap);
scl=(adap->getscl==NULL?1:getscl(adap)); scl=(adap->getscl==NULL?1:getscl(adap));
printk(KERN_DEBUG "i2c-algo-bit.o: (1) scl=%d, sda=%d\n",scl,sda);
if ( 0 != sda ) { if ( 0 != sda ) {
printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck high!\n"); printk(KERN_WARNING "%s: SDA stuck high!\n", name);
goto bailout; goto bailout;
} }
if ( 0 == scl ) { if ( 0 == scl ) {
printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " printk(KERN_WARNING "%s: SCL unexpected low "
"while pulling SDA low!\n"); "while pulling SDA low!\n", name);
goto bailout; goto bailout;
} }
sdahi(adap); sdahi(adap);
sda=getsda(adap); sda=getsda(adap);
scl=(adap->getscl==NULL?1:getscl(adap)); scl=(adap->getscl==NULL?1:getscl(adap));
printk(KERN_DEBUG "i2c-algo-bit.o: (2) scl=%d, sda=%d\n",scl,sda);
if ( 0 == sda ) { if ( 0 == sda ) {
printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck low!\n"); printk(KERN_WARNING "%s: SDA stuck low!\n", name);
goto bailout; goto bailout;
} }
if ( 0 == scl ) { if ( 0 == scl ) {
printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " printk(KERN_WARNING "%s: SCL unexpected low "
"while pulling SDA high!\n"); "while pulling SDA high!\n", name);
goto bailout; goto bailout;
} }
scllo(adap); scllo(adap);
sda=getsda(adap); sda=getsda(adap);
scl=(adap->getscl==NULL?0:getscl(adap)); scl=(adap->getscl==NULL?0:getscl(adap));
printk(KERN_DEBUG "i2c-algo-bit.o: (3) scl=%d, sda=%d\n",scl,sda);
if ( 0 != scl ) { if ( 0 != scl ) {
printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck high!\n"); printk(KERN_WARNING "%s: SCL stuck high!\n", name);
goto bailout; goto bailout;
} }
if ( 0 == sda ) { if ( 0 == sda ) {
printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " printk(KERN_WARNING "%s: SDA unexpected low "
"while pulling SCL low!\n"); "while pulling SCL low!\n", name);
goto bailout; goto bailout;
} }
sclhi(adap); sclhi(adap);
sda=getsda(adap); sda=getsda(adap);
scl=(adap->getscl==NULL?1:getscl(adap)); scl=(adap->getscl==NULL?1:getscl(adap));
printk(KERN_DEBUG "i2c-algo-bit.o: (4) scl=%d, sda=%d\n",scl,sda);
if ( 0 == scl ) { if ( 0 == scl ) {
printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck low!\n"); printk(KERN_WARNING "%s: SCL stuck low!\n", name);
goto bailout; goto bailout;
} }
if ( 0 == sda ) { if ( 0 == sda ) {
printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " printk(KERN_WARNING "%s: SDA unexpected low "
"while pulling SCL high!\n"); "while pulling SCL high!\n", name);
goto bailout; goto bailout;
} }
printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name); pr_info("%s: Test OK\n", name);
return 0; return 0;
bailout: bailout:
sdahi(adap); sdahi(adap);
...@@ -312,44 +317,39 @@ static int try_address(struct i2c_adapter *i2c_adap, ...@@ -312,44 +317,39 @@ static int try_address(struct i2c_adapter *i2c_adap,
int i,ret = -1; int i,ret = -1;
for (i=0;i<=retries;i++) { for (i=0;i<=retries;i++) {
ret = i2c_outb(i2c_adap,addr); ret = i2c_outb(i2c_adap,addr);
if (ret==1) if (ret == 1 || i == retries)
break; /* success! */
i2c_stop(adap);
udelay(5/*adap->udelay*/);
if (i==retries) /* no success */
break; break;
i2c_start(adap); bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
i2c_stop(adap);
udelay(adap->udelay); udelay(adap->udelay);
yield();
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
i2c_start(adap);
} }
DEB2(if (i) if (i && ret)
printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n", bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
i+1, addr & 1 ? "read" : "write", addr>>1, "0x%02x: %s\n", i + 1,
ret==1 ? "success" : ret==0 ? "no ack" : "failed, timeout?" ) addr & 1 ? "read from" : "write to", addr >> 1,
); ret == 1 ? "success" : "failed, timeout?");
return ret; return ret;
} }
static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
{ {
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; const unsigned char *temp = msg->buf;
char c;
const char *temp = msg->buf;
int count = msg->len; int count = msg->len;
unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
int retval; int retval;
int wrcount=0; int wrcount=0;
while (count > 0) { while (count > 0) {
c = *temp; retval = i2c_outb(i2c_adap, *temp);
DEB2(dev_dbg(&i2c_adap->dev, "sendbytes: writing %2.2X\n", c&0xff));
retval = i2c_outb(i2c_adap,c);
if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */ if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */
count--; count--;
temp++; temp++;
wrcount++; wrcount++;
} else { /* arbitration or no acknowledge */ } else { /* arbitration or no acknowledge */
dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n"); dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n");
i2c_stop(adap);
return (retval<0)? retval : -EFAULT; return (retval<0)? retval : -EFAULT;
/* got a better one ?? */ /* got a better one ?? */
} }
...@@ -362,7 +362,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ...@@ -362,7 +362,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
int inval; int inval;
int rdcount=0; /* counts bytes read */ int rdcount=0; /* counts bytes read */
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
char *temp = msg->buf; unsigned char *temp = msg->buf;
int count = msg->len; int count = msg->len;
while (count > 0) { while (count > 0) {
...@@ -371,30 +371,44 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ...@@ -371,30 +371,44 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
*temp = inval; *temp = inval;
rdcount++; rdcount++;
} else { /* read timed out */ } else { /* read timed out */
printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n");
break; break;
} }
temp++; temp++;
count--; count--;
if (msg->flags & I2C_M_NO_RD_ACK) if (msg->flags & I2C_M_NO_RD_ACK) {
bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n",
inval);
continue; continue;
if ( count > 0 ) { /* send ack */
sdalo(adap);
DEBPROTO(printk(" Am "));
} else {
sdahi(adap); /* neg. ack on last byte */
DEBPROTO(printk(" NAm "));
} }
/* assert: sda is high */
if (count) /* send ack */
setsda(adap, 0);
udelay((adap->udelay + 1) / 2);
bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval,
count ? "A" : "NA");
if (sclhi(adap)<0) { /* timeout */ if (sclhi(adap)<0) { /* timeout */
sdahi(adap); dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n");
printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
return -ETIMEDOUT; return -ETIMEDOUT;
}; };
scllo(adap); scllo(adap);
sdahi(adap);
/* Some SMBus transactions require that we receive the
transaction length as the first read byte. */
if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) {
if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
dev_err(&i2c_adap->dev, "readbytes: invalid "
"block length (%d)\n", inval);
return -EREMOTEIO;
}
/* 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;
}
} }
return rdcount; return rdcount;
} }
...@@ -421,27 +435,31 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ...@@ -421,27 +435,31 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
if ( (flags & I2C_M_TEN) ) { if ( (flags & I2C_M_TEN) ) {
/* a ten bit address */ /* a ten bit address */
addr = 0xf0 | (( msg->addr >> 7) & 0x03); addr = 0xf0 | (( msg->addr >> 7) & 0x03);
DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
/* try extended address code...*/ /* try extended address code...*/
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
if ((ret != 1) && !nak_ok) { if ((ret != 1) && !nak_ok) {
printk(KERN_ERR "died at extended address code.\n"); dev_err(&i2c_adap->dev,
"died at extended address code\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
/* the remaining 8 bit address */ /* the remaining 8 bit address */
ret = i2c_outb(i2c_adap,msg->addr & 0x7f); ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
if ((ret != 1) && !nak_ok) { if ((ret != 1) && !nak_ok) {
/* the chip did not ack / xmission error occurred */ /* the chip did not ack / xmission error occurred */
printk(KERN_ERR "died at 2nd address code.\n"); dev_err(&i2c_adap->dev, "died at 2nd address code\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
if ( flags & I2C_M_RD ) { if ( flags & I2C_M_RD ) {
bit_dbg(3, &i2c_adap->dev, "emitting repeated "
"start condition\n");
i2c_repstart(adap); i2c_repstart(adap);
/* okay, now switch into reading mode */ /* okay, now switch into reading mode */
addr |= 0x01; addr |= 0x01;
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
if ((ret!=1) && !nak_ok) { if ((ret!=1) && !nak_ok) {
printk(KERN_ERR "died at extended address code.\n"); dev_err(&i2c_adap->dev,
"died at repeated address code\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
} }
...@@ -468,44 +486,62 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ...@@ -468,44 +486,62 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
int i,ret; int i,ret;
unsigned short nak_ok; unsigned short nak_ok;
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
i2c_start(adap); i2c_start(adap);
for (i=0;i<num;i++) { for (i=0;i<num;i++) {
pmsg = &msgs[i]; pmsg = &msgs[i];
nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
if (!(pmsg->flags & I2C_M_NOSTART)) { if (!(pmsg->flags & I2C_M_NOSTART)) {
if (i) { if (i) {
bit_dbg(3, &i2c_adap->dev, "emitting "
"repeated start condition\n");
i2c_repstart(adap); i2c_repstart(adap);
} }
ret = bit_doAddress(i2c_adap, pmsg); ret = bit_doAddress(i2c_adap, pmsg);
if ((ret != 0) && !nak_ok) { if ((ret != 0) && !nak_ok) {
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n" bit_dbg(1, &i2c_adap->dev, "NAK from "
,msgs[i].addr,i)); "device addr 0x%02x msg #%d\n",
return (ret<0) ? ret : -EREMOTEIO; msgs[i].addr, i);
goto bailout;
} }
} }
if (pmsg->flags & I2C_M_RD ) { if (pmsg->flags & I2C_M_RD ) {
/* read bytes into buffer*/ /* read bytes into buffer*/
ret = readbytes(i2c_adap, pmsg); ret = readbytes(i2c_adap, pmsg);
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); if (ret >= 1)
if (ret < pmsg->len ) { bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n",
return (ret<0)? ret : -EREMOTEIO; ret, ret == 1 ? "" : "s");
if (ret < pmsg->len) {
if (ret >= 0)
ret = -EREMOTEIO;
goto bailout;
} }
} else { } else {
/* write bytes from buffer */ /* write bytes from buffer */
ret = sendbytes(i2c_adap, pmsg); ret = sendbytes(i2c_adap, pmsg);
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); if (ret >= 1)
if (ret < pmsg->len ) { bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n",
return (ret<0) ? ret : -EREMOTEIO; ret, ret == 1 ? "" : "s");
if (ret < pmsg->len) {
if (ret >= 0)
ret = -EREMOTEIO;
goto bailout;
} }
} }
} }
ret = i;
bailout:
bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
i2c_stop(adap); i2c_stop(adap);
return num; return ret;
} }
static u32 bit_func(struct i2c_adapter *adap) static u32 bit_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 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; I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
} }
...@@ -520,7 +556,7 @@ static const struct i2c_algorithm i2c_bit_algo = { ...@@ -520,7 +556,7 @@ static const struct i2c_algorithm i2c_bit_algo = {
/* /*
* registering functions to load algorithms at runtime * registering functions to load algorithms at runtime
*/ */
int i2c_bit_add_bus(struct i2c_adapter *adap) static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
{ {
struct i2c_algo_bit_data *bit_adap = adap->algo_data; struct i2c_algo_bit_data *bit_adap = adap->algo_data;
...@@ -530,25 +566,39 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) ...@@ -530,25 +566,39 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
return -ENODEV; return -ENODEV;
} }
DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));
/* register new adapter to i2c module... */ /* register new adapter to i2c module... */
adap->algo = &i2c_bit_algo; adap->algo = &i2c_bit_algo;
adap->timeout = 100; /* default values, should */ adap->timeout = 100; /* default values, should */
adap->retries = 3; /* be replaced by defines */ adap->retries = 3; /* be replaced by defines */
return 0;
}
int i2c_bit_add_bus(struct i2c_adapter *adap)
{
int err;
err = i2c_bit_prepare_bus(adap);
if (err)
return err;
return i2c_add_adapter(adap); return i2c_add_adapter(adap);
} }
EXPORT_SYMBOL(i2c_bit_add_bus); EXPORT_SYMBOL(i2c_bit_add_bus);
int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
{
int err;
err = i2c_bit_prepare_bus(adap);
if (err)
return err;
return i2c_add_numbered_adapter(adap);
}
EXPORT_SYMBOL(i2c_bit_add_numbered_bus);
MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_param(bit_test, bool, 0);
module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck");
MODULE_PARM_DESC(i2c_debug,
"debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol");
/* /*
* i2c-algo-sgi.c: i2c driver algorithms for SGI adapters. * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
* * MACE (SGI O2) chips.
*
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License version 2 as published by the Free Software Foundation. * License version 2 as published by the Free Software Foundation.
* *
...@@ -162,8 +163,8 @@ static const struct i2c_algorithm sgi_algo = { ...@@ -162,8 +163,8 @@ static const struct i2c_algorithm sgi_algo = {
.functionality = sgi_func, .functionality = sgi_func,
}; };
/* /*
* registering functions to load algorithms at runtime * registering functions to load algorithms at runtime
*/ */
int i2c_sgi_add_bus(struct i2c_adapter *adap) int i2c_sgi_add_bus(struct i2c_adapter *adap)
{ {
......
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
# #
menu "I2C Hardware Bus support" menu "I2C Hardware Bus support"
depends on I2C
config I2C_ALI1535 config I2C_ALI1535
tristate "ALI 1535" tristate "ALI 1535"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the SMB 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 Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB
...@@ -19,7 +18,7 @@ config I2C_ALI1535 ...@@ -19,7 +18,7 @@ config I2C_ALI1535
config I2C_ALI1563 config I2C_ALI1563
tristate "ALI 1563" tristate "ALI 1563"
depends on I2C && PCI && EXPERIMENTAL depends on PCI && EXPERIMENTAL
help help
If you say yes to this option, support will be included for the SMB 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 Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB
...@@ -31,7 +30,7 @@ config I2C_ALI1563 ...@@ -31,7 +30,7 @@ config I2C_ALI1563
config I2C_ALI15X3 config I2C_ALI15X3
tristate "ALI 15x3" tristate "ALI 15x3"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces. Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
...@@ -41,7 +40,7 @@ config I2C_ALI15X3 ...@@ -41,7 +40,7 @@ config I2C_ALI15X3
config I2C_AMD756 config I2C_AMD756
tristate "AMD 756/766/768/8111 and nVidia nForce" tristate "AMD 756/766/768/8111 and nVidia nForce"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the AMD If you say yes to this option, support will be included for the AMD
756/766/768 mainboard I2C interfaces. The driver also includes 756/766/768 mainboard I2C interfaces. The driver also includes
...@@ -66,7 +65,7 @@ config I2C_AMD756_S4882 ...@@ -66,7 +65,7 @@ config I2C_AMD756_S4882
config I2C_AMD8111 config I2C_AMD8111
tristate "AMD 8111" tristate "AMD 8111"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
second (SMBus 2.0) AMD 8111 mainboard I2C interface. second (SMBus 2.0) AMD 8111 mainboard I2C interface.
...@@ -76,14 +75,14 @@ config I2C_AMD8111 ...@@ -76,14 +75,14 @@ config I2C_AMD8111
config I2C_AT91 config I2C_AT91
tristate "Atmel AT91 I2C Two-Wire interface (TWI)" tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
depends on I2C && ARCH_AT91 && EXPERIMENTAL depends on ARCH_AT91 && EXPERIMENTAL
help help
This supports the use of the I2C interface on Atmel AT91 This supports the use of the I2C interface on Atmel AT91
processors. processors.
config I2C_AU1550 config I2C_AU1550
tristate "Au1550/Au1200 SMBus interface" tristate "Au1550/Au1200 SMBus interface"
depends on I2C && (SOC_AU1550 || SOC_AU1200) depends on SOC_AU1550 || SOC_AU1200
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
Au1550 and Au1200 SMBus interface. Au1550 and Au1200 SMBus interface.
...@@ -91,9 +90,25 @@ config I2C_AU1550 ...@@ -91,9 +90,25 @@ config I2C_AU1550
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-au1550. will be called i2c-au1550.
config I2C_BLACKFIN_TWI
tristate "Blackfin TWI I2C support"
depends on BF534 || BF536 || BF537
help
This is the TWI I2C device driver for Blackfin 534/536/537.
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 10 400
default 50
help
The unit of the TWI clock is kHz.
config I2C_ELEKTOR config I2C_ELEKTOR
tristate "Elektor ISA card" tristate "Elektor ISA card"
depends on I2C && ISA && BROKEN_ON_SMP depends on ISA && BROKEN_ON_SMP
select I2C_ALGOPCF select I2C_ALGOPCF
help help
This supports the PCF8584 ISA bus I2C adapter. Say Y if you own This supports the PCF8584 ISA bus I2C adapter. Say Y if you own
...@@ -102,9 +117,17 @@ config I2C_ELEKTOR ...@@ -102,9 +117,17 @@ config I2C_ELEKTOR
This support is also available as a module. If so, the module This support is also available as a module. If so, the module
will be called i2c-elektor. will be called i2c-elektor.
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_HYDRA config I2C_HYDRA
tristate "CHRP Apple Hydra Mac I/O I2C interface" tristate "CHRP Apple Hydra Mac I/O I2C interface"
depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL depends on PCI && PPC_CHRP && EXPERIMENTAL
select I2C_ALGOBIT select I2C_ALGOBIT
help help
This supports the use of the I2C interface in the Apple Hydra Mac This supports the use of the I2C interface in the Apple Hydra Mac
...@@ -116,7 +139,7 @@ config I2C_HYDRA ...@@ -116,7 +139,7 @@ config I2C_HYDRA
config I2C_I801 config I2C_I801
tristate "Intel 82801 (ICH)" tristate "Intel 82801 (ICH)"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the Intel If you say yes to this option, support will be included for the Intel
801 family of mainboard I2C interfaces. Specifically, the following 801 family of mainboard I2C interfaces. Specifically, the following
...@@ -139,7 +162,7 @@ config I2C_I801 ...@@ -139,7 +162,7 @@ config I2C_I801
config I2C_I810 config I2C_I810
tristate "Intel 810/815" tristate "Intel 810/815"
depends on I2C && PCI depends on PCI
select I2C_ALGOBIT select I2C_ALGOBIT
help help
If you say yes to this option, support will be included for the Intel If you say yes to this option, support will be included for the Intel
...@@ -156,7 +179,7 @@ config I2C_I810 ...@@ -156,7 +179,7 @@ config I2C_I810
config I2C_PXA config I2C_PXA
tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
depends on I2C && EXPERIMENTAL && ARCH_PXA depends on EXPERIMENTAL && ARCH_PXA
help help
If you have devices in the PXA I2C bus, say yes to this option. 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 This driver can also be built as a module. If so, the module
...@@ -172,7 +195,7 @@ config I2C_PXA_SLAVE ...@@ -172,7 +195,7 @@ config I2C_PXA_SLAVE
config I2C_PIIX4 config I2C_PIIX4
tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the Intel If you say yes to this option, support will be included for the Intel
PIIX4 family of mainboard I2C interfaces. Specifically, the following PIIX4 family of mainboard I2C interfaces. Specifically, the following
...@@ -195,7 +218,7 @@ config I2C_PIIX4 ...@@ -195,7 +218,7 @@ config I2C_PIIX4
config I2C_IBM_IIC config I2C_IBM_IIC
tristate "IBM PPC 4xx on-chip I2C interface" tristate "IBM PPC 4xx on-chip I2C interface"
depends on IBM_OCP && I2C depends on IBM_OCP
help help
Say Y here if you want to use IIC peripheral found on Say Y here if you want to use IIC peripheral found on
embedded IBM PPC 4xx based systems. embedded IBM PPC 4xx based systems.
...@@ -205,7 +228,7 @@ config I2C_IBM_IIC ...@@ -205,7 +228,7 @@ config I2C_IBM_IIC
config I2C_IOP3XX config I2C_IOP3XX
tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX) && I2C depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
help help
Say Y here if you want to use the IIC bus controller on Say Y here if you want to use the IIC bus controller on
the Intel IOPx3xx I/O Processors or IXP4xx Network Processors. the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
...@@ -215,11 +238,10 @@ config I2C_IOP3XX ...@@ -215,11 +238,10 @@ config I2C_IOP3XX
config I2C_ISA config I2C_ISA
tristate tristate
depends on I2C
config I2C_IXP4XX config I2C_IXP4XX
tristate "IXP4xx GPIO-Based I2C Interface" tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)"
depends on I2C && ARCH_IXP4XX depends on ARCH_IXP4XX
select I2C_ALGOBIT select I2C_ALGOBIT
help help
Say Y here if you have an Intel IXP4xx(420,421,422,425) based Say Y here if you have an Intel IXP4xx(420,421,422,425) based
...@@ -228,9 +250,12 @@ config I2C_IXP4XX ...@@ -228,9 +250,12 @@ config I2C_IXP4XX
This support is also available as a module. If so, the module This support is also available as a module. If so, the module
will be called i2c-ixp4xx. will be called i2c-ixp4xx.
This driver is deprecated and will be dropped soon. Use i2c-gpio
instead.
config I2C_IXP2000 config I2C_IXP2000
tristate "IXP2000 GPIO-Based I2C Interface" tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)"
depends on I2C && ARCH_IXP2000 depends on ARCH_IXP2000
select I2C_ALGOBIT select I2C_ALGOBIT
help help
Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based
...@@ -239,9 +264,12 @@ config I2C_IXP2000 ...@@ -239,9 +264,12 @@ config I2C_IXP2000
This support is also available as a module. If so, the module This support is also available as a module. If so, the module
will be called i2c-ixp2000. will be called i2c-ixp2000.
This driver is deprecated and will be dropped soon. Use i2c-gpio
instead.
config I2C_POWERMAC config I2C_POWERMAC
tristate "Powermac I2C interface" tristate "Powermac I2C interface"
depends on I2C && PPC_PMAC depends on PPC_PMAC
default y default y
help help
This exposes the various PowerMac i2c interfaces to the linux i2c This exposes the various PowerMac i2c interfaces to the linux i2c
...@@ -253,7 +281,7 @@ config I2C_POWERMAC ...@@ -253,7 +281,7 @@ config I2C_POWERMAC
config I2C_MPC config I2C_MPC
tristate "MPC107/824x/85xx/52xx/86xx" tristate "MPC107/824x/85xx/52xx/86xx"
depends on I2C && PPC32 depends on PPC32
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
...@@ -265,7 +293,7 @@ config I2C_MPC ...@@ -265,7 +293,7 @@ config I2C_MPC
config I2C_NFORCE2 config I2C_NFORCE2
tristate "Nvidia nForce2, nForce3 and nForce4" tristate "Nvidia nForce2, nForce3 and nForce4"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the Nvidia If you say yes to this option, support will be included for the Nvidia
nForce2, nForce3 and nForce4 families of mainboard I2C interfaces. nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
...@@ -275,7 +303,7 @@ config I2C_NFORCE2 ...@@ -275,7 +303,7 @@ config I2C_NFORCE2
config I2C_OCORES config I2C_OCORES
tristate "OpenCores I2C Controller" tristate "OpenCores I2C Controller"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
OpenCores I2C controller. For details see OpenCores I2C controller. For details see
...@@ -286,7 +314,7 @@ config I2C_OCORES ...@@ -286,7 +314,7 @@ config I2C_OCORES
config I2C_OMAP config I2C_OMAP
tristate "OMAP I2C adapter" tristate "OMAP I2C adapter"
depends on I2C && ARCH_OMAP depends on ARCH_OMAP
default y if MACH_OMAP_H3 || MACH_OMAP_OSK default y if MACH_OMAP_H3 || MACH_OMAP_OSK
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
...@@ -296,7 +324,7 @@ config I2C_OMAP ...@@ -296,7 +324,7 @@ config I2C_OMAP
config I2C_PARPORT config I2C_PARPORT
tristate "Parallel port adapter" tristate "Parallel port adapter"
depends on I2C && PARPORT depends on PARPORT
select I2C_ALGOBIT select I2C_ALGOBIT
help help
This supports parallel port I2C adapters such as the ones made by This supports parallel port I2C adapters such as the ones made by
...@@ -320,7 +348,6 @@ config I2C_PARPORT ...@@ -320,7 +348,6 @@ config I2C_PARPORT
config I2C_PARPORT_LIGHT config I2C_PARPORT_LIGHT
tristate "Parallel port adapter (light)" tristate "Parallel port adapter (light)"
depends on I2C
select I2C_ALGOBIT select I2C_ALGOBIT
help help
This supports parallel port I2C adapters such as the ones made by This supports parallel port I2C adapters such as the ones made by
...@@ -344,13 +371,13 @@ config I2C_PARPORT_LIGHT ...@@ -344,13 +371,13 @@ config I2C_PARPORT_LIGHT
config I2C_PASEMI config I2C_PASEMI
tristate "PA Semi SMBus interface" tristate "PA Semi SMBus interface"
depends on PPC_PASEMI && I2C && PCI depends on PPC_PASEMI && PCI
help help
Supports the PA Semi PWRficient on-chip SMBus interfaces. Supports the PA Semi PWRficient on-chip SMBus interfaces.
config I2C_PROSAVAGE config I2C_PROSAVAGE
tristate "S3/VIA (Pro)Savage" tristate "S3/VIA (Pro)Savage"
depends on I2C && PCI depends on PCI
select I2C_ALGOBIT select I2C_ALGOBIT
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
...@@ -365,19 +392,19 @@ config I2C_PROSAVAGE ...@@ -365,19 +392,19 @@ config I2C_PROSAVAGE
config I2C_RPXLITE config I2C_RPXLITE
tristate "Embedded Planet RPX Lite/Classic support" tristate "Embedded Planet RPX Lite/Classic support"
depends on (RPXLITE || RPXCLASSIC) && I2C depends on RPXLITE || RPXCLASSIC
select I2C_ALGO8XX select I2C_ALGO8XX
config I2C_S3C2410 config I2C_S3C2410
tristate "S3C2410 I2C Driver" tristate "S3C2410 I2C Driver"
depends on I2C && ARCH_S3C2410 depends on ARCH_S3C2410
help help
Say Y here to include support for I2C controller in the Say Y here to include support for I2C controller in the
Samsung S3C2410 based System-on-Chip devices. Samsung S3C2410 based System-on-Chip devices.
config I2C_SAVAGE4 config I2C_SAVAGE4
tristate "S3 Savage 4" tristate "S3 Savage 4"
depends on I2C && PCI && EXPERIMENTAL depends on PCI && EXPERIMENTAL
select I2C_ALGOBIT select I2C_ALGOBIT
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
...@@ -388,13 +415,25 @@ config I2C_SAVAGE4 ...@@ -388,13 +415,25 @@ config I2C_SAVAGE4
config I2C_SIBYTE config I2C_SIBYTE
tristate "SiByte SMBus interface" tristate "SiByte SMBus interface"
depends on SIBYTE_SB1xxx_SOC && I2C depends on SIBYTE_SB1xxx_SOC
help help
Supports the SiByte SOC on-chip I2C interfaces (2 channels). Supports the SiByte SOC on-chip I2C interfaces (2 channels).
config I2C_SIMTEC
tristate "Simtec Generic I2C interface"
select I2C_ALGOBIT
help
If you say yes to this option, support will be inclyded 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 build as a module. If so, the module
will be called i2c-simtec.
config SCx200_I2C config SCx200_I2C
tristate "NatSemi SCx200 I2C using GPIO pins" tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
depends on SCx200_GPIO && I2C depends on SCx200_GPIO
select I2C_ALGOBIT select I2C_ALGOBIT
help help
Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
...@@ -404,6 +443,9 @@ config SCx200_I2C ...@@ -404,6 +443,9 @@ config SCx200_I2C
This support is also available as a module. If so, the module This support is also available as a module. If so, the module
will be called scx200_i2c. 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 config SCx200_I2C_SCL
int "GPIO pin used for SCL" int "GPIO pin used for SCL"
depends on SCx200_I2C depends on SCx200_I2C
...@@ -422,7 +464,7 @@ config SCx200_I2C_SDA ...@@ -422,7 +464,7 @@ config SCx200_I2C_SDA
config SCx200_ACB config SCx200_ACB
tristate "Geode ACCESS.bus support" tristate "Geode ACCESS.bus support"
depends on X86_32 && I2C && PCI depends on X86_32 && PCI
help help
Enable the use of the ACCESS.bus controllers on the Geode SCx200 and Enable the use of the ACCESS.bus controllers on the Geode SCx200 and
SC1100 processors and the CS5535 and CS5536 Geode companion devices. SC1100 processors and the CS5535 and CS5536 Geode companion devices.
...@@ -434,7 +476,7 @@ config SCx200_ACB ...@@ -434,7 +476,7 @@ config SCx200_ACB
config I2C_SIS5595 config I2C_SIS5595
tristate "SiS 5595" tristate "SiS 5595"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
SiS5595 SMBus (a subset of I2C) interface. SiS5595 SMBus (a subset of I2C) interface.
...@@ -444,7 +486,7 @@ config I2C_SIS5595 ...@@ -444,7 +486,7 @@ config I2C_SIS5595
config I2C_SIS630 config I2C_SIS630
tristate "SiS 630/730" tristate "SiS 630/730"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
SiS630 and SiS730 SMBus (a subset of I2C) interface. SiS630 and SiS730 SMBus (a subset of I2C) interface.
...@@ -454,7 +496,7 @@ config I2C_SIS630 ...@@ -454,7 +496,7 @@ config I2C_SIS630
config I2C_SIS96X config I2C_SIS96X
tristate "SiS 96x" tristate "SiS 96x"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the SiS If you say yes to this option, support will be included for the SiS
96x SMBus (a subset of I2C) interfaces. Specifically, the following 96x SMBus (a subset of I2C) interfaces. Specifically, the following
...@@ -472,7 +514,7 @@ config I2C_SIS96X ...@@ -472,7 +514,7 @@ config I2C_SIS96X
config I2C_STUB config I2C_STUB
tristate "I2C/SMBus Test Stub" tristate "I2C/SMBus Test Stub"
depends on I2C && EXPERIMENTAL && 'm' depends on EXPERIMENTAL && m
default 'n' default 'n'
help help
This module may be useful to developers of SMBus client drivers, This module may be useful to developers of SMBus client drivers,
...@@ -483,9 +525,20 @@ config I2C_STUB ...@@ -483,9 +525,20 @@ config I2C_STUB
If you don't know what to do here, definitely say N. If you don't know what to do here, definitely say N.
config I2C_TINY_USB
tristate "I2C-Tiny-USB"
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.
config I2C_VERSATILE config I2C_VERSATILE
tristate "ARM Versatile/Realview I2C bus support" tristate "ARM Versatile/Realview I2C bus support"
depends on I2C && (ARCH_VERSATILE || ARCH_REALVIEW) depends on ARCH_VERSATILE || ARCH_REALVIEW
select I2C_ALGOBIT select I2C_ALGOBIT
help help
Say yes if you want to support the I2C serial bus on ARMs Versatile Say yes if you want to support the I2C serial bus on ARMs Versatile
...@@ -496,7 +549,7 @@ config I2C_VERSATILE ...@@ -496,7 +549,7 @@ config I2C_VERSATILE
config I2C_ACORN config I2C_ACORN
bool "Acorn IOC/IOMD I2C bus support" bool "Acorn IOC/IOMD I2C bus support"
depends on I2C && ARCH_ACORN depends on ARCH_ACORN
default y default y
select I2C_ALGOBIT select I2C_ALGOBIT
help help
...@@ -506,7 +559,7 @@ config I2C_ACORN ...@@ -506,7 +559,7 @@ config I2C_ACORN
config I2C_VIA config I2C_VIA
tristate "VIA 82C586B" tristate "VIA 82C586B"
depends on I2C && PCI && EXPERIMENTAL depends on PCI && EXPERIMENTAL
select I2C_ALGOBIT select I2C_ALGOBIT
help help
If you say yes to this option, support will be included for the VIA If you say yes to this option, support will be included for the VIA
...@@ -517,7 +570,7 @@ config I2C_VIA ...@@ -517,7 +570,7 @@ config I2C_VIA
config I2C_VIAPRO config I2C_VIAPRO
tristate "VIA VT82C596/82C686/82xx and CX700" tristate "VIA VT82C596/82C686/82xx and CX700"
depends on I2C && PCI depends on PCI
help help
If you say yes to this option, support will be included for the VIA If you say yes to this option, support will be included for the VIA
VT82C596 and later SMBus interface. Specifically, the following VT82C596 and later SMBus interface. Specifically, the following
...@@ -536,7 +589,7 @@ config I2C_VIAPRO ...@@ -536,7 +589,7 @@ config I2C_VIAPRO
config I2C_VOODOO3 config I2C_VOODOO3
tristate "Voodoo 3" tristate "Voodoo 3"
depends on I2C && PCI depends on PCI
select I2C_ALGOBIT select I2C_ALGOBIT
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
...@@ -547,7 +600,7 @@ config I2C_VOODOO3 ...@@ -547,7 +600,7 @@ config I2C_VOODOO3
config I2C_PCA_ISA config I2C_PCA_ISA
tristate "PCA9564 on an ISA bus" tristate "PCA9564 on an ISA bus"
depends on I2C depends on ISA
select I2C_ALGOPCA select I2C_ALGOPCA
default n default n
help help
...@@ -564,7 +617,7 @@ config I2C_PCA_ISA ...@@ -564,7 +617,7 @@ config I2C_PCA_ISA
config I2C_MV64XXX config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller" tristate "Marvell mv64xxx I2C Controller"
depends on I2C && MV64X60 && EXPERIMENTAL depends on MV64X60 && EXPERIMENTAL
help help
If you say yes to this option, support will be included for the 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. built-in I2C interface on the Marvell 64xxx line of host bridges.
...@@ -574,7 +627,7 @@ config I2C_MV64XXX ...@@ -574,7 +627,7 @@ config I2C_MV64XXX
config I2C_PNX config I2C_PNX
tristate "I2C bus support for Philips PNX targets" tristate "I2C bus support for Philips PNX targets"
depends on ARCH_PNX4008 && I2C depends on ARCH_PNX4008
help help
This driver supports the Philips IP3204 I2C IP block master and/or This driver supports the Philips IP3204 I2C IP block master and/or
slave controller slave controller
......
...@@ -10,7 +10,9 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o ...@@ -10,7 +10,9 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_I810) += i2c-i810.o obj-$(CONFIG_I2C_I810) += i2c-i810.o
...@@ -37,10 +39,12 @@ obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o ...@@ -37,10 +39,12 @@ obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_I2C_STUB) += i2c-stub.o
obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o
obj-$(CONFIG_I2C_VIA) += i2c-via.o obj-$(CONFIG_I2C_VIA) += i2c-via.o
......
...@@ -497,7 +497,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_ ...@@ -497,7 +497,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_
/* set up the sysfs linkage to our parent device */ /* set up the sysfs linkage to our parent device */
ali1535_adapter.dev.parent = &dev->dev; ali1535_adapter.dev.parent = &dev->dev;
snprintf(ali1535_adapter.name, I2C_NAME_SIZE, snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
"SMBus ALI1535 adapter at %04x", ali1535_smba); "SMBus ALI1535 adapter at %04x", ali1535_smba);
return i2c_add_adapter(&ali1535_adapter); return i2c_add_adapter(&ali1535_adapter);
} }
......
...@@ -492,7 +492,7 @@ static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_ ...@@ -492,7 +492,7 @@ static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_
/* set up the sysfs linkage to our parent device */ /* set up the sysfs linkage to our parent device */
ali15x3_adapter.dev.parent = &dev->dev; ali15x3_adapter.dev.parent = &dev->dev;
snprintf(ali15x3_adapter.name, I2C_NAME_SIZE, snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name),
"SMBus ALI15X3 adapter at %04x", ali15x3_smba); "SMBus ALI15X3 adapter at %04x", ali15x3_smba);
return i2c_add_adapter(&ali15x3_adapter); return i2c_add_adapter(&ali15x3_adapter);
} }
......
...@@ -365,7 +365,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, ...@@ -365,7 +365,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
} }
smbus->adapter.owner = THIS_MODULE; smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, I2C_NAME_SIZE, snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus2 AMD8111 adapter at %04x", smbus->base); "SMBus2 AMD8111 adapter at %04x", smbus->base);
smbus->adapter.id = I2C_HW_SMBUS_AMD8111; smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
smbus->adapter.class = I2C_CLASS_HWMON; smbus->adapter.class = I2C_CLASS_HWMON;
......
/*
* drivers/i2c/busses/i2c-bfin-twi.c
*
* Description: Driver for Blackfin Two Wire Interface
*
* Author: sonicz <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/i2c.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 <asm/blackfin.h>
#include <asm/irq.h>
#define POLL_TIMEOUT (2 * HZ)
/* SMBus mode*/
#define TWI_I2C_MODE_STANDARD 0x01
#define TWI_I2C_MODE_STANDARDSUB 0x02
#define TWI_I2C_MODE_COMBINED 0x04
struct bfin_twi_iface {
struct mutex twi_lock;
int irq;
spinlock_t lock;
char read_write;
u8 command;
u8 *transPtr;
int readNum;
int writeNum;
int cur_mode;
int manual_stop;
int result;
int timeout_count;
struct timer_list timeout_timer;
struct i2c_adapter adap;
struct completion complete;
};
static struct bfin_twi_iface twi_iface;
static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
{
unsigned short twi_int_status = bfin_read_TWI_INT_STAT();
unsigned short mast_stat = bfin_read_TWI_MASTER_STAT();
if (twi_int_status & XMTSERV) {
/* Transmit next data */
if (iface->writeNum > 0) {
bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
iface->writeNum--;
}
/* start receive immediately after complete sending in
* combine mode.
*/
else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
| MDIR | RSTART);
} else if (iface->manual_stop)
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
| STOP);
SSYNC();
/* Clear status */
bfin_write_TWI_INT_STAT(XMTSERV);
SSYNC();
}
if (twi_int_status & RCVSERV) {
if (iface->readNum > 0) {
/* Receive next data */
*(iface->transPtr) = bfin_read_TWI_RCV_DATA8();
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) {
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
| STOP);
SSYNC();
}
/* Clear interrupt source */
bfin_write_TWI_INT_STAT(RCVSERV);
SSYNC();
}
if (twi_int_status & MERR) {
bfin_write_TWI_INT_STAT(MERR);
bfin_write_TWI_INT_MASK(0);
bfin_write_TWI_MASTER_STAT(0x3e);
bfin_write_TWI_MASTER_CTL(0);
SSYNC();
iface->result = -1;
/* if both err and complete int stats are set, return proper
* results.
*/
if (twi_int_status & MCOMP) {
bfin_write_TWI_INT_STAT(MCOMP);
bfin_write_TWI_INT_MASK(0);
bfin_write_TWI_MASTER_CTL(0);
SSYNC();
/* If it is a quick transfer, only address bug no data,
* not an err, return 1.
*/
if (iface->writeNum == 0 && (mast_stat & BUFRDERR))
iface->result = 1;
/* If address not acknowledged return -1,
* else return 0.
*/
else if (!(mast_stat & ANAK))
iface->result = 0;
}
complete(&iface->complete);
return;
}
if (twi_int_status & MCOMP) {
bfin_write_TWI_INT_STAT(MCOMP);
SSYNC();
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;
bfin_write_TWI_MASTER_CTL(
bfin_read_TWI_MASTER_CTL()
| (0xff << 6));
} else {
/* set the readd number in other
* combine mode.
*/
bfin_write_TWI_MASTER_CTL(
(bfin_read_TWI_MASTER_CTL() &
(~(0xff << 6))) |
( iface->readNum << 6));
}
/* remove restart bit and enable master receive */
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() &
~RSTART);
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() |
MEN | MDIR);
SSYNC();
} else {
iface->result = 1;
bfin_write_TWI_INT_MASK(0);
bfin_write_TWI_MASTER_CTL(0);
SSYNC();
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;
spin_lock_irqsave(&iface->lock, flags);
del_timer(&iface->timeout_timer);
bfin_twi_handle_interrupt(iface);
spin_unlock_irqrestore(&iface->lock, flags);
return IRQ_HANDLED;
}
static void bfin_twi_timeout(unsigned long data)
{
struct bfin_twi_iface *iface = (struct bfin_twi_iface *)data;
unsigned long flags;
spin_lock_irqsave(&iface->lock, flags);
bfin_twi_handle_interrupt(iface);
if (iface->result == 0) {
iface->timeout_count--;
if (iface->timeout_count > 0) {
iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
add_timer(&iface->timeout_timer);
} else {
iface->result = -1;
complete(&iface->complete);
}
}
spin_unlock_irqrestore(&iface->lock, flags);
}
/*
* Generic i2c master transfer entrypoint
*/
static int bfin_twi_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 i, ret;
int rc = 0;
if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
return -ENXIO;
mutex_lock(&iface->twi_lock);
while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
mutex_unlock(&iface->twi_lock);
yield();
mutex_lock(&iface->twi_lock);
}
ret = 0;
for (i = 0; rc >= 0 && i < num; i++) {
pmsg = &msgs[i];
if (pmsg->flags & I2C_M_TEN) {
dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr "
"not supported !\n");
rc = -EINVAL;
break;
}
iface->cur_mode = TWI_I2C_MODE_STANDARD;
iface->manual_stop = 0;
iface->transPtr = pmsg->buf;
iface->writeNum = iface->readNum = pmsg->len;
iface->result = 0;
iface->timeout_count = 10;
/* Set Transmit device address */
bfin_write_TWI_MASTER_ADDR(pmsg->addr);
/* FIFO Initiation. Data in FIFO should be
* discarded before start a new operation.
*/
bfin_write_TWI_FIFO_CTL(0x3);
SSYNC();
bfin_write_TWI_FIFO_CTL(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) {
bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
iface->writeNum--;
SSYNC();
}
}
/* clear int stat */
bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
/* Interrupt mask . Enable XMT, RCV interrupt */
bfin_write_TWI_INT_MASK(MCOMP | MERR |
((iface->read_write == I2C_SMBUS_READ)?
RCVSERV : XMTSERV));
SSYNC();
if (pmsg->len > 0 && pmsg->len <= 255)
bfin_write_TWI_MASTER_CTL(pmsg->len << 6);
else if (pmsg->len > 255) {
bfin_write_TWI_MASTER_CTL(0xff << 6);
iface->manual_stop = 1;
} else
break;
iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
add_timer(&iface->timeout_timer);
/* Master enable */
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
SSYNC();
wait_for_completion(&iface->complete);
rc = iface->result;
if (rc == 1)
ret++;
else if (rc == -1)
break;
}
/* Release mutex */
mutex_unlock(&iface->twi_lock);
return ret;
}
/*
* SMBus type 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)
{
struct bfin_twi_iface *iface = adap->algo_data;
int rc = 0;
if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
return -ENXIO;
mutex_lock(&iface->twi_lock);
while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
mutex_unlock(&iface->twi_lock);
yield();
mutex_lock(&iface->twi_lock);
}
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;
default:
return -1;
}
iface->result = 0;
iface->manual_stop = 0;
iface->read_write = read_write;
iface->command = command;
iface->timeout_count = 10;
/* FIFO Initiation. Data in FIFO should be discarded before
* start a new operation.
*/
bfin_write_TWI_FIFO_CTL(0x3);
SSYNC();
bfin_write_TWI_FIFO_CTL(0);
/* clear int stat */
bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
/* Set Transmit device address */
bfin_write_TWI_MASTER_ADDR(addr);
SSYNC();
iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
add_timer(&iface->timeout_timer);
switch (iface->cur_mode) {
case TWI_I2C_MODE_STANDARDSUB:
bfin_write_TWI_XMT_DATA8(iface->command);
bfin_write_TWI_INT_MASK(MCOMP | MERR |
((iface->read_write == I2C_SMBUS_READ) ?
RCVSERV : XMTSERV));
SSYNC();
if (iface->writeNum + 1 <= 255)
bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
else {
bfin_write_TWI_MASTER_CTL(0xff << 6);
iface->manual_stop = 1;
}
/* Master enable */
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
break;
case TWI_I2C_MODE_COMBINED:
bfin_write_TWI_XMT_DATA8(iface->command);
bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV);
SSYNC();
if (iface->writeNum > 0)
bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
else
bfin_write_TWI_MASTER_CTL(0x1 << 6);
/* Master enable */
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
break;
default:
bfin_write_TWI_MASTER_CTL(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) {
bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
if (iface->writeNum <= 255)
bfin_write_TWI_MASTER_CTL(iface->writeNum << 6);
else {
bfin_write_TWI_MASTER_CTL(0xff << 6);
iface->manual_stop = 1;
}
iface->writeNum--;
} else {
bfin_write_TWI_XMT_DATA8(iface->command);
bfin_write_TWI_MASTER_CTL(1 << 6);
}
} else {
if (iface->readNum > 0 && iface->readNum <= 255)
bfin_write_TWI_MASTER_CTL(iface->readNum << 6);
else if (iface->readNum > 255) {
bfin_write_TWI_MASTER_CTL(0xff << 6);
iface->manual_stop = 1;
} else {
del_timer(&iface->timeout_timer);
break;
}
}
}
bfin_write_TWI_INT_MASK(MCOMP | MERR |
((iface->read_write == I2C_SMBUS_READ) ?
RCVSERV : XMTSERV));
SSYNC();
/* Master enable */
bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
break;
}
SSYNC();
wait_for_completion(&iface->complete);
rc = (iface->result >= 0) ? 0 : -1;
/* Release mutex */
mutex_unlock(&iface->twi_lock);
return rc;
}
/*
* 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;
}
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 *dev, pm_message_t state)
{
/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
/* Disable TWI */
bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA);
SSYNC();
return 0;
}
static int i2c_bfin_twi_resume(struct platform_device *dev)
{
/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
/* Enable TWI */
bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
SSYNC();
return 0;
}
static int i2c_bfin_twi_probe(struct platform_device *dev)
{
struct bfin_twi_iface *iface = &twi_iface;
struct i2c_adapter *p_adap;
int rc;
mutex_init(&(iface->twi_lock));
spin_lock_init(&(iface->lock));
init_completion(&(iface->complete));
iface->irq = IRQ_TWI;
init_timer(&(iface->timeout_timer));
iface->timeout_timer.function = bfin_twi_timeout;
iface->timeout_timer.data = (unsigned long)iface;
p_adap = &iface->adap;
p_adap->id = I2C_HW_BLACKFIN;
strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
p_adap->algo = &bfin_twi_algorithm;
p_adap->algo_data = iface;
p_adap->class = I2C_CLASS_ALL;
p_adap->dev.parent = &dev->dev;
rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
IRQF_DISABLED, dev->name, iface);
if (rc) {
dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n",
iface->irq);
return -ENODEV;
}
/* Set TWI internal clock as 10MHz */
bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
/* Set Twi interface clock as specified */
bfin_write_TWI_CLKDIV((( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ )
<< 8) | (( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ )
& 0xFF));
/* Enable TWI */
bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
SSYNC();
rc = i2c_add_adapter(p_adap);
if (rc < 0)
free_irq(iface->irq, iface);
else
platform_set_drvdata(dev, iface);
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);
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)
{
pr_info("I2C: Blackfin I2C TWI driver\n");
return platform_driver_register(&i2c_bfin_twi_driver);
}
static void __exit i2c_bfin_twi_exit(void)
{
platform_driver_unregister(&i2c_bfin_twi_driver);
}
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
MODULE_DESCRIPTION("I2C-Bus adapter routines for Blackfin TWI");
MODULE_LICENSE("GPL");
module_init(i2c_bfin_twi_init);
module_exit(i2c_bfin_twi_exit);
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/isa.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-pcf.h> #include <linux/i2c-algo-pcf.h>
...@@ -207,7 +208,7 @@ static struct i2c_adapter pcf_isa_ops = { ...@@ -207,7 +208,7 @@ static struct i2c_adapter pcf_isa_ops = {
.name = "i2c-elektor", .name = "i2c-elektor",
}; };
static int __init i2c_pcfisa_init(void) static int __devinit elektor_match(struct device *dev, unsigned int id)
{ {
#ifdef __alpha__ #ifdef __alpha__
/* check to see we have memory mapped PCF8584 connected to the /* check to see we have memory mapped PCF8584 connected to the
...@@ -222,9 +223,8 @@ static int __init i2c_pcfisa_init(void) ...@@ -222,9 +223,8 @@ static int __init i2c_pcfisa_init(void)
/* yeap, we've found cypress, let's check config */ /* yeap, we've found cypress, let's check config */
if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
pr_debug("%s: found cy82c693, config " dev_dbg(dev, "found cy82c693, config "
"register 0x47 = 0x%02x\n", "register 0x47 = 0x%02x\n", config);
pcf_isa_ops.name, config);
/* UP2000 board has this register set to 0xe1, /* UP2000 board has this register set to 0xe1,
but the most significant bit as seems can be but the most significant bit as seems can be
...@@ -244,9 +244,9 @@ static int __init i2c_pcfisa_init(void) ...@@ -244,9 +244,9 @@ static int __init i2c_pcfisa_init(void)
8.25 MHz (PCI/4) clock 8.25 MHz (PCI/4) clock
(this can be read from cypress) */ (this can be read from cypress) */
clock = I2C_PCF_CLK | I2C_PCF_TRNS90; clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
pr_info("%s: found API UP2000 like " dev_info(dev, "found API UP2000 like "
"board, will probe PCF8584 " "board, will probe PCF8584 "
"later\n", pcf_isa_ops.name); "later\n");
} }
} }
pci_dev_put(cy693_dev); pci_dev_put(cy693_dev);
...@@ -256,22 +256,27 @@ static int __init i2c_pcfisa_init(void) ...@@ -256,22 +256,27 @@ static int __init i2c_pcfisa_init(void)
/* sanity checks for mmapped I/O */ /* sanity checks for mmapped I/O */
if (mmapped && base < 0xc8000) { if (mmapped && base < 0xc8000) {
printk(KERN_ERR "%s: incorrect base address (%#x) specified " dev_err(dev, "incorrect base address (%#x) specified "
"for mmapped I/O\n", pcf_isa_ops.name, base); "for mmapped I/O\n", base);
return -ENODEV; return 0;
} }
if (base == 0) { if (base == 0) {
base = DEFAULT_BASE; base = DEFAULT_BASE;
} }
return 1;
}
static int __devinit elektor_probe(struct device *dev, unsigned int id)
{
init_waitqueue_head(&pcf_wait); init_waitqueue_head(&pcf_wait);
if (pcf_isa_init()) if (pcf_isa_init())
return -ENODEV; return -ENODEV;
pcf_isa_ops.dev.parent = dev;
if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
goto fail; goto fail;
dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base); dev_info(dev, "found device at %#x\n", base);
return 0; return 0;
...@@ -291,7 +296,7 @@ static int __init i2c_pcfisa_init(void) ...@@ -291,7 +296,7 @@ static int __init i2c_pcfisa_init(void)
return -ENODEV; return -ENODEV;
} }
static void i2c_pcfisa_exit(void) static int __devexit elektor_remove(struct device *dev, unsigned int id)
{ {
i2c_del_adapter(&pcf_isa_ops); i2c_del_adapter(&pcf_isa_ops);
...@@ -307,6 +312,28 @@ static void i2c_pcfisa_exit(void) ...@@ -307,6 +312,28 @@ static void i2c_pcfisa_exit(void)
iounmap(base_iomem); iounmap(base_iomem);
release_mem_region(base, 2); 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_AUTHOR("Hans Berglund <hb@spacetec.no>");
......
/*
* 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/platform_device.h>
#include <asm/gpio.h>
/* 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);
}
int i2c_gpio_getsda(void *data)
{
struct i2c_gpio_platform_data *pdata = data;
return gpio_get_value(pdata->sda_pin);
}
int i2c_gpio_getscl(void *data)
{
struct i2c_gpio_platform_data *pdata = data;
return gpio_get_value(pdata->scl_pin);
}
static int __init i2c_gpio_probe(struct platform_device *pdev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap;
int ret;
pdata = pdev->dev.platform_data;
if (!pdata)
return -ENXIO;
ret = -ENOMEM;
adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
if (!adap)
goto err_alloc_adap;
bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
if (!bit_data)
goto err_alloc_bit_data;
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->dev.parent = &pdev->dev;
ret = i2c_bit_add_bus(adap);
if (ret)
goto err_add_bus;
platform_set_drvdata(pdev, adap);
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:
kfree(bit_data);
err_alloc_bit_data:
kfree(adap);
err_alloc_adap:
return ret;
}
static int __exit i2c_gpio_remove(struct platform_device *pdev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_adapter *adap;
adap = platform_get_drvdata(pdev);
pdata = pdev->dev.platform_data;
i2c_del_adapter(adap);
gpio_free(pdata->scl_pin);
gpio_free(pdata->sda_pin);
kfree(adap->algo_data);
kfree(adap);
return 0;
}
static struct platform_driver i2c_gpio_driver = {
.driver = {
.name = "i2c-gpio",
.owner = THIS_MODULE,
},
.remove = __exit_p(i2c_gpio_remove),
};
static int __init i2c_gpio_init(void)
{
int ret;
ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe);
if (ret)
printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
return ret;
}
module_init(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 <hskinnemoen@atmel.com>");
MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
MODULE_LICENSE("GPL");
...@@ -527,7 +527,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id ...@@ -527,7 +527,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
/* set up the sysfs linkage to our parent device */ /* set up the sysfs linkage to our parent device */
i801_adapter.dev.parent = &dev->dev; i801_adapter.dev.parent = &dev->dev;
snprintf(i801_adapter.name, I2C_NAME_SIZE, snprintf(i801_adapter.name, sizeof(i801_adapter.name),
"SMBus I801 adapter at %04lx", i801_smba); "SMBus I801 adapter at %04lx", i801_smba);
err = i2c_add_adapter(&i801_adapter); err = i2c_add_adapter(&i801_adapter);
if (err) { if (err) {
......
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/completion.h> #include <linux/completion.h>
/* Exported by i2c-core for i2c-isa only */
extern void i2c_adapter_dev_release(struct device *dev);
extern struct class i2c_adapter_class;
static u32 isa_func(struct i2c_adapter *adapter); static u32 isa_func(struct i2c_adapter *adapter);
/* This is the actual algorithm we define */ /* This is the actual algorithm we define */
...@@ -64,16 +68,6 @@ static u32 isa_func(struct i2c_adapter *adapter) ...@@ -64,16 +68,6 @@ static u32 isa_func(struct i2c_adapter *adapter)
} }
/* Copied from i2c-core */
static ssize_t show_adapter_name(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
return sprintf(buf, "%s\n", adap->name);
}
static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
/* We implement an interface which resembles i2c_{add,del}_driver, /* We implement an interface which resembles i2c_{add,del}_driver,
but for i2c-isa drivers. We don't have to remember and handle lists but for i2c-isa drivers. We don't have to remember and handle lists
of drivers and adapters so this is much more simple, of course. */ of drivers and adapters so this is much more simple, of course. */
...@@ -139,41 +133,18 @@ static int __init i2c_isa_init(void) ...@@ -139,41 +133,18 @@ static int __init i2c_isa_init(void)
isa_adapter.nr = ANY_I2C_ISA_BUS; isa_adapter.nr = ANY_I2C_ISA_BUS;
isa_adapter.dev.parent = &platform_bus; isa_adapter.dev.parent = &platform_bus;
sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr); sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
isa_adapter.dev.driver = &i2c_adapter_driver;
isa_adapter.dev.release = &i2c_adapter_dev_release; isa_adapter.dev.release = &i2c_adapter_dev_release;
isa_adapter.dev.class = &i2c_adapter_class;
err = device_register(&isa_adapter.dev); err = device_register(&isa_adapter.dev);
if (err) { if (err) {
printk(KERN_ERR "i2c-isa: Failed to register device\n"); printk(KERN_ERR "i2c-isa: Failed to register device\n");
goto exit; goto exit;
} }
err = device_create_file(&isa_adapter.dev, &dev_attr_name);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to create name file\n");
goto exit_unregister;
}
/* Add this adapter to the i2c_adapter class */
memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device));
isa_adapter.class_dev.dev = &isa_adapter.dev;
isa_adapter.class_dev.class = &i2c_adapter_class;
strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id,
BUS_ID_SIZE);
err = class_device_register(&isa_adapter.class_dev);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to register class device\n");
goto exit_remove_name;
}
dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name); dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
return 0; return 0;
exit_remove_name:
device_remove_file(&isa_adapter.dev, &dev_attr_name);
exit_unregister:
init_completion(&isa_adapter.dev_released); /* Needed? */
device_unregister(&isa_adapter.dev);
wait_for_completion(&isa_adapter.dev_released);
exit: exit:
return err; return err;
} }
...@@ -201,15 +172,11 @@ static void __exit i2c_isa_exit(void) ...@@ -201,15 +172,11 @@ static void __exit i2c_isa_exit(void)
/* Clean up the sysfs representation */ /* Clean up the sysfs representation */
dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n"); dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n");
init_completion(&isa_adapter.dev_released); init_completion(&isa_adapter.dev_released);
init_completion(&isa_adapter.class_dev_released);
class_device_unregister(&isa_adapter.class_dev);
device_remove_file(&isa_adapter.dev, &dev_attr_name);
device_unregister(&isa_adapter.dev); device_unregister(&isa_adapter.dev);
/* Wait for sysfs to drop all references */ /* Wait for sysfs to drop all references */
dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n"); dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n");
wait_for_completion(&isa_adapter.dev_released); wait_for_completion(&isa_adapter.dev_released);
wait_for_completion(&isa_adapter.class_dev_released);
dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name); dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name);
} }
......
...@@ -118,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev) ...@@ -118,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->adapter.id = I2C_HW_B_IXP2000, drv_data->adapter.id = I2C_HW_B_IXP2000,
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE); sizeof(drv_data->adapter.name));
drv_data->adapter.algo_data = &drv_data->algo_data, drv_data->adapter.algo_data = &drv_data->algo_data,
drv_data->adapter.dev.parent = &plat_dev->dev; drv_data->adapter.dev.parent = &plat_dev->dev;
......
...@@ -127,7 +127,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) ...@@ -127,7 +127,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
drv_data->adapter.id = I2C_HW_B_IXP4XX; drv_data->adapter.id = I2C_HW_B_IXP4XX;
drv_data->adapter.class = I2C_CLASS_HWMON; drv_data->adapter.class = I2C_CLASS_HWMON;
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE); sizeof(drv_data->adapter.name));
drv_data->adapter.algo_data = &drv_data->algo_data; drv_data->adapter.algo_data = &drv_data->algo_data;
drv_data->adapter.dev.parent = &plat_dev->dev; drv_data->adapter.dev.parent = &plat_dev->dev;
......
...@@ -508,7 +508,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) ...@@ -508,7 +508,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
} }
strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
I2C_NAME_SIZE); sizeof(drv_data->adapter.name));
init_waitqueue_head(&drv_data->waitq); init_waitqueue_head(&drv_data->waitq);
spin_lock_init(&drv_data->lock); spin_lock_init(&drv_data->lock);
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
nForce4 MCP-04 0034 nForce4 MCP-04 0034
nForce4 MCP51 0264 nForce4 MCP51 0264
nForce4 MCP55 0368 nForce4 MCP55 0368
nForce MCP61 03EB
nForce MCP65 0446
This driver supports the 2 SMBuses that are included in the MCP of the This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4/5xx chipsets. nForce2/3/4/5xx chipsets.
...@@ -200,6 +202,8 @@ static struct pci_device_id nforce2_ids[] = { ...@@ -200,6 +202,8 @@ static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_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_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_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) },
{ 0 } { 0 }
}; };
...@@ -240,7 +244,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, ...@@ -240,7 +244,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus; smbus->adapter.algo_data = smbus;
smbus->adapter.dev.parent = &dev->dev; smbus->adapter.dev.parent = &dev->dev;
snprintf(smbus->adapter.name, I2C_NAME_SIZE, snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus nForce2 adapter at %04x", smbus->base); "SMBus nForce2 adapter at %04x", smbus->base);
error = i2c_add_adapter(&smbus->adapter); error = i2c_add_adapter(&smbus->adapter);
......
...@@ -605,7 +605,8 @@ omap_i2c_probe(struct platform_device *pdev) ...@@ -605,7 +605,8 @@ omap_i2c_probe(struct platform_device *pdev)
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
/* i2c device drivers may be active on return from add_adapter() */ /* i2c device drivers may be active on return from add_adapter() */
r = i2c_add_adapter(adap); adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
if (r) { if (r) {
dev_err(dev->dev, "failure adding adapter\n"); dev_err(dev->dev, "failure adding adapter\n");
goto err_free_irq; goto err_free_irq;
......
/* ------------------------------------------------------------------------ * /* ------------------------------------------------------------------------ *
* i2c-parport.c I2C bus over parallel port * * i2c-parport-light.c I2C bus over parallel port *
* ------------------------------------------------------------------------ * * ------------------------------------------------------------------------ *
Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org> Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
Based on older i2c-velleman.c driver Based on older i2c-velleman.c driver
Copyright (C) 1995-2000 Simon G. Vogl Copyright (C) 1995-2000 Simon G. Vogl
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
...@@ -34,6 +35,9 @@ ...@@ -34,6 +35,9 @@
#include "i2c-parport.h" #include "i2c-parport.h"
#define DEFAULT_BASE 0x378 #define DEFAULT_BASE 0x378
#define DRVNAME "i2c-parport-light"
static struct platform_device *pdev;
static u16 base; static u16 base;
module_param(base, ushort, 0); module_param(base, ushort, 0);
...@@ -106,7 +110,7 @@ static struct i2c_algo_bit_data parport_algo_data = { ...@@ -106,7 +110,7 @@ static struct i2c_algo_bit_data parport_algo_data = {
.timeout = HZ, .timeout = HZ,
}; };
/* ----- I2c structure ---------------------------------------------------- */ /* ----- Driver registration ---------------------------------------------- */
static struct i2c_adapter parport_adapter = { static struct i2c_adapter parport_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -116,55 +120,141 @@ static struct i2c_adapter parport_adapter = { ...@@ -116,55 +120,141 @@ static struct i2c_adapter parport_adapter = {
.name = "Parallel port adapter (light)", .name = "Parallel port adapter (light)",
}; };
/* ----- Module loading, unloading and information ------------------------ */ static int __devinit i2c_parport_probe(struct platform_device *pdev)
{
int err;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!request_region(res->start, res->end - res->start + 1, DRVNAME))
return -EBUSY;
/* 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);
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");
goto exit_region;
}
return 0;
exit_region:
release_region(res->start, res->end - res->start + 1);
return err;
}
static int __devexit i2c_parport_remove(struct platform_device *pdev)
{
struct resource *res;
i2c_del_adapter(&parport_adapter);
/* Un-init if needed (power off...) */
if (adapter_parm[type].init.val)
line_set(0, &adapter_parm[type].init);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, res->end - res->start + 1);
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)
{
struct resource res = {
.start = address,
.end = address + 2,
.name = DRVNAME,
.flags = IORESOURCE_IO,
};
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_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed "
"(%d)\n", err);
goto exit_device_put;
}
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) static int __init i2c_parport_init(void)
{ {
int err;
if (type < 0) { if (type < 0) {
printk(KERN_WARNING "i2c-parport: adapter type unspecified\n"); printk(KERN_ERR DRVNAME ": adapter type unspecified\n");
return -ENODEV; return -ENODEV;
} }
if (type >= ARRAY_SIZE(adapter_parm)) { if (type >= ARRAY_SIZE(adapter_parm)) {
printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); printk(KERN_ERR DRVNAME ": invalid type (%d)\n", type);
return -ENODEV; return -ENODEV;
} }
if (base == 0) { if (base == 0) {
printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); pr_info(DRVNAME ": using default base 0x%x\n", DEFAULT_BASE);
base = DEFAULT_BASE; base = DEFAULT_BASE;
} }
if (!request_region(base, 3, "i2c-parport"))
return -ENODEV;
if (!adapter_parm[type].getscl.val) if (!adapter_parm[type].getscl.val)
parport_algo_data.getscl = NULL; parport_algo_data.getscl = NULL;
/* Reset hardware to a sane state (SCL and SDA high) */ /* Sets global pdev as a side effect */
parport_setsda(NULL, 1); err = i2c_parport_device_add(base);
parport_setscl(NULL, 1); if (err)
/* Other init if needed (power on...) */ goto exit;
if (adapter_parm[type].init.val)
line_set(1, &adapter_parm[type].init);
if (i2c_bit_add_bus(&parport_adapter) < 0) { err = platform_driver_register(&i2c_parport_driver);
printk(KERN_ERR "i2c-parport: Unable to register with I2C\n"); if (err)
release_region(base, 3); goto exit_device;
return -ENODEV;
}
return 0; return 0;
exit_device:
platform_device_unregister(pdev);
exit:
return err;
} }
static void __exit i2c_parport_exit(void) static void __exit i2c_parport_exit(void)
{ {
/* Un-init if needed (power off...) */ platform_driver_unregister(&i2c_parport_driver);
if (adapter_parm[type].init.val) platform_device_unregister(pdev);
line_set(0, &adapter_parm[type].init);
i2c_del_adapter(&parport_adapter);
release_region(base, 3);
} }
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
......
/* ------------------------------------------------------------------------ * /* ------------------------------------------------------------------------ *
* i2c-parport.c I2C bus over parallel port * * i2c-parport.c I2C bus over parallel port *
* ------------------------------------------------------------------------ * * ------------------------------------------------------------------------ *
Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org> Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
Based on older i2c-philips-par.c driver Based on older i2c-philips-par.c driver
Copyright (C) 1995-2000 Simon G. Vogl Copyright (C) 1995-2000 Simon G. Vogl
...@@ -137,19 +137,12 @@ static struct i2c_algo_bit_data parport_algo_data = { ...@@ -137,19 +137,12 @@ static struct i2c_algo_bit_data parport_algo_data = {
.setscl = parport_setscl, .setscl = parport_setscl,
.getsda = parport_getsda, .getsda = parport_getsda,
.getscl = parport_getscl, .getscl = parport_getscl,
.udelay = 60, .udelay = 10, /* ~50 kbps */
.timeout = HZ, .timeout = HZ,
}; };
/* ----- I2c and parallel port call-back functions and structures --------- */ /* ----- I2c and parallel port call-back functions and structures --------- */
static struct i2c_adapter parport_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.id = I2C_HW_B_LP,
.name = "Parallel port adapter",
};
static void i2c_parport_attach (struct parport *port) static void i2c_parport_attach (struct parport *port)
{ {
struct i2c_par *adapter; struct i2c_par *adapter;
...@@ -169,10 +162,17 @@ static void i2c_parport_attach (struct parport *port) ...@@ -169,10 +162,17 @@ static void i2c_parport_attach (struct parport *port)
} }
/* Fill the rest of the structure */ /* Fill the rest of the structure */
adapter->adapter = parport_adapter; adapter->adapter.owner = THIS_MODULE;
adapter->adapter.class = I2C_CLASS_HWMON;
adapter->adapter.id = I2C_HW_B_LP;
strlcpy(adapter->adapter.name, "Parallel port adapter",
sizeof(adapter->adapter.name));
adapter->algo_data = parport_algo_data; adapter->algo_data = parport_algo_data;
if (!adapter_parm[type].getscl.val) /* Slow down if we can't sense SCL */
if (!adapter_parm[type].getscl.val) {
adapter->algo_data.getscl = NULL; adapter->algo_data.getscl = NULL;
adapter->algo_data.udelay = 50; /* ~10 kbps */
}
adapter->algo_data.data = port; adapter->algo_data.data = port;
adapter->adapter.algo_data = &adapter->algo_data; adapter->adapter.algo_data = &adapter->algo_data;
...@@ -214,11 +214,12 @@ static void i2c_parport_detach (struct parport *port) ...@@ -214,11 +214,12 @@ static void i2c_parport_detach (struct parport *port)
for (prev = NULL, adapter = adapter_list; adapter; for (prev = NULL, adapter = adapter_list; adapter;
prev = adapter, adapter = adapter->next) { prev = adapter, adapter = adapter->next) {
if (adapter->pdev->port == port) { if (adapter->pdev->port == port) {
i2c_del_adapter(&adapter->adapter);
/* Un-init if needed (power off...) */ /* Un-init if needed (power off...) */
if (adapter_parm[type].init.val) if (adapter_parm[type].init.val)
line_set(port, 0, &adapter_parm[type].init); line_set(port, 0, &adapter_parm[type].init);
i2c_del_adapter(&adapter->adapter);
parport_unregister_device(adapter->pdev); parport_unregister_device(adapter->pdev);
if (prev) if (prev)
prev->next = adapter->next; prev->next = adapter->next;
......
...@@ -358,7 +358,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev, ...@@ -358,7 +358,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
} }
smbus->adapter.owner = THIS_MODULE; smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, I2C_NAME_SIZE, snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"PA Semi SMBus adapter at 0x%lx", smbus->base); "PA Semi SMBus adapter at 0x%lx", smbus->base);
smbus->adapter.class = I2C_CLASS_HWMON; smbus->adapter.class = I2C_CLASS_HWMON;
smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo = &smbus_algorithm;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/isa.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-pca.h> #include <linux/i2c-algo-pca.h>
...@@ -119,27 +120,26 @@ static struct i2c_adapter pca_isa_ops = { ...@@ -119,27 +120,26 @@ static struct i2c_adapter pca_isa_ops = {
.name = "PCA9564 ISA Adapter", .name = "PCA9564 ISA Adapter",
}; };
static int __init pca_isa_init(void) static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
{ {
init_waitqueue_head(&pca_wait); init_waitqueue_head(&pca_wait);
printk(KERN_INFO "i2c-pca-isa: i/o base %#08lx. irq %d\n", base, irq); dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
if (!request_region(base, IO_SIZE, "i2c-pca-isa")) { if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
printk(KERN_ERR "i2c-pca-isa: I/O address %#08lx is in use.\n", base); dev_err(dev, "I/O address %#08lx is in use\n", base);
goto out; goto out;
} }
if (irq > -1) { if (irq > -1) {
if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) { if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) {
printk(KERN_ERR "i2c-pca-isa: Request irq%d failed\n", irq); dev_err(dev, "Request irq%d failed\n", irq);
goto out_region; goto out_region;
} }
} }
if (i2c_pca_add_bus(&pca_isa_ops) < 0) { if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
printk(KERN_ERR "i2c-pca-isa: Failed to add i2c bus\n"); dev_err(dev, "Failed to add i2c bus\n");
goto out_irq; goto out_irq;
} }
...@@ -154,7 +154,7 @@ static int __init pca_isa_init(void) ...@@ -154,7 +154,7 @@ static int __init pca_isa_init(void)
return -ENODEV; return -ENODEV;
} }
static void pca_isa_exit(void) static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
{ {
i2c_del_adapter(&pca_isa_ops); i2c_del_adapter(&pca_isa_ops);
...@@ -163,6 +163,27 @@ static void pca_isa_exit(void) ...@@ -163,6 +163,27 @@ static void pca_isa_exit(void)
free_irq(irq, &pca_isa_ops); free_irq(irq, &pca_isa_ops);
} }
release_region(base, IO_SIZE); release_region(base, IO_SIZE);
return 0;
}
static struct isa_driver pca_isa_driver = {
.probe = pca_isa_probe,
.remove = __devexit_p(pca_isa_remove),
.driver = {
.owner = THIS_MODULE,
.name = "i2c-pca-isa",
}
};
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_AUTHOR("Ian Campbell <icampbell@arcom.com>");
......
...@@ -428,7 +428,7 @@ static int __devinit piix4_probe(struct pci_dev *dev, ...@@ -428,7 +428,7 @@ static int __devinit piix4_probe(struct pci_dev *dev,
/* set up the sysfs linkage to our parent device */ /* set up the sysfs linkage to our parent device */
piix4_adapter.dev.parent = &dev->dev; piix4_adapter.dev.parent = &dev->dev;
snprintf(piix4_adapter.name, I2C_NAME_SIZE, snprintf(piix4_adapter.name, sizeof(piix4_adapter.name),
"SMBus PIIX4 adapter at %04x", piix4_smba); "SMBus PIIX4 adapter at %04x", piix4_smba);
if ((retval = i2c_add_adapter(&piix4_adapter))) { if ((retval = i2c_add_adapter(&piix4_adapter))) {
......
...@@ -539,6 +539,18 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c) ...@@ -539,6 +539,18 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
writel(icr | ICR_START | ICR_TB, _ICR(i2c)); 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, _IRC(i2c));
}
/* /*
* We are protected by the adapter bus mutex. * We are protected by the adapter bus mutex.
*/ */
...@@ -581,6 +593,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num) ...@@ -581,6 +593,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
* The rest of the processing occurs in the interrupt handler. * The rest of the processing occurs in the interrupt handler.
*/ */
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); 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. * We place the return code in i2c->msg_idx.
...@@ -825,7 +838,7 @@ static const struct i2c_algorithm i2c_pxa_algorithm = { ...@@ -825,7 +838,7 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
}; };
static struct pxa_i2c i2c_pxa = { static struct pxa_i2c i2c_pxa = {
.lock = SPIN_LOCK_UNLOCKED, .lock = __SPIN_LOCK_UNLOCKED(i2c_pxa.lock),
.adap = { .adap = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.algo = &i2c_pxa_algorithm, .algo = &i2c_pxa_algorithm,
......
...@@ -61,6 +61,8 @@ struct s3c24xx_i2c { ...@@ -61,6 +61,8 @@ struct s3c24xx_i2c {
unsigned int msg_idx; unsigned int msg_idx;
unsigned int msg_ptr; unsigned int msg_ptr;
unsigned int tx_setup;
enum s3c24xx_i2c_state state; enum s3c24xx_i2c_state state;
void __iomem *regs; void __iomem *regs;
...@@ -199,8 +201,11 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, ...@@ -199,8 +201,11 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr); dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
writeb(addr, i2c->regs + S3C2410_IICDS); writeb(addr, i2c->regs + S3C2410_IICDS);
// delay a bit and reset iiccon before setting start (per samsung) /* delay here to ensure the data byte has gotten onto the bus
udelay(1); * before the transaction is started */
ndelay(i2c->tx_setup);
dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon); dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
writel(iiccon, i2c->regs + S3C2410_IICCON); writel(iiccon, i2c->regs + S3C2410_IICCON);
...@@ -322,7 +327,15 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) ...@@ -322,7 +327,15 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
if (!is_msgend(i2c)) { if (!is_msgend(i2c)) {
byte = i2c->msg->buf[i2c->msg_ptr++]; byte = i2c->msg->buf[i2c->msg_ptr++];
writeb(byte, i2c->regs + S3C2410_IICDS); 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)) { } else if (!is_lastmsg(i2c)) {
/* we need to go to the next i2c message */ /* we need to go to the next i2c message */
...@@ -570,9 +583,10 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = { ...@@ -570,9 +583,10 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
}; };
static struct s3c24xx_i2c s3c24xx_i2c = { static struct s3c24xx_i2c s3c24xx_i2c = {
.lock = SPIN_LOCK_UNLOCKED, .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock),
.wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait), .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
.adap = { .tx_setup = 50,
.adap = {
.name = "s3c2410-i2c", .name = "s3c2410-i2c",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.algo = &s3c24xx_i2c_algorithm, .algo = &s3c24xx_i2c_algorithm,
...@@ -731,26 +745,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) ...@@ -731,26 +745,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
return 0; return 0;
} }
static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c)
{
if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {
clk_disable(i2c->clk);
clk_put(i2c->clk);
i2c->clk = NULL;
}
if (i2c->regs != NULL) {
iounmap(i2c->regs);
i2c->regs = NULL;
}
if (i2c->ioarea != NULL) {
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
i2c->ioarea = NULL;
}
}
/* s3c24xx_i2c_probe /* s3c24xx_i2c_probe
* *
* called by the bus driver when a suitable device is found * called by the bus driver when a suitable device is found
...@@ -769,7 +763,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -769,7 +763,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (IS_ERR(i2c->clk)) { if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n"); dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT; ret = -ENOENT;
goto out; goto err_noclk;
} }
dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk); dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
...@@ -782,7 +776,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -782,7 +776,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (res == NULL) { if (res == NULL) {
dev_err(&pdev->dev, "cannot find IO resource\n"); dev_err(&pdev->dev, "cannot find IO resource\n");
ret = -ENOENT; ret = -ENOENT;
goto out; goto err_clk;
} }
i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1, i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1,
...@@ -791,7 +785,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -791,7 +785,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (i2c->ioarea == NULL) { if (i2c->ioarea == NULL) {
dev_err(&pdev->dev, "cannot request IO\n"); dev_err(&pdev->dev, "cannot request IO\n");
ret = -ENXIO; ret = -ENXIO;
goto out; goto err_clk;
} }
i2c->regs = ioremap(res->start, (res->end-res->start)+1); i2c->regs = ioremap(res->start, (res->end-res->start)+1);
...@@ -799,7 +793,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -799,7 +793,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (i2c->regs == NULL) { if (i2c->regs == NULL) {
dev_err(&pdev->dev, "cannot map IO\n"); dev_err(&pdev->dev, "cannot map IO\n");
ret = -ENXIO; ret = -ENXIO;
goto out; goto err_ioarea;
} }
dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res); dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
...@@ -813,7 +807,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -813,7 +807,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
ret = s3c24xx_i2c_init(i2c); ret = s3c24xx_i2c_init(i2c);
if (ret != 0) if (ret != 0)
goto out; goto err_iomap;
/* find the IRQ for this unit (note, this relies on the init call to /* find the IRQ for this unit (note, this relies on the init call to
* ensure no current IRQs pending * ensure no current IRQs pending
...@@ -823,7 +817,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -823,7 +817,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (res == NULL) { if (res == NULL) {
dev_err(&pdev->dev, "cannot find IRQ\n"); dev_err(&pdev->dev, "cannot find IRQ\n");
ret = -ENOENT; ret = -ENOENT;
goto out; goto err_iomap;
} }
ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED, ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED,
...@@ -831,7 +825,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -831,7 +825,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ\n"); dev_err(&pdev->dev, "cannot claim IRQ\n");
goto out; goto err_iomap;
} }
i2c->irq = res; i2c->irq = res;
...@@ -841,17 +835,29 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -841,17 +835,29 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
ret = i2c_add_adapter(&i2c->adap); ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n"); dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto out; goto err_irq;
} }
platform_set_drvdata(pdev, i2c); platform_set_drvdata(pdev, i2c);
dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
return 0;
out: err_irq:
if (ret < 0) free_irq(i2c->irq->start, i2c);
s3c24xx_i2c_free(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; return ret;
} }
...@@ -863,11 +869,17 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -863,11 +869,17 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
static int s3c24xx_i2c_remove(struct platform_device *pdev) static int s3c24xx_i2c_remove(struct platform_device *pdev)
{ {
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
if (i2c != NULL) { i2c_del_adapter(&i2c->adap);
s3c24xx_i2c_free(i2c); free_irq(i2c->irq->start, i2c);
platform_set_drvdata(pdev, NULL);
} clk_disable(i2c->clk);
clk_put(i2c->clk);
iounmap(i2c->regs);
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
return 0; return 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/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.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 = (res->end-res->start)+1;
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,
};
static int __init i2c_adap_simtec_init(void)
{
return platform_driver_register(&simtec_i2c_driver);
}
static void __exit i2c_adap_simtec_exit(void)
{
platform_driver_unregister(&simtec_i2c_driver);
}
module_init(i2c_adap_simtec_init);
module_exit(i2c_adap_simtec_exit);
MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
...@@ -300,7 +300,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev, ...@@ -300,7 +300,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
/* set up the sysfs linkage to our parent device */ /* set up the sysfs linkage to our parent device */
sis96x_adapter.dev.parent = &dev->dev; sis96x_adapter.dev.parent = &dev->dev;
snprintf(sis96x_adapter.name, I2C_NAME_SIZE, snprintf(sis96x_adapter.name, sizeof(sis96x_adapter.name),
"SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base); "SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
if ((retval = i2c_add_adapter(&sis96x_adapter))) { if ((retval = i2c_add_adapter(&sis96x_adapter))) {
......
/*
* 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 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 */
static int delay = 10;
module_param(delay, int, 0);
MODULE_PARM_DESC(delay, "bit delay in microseconds, "
"e.g. 10 for 100kHz (default is 100kHz)");
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)
{
u32 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 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 ---------------------------------------------- */
/* The usb i2c interface uses a vid/pid pair donated by */
/* Future Technology Devices International Ltd. */
static struct usb_device_id i2c_tiny_usb_table [] = {
{ USB_DEVICE(0x0403, 0xc631) },
{ } /* 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, I2C_NAME_SIZE,
"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,
cpu_to_le16(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,
};
static int __init usb_i2c_tiny_usb_init(void)
{
/* register this driver with the USB subsystem */
return usb_register(&i2c_tiny_usb_driver);
}
static void __exit usb_i2c_tiny_usb_exit(void)
{
/* deregister this driver with the USB subsystem */
usb_deregister(&i2c_tiny_usb_driver);
}
module_init(usb_i2c_tiny_usb_init);
module_exit(usb_i2c_tiny_usb_exit);
/* ----- end of usb layer ------------------------------------------------ */
MODULE_AUTHOR("Till Harbaum <Till@Harbaum.org>");
MODULE_DESCRIPTION("i2c-tiny-usb driver v1.0");
MODULE_LICENSE("GPL");
...@@ -404,7 +404,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, ...@@ -404,7 +404,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
} }
vt596_adapter.dev.parent = &pdev->dev; vt596_adapter.dev.parent = &pdev->dev;
snprintf(vt596_adapter.name, I2C_NAME_SIZE, snprintf(vt596_adapter.name, sizeof(vt596_adapter.name),
"SMBus Via Pro adapter at %04x", vt596_smba); "SMBus Via Pro adapter at %04x", vt596_smba);
vt596_pdev = pci_dev_get(pdev); vt596_pdev = pci_dev_get(pdev);
......
...@@ -441,7 +441,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text, ...@@ -441,7 +441,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
adapter = &iface->adapter; adapter = &iface->adapter;
i2c_set_adapdata(adapter, iface); i2c_set_adapdata(adapter, iface);
snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index); snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
adapter->owner = THIS_MODULE; adapter->owner = THIS_MODULE;
adapter->id = I2C_HW_SMBUS_SCX200; adapter->id = I2C_HW_SMBUS_SCX200;
adapter->algo = &scx200_acb_algorithm; adapter->algo = &scx200_acb_algorithm;
...@@ -599,6 +599,7 @@ static __init int scx200_scan_pci(void) ...@@ -599,6 +599,7 @@ static __init int scx200_scan_pci(void)
else { else {
int i; int i;
pci_dev_put(pdev);
for (i = 0; i < MAX_DEVICES; ++i) { for (i = 0; i < MAX_DEVICES; ++i) {
if (base[i] == 0) if (base[i] == 0)
continue; continue;
......
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
# #
menu "Miscellaneous I2C Chip support" menu "Miscellaneous I2C Chip support"
depends on I2C
config SENSORS_DS1337 config SENSORS_DS1337
tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock" tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
help help
If you say yes here you get support for Dallas Semiconductor If you say yes here you get support for Dallas Semiconductor
DS1337 and DS1339 real-time clock chips. DS1337 and DS1339 real-time clock chips.
...@@ -17,7 +16,7 @@ config SENSORS_DS1337 ...@@ -17,7 +16,7 @@ config SENSORS_DS1337
config SENSORS_DS1374 config SENSORS_DS1374
tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock" tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
help help
If you say yes here you get support for Dallas Semiconductor If you say yes here you get support for Dallas Semiconductor
DS1374 real-time clock chips. DS1374 real-time clock chips.
...@@ -27,7 +26,7 @@ config SENSORS_DS1374 ...@@ -27,7 +26,7 @@ config SENSORS_DS1374
config SENSORS_EEPROM config SENSORS_EEPROM
tristate "EEPROM reader" tristate "EEPROM reader"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
help help
If you say yes here you get read-only access to the EEPROM data If you say yes here you get read-only access to the EEPROM data
available on modern memory DIMMs and Sony Vaio laptops. Such available on modern memory DIMMs and Sony Vaio laptops. Such
...@@ -38,7 +37,7 @@ config SENSORS_EEPROM ...@@ -38,7 +37,7 @@ config SENSORS_EEPROM
config SENSORS_PCF8574 config SENSORS_PCF8574
tristate "Philips PCF8574 and PCF8574A" tristate "Philips PCF8574 and PCF8574A"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
default n default n
help help
If you say yes here you get support for Philips PCF8574 and If you say yes here you get support for Philips PCF8574 and
...@@ -52,7 +51,7 @@ config SENSORS_PCF8574 ...@@ -52,7 +51,7 @@ config SENSORS_PCF8574
config SENSORS_PCA9539 config SENSORS_PCA9539
tristate "Philips PCA9539 16-bit I/O port" tristate "Philips PCA9539 16-bit I/O port"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
help help
If you say yes here you get support for the Philips PCA9539 If you say yes here you get support for the Philips PCA9539
16-bit I/O port. 16-bit I/O port.
...@@ -62,7 +61,7 @@ config SENSORS_PCA9539 ...@@ -62,7 +61,7 @@ config SENSORS_PCA9539
config SENSORS_PCF8591 config SENSORS_PCF8591
tristate "Philips PCF8591" tristate "Philips PCF8591"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
default n default n
help help
If you say yes here you get support for Philips PCF8591 chips. If you say yes here you get support for Philips PCF8591 chips.
...@@ -75,7 +74,7 @@ config SENSORS_PCF8591 ...@@ -75,7 +74,7 @@ config SENSORS_PCF8591
config ISP1301_OMAP config ISP1301_OMAP
tristate "Philips ISP1301 with OMAP OTG" tristate "Philips ISP1301 with OMAP OTG"
depends on I2C && ARCH_OMAP_OTG depends on ARCH_OMAP_OTG
help help
If you say yes here you get support for the Philips ISP1301 If you say yes here you get support for the Philips ISP1301
USB-On-The-Go transceiver working with the OMAP OTG controller. USB-On-The-Go transceiver working with the OMAP OTG controller.
...@@ -90,7 +89,7 @@ config ISP1301_OMAP ...@@ -90,7 +89,7 @@ config ISP1301_OMAP
# and having mostly OMAP-specific board support # and having mostly OMAP-specific board support
config TPS65010 config TPS65010
tristate "TPS6501x Power Management chips" tristate "TPS6501x Power Management chips"
depends on I2C && ARCH_OMAP depends on ARCH_OMAP
default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
help help
If you say yes here you get support for the TPS6501x series of If you say yes here you get support for the TPS6501x series of
...@@ -103,7 +102,7 @@ config TPS65010 ...@@ -103,7 +102,7 @@ config TPS65010
config SENSORS_M41T00 config SENSORS_M41T00
tristate "ST M41T00 RTC chip" tristate "ST M41T00 RTC chip"
depends on I2C && PPC32 depends on PPC32
help help
If you say yes here you get support for the ST M41T00 RTC chip. If you say yes here you get support for the ST M41T00 RTC chip.
...@@ -112,7 +111,7 @@ config SENSORS_M41T00 ...@@ -112,7 +111,7 @@ config SENSORS_M41T00
config SENSORS_MAX6875 config SENSORS_MAX6875
tristate "Maxim MAX6875 Power supply supervisor" tristate "Maxim MAX6875 Power supply supervisor"
depends on I2C && EXPERIMENTAL depends on EXPERIMENTAL
help help
If you say yes here you get support for the Maxim MAX6875 If you say yes here you get support for the Maxim MAX6875
EEPROM-programmable, quad power-supply sequencer/supervisor. EEPROM-programmable, quad power-supply sequencer/supervisor.
......
/*
* i2c-boardinfo.h - 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/i2c.h>
#include "i2c-core.h"
/* These symbols are exported ONLY FOR the i2c core.
* No other users will be supported.
*/
DEFINE_MUTEX(__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;
mutex_lock(&__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);
}
mutex_unlock(&__i2c_board_lock);
return status;
}
此差异已折叠。
/*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
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 mutex __i2c_board_lock;
extern struct list_head __i2c_board_list;
extern int __i2c_first_dynamic_bus_num;
...@@ -459,7 +459,8 @@ therm_of_probe( struct of_device *dev, const struct of_device_id *match ) ...@@ -459,7 +459,8 @@ therm_of_probe( struct of_device *dev, const struct of_device_id *match )
static int static int
therm_of_remove( struct of_device *dev ) therm_of_remove( struct of_device *dev )
{ {
return i2c_del_driver( &g4fan_driver ); i2c_del_driver( &g4fan_driver );
return 0;
} }
static struct of_device_id therm_of_match[] = {{ static struct of_device_id therm_of_match[] = {{
......
...@@ -183,7 +183,8 @@ int flexcop_i2c_init(struct flexcop_device *fc) ...@@ -183,7 +183,8 @@ int flexcop_i2c_init(struct flexcop_device *fc)
mutex_init(&fc->i2c_mutex); mutex_init(&fc->i2c_mutex);
memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter)); memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE); strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",
sizeof(fc->i2c_adap.name));
i2c_set_adapdata(&fc->i2c_adap,fc); i2c_set_adapdata(&fc->i2c_adap,fc);
......
...@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) ...@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
return -EINVAL; return -EINVAL;
} }
strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE); strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
#ifdef I2C_ADAP_CLASS_TV_DIGITAL #ifdef I2C_ADAP_CLASS_TV_DIGITAL
d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
#else #else
......
...@@ -105,9 +105,9 @@ struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enu ...@@ -105,9 +105,9 @@ struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enu
} }
EXPORT_SYMBOL(dibx000_get_i2c_adapter); EXPORT_SYMBOL(dibx000_get_i2c_adapter);
static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst) static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst)
{ {
strncpy(i2c_adap->name, name, I2C_NAME_SIZE); strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->class = I2C_CLASS_TV_DIGITAL,
i2c_adap->algo = algo; i2c_adap->algo = algo;
i2c_adap->algo_data = NULL; i2c_adap->algo_data = NULL;
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/tuner.h> #include <media/tuner.h>
#include <media/cx2341x.h> #include <media/cx2341x.h>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#ifndef __LINUX_OVCAMCHIP_PRIV_H #ifndef __LINUX_OVCAMCHIP_PRIV_H
#define __LINUX_OVCAMCHIP_PRIV_H #define __LINUX_OVCAMCHIP_PRIV_H
#include <linux/i2c.h>
#include <media/ovcamchip.h> #include <media/ovcamchip.h>
#ifdef DEBUG #ifdef DEBUG
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/i2c.h>
#include <media/v4l2-dev.h> #include <media/v4l2-dev.h>
#include <media/tuner.h> #include <media/tuner.h>
#include "usbvision.h" #include "usbvision.h"
......
...@@ -104,7 +104,8 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, ...@@ -104,7 +104,8 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
chan->dinfo = dinfo; chan->dinfo = dinfo;
chan->reg = reg; chan->reg = reg;
snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name); snprintf(chan->adapter.name, sizeof(chan->adapter.name),
"intelfb %s", name);
chan->adapter.owner = THIS_MODULE; chan->adapter.owner = THIS_MODULE;
chan->adapter.id = I2C_HW_B_INTELFB; chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo; chan->adapter.algo_data = &chan->algo;
......
...@@ -111,7 +111,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, ...@@ -111,7 +111,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
b->mask.data = data; b->mask.data = data;
b->mask.clock = clock; b->mask.clock = clock;
b->adapter = matrox_i2c_adapter_template; b->adapter = matrox_i2c_adapter_template;
snprintf(b->adapter.name, I2C_NAME_SIZE, name, snprintf(b->adapter.name, sizeof(b->adapter.name), name,
minfo->fbcon.node); minfo->fbcon.node);
i2c_set_adapdata(&b->adapter, b); i2c_set_adapdata(&b->adapter, b);
b->adapter.algo_data = &b->bac; b->adapter.algo_data = &b->bac;
......
...@@ -38,11 +38,14 @@ struct i2c_algo_bit_data { ...@@ -38,11 +38,14 @@ struct i2c_algo_bit_data {
int (*getscl) (void *data); int (*getscl) (void *data);
/* local settings */ /* local settings */
int udelay; /* half-clock-cycle time in microsecs */ int udelay; /* half clock cycle time in us,
/* i.e. clock is (500 / udelay) KHz */ minimum 2 us for fast-mode I2C,
minimum 5 us for standard-mode I2C and SMBus,
maximum 50 us for SMBus */
int timeout; /* in jiffies */ int timeout; /* in jiffies */
}; };
int i2c_bit_add_bus(struct i2c_adapter *); int i2c_bit_add_bus(struct i2c_adapter *);
int i2c_bit_add_numbered_bus(struct i2c_adapter *);
#endif /* _LINUX_I2C_ALGO_BIT_H */ #endif /* _LINUX_I2C_ALGO_BIT_H */
/*
* i2c-gpio interface to platform code
*
* 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.
*/
#ifndef _LINUX_I2C_GPIO_H
#define _LINUX_I2C_GPIO_H
/**
* struct i2c_gpio_platform_data - Platform-dependent data for i2c-gpio
* @sda_pin: GPIO pin ID to use for SDA
* @scl_pin: GPIO pin ID to use for SCL
* @udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz
* @timeout: clock stretching timeout in jiffies. If the slave keeps
* SCL low for longer than this, the transfer will time out.
* @sda_is_open_drain: SDA is configured as open drain, i.e. the pin
* isn't actively driven high when setting the output value high.
* gpio_get_value() must return the actual pin state even if the
* pin is configured as an output.
* @scl_is_open_drain: SCL is set up as open drain. Same requirements
* as for sda_is_open_drain apply.
* @scl_is_output_only: SCL output drivers cannot be turned off.
*/
struct i2c_gpio_platform_data {
unsigned int sda_pin;
unsigned int scl_pin;
int udelay;
int timeout;
unsigned int sda_is_open_drain:1;
unsigned int scl_is_open_drain:1;
unsigned int scl_is_output_only:1;
};
#endif /* _LINUX_I2C_GPIO_H */
...@@ -258,8 +258,9 @@ ...@@ -258,8 +258,9 @@
/* --- MCP107 adapter */ /* --- MCP107 adapter */
#define I2C_HW_MPC107 0x0d0000 #define I2C_HW_MPC107 0x0d0000
/* --- Marvell mv64xxx i2c adapter */ /* --- Embedded adapters */
#define I2C_HW_MV64XXX 0x190000 #define I2C_HW_MV64XXX 0x190000
#define I2C_HW_BLACKFIN 0x190001 /* ADI Blackfin I2C TWI driver */
/* --- Miscellaneous adapters */ /* --- Miscellaneous adapters */
#define I2C_HW_SAA7146 0x060000 /* SAA7146 video decoder bus */ #define I2C_HW_SAA7146 0x060000 /* SAA7146 video decoder bus */
......
...@@ -35,11 +35,6 @@ ...@@ -35,11 +35,6 @@
#include <linux/sched.h> /* for completion */ #include <linux/sched.h> /* for completion */
#include <linux/mutex.h> #include <linux/mutex.h>
/* --- For i2c-isa ---------------------------------------------------- */
extern void i2c_adapter_dev_release(struct device *dev);
extern struct device_driver i2c_adapter_driver;
extern struct class i2c_adapter_class;
extern struct bus_type i2c_bus_type; extern struct bus_type i2c_bus_type;
/* --- General options ------------------------------------------------ */ /* --- General options ------------------------------------------------ */
...@@ -87,6 +82,9 @@ extern s32 i2c_smbus_write_byte_data(struct i2c_client * client, ...@@ -87,6 +82,9 @@ extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_word_data(struct i2c_client * client, extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value); u8 command, u16 value);
/* Returns the number of read bytes */
extern s32 i2c_smbus_read_block_data(struct i2c_client *client,
u8 command, u8 *values);
extern s32 i2c_smbus_write_block_data(struct i2c_client * client, extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
u8 command, u8 length, u8 command, u8 length,
const u8 *values); const u8 *values);
...@@ -114,7 +112,7 @@ struct i2c_driver { ...@@ -114,7 +112,7 @@ struct i2c_driver {
* can be used by the driver to test if the bus meets its conditions * can be used by the driver to test if the bus meets its conditions
* & seek for the presence of the chip(s) it supports. If found, it * & seek for the presence of the chip(s) it supports. If found, it
* registers the client(s) that are on the bus to the i2c admin. via * registers the client(s) that are on the bus to the i2c admin. via
* i2c_attach_client. * i2c_attach_client. (LEGACY I2C DRIVERS ONLY)
*/ */
int (*attach_adapter)(struct i2c_adapter *); int (*attach_adapter)(struct i2c_adapter *);
int (*detach_adapter)(struct i2c_adapter *); int (*detach_adapter)(struct i2c_adapter *);
...@@ -122,10 +120,17 @@ struct i2c_driver { ...@@ -122,10 +120,17 @@ struct i2c_driver {
/* tells the driver that a client is about to be deleted & gives it /* tells the driver that a client is about to be deleted & gives it
* the chance to remove its private data. Also, if the client struct * the chance to remove its private data. Also, if the client struct
* has been dynamically allocated by the driver in the function above, * has been dynamically allocated by the driver in the function above,
* it must be freed here. * it must be freed here. (LEGACY I2C DRIVERS ONLY)
*/ */
int (*detach_client)(struct i2c_client *); int (*detach_client)(struct i2c_client *);
/* Standard driver model interfaces, for "new style" i2c drivers.
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
int (*probe)(struct i2c_client *);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */ /* driver model interfaces that don't relate to enumeration */
void (*shutdown)(struct i2c_client *); void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_t mesg); int (*suspend)(struct i2c_client *, pm_message_t mesg);
...@@ -141,25 +146,34 @@ struct i2c_driver { ...@@ -141,25 +146,34 @@ struct i2c_driver {
}; };
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
#define I2C_NAME_SIZE 50 #define I2C_NAME_SIZE 20
/* /**
* i2c_client identifies a single device (i.e. chip) that is connected to an * struct i2c_client - represent an I2C slave device
* i2c bus. The behaviour is defined by the routines of the driver. This * @addr: Address used on the I2C bus connected to the parent adapter.
* function is mainly used for lookup & other admin. functions. * @name: Indicates the type of the device, usually a chip name that's
* generic enough to hide second-sourcing and compatible revisions.
* @dev: Driver model device node for the slave.
* @driver_name: Identifies new-style driver used with this device; also
* used as the module name for hotplug/coldplug modprobe support.
*
* An i2c_client identifies a single device (i.e. chip) connected to an
* i2c bus. The behaviour is defined by the routines of the driver.
*/ */
struct i2c_client { struct i2c_client {
unsigned int flags; /* div., see below */ unsigned short flags; /* div., see below */
unsigned short addr; /* chip address - NOTE: 7bit */ unsigned short addr; /* chip address - NOTE: 7bit */
/* addresses are stored in the */ /* addresses are stored in the */
/* _LOWER_ 7 bits */ /* _LOWER_ 7 bits */
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */ struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */ struct i2c_driver *driver; /* and our access routines */
int usage_count; /* How many accesses currently */ int usage_count; /* How many accesses currently */
/* to the client */ /* to the client */
struct device dev; /* the device structure */ struct device dev; /* the device structure */
int irq; /* irq issued by device (or -1) */
char driver_name[KOBJ_NAME_LEN];
struct list_head list; struct list_head list;
char name[I2C_NAME_SIZE];
struct completion released; struct completion released;
}; };
#define to_i2c_client(d) container_of(d, struct i2c_client, dev) #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
...@@ -179,6 +193,76 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data) ...@@ -179,6 +193,76 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
dev_set_drvdata (&dev->dev, data); dev_set_drvdata (&dev->dev, data);
} }
/**
* struct i2c_board_info - template for device creation
* @driver_name: identifies the driver to be bound to the device
* @type: optional chip type information, to initialize i2c_client.name
* @flags: to initialize i2c_client.flags
* @addr: stored in i2c_client.addr
* @platform_data: stored in i2c_client.dev.platform_data
* @irq: stored in i2c_client.irq
* I2C doesn't actually support hardware probing, although controllers and
* devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
* a device at a given address. Drivers commonly need more information than
* that, such as chip type, configuration, associated IRQ, and so on.
*
* i2c_board_info is used to build tables of information listing I2C devices
* that are present. This information is used to grow the driver model tree
* for "new style" I2C drivers. For mainboards this is done statically using
* i2c_register_board_info(), where @bus_num represents an adapter that isn't
* yet available. For add-on boards, i2c_new_device() does this dynamically
* with the adapter already known.
*/
struct i2c_board_info {
char driver_name[KOBJ_NAME_LEN];
char type[I2C_NAME_SIZE];
unsigned short flags;
unsigned short addr;
void *platform_data;
int irq;
};
/**
* I2C_BOARD_INFO - macro used to list an i2c device and its driver
* @driver: identifies the driver to use with the device
* @dev_addr: the device's address on the bus.
*
* This macro initializes essential fields of a struct i2c_board_info,
* declaring what has been provided on a particular board. Optional
* fields (such as the chip type, its associated irq, or device-specific
* platform_data) are provided using conventional syntax.
*/
#define I2C_BOARD_INFO(driver,dev_addr) \
.driver_name = (driver), .addr = (dev_addr)
/* Add-on boards should register/unregister their devices; e.g. a board
* with integrated I2C, a config eeprom, sensors, and a codec that's
* used in conjunction with the primary hardware.
*/
extern struct i2c_client *
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
/* If you don't know the exact address of an I2C device, use this variant
* instead, which can probe for device presence in a list of possible
* addresses.
*/
extern struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
unsigned short const *addr_list);
extern void i2c_unregister_device(struct i2c_client *);
/* Mainboard arch_initcall() code should register all its I2C devices.
* This is done at arch_initcall time, before declaring any i2c adapters.
* Modules for add-on boards must use other calls.
*/
extern int
i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n);
/* /*
* The following structs are for those who like to implement new bus drivers: * The following structs are for those who like to implement new bus drivers:
* i2c_algorithm is the interface to a class of hardware solutions which can * i2c_algorithm is the interface to a class of hardware solutions which can
...@@ -228,17 +312,14 @@ struct i2c_adapter { ...@@ -228,17 +312,14 @@ struct i2c_adapter {
int timeout; int timeout;
int retries; int retries;
struct device dev; /* the adapter device */ struct device dev; /* the adapter device */
struct class_device class_dev; /* the class device */
int nr; int nr;
struct list_head clients; struct list_head clients;
struct list_head list; struct list_head list;
char name[I2C_NAME_SIZE]; char name[48];
struct completion dev_released; struct completion dev_released;
struct completion class_dev_released;
}; };
#define dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
#define class_dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, class_dev)
static inline void *i2c_get_adapdata (struct i2c_adapter *dev) static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
{ {
...@@ -290,9 +371,10 @@ struct i2c_client_address_data { ...@@ -290,9 +371,10 @@ struct i2c_client_address_data {
*/ */
extern int i2c_add_adapter(struct i2c_adapter *); extern int i2c_add_adapter(struct i2c_adapter *);
extern int i2c_del_adapter(struct i2c_adapter *); extern int i2c_del_adapter(struct i2c_adapter *);
extern int i2c_add_numbered_adapter(struct i2c_adapter *);
extern int i2c_register_driver(struct module *, struct i2c_driver *); extern int i2c_register_driver(struct module *, struct i2c_driver *);
extern int i2c_del_driver(struct i2c_driver *); extern void i2c_del_driver(struct i2c_driver *);
static inline int i2c_add_driver(struct i2c_driver *driver) static inline int i2c_add_driver(struct i2c_driver *driver)
{ {
...@@ -365,6 +447,7 @@ struct i2c_msg { ...@@ -365,6 +447,7 @@ struct i2c_msg {
#define I2C_M_REV_DIR_ADDR 0x2000 #define I2C_M_REV_DIR_ADDR 0x2000
#define I2C_M_IGNORE_NAK 0x1000 #define I2C_M_IGNORE_NAK 0x1000
#define I2C_M_NO_RD_ACK 0x0800 #define I2C_M_NO_RD_ACK 0x0800
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
__u16 len; /* msg length */ __u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */ __u8 *buf; /* pointer to msg data */
}; };
......
...@@ -1213,11 +1213,13 @@ ...@@ -1213,11 +1213,13 @@
#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5 #define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5
#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6 #define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS 0x03EB
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC
#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE #define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE
#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF #define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS 0x0446
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448
#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450 #define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450
#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 #define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/videodev.h> #include <linux/videodev.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <linux/i2c.h>
/* --------------------------------- */ /* --------------------------------- */
/* ENUMERATIONS */ /* ENUMERATIONS */
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define _TUNER_H #define _TUNER_H
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/tuner-types.h> #include <media/tuner-types.h>
extern int tuner_debug; extern int tuner_debug;
......
#ifndef _TAS_IOCTL_H_ #ifndef _TAS_IOCTL_H_
#define _TAS_IOCTL_H_ #define _TAS_IOCTL_H_
#include <linux/i2c.h>
#include <linux/soundcard.h> #include <linux/soundcard.h>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册