summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 22:04:53 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 22:04:53 +0100
commit07d43ba98621f08e252a48c96b258b4d572b0257 (patch)
treec5dd8be6b2032b02fb2a27a91b02a55d54ed702d
parentMerge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm (diff)
parenti2c-core: Some style cleanups (diff)
downloadlinux-07d43ba98621f08e252a48c96b258b4d572b0257.tar.xz
linux-07d43ba98621f08e252a48c96b258b4d572b0257.zip
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: i2c-core: Some style cleanups i2c-piix4: Add support for the Broadcom HT1100 chipset i2c-piix4: Add support to SB800 SMBus changes i2c-pca-platform: Use defaults if no platform_data given i2c-algo-pca: Use timeout for checking the state machine i2c-algo-pca: Rework waiting for a free bus i2c-algo-pca: Add PCA9665 support i2c: Adapt debug macros for KERN_* constants i2c-davinci: Fix timeout handling i2c: Adapter timeout is in jiffies i2c: Set a default timeout value for all adapters i2c: Add missing KERN_* constants to printks i2c-algo-pcf: Handle timeout correctly i2c-algo-pcf: Style cleanups eeprom/at24: Remove EXPERIMENTAL i2c-nforce2: Add support for MCP67, MCP73, MCP78S and MCP79 i2c: Clarify which clients are auto-removed i2c: Let checkpatch shout on users of the legacy model i2c: Document the different ways to instantiate i2c devices
-rw-r--r--Documentation/feature-removal-schedule.txt3
-rw-r--r--Documentation/i2c/busses/i2c-nforce212
-rw-r--r--Documentation/i2c/busses/i2c-piix42
-rw-r--r--Documentation/i2c/instantiating-devices167
-rw-r--r--Documentation/i2c/writing-clients19
-rw-r--r--arch/sh/boards/board-sh7785lcr.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c4
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c250
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c261
-rw-r--r--drivers/i2c/busses/Kconfig9
-rw-r--r--drivers/i2c/busses/i2c-davinci.c8
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c6
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c2
-rw-r--r--drivers/i2c/busses/i2c-mpc.c4
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c7
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c12
-rw-r--r--drivers/i2c/busses/i2c-pca-isa.c39
-rw-r--r--drivers/i2c/busses/i2c-pca-platform.c48
-rw-r--r--drivers/i2c/busses/i2c-piix4.c77
-rw-r--r--drivers/i2c/busses/i2c-powermac.c3
-rw-r--r--drivers/i2c/busses/i2c-pxa.c9
-rw-r--r--drivers/i2c/i2c-core.c36
-rw-r--r--drivers/misc/eeprom/Kconfig2
-rw-r--r--include/linux/i2c-algo-pca.h33
-rw-r--r--include/linux/i2c-pca-platform.h2
-rw-r--r--include/linux/pci_ids.h5
26 files changed, 746 insertions, 276 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 02ea3773535e..7907586c6e08 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -340,7 +340,8 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
---------------------------
What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
-When: 2.6.29 (ideally) or 2.6.30 (more likely)
+When: 2.6.30
+Check: i2c_attach_client i2c_detach_client
Why: Deprecated by the new (standard) device driver binding model. Use
i2c_driver->probe() and ->remove() instead.
Who: Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/i2c/busses/i2c-nforce2 b/Documentation/i2c/busses/i2c-nforce2
index fae3495bcbaf..9698c396b830 100644
--- a/Documentation/i2c/busses/i2c-nforce2
+++ b/Documentation/i2c/busses/i2c-nforce2
@@ -7,10 +7,14 @@ Supported adapters:
* nForce3 250Gb MCP 10de:00E4
* nForce4 MCP 10de:0052
* nForce4 MCP-04 10de:0034
- * nForce4 MCP51 10de:0264
- * nForce4 MCP55 10de:0368
- * nForce4 MCP61 10de:03EB
- * nForce4 MCP65 10de:0446
+ * nForce MCP51 10de:0264
+ * nForce MCP55 10de:0368
+ * nForce MCP61 10de:03EB
+ * nForce MCP65 10de:0446
+ * nForce MCP67 10de:0542
+ * nForce MCP73 10de:07D8
+ * nForce MCP78S 10de:0752
+ * nForce MCP79 10de:0AA2
Datasheet: not publicly available, but seems to be similar to the
AMD-8111 SMBus 2.0 adapter.
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4
index ef1efa79b1df..f889481762b5 100644
--- a/Documentation/i2c/busses/i2c-piix4
+++ b/Documentation/i2c/busses/i2c-piix4
@@ -4,7 +4,7 @@ Supported adapters:
* Intel 82371AB PIIX4 and PIIX4E
* Intel 82443MX (440MX)
Datasheet: Publicly available at the Intel website
- * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
+ * ServerWorks OSB4, CSB5, CSB6, HT-1000 and HT-1100 southbridges
Datasheet: Only available via NDA from ServerWorks
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
Datasheet: Not publicly available
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices
new file mode 100644
index 000000000000..b55ce57a84db
--- /dev/null
+++ b/Documentation/i2c/instantiating-devices
@@ -0,0 +1,167 @@
+How to instantiate I2C devices
+==============================
+
+Unlike PCI or USB devices, I2C devices are not enumerated at the hardware
+level. Instead, the software must know which devices are connected on each
+I2C bus segment, and what address these devices are using. For this
+reason, the kernel code must instantiate I2C devices explicitly. There are
+several ways to achieve this, depending on the context and requirements.
+
+
+Method 1: Declare the I2C devices by bus number
+-----------------------------------------------
+
+This method is appropriate when the I2C bus is a system bus as is the case
+for many embedded systems. On such systems, each I2C bus has a number
+which is known in advance. It is thus possible to pre-declare the I2C
+devices which live on this bus. This is done with an array of struct
+i2c_board_info which is registered by calling i2c_register_board_info().
+
+Example (from omap2 h4):
+
+static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ .irq = OMAP_GPIO_IRQ(125),
+ },
+ { /* EEPROM on mainboard */
+ I2C_BOARD_INFO("24c01", 0x52),
+ .platform_data = &m24c01,
+ },
+ { /* EEPROM on cpu card */
+ I2C_BOARD_INFO("24c01", 0x57),
+ .platform_data = &m24c01,
+ },
+};
+
+static void __init omap_h4_init(void)
+{
+ (...)
+ i2c_register_board_info(1, h4_i2c_board_info,
+ ARRAY_SIZE(h4_i2c_board_info));
+ (...)
+}
+
+The above code declares 3 devices on I2C bus 1, including their respective
+addresses and custom data needed by their drivers. When the I2C bus in
+question is registered, the I2C devices will be instantiated automatically
+by i2c-core.
+
+The devices will be automatically unbound and destroyed when the I2C bus
+they sit on goes away (if ever.)
+
+
+Method 2: Instantiate the devices explicitly
+--------------------------------------------
+
+This method is appropriate when a larger device uses an I2C bus for
+internal communication. A typical case is TV adapters. These can have a
+tuner, a video decoder, an audio decoder, etc. usually connected to the
+main chip by the means of an I2C bus. You won't know the number of the I2C
+bus in advance, so the method 1 described above can't be used. Instead,
+you can instantiate your I2C devices explicitly. This is done by filling
+a struct i2c_board_info and calling i2c_new_device().
+
+Example (from the sfe4001 network driver):
+
+static struct i2c_board_info sfe4001_hwmon_info = {
+ I2C_BOARD_INFO("max6647", 0x4e),
+};
+
+int sfe4001_init(struct efx_nic *efx)
+{
+ (...)
+ efx->board_info.hwmon_client =
+ i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
+
+ (...)
+}
+
+The above code instantiates 1 I2C device on the I2C bus which is on the
+network adapter in question.
+
+A variant of this is when you don't know for sure if an I2C device is
+present or not (for example for an optional feature which is not present
+on cheap variants of a board but you have no way to tell them apart), or
+it may have different addresses from one board to the next (manufacturer
+changing its design without notice). In this case, you can call
+i2c_new_probed_device() instead of i2c_new_device().
+
+Example (from the pnx4008 OHCI driver):
+
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+
+static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
+{
+ (...)
+ struct i2c_adapter *i2c_adap;
+ struct i2c_board_info i2c_info;
+
+ (...)
+ i2c_adap = i2c_get_adapter(2);
+ memset(&i2c_info, 0, sizeof(struct i2c_board_info));
+ strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
+ isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
+ normal_i2c);
+ i2c_put_adapter(i2c_adap);
+ (...)
+}
+
+The above code instantiates up to 1 I2C device on the I2C bus which is on
+the OHCI adapter in question. It first tries at address 0x2c, if nothing
+is found there it tries address 0x2d, and if still nothing is found, it
+simply gives up.
+
+The driver which instantiated the I2C device is responsible for destroying
+it on cleanup. This is done by calling i2c_unregister_device() on the
+pointer that was earlier returned by i2c_new_device() or
+i2c_new_probed_device().
+
+
+Method 3: Probe an I2C bus for certain devices
+----------------------------------------------
+
+Sometimes you do not have enough information about an I2C device, not even
+to call i2c_new_probed_device(). The typical case is hardware monitoring
+chips on PC mainboards. There are several dozen models, which can live
+at 25 different addresses. Given the huge number of mainboards out there,
+it is next to impossible to build an exhaustive list of the hardware
+monitoring chips being used. Fortunately, most of these chips have
+manufacturer and device ID registers, so they can be identified by
+probing.
+
+In that case, I2C devices are neither declared nor instantiated
+explicitly. Instead, i2c-core will probe for such devices as soon as their
+drivers are loaded, and if any is found, an I2C device will be
+instantiated automatically. In order to prevent any misbehavior of this
+mechanism, the following restrictions apply:
+* The I2C device driver must implement the detect() method, which
+ identifies a supported device by reading from arbitrary registers.
+* Only buses which are likely to have a supported device and agree to be
+ probed, will be probed. For example this avoids probing for hardware
+ monitoring chips on a TV adapter.
+
+Example:
+See lm90_driver and lm90_detect() in drivers/hwmon/lm90.c
+
+I2C devices instantiated as a result of such a successful probe will be
+destroyed automatically when the driver which detected them is removed,
+or when the underlying I2C bus is itself destroyed, whichever happens
+first.
+
+Those of you familiar with the i2c subsystem of 2.4 kernels and early 2.6
+kernels will find out that this method 3 is essentially similar to what
+was done there. Two significant differences are:
+* Probing is only one way to instantiate I2C devices now, while it was the
+ only way back then. Where possible, methods 1 and 2 should be preferred.
+ Method 3 should only be used when there is no other way, as it can have
+ undesirable side effects.
+* I2C buses must now explicitly say which I2C driver classes can probe
+ them (by the means of the class bitfield), while all I2C buses were
+ probed by default back then. The default is an empty class which means
+ that no probing happens. The purpose of the class bitfield is to limit
+ the aforementioned undesirable side effects.
+
+Once again, method 3 should be avoided wherever possible. Explicit device
+instantiation (methods 1 and 2) is much preferred for it is safer and
+faster.
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index 6b9af7d479c2..c1a06f989cf7 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -207,15 +207,26 @@ You simply have to define a detect callback which will attempt to
identify supported devices (returning 0 for supported ones and -ENODEV
for unsupported ones), a list of addresses to probe, and a device type
(or class) so that only I2C buses which may have that type of device
-connected (and not otherwise enumerated) will be probed. The i2c
-core will then call you back as needed and will instantiate a device
-for you for every successful detection.
+connected (and not otherwise enumerated) will be probed. For example,
+a driver for a hardware monitoring chip for which auto-detection is
+needed would set its class to I2C_CLASS_HWMON, and only I2C adapters
+with a class including I2C_CLASS_HWMON would be probed by this driver.
+Note that the absence of matching classes does not prevent the use of
+a device of that type on the given I2C adapter. All it prevents is
+auto-detection; explicit instantiation of devices is still possible.
Note that this mechanism is purely optional and not suitable for all
devices. You need some reliable way to identify the supported devices
(typically using device-specific, dedicated identification registers),
otherwise misdetections are likely to occur and things can get wrong
-quickly.
+quickly. Keep in mind that the I2C protocol doesn't include any
+standard way to detect the presence of a chip at a given address, let
+alone a standard way to identify devices. Even worse is the lack of
+semantics associated to bus transfers, which means that the same
+transfer can be seen as a read operation by a chip and as a write
+operation by another chip. For these reasons, explicit device
+instantiation should always be preferred to auto-detection where
+possible.
Device Deletion
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index 94c0296bc35d..6f94f17adc46 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -229,7 +229,7 @@ static struct resource i2c_resources[] = {
static struct i2c_pca9564_pf_platform_data i2c_platform_data = {
.gpio = 0,
.i2c_clock_speed = I2C_PCA_CON_330kHz,
- .timeout = 100,
+ .timeout = HZ,
};
static struct platform_device i2c_device = {
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index eb8f72ca02f4..d420cc5f5633 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -604,9 +604,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
/* register new adapter to i2c module... */
adap->algo = &i2c_bit_algo;
-
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
+ adap->retries = 3;
return 0;
}
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index d50b329a3c94..f68e5f8e23ee 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -22,14 +22,18 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pca.h>
-#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
-#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
-#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0)
+#define DEB1(fmt, args...) do { if (i2c_debug >= 1) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB2(fmt, args...) do { if (i2c_debug >= 2) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB3(fmt, args...) do { if (i2c_debug >= 3) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
static int i2c_debug;
@@ -43,19 +47,27 @@ static int i2c_debug;
#define pca_wait(adap) adap->wait_for_completion(adap->data)
#define pca_reset(adap) adap->reset_chip(adap->data)
+static void pca9665_reset(void *pd)
+{
+ struct i2c_algo_pca_data *adap = pd;
+ pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
+ pca_outw(adap, I2C_PCA_IND, 0xA5);
+ pca_outw(adap, I2C_PCA_IND, 0x5A);
+}
+
/*
* Generate a start condition on the i2c bus.
*
* returns after the start condition has occurred
*/
-static void pca_start(struct i2c_algo_pca_data *adap)
+static int pca_start(struct i2c_algo_pca_data *adap)
{
int sta = pca_get_con(adap);
DEB2("=== START\n");
sta |= I2C_PCA_CON_STA;
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -63,14 +75,14 @@ static void pca_start(struct i2c_algo_pca_data *adap)
*
* return after the repeated start condition has occurred
*/
-static void pca_repeated_start(struct i2c_algo_pca_data *adap)
+static int pca_repeated_start(struct i2c_algo_pca_data *adap)
{
int sta = pca_get_con(adap);
DEB2("=== REPEATED START\n");
sta |= I2C_PCA_CON_STA;
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -96,7 +108,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap)
*
* returns after the address has been sent
*/
-static void pca_address(struct i2c_algo_pca_data *adap,
+static int pca_address(struct i2c_algo_pca_data *adap,
struct i2c_msg *msg)
{
int sta = pca_get_con(adap);
@@ -113,7 +125,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -121,7 +133,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
*
* Returns after the byte has been transmitted
*/
-static void pca_tx_byte(struct i2c_algo_pca_data *adap,
+static int pca_tx_byte(struct i2c_algo_pca_data *adap,
__u8 b)
{
int sta = pca_get_con(adap);
@@ -131,7 +143,7 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap,
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -151,7 +163,7 @@ static void pca_rx_byte(struct i2c_algo_pca_data *adap,
*
* Returns after next byte has arrived.
*/
-static void pca_rx_ack(struct i2c_algo_pca_data *adap,
+static int pca_rx_ack(struct i2c_algo_pca_data *adap,
int ack)
{
int sta = pca_get_con(adap);
@@ -162,7 +174,7 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap,
sta |= I2C_PCA_CON_AA;
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
static int pca_xfer(struct i2c_adapter *i2c_adap,
@@ -175,14 +187,17 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
int numbytes = 0;
int state;
int ret;
- int timeout = i2c_adap->timeout;
-
- while ((state = pca_status(adap)) != 0xf8 && timeout--) {
- msleep(10);
- }
- if (state != 0xf8) {
- dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state);
- return -EAGAIN;
+ int completed = 1;
+ unsigned long timeout = jiffies + i2c_adap->timeout;
+
+ while (pca_status(adap) != 0xf8) {
+ if (time_before(jiffies, timeout)) {
+ msleep(10);
+ } else {
+ dev_dbg(&i2c_adap->dev, "bus is not idle. status is "
+ "%#04x\n", state);
+ return -EAGAIN;
+ }
}
DEB1("{{{ XFER %d messages\n", num);
@@ -218,18 +233,19 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
switch (state) {
case 0xf8: /* On reset or stop the bus is idle */
- pca_start(adap);
+ completed = pca_start(adap);
break;
case 0x08: /* A START condition has been transmitted */
case 0x10: /* A repeated start condition has been transmitted */
- pca_address(adap, msg);
+ completed = pca_address(adap, msg);
break;
case 0x18: /* SLA+W has been transmitted; ACK has been received */
case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
if (numbytes < msg->len) {
- pca_tx_byte(adap, msg->buf[numbytes]);
+ completed = pca_tx_byte(adap,
+ msg->buf[numbytes]);
numbytes++;
break;
}
@@ -237,7 +253,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
if (curmsg == num)
pca_stop(adap);
else
- pca_repeated_start(adap);
+ completed = pca_repeated_start(adap);
break;
case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
@@ -246,21 +262,22 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
goto out;
case 0x40: /* SLA+R has been transmitted; ACK has been received */
- pca_rx_ack(adap, msg->len > 1);
+ completed = pca_rx_ack(adap, msg->len > 1);
break;
case 0x50: /* Data bytes has been received; ACK has been returned */
if (numbytes < msg->len) {
pca_rx_byte(adap, &msg->buf[numbytes], 1);
numbytes++;
- pca_rx_ack(adap, numbytes < msg->len - 1);
+ completed = pca_rx_ack(adap,
+ numbytes < msg->len - 1);
break;
}
curmsg++; numbytes = 0;
if (curmsg == num)
pca_stop(adap);
else
- pca_repeated_start(adap);
+ completed = pca_repeated_start(adap);
break;
case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
@@ -283,7 +300,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
if (curmsg == num)
pca_stop(adap);
else
- pca_repeated_start(adap);
+ completed = pca_repeated_start(adap);
} else {
DEB2("NOT ACK sent after data byte received. "
"Not final byte. numbytes %d. len %d\n",
@@ -309,11 +326,13 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
break;
}
+ if (!completed)
+ goto out;
}
ret = curmsg;
out:
- DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
+ DEB1("}}} transfered %d/%d messages. "
"status is %#04x. control is %#04x\n",
curmsg, num, pca_status(adap),
pca_get_con(adap));
@@ -330,26 +349,171 @@ static const struct i2c_algorithm pca_algo = {
.functionality = pca_func,
};
-static int pca_init(struct i2c_adapter *adap)
+static unsigned int pca_probe_chip(struct i2c_adapter *adap)
{
- static int freqs[] = {330,288,217,146,88,59,44,36};
- int clock;
struct i2c_algo_pca_data *pca_data = adap->algo_data;
-
- if (pca_data->i2c_clock > 7) {
- printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n",
- adap->name);
- pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ /* The trick here is to check if there is an indirect register
+ * available. If there is one, we will read the value we first
+ * wrote on I2C_PCA_IADR. Otherwise, we will read the last value
+ * we wrote on I2C_PCA_ADR
+ */
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+ pca_outw(pca_data, I2C_PCA_IND, 0xAA);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO);
+ pca_outw(pca_data, I2C_PCA_IND, 0x00);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+ if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
+ printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
+ return I2C_PCA_CHIP_9665;
+ } else {
+ printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
+ return I2C_PCA_CHIP_9564;
}
+}
+
+static int pca_init(struct i2c_adapter *adap)
+{
+ struct i2c_algo_pca_data *pca_data = adap->algo_data;
adap->algo = &pca_algo;
- pca_reset(pca_data);
+ if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) {
+ static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36};
+ int clock;
+
+ if (pca_data->i2c_clock > 7) {
+ switch (pca_data->i2c_clock) {
+ case 330000:
+ pca_data->i2c_clock = I2C_PCA_CON_330kHz;
+ break;
+ case 288000:
+ pca_data->i2c_clock = I2C_PCA_CON_288kHz;
+ break;
+ case 217000:
+ pca_data->i2c_clock = I2C_PCA_CON_217kHz;
+ break;
+ case 146000:
+ pca_data->i2c_clock = I2C_PCA_CON_146kHz;
+ break;
+ case 88000:
+ pca_data->i2c_clock = I2C_PCA_CON_88kHz;
+ break;
+ case 59000:
+ pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ break;
+ case 44000:
+ pca_data->i2c_clock = I2C_PCA_CON_44kHz;
+ break;
+ case 36000:
+ pca_data->i2c_clock = I2C_PCA_CON_36kHz;
+ break;
+ default:
+ printk(KERN_WARNING
+ "%s: Invalid I2C clock speed selected."
+ " Using default 59kHz.\n", adap->name);
+ pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ }
+ } else {
+ printk(KERN_WARNING "%s: "
+ "Choosing the clock frequency based on "
+ "index is deprecated."
+ " Use the nominal frequency.\n", adap->name);
+ }
+
+ pca_reset(pca_data);
+
+ clock = pca_clock(pca_data);
+ printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
+ adap->name, freqs[clock]);
+
+ pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+ } else {
+ int clock;
+ int mode;
+ int tlow, thi;
+ /* Values can be found on PCA9665 datasheet section 7.3.2.6 */
+ int min_tlow, min_thi;
+ /* These values are the maximum raise and fall values allowed
+ * by the I2C operation mode (Standard, Fast or Fast+)
+ * They are used (added) below to calculate the clock dividers
+ * of PCA9665. Note that they are slightly different of the
+ * real maximum, to allow the change on mode exactly on the
+ * maximum clock rate for each mode
+ */
+ int raise_fall_time;
+
+ struct i2c_algo_pca_data *pca_data = adap->algo_data;
+
+ /* Ignore the reset function from the module,
+ * we can use the parallel bus reset
+ */
+ pca_data->reset_chip = pca9665_reset;
+
+ if (pca_data->i2c_clock > 1265800) {
+ printk(KERN_WARNING "%s: I2C clock speed too high."
+ " Using 1265.8kHz.\n", adap->name);
+ pca_data->i2c_clock = 1265800;
+ }
+
+ if (pca_data->i2c_clock < 60300) {
+ printk(KERN_WARNING "%s: I2C clock speed too low."
+ " Using 60.3kHz.\n", adap->name);
+ pca_data->i2c_clock = 60300;
+ }
- clock = pca_clock(pca_data);
- DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
+ /* To avoid integer overflow, use clock/100 for calculations */
+ clock = pca_clock(pca_data) / 100;
+
+ if (pca_data->i2c_clock > 10000) {
+ mode = I2C_PCA_MODE_TURBO;
+ min_tlow = 14;
+ min_thi = 5;
+ raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+ } else if (pca_data->i2c_clock > 4000) {
+ mode = I2C_PCA_MODE_FASTP;
+ min_tlow = 17;
+ min_thi = 9;
+ raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+ } else if (pca_data->i2c_clock > 1000) {
+ mode = I2C_PCA_MODE_FAST;
+ min_tlow = 44;
+ min_thi = 20;
+ raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */
+ } else {
+ mode = I2C_PCA_MODE_STD;
+ min_tlow = 157;
+ min_thi = 134;
+ raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */
+ }
+
+ /* The minimum clock that respects the thi/tlow = 134/157 is
+ * 64800 Hz. Below that, we have to fix the tlow to 255 and
+ * calculate the thi factor.
+ */
+ if (clock < 648) {
+ tlow = 255;
+ thi = 1000000 - clock * raise_fall_time;
+ thi /= (I2C_PCA_OSC_PER * clock) - tlow;
+ } else {
+ tlow = (1000000 - clock * raise_fall_time) * min_tlow;
+ tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow);
+ thi = tlow * min_thi / min_tlow;
+ }
- pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+ pca_reset(pca_data);
+
+ printk(KERN_INFO
+ "%s: Clock frequency is %dHz\n", adap->name, clock * 100);
+
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
+ pca_outw(pca_data, I2C_PCA_IND, mode);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
+ pca_outw(pca_data, I2C_PCA_IND, tlow);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
+ pca_outw(pca_data, I2C_PCA_IND, thi);
+
+ pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
+ }
udelay(500); /* 500 us for oscilator to stabilise */
return 0;
@@ -384,7 +548,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
"Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
+MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
MODULE_LICENSE("GPL");
module_param(i2c_debug, int, 0);
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index 3e01992230b8..7ce75775ec73 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -1,31 +1,30 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 1995-1997 Simon G. Vogl
- 1998-2000 Hans Berglund
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
- Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
- <mbailey@littlefeet-inc.com> */
-
-/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
- messages, proper stop/repstart signaling during receive,
- added detect code */
+/*
+ * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
+ *
+ * Copyright (C) 1995-1997 Simon G. Vogl
+ * 1998-2000 Hans Berglund
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
+ * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
+ * <mbailey@littlefeet-inc.com>
+ *
+ * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
+ * messages, proper stop/repstart signaling during receive, added detect code
+ */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -38,17 +37,18 @@
#include "i2c-algo-pcf.h"
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEBPROTO(x) if (i2c_debug>=9) x;
- /* debug the protocol by showing transferred bits */
+#define DEB2(x) if (i2c_debug >= 2) x
+#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
+#define DEBPROTO(x) if (i2c_debug >= 9) x;
+ /* debug the protocol by showing transferred bits */
#define DEF_TIMEOUT 16
-/* module parameters:
+/*
+ * module parameters:
*/
static int i2c_debug;
-/* --- setting states on the bus with the right timing: --------------- */
+/* setting states on the bus with the right timing: */
#define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
#define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
@@ -57,22 +57,21 @@ static int i2c_debug;
#define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
#define i2c_inb(adap) adap->getpcf(adap->data, 0)
-/* --- other auxiliary functions -------------------------------------- */
+/* other auxiliary functions */
-static void i2c_start(struct i2c_algo_pcf_data *adap)
+static void i2c_start(struct i2c_algo_pcf_data *adap)
{
- DEBPROTO(printk("S "));
+ DEBPROTO(printk(KERN_DEBUG "S "));
set_pcf(adap, 1, I2C_PCF_START);
}
-static void i2c_repstart(struct i2c_algo_pcf_data *adap)
+static void i2c_repstart(struct i2c_algo_pcf_data *adap)
{
DEBPROTO(printk(" Sr "));
set_pcf(adap, 1, I2C_PCF_REPSTART);
}
-
-static void i2c_stop(struct i2c_algo_pcf_data *adap)
+static void i2c_stop(struct i2c_algo_pcf_data *adap)
{
DEBPROTO(printk("P\n"));
set_pcf(adap, 1, I2C_PCF_STOP);
@@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
{
DEB2(printk(KERN_INFO
"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
- *status));
-
- /* Cleanup from LAB -- reset and enable ESO.
+ *status));
+ /*
+ * Cleanup from LAB -- reset and enable ESO.
* This resets the PCF8584; since we've lost the bus, no
* further attempts should be made by callers to clean up
* (no i2c_stop() etc.)
*/
set_pcf(adap, 1, I2C_PCF_PIN);
set_pcf(adap, 1, I2C_PCF_ESO);
-
- /* We pause for a time period sufficient for any running
+ /*
+ * We pause for a time period sufficient for any running
* I2C transaction to complete -- the arbitration logic won't
* work properly until the next START is seen.
* It is assumed the bus driver or client has set a proper value.
@@ -108,48 +107,50 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
get_pcf(adap, 1)));
}
-static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
+static int wait_for_bb(struct i2c_algo_pcf_data *adap)
+{
int timeout = DEF_TIMEOUT;
int status;
status = get_pcf(adap, 1);
-#ifndef STUB_I2C
- while (timeout-- && !(status & I2C_PCF_BB)) {
+
+ while (!(status & I2C_PCF_BB) && --timeout) {
udelay(100); /* wait for 100 us */
status = get_pcf(adap, 1);
}
-#endif
- if (timeout <= 0) {
+
+ if (timeout == 0) {
printk(KERN_ERR "Timeout waiting for Bus Busy\n");
+ return -ETIMEDOUT;
}
-
- return (timeout<=0);
-}
+ return 0;
+}
-static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
+static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
+{
int timeout = DEF_TIMEOUT;
*status = get_pcf(adap, 1);
-#ifndef STUB_I2C
- while (timeout-- && (*status & I2C_PCF_PIN)) {
+
+ while ((*status & I2C_PCF_PIN) && --timeout) {
adap->waitforpin(adap->data);
*status = get_pcf(adap, 1);
}
if (*status & I2C_PCF_LAB) {
handle_lab(adap, status);
- return(-EINTR);
+ return -EINTR;
}
-#endif
- if (timeout <= 0)
- return(-1);
- else
- return(0);
+
+ if (timeout == 0)
+ return -ETIMEDOUT;
+
+ return 0;
}
-/*
+/*
* This should perform the 'PCF8584 initialization sequence' as described
* in the Philips IC12 data book (1995, Aug 29).
* There should be a 30 clock cycle wait after reset, I assume this
@@ -164,18 +165,21 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
{
unsigned char temp;
- DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
+ DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
+ get_pcf(adap, 1)));
/* S1=0x80: S0 selected, serial interface off */
set_pcf(adap, 1, I2C_PCF_PIN);
- /* check to see S1 now used as R/W ctrl -
- PCF8584 does that when ESO is zero */
+ /*
+ * check to see S1 now used as R/W ctrl -
+ * PCF8584 does that when ESO is zero
+ */
if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
return -ENXIO; /* definetly not PCF8584 */
}
- /* load own address in S0, effective address is (own << 1) */
+ /* load own address in S0, effective address is (own << 1) */
i2c_outb(adap, get_own(adap));
/* check it's really written */
if ((temp = i2c_inb(adap)) != get_own(adap)) {
@@ -183,7 +187,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* S1=0xA0, next byte in S2 */
+ /* S1=0xA0, next byte in S2 */
set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
/* check to see S2 now selected */
if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
@@ -191,7 +195,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* load clock register S2 */
+ /* load clock register S2 */
i2c_outb(adap, get_clock(adap));
/* check it's really written, the only 5 lowest bits does matter */
if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
@@ -199,7 +203,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* Enable serial interface, idle, S0 selected */
+ /* Enable serial interface, idle, S0 selected */
set_pcf(adap, 1, I2C_PCF_IDLE);
/* check to see PCF is really idled and we can access status register */
@@ -207,57 +211,47 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
return -ENXIO;
}
-
+
printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
return 0;
}
-
-/* ----- Utility functions
- */
-
static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
- int count, int last)
+ int count, int last)
{
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
int wrcount, status, timeout;
-
+
for (wrcount=0; wrcount<count; ++wrcount) {
DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
- buf[wrcount]&0xff));
+ buf[wrcount] & 0xff));
i2c_outb(adap, buf[wrcount]);
timeout = wait_for_pin(adap, &status);
if (timeout) {
- if (timeout == -EINTR) {
- /* arbitration lost */
- return -EINTR;
- }
+ if (timeout == -EINTR)
+ return -EINTR; /* arbitration lost */
+
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
return -EREMOTEIO; /* got a better one ?? */
}
-#ifndef STUB_I2C
if (status & I2C_PCF_LRB) {
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
return -EREMOTEIO; /* got a better one ?? */
}
-#endif
}
- if (last) {
+ if (last)
i2c_stop(adap);
- }
- else {
+ else
i2c_repstart(adap);
- }
- return (wrcount);
+ return wrcount;
}
-
static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
- int count, int last)
+ int count, int last)
{
int i, status;
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
@@ -267,42 +261,36 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
for (i = 0; i <= count; i++) {
if ((wfp = wait_for_pin(adap, &status))) {
- if (wfp == -EINTR) {
- /* arbitration lost */
- return -EINTR;
- }
+ if (wfp == -EINTR)
+ return -EINTR; /* arbitration lost */
+
i2c_stop(adap);
dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
- return (-1);
+ return -1;
}
-#ifndef STUB_I2C
if ((status & I2C_PCF_LRB) && (i != count)) {
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
- return (-1);
+ return -1;
}
-#endif
-
+
if (i == count - 1) {
set_pcf(adap, 1, I2C_PCF_ESO);
- } else
- if (i == count) {
- if (last) {
+ } else if (i == count) {
+ if (last)
i2c_stop(adap);
- } else {
+ else
i2c_repstart(adap);
- }
- };
+ }
- if (i) {
+ if (i)
buf[i - 1] = i2c_inb(adap);
- } else {
+ else
i2c_inb(adap); /* dummy read */
- }
}
- return (i - 1);
+ return i - 1;
}
@@ -323,14 +311,14 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
}
static int pcf_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs,
+ struct i2c_msg *msgs,
int num)
{
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
struct i2c_msg *pmsg;
int i;
int ret=0, timeout, status;
-
+
if (adap->xfer_begin)
adap->xfer_begin(adap->data);
@@ -338,25 +326,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
timeout = wait_for_bb(adap);
if (timeout) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
- "Timeout waiting for BB in pcf_xfer\n");)
+ "Timeout waiting for BB in pcf_xfer\n");)
i = -EIO;
goto out;
}
-
+
for (i = 0;ret >= 0 && i < num; i++) {
pmsg = &msgs[i];
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);)
-
+ pmsg->len, pmsg->addr, i + 1, num);)
+
ret = pcf_doAddress(adap, pmsg);
/* Send START */
- if (i == 0) {
- i2c_start(adap);
- }
-
+ if (i == 0)
+ i2c_start(adap);
+
/* Wait for PIN (pending interrupt NOT) */
timeout = wait_for_pin(adap, &status);
if (timeout) {
@@ -371,8 +358,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
i = -EREMOTEIO;
goto out;
}
-
-#ifndef STUB_I2C
+
/* Check LRB (last rcvd bit - slave ack) */
if (status & I2C_PCF_LRB) {
i2c_stop(adap);
@@ -380,27 +366,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
i = -EREMOTEIO;
goto out;
}
-#endif
-
+
DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-
- /* Read */
+
if (pmsg->flags & I2C_M_RD) {
- /* read bytes into buffer*/
ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
+ (i + 1 == num));
+
if (ret != pmsg->len) {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
"only read %d bytes.\n",ret));
} else {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
}
- } else { /* Write */
+ } else {
ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
+ (i + 1 == num));
+
if (ret != pmsg->len) {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
"only wrote %d bytes.\n",ret));
@@ -413,24 +396,23 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
out:
if (adap->xfer_end)
adap->xfer_end(adap->data);
- return (i);
+ return i;
}
static u32 pcf_func(struct i2c_adapter *adap)
{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_PROTOCOL_MANGLING;
}
-/* -----exported algorithm data: ------------------------------------- */
-
+/* exported algorithm data: */
static const struct i2c_algorithm pcf_algo = {
.master_xfer = pcf_xfer,
.functionality = pcf_func,
};
-/*
- * registering functions to load algorithms at runtime
+/*
+ * registering functions to load algorithms at runtime
*/
int i2c_pcf_add_bus(struct i2c_adapter *adap)
{
@@ -441,7 +423,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
/* register new adapter to i2c module... */
adap->algo = &pcf_algo;
- adap->timeout = 100;
if ((rval = pcf_init_8584(pcf_adap)))
return rval;
@@ -458,4 +439,4 @@ MODULE_LICENSE("GPL");
module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
+ "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 7f95905bbb9d..da809ad0996a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -132,6 +132,7 @@ config I2C_PIIX4
Serverworks CSB5
Serverworks CSB6
Serverworks HT-1000
+ Serverworks HT-1100
SMSC Victory66
This driver can also be built as a module. If so, the module
@@ -617,12 +618,12 @@ config I2C_ELEKTOR
will be called i2c-elektor.
config I2C_PCA_ISA
- tristate "PCA9564 on an ISA bus"
+ tristate "PCA9564/PCA9665 on an ISA bus"
depends on ISA
select I2C_ALGOPCA
default n
help
- This driver supports ISA boards using the Philips PCA9564
+ This driver supports ISA boards using the Philips PCA9564/PCA9665
parallel bus to I2C bus controller.
This driver can also be built as a module. If so, the module
@@ -634,11 +635,11 @@ config I2C_PCA_ISA
time). If unsure, say N.
config I2C_PCA_PLATFORM
- tristate "PCA9564 as platform device"
+ tristate "PCA9564/PCA9665 as platform device"
select I2C_ALGOPCA
default n
help
- This driver supports a memory mapped Philips PCA9564
+ This driver supports a memory mapped Philips PCA9564/PCA9665
parallel bus to I2C bus controller.
This driver can also be built as a module. If so, the module
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5d7789834b95..3fae3a91ce5b 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -216,7 +216,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
{
unsigned long timeout;
- timeout = jiffies + DAVINCI_I2C_TIMEOUT;
+ timeout = jiffies + dev->adapter.timeout;
while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
& DAVINCI_I2C_STR_BB) {
if (time_after(jiffies, timeout)) {
@@ -289,7 +289,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
- DAVINCI_I2C_TIMEOUT);
+ dev->adapter.timeout);
if (r == 0) {
dev_err(dev->dev, "controller timed out\n");
i2c_davinci_init(dev);
@@ -546,9 +546,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
adap->algo = &i2c_davinci_algo;
adap->dev.parent = &pdev->dev;
-
- /* FIXME */
- adap->timeout = 1;
+ adap->timeout = DAVINCI_I2C_TIMEOUT;
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 88f0db73b364..8b92a4666e02 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -415,7 +415,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
if (dev->irq >= 0){
/* Interrupt mode */
ret = wait_event_interruptible_timeout(dev->wq,
- !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);
+ !(in_8(&iic->sts) & STS_PT), dev->adap.timeout);
if (unlikely(ret < 0))
DBG("%d: wait interrupted\n", dev->idx);
@@ -426,7 +426,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
}
else {
/* Polling mode */
- unsigned long x = jiffies + dev->adap.timeout * HZ;
+ unsigned long x = jiffies + dev->adap.timeout;
while (in_8(&iic->sts) & STS_PT){
if (unlikely(time_after(jiffies, x))){
@@ -748,7 +748,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
i2c_set_adapdata(adap, dev);
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &iic_algo;
- adap->timeout = 1;
+ adap->timeout = HZ;
ret = i2c_add_adapter(adap);
if (ret < 0) {
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 3190690c26ce..a75c75e77b92 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -488,7 +488,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
/*
* Default values...should these come in from board code?
*/
- new_adapter->timeout = 100;
+ new_adapter->timeout = HZ;
new_adapter->algo = &iop3xx_i2c_algo;
init_waitqueue_head(&adapter_data->waitq);
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index aedbbe6618db..2b847d875946 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -116,7 +116,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
} else {
/* Interrupt mode */
result = wait_event_interruptible_timeout(i2c->queue,
- (i2c->interrupt & CSR_MIF), timeout * HZ);
+ (i2c->interrupt & CSR_MIF), timeout);
if (unlikely(result < 0)) {
pr_debug("I2C: wait interrupted\n");
@@ -311,7 +311,7 @@ static struct i2c_adapter mpc_ops = {
.owner = THIS_MODULE,
.name = "MPC adapter",
.algo = &mpc_algo,
- .timeout = 1,
+ .timeout = HZ,
};
static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 7f186bbcb99d..5a4945d1dba4 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -358,7 +358,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
char abort = 0;
time_left = wait_event_interruptible_timeout(drv_data->waitq,
- !drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout));
+ !drv_data->block, drv_data->adapter.timeout);
spin_lock_irqsave(&drv_data->lock, flags);
if (!time_left) { /* Timed out */
@@ -374,8 +374,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
spin_unlock_irqrestore(&drv_data->lock, flags);
time_left = wait_event_timeout(drv_data->waitq,
- !drv_data->block,
- msecs_to_jiffies(drv_data->adapter.timeout));
+ !drv_data->block, drv_data->adapter.timeout);
if ((time_left <= 0) && drv_data->block) {
drv_data->state = MV64XXX_I2C_STATE_IDLE;
@@ -530,7 +529,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
drv_data->adapter.algo = &mv64xxx_i2c_algo;
drv_data->adapter.owner = THIS_MODULE;
drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- drv_data->adapter.timeout = pdata->timeout;
+ drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
drv_data->adapter.nr = pd->id;
platform_set_drvdata(pd, drv_data);
i2c_set_adapdata(&drv_data->adapter, drv_data);
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 05af6cd7f270..2ff4683703a8 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -31,10 +31,14 @@
nForce3 250Gb MCP 00E4
nForce4 MCP 0052
nForce4 MCP-04 0034
- nForce4 MCP51 0264
- nForce4 MCP55 0368
+ nForce MCP51 0264
+ nForce MCP55 0368
nForce MCP61 03EB
nForce MCP65 0446
+ nForce MCP67 0542
+ nForce MCP73 07D8
+ nForce MCP78S 0752
+ nForce MCP79 0AA2
This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4/5xx chipsets.
@@ -315,6 +319,10 @@ static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) },
{ 0 }
};
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index 4aa8138cb0a9..0ed68e2ccd22 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
@@ -41,15 +42,17 @@ static int irq = -1;
/* Data sheet recommends 59kHz for 100kHz operation due to variation
* in the actual clock rate */
-static int clock = I2C_PCA_CON_59kHz;
+static int clock = 59000;
+static struct i2c_adapter pca_isa_ops;
static wait_queue_head_t pca_wait;
static void pca_isa_writebyte(void *pd, int reg, int val)
{
#ifdef DEBUG_IO
static char *names[] = { "T/O", "DAT", "ADR", "CON" };
- printk("*** write %s at %#lx <= %#04x\n", names[reg], base+reg, val);
+ printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg],
+ base+reg, val);
#endif
outb(val, base+reg);
}
@@ -60,7 +63,7 @@ static int pca_isa_readbyte(void *pd, int reg)
#ifdef DEBUG_IO
{
static char *names[] = { "STA", "DAT", "ADR", "CON" };
- printk("*** read %s => %#04x\n", names[reg], res);
+ printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res);
}
#endif
return res;
@@ -68,16 +71,22 @@ static int pca_isa_readbyte(void *pd, int reg)
static int pca_isa_waitforcompletion(void *pd)
{
- int ret = 0;
+ long ret = ~0;
+ unsigned long timeout;
if (irq > -1) {
- ret = wait_event_interruptible(pca_wait,
- pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI);
+ ret = wait_event_interruptible_timeout(pca_wait,
+ pca_isa_readbyte(pd, I2C_PCA_CON)
+ & I2C_PCA_CON_SI, pca_isa_ops.timeout);
} else {
- while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+ /* Do polling */
+ timeout = jiffies + pca_isa_ops.timeout;
+ while (((pca_isa_readbyte(pd, I2C_PCA_CON)
+ & I2C_PCA_CON_SI) == 0)
+ && (ret = time_before(jiffies, timeout)))
udelay(100);
}
- return ret;
+ return ret > 0;
}
static void pca_isa_resetchip(void *pd)
@@ -102,8 +111,8 @@ static struct i2c_algo_pca_data pca_isa_data = {
static struct i2c_adapter pca_isa_ops = {
.owner = THIS_MODULE,
.algo_data = &pca_isa_data,
- .name = "PCA9564 ISA Adapter",
- .timeout = 100,
+ .name = "PCA9564/PCA9665 ISA Adapter",
+ .timeout = HZ,
};
static int __devinit pca_isa_match(struct device *dev, unsigned int id)
@@ -195,7 +204,7 @@ static void __exit pca_isa_exit(void)
}
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
-MODULE_DESCRIPTION("ISA base PCA9564 driver");
+MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver");
MODULE_LICENSE("GPL");
module_param(base, ulong, 0);
@@ -204,7 +213,13 @@ MODULE_PARM_DESC(base, "I/O base address");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "IRQ");
module_param(clock, int, 0);
-MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet");
+MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t"
+ "For PCA9564: 330000,288000,217000,146000,"
+ "88000,59000,44000,36000\n"
+ "\t\tFor PCA9665:\tStandard: 60300 - 100099\n"
+ "\t\t\t\tFast: 100100 - 400099\n"
+ "\t\t\t\tFast+: 400100 - 10000099\n"
+ "\t\t\t\tTurbo: Up to 1265800");
module_init(pca_isa_init);
module_exit(pca_isa_exit);
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index 6bb15ad0a6b6..7b23891b7d59 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@@ -81,24 +82,23 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
static int i2c_pca_pf_waitforcompletion(void *pd)
{
struct i2c_pca_pf_data *i2c = pd;
- int ret = 0;
+ long ret = ~0;
+ unsigned long timeout;
if (i2c->irq) {
- ret = wait_event_interruptible(i2c->wait,
+ ret = wait_event_interruptible_timeout(i2c->wait,
i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
- & I2C_PCA_CON_SI);
+ & I2C_PCA_CON_SI, i2c->adap.timeout);
} else {
- /*
- * Do polling...
- * XXX: Could get stuck in extreme cases!
- * Maybe add timeout, but using irqs is preferred anyhow.
- */
- while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+ /* Do polling */
+ timeout = jiffies + i2c->adap.timeout;
+ while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
& I2C_PCA_CON_SI) == 0)
+ && (ret = time_before(jiffies, timeout)))
udelay(100);
}
- return ret;
+ return ret > 0;
}
static void i2c_pca_pf_dummyreset(void *pd)
@@ -172,14 +172,25 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
i2c->adap.owner = THIS_MODULE;
- snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx",
- (unsigned long) res->start);
+ snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+ "PCA9564/PCA9665 at 0x%08lx",
+ (unsigned long) res->start);
i2c->adap.algo_data = &i2c->algo_data;
i2c->adap.dev.parent = &pdev->dev;
- i2c->adap.timeout = platform_data->timeout;
- i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+ if (platform_data) {
+ i2c->adap.timeout = platform_data->timeout;
+ i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+ i2c->gpio = platform_data->gpio;
+ } else {
+ i2c->adap.timeout = HZ;
+ i2c->algo_data.i2c_clock = 59000;
+ i2c->gpio = -1;
+ }
+
i2c->algo_data.data = i2c;
+ i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
+ i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
case IORESOURCE_MEM_32BIT:
@@ -197,11 +208,6 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
break;
}
- i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
-
- i2c->gpio = platform_data->gpio;
- i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
-
/* Use gpio_is_valid() when in mainline */
if (i2c->gpio > -1) {
ret = gpio_request(i2c->gpio, i2c->adap.name);
@@ -246,7 +252,7 @@ e_remap:
e_alloc:
release_mem_region(res->start, res_len(res));
e_print:
- printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
+ printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
return ret;
}
@@ -290,7 +296,7 @@ static void __exit i2c_pca_pf_exit(void)
}
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
+MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
MODULE_LICENSE("GPL");
module_init(i2c_pca_pf_init);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 761f9dd53620..0249a7d762b9 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -20,7 +20,7 @@
/*
Supports:
Intel PIIX4, 440MX
- Serverworks OSB4, CSB5, CSB6, HT-1000
+ Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
SMSC Victory66
@@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
return 0;
}
+static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
+ const struct pci_device_id *id)
+{
+ unsigned short smba_idx = 0xcd6;
+ u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
+
+ /* SB800 SMBus does not support forcing address */
+ if (force || force_addr) {
+ dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support "
+ "forcing address!\n");
+ return -EINVAL;
+ }
+
+ /* Determine the address of the SMBus areas */
+ if (!request_region(smba_idx, 2, "smba_idx")) {
+ dev_err(&PIIX4_dev->dev, "SMBus base address index region "
+ "0x%x already in use!\n", smba_idx);
+ return -EBUSY;
+ }
+ outb_p(smb_en, smba_idx);
+ smba_en_lo = inb_p(smba_idx + 1);
+ outb_p(smb_en + 1, smba_idx);
+ smba_en_hi = inb_p(smba_idx + 1);
+ release_region(smba_idx, 2);
+
+ if ((smba_en_lo & 1) == 0) {
+ dev_err(&PIIX4_dev->dev,
+ "Host SMBus controller not enabled!\n");
+ return -ENODEV;
+ }
+
+ piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
+ if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
+ return -EBUSY;
+
+ if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
+ dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
+ piix4_smba);
+ return -EBUSY;
+ }
+
+ /* Request the SMBus I2C bus config region */
+ if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
+ dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
+ "0x%x already in use!\n", piix4_smba + i2ccfg_offset);
+ release_region(piix4_smba, SMBIOSIZE);
+ piix4_smba = 0;
+ return -EBUSY;
+ }
+ i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
+ release_region(piix4_smba + i2ccfg_offset, 1);
+
+ if (i2ccfg & 1)
+ dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n");
+ else
+ dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n");
+
+ dev_info(&PIIX4_dev->dev,
+ "SMBus Host Controller at 0x%x, revision %d\n",
+ piix4_smba, i2ccfg >> 4);
+
+ return 0;
+}
+
static int piix4_transaction(void)
{
int temp;
@@ -423,6 +487,8 @@ static struct pci_device_id piix4_ids[] = {
PCI_DEVICE_ID_SERVERWORKS_CSB6) },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
+ PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
{ 0, }
};
@@ -433,7 +499,14 @@ static int __devinit piix4_probe(struct pci_dev *dev,
{
int retval;
- retval = piix4_setup(dev, id);
+ if ((dev->vendor == PCI_VENDOR_ID_ATI) &&
+ (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) &&
+ (dev->revision >= 0x40))
+ /* base address location etc changed in SB800 */
+ retval = piix4_setup_sb800(dev, id);
+ else
+ retval = piix4_setup(dev, id);
+
if (retval)
return retval;
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 60ca91745e55..3c9d71f60187 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -191,7 +191,8 @@ static int __devexit i2c_powermac_remove(struct platform_device *dev)
i2c_set_adapdata(adapter, NULL);
/* We aren't that prepared to deal with this... */
if (rc)
- printk("i2c-powermac.c: Failed to remove bus %s !\n",
+ printk(KERN_WARNING
+ "i2c-powermac.c: Failed to remove bus %s !\n",
adapter->name);
platform_set_drvdata(dev, NULL);
kfree(adapter);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index bdb1f7510e91..c1405c8f6ba5 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -210,11 +210,12 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
{
unsigned int i;
- printk("i2c: error: %s\n", why);
- printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
+ printk(KERN_ERR "i2c: error: %s\n", why);
+ printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
- printk("i2c: ICR: %08x ISR: %08x\n"
- "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
+ printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n",
+ readl(_ICR(i2c)), readl(_ISR(i2c)));
+ printk(KERN_DEBUG "i2c: log: ");
for (i = 0; i < i2c->irqlogidx; i++)
printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
printk("\n");
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index fbb9030b68a5..b6f3a0de6ca2 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -152,7 +152,7 @@ static void i2c_device_shutdown(struct device *dev)
driver->shutdown(to_i2c_client(dev));
}
-static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
+static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
{
struct i2c_driver *driver;
@@ -164,7 +164,7 @@ static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
return driver->suspend(to_i2c_client(dev), mesg);
}
-static int i2c_device_resume(struct device * dev)
+static int i2c_device_resume(struct device *dev)
{
struct i2c_driver *driver;
@@ -187,13 +187,15 @@ static void i2c_client_dev_release(struct device *dev)
kfree(to_i2c_client(dev));
}
-static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t
+show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return sprintf(buf, "%s\n", client->name);
}
-static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t
+show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
@@ -365,8 +367,7 @@ static struct i2c_driver dummy_driver = {
* This returns the new i2c client, which should be saved for later use with
* i2c_unregister_device(); or NULL to indicate an error.
*/
-struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
+struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
{
struct i2c_board_info info = {
I2C_BOARD_INFO("dummy", address),
@@ -413,8 +414,8 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
if (devinfo->busnum == adapter->nr
&& !i2c_new_device(adapter,
&devinfo->board_info))
- printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",
- i2c_adapter_id(adapter),
+ dev_err(&adapter->dev,
+ "Can't create device at 0x%02x\n",
devinfo->board_info.addr);
}
mutex_unlock(&__i2c_board_lock);
@@ -459,6 +460,11 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
pr_debug("I2C adapter driver [%s] forgot to specify "
"physical device\n", adap->name);
}
+
+ /* Set default timeout to 1 second if not already set */
+ if (adap->timeout == 0)
+ adap->timeout = HZ;
+
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
adap->dev.release = &i2c_adapter_dev_release;
adap->dev.class = &i2c_adapter_class;
@@ -581,7 +587,8 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data)
struct i2c_client *client, *_n;
int res;
- /* Remove the devices we created ourselves */
+ /* Remove the devices we created ourselves as the result of hardware
+ * probing (using a driver's detect method) */
list_for_each_entry_safe(client, _n, &driver->clients, detected) {
if (client->adapter == adapter) {
dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
@@ -749,6 +756,8 @@ static int __detach_adapter(struct device *dev, void *data)
struct i2c_driver *driver = data;
struct i2c_client *client, *_n;
+ /* Remove the devices we created ourselves as the result of hardware
+ * probing (using a driver's detect method) */
list_for_each_entry_safe(client, _n, &driver->clients, detected) {
dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
client->name, client->addr);
@@ -1012,7 +1021,7 @@ module_exit(i2c_exit);
* Note that there is no requirement that each message be sent to
* the same slave address, although that is the most common model.
*/
-int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
int ret;
@@ -1519,8 +1528,7 @@ EXPORT_SYMBOL(i2c_put_adapter);
/* The SMBus parts */
#define POLY (0x1070U << 3)
-static u8
-crc8(u16 data)
+static u8 crc8(u16 data)
{
int i;
@@ -1984,9 +1992,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
* This executes an SMBus protocol operation, and returns a negative
* errno code else zero on success.
*/
-s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
+s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
char read_write, u8 command, int protocol,
- union i2c_smbus_data * data)
+ union i2c_smbus_data *data)
{
s32 res;
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index c76df8cda5ef..89fec052f3b4 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -2,7 +2,7 @@ menu "EEPROM support"
config EEPROM_AT24
tristate "I2C EEPROMs from most vendors"
- depends on I2C && SYSFS && EXPERIMENTAL
+ depends on I2C && SYSFS
help
Enable this driver to get read/write support to most I2C EEPROMs,
after you configure the driver to know about each EEPROM on
diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h
index adcb3dc7ac26..1364d62e2fbe 100644
--- a/include/linux/i2c-algo-pca.h
+++ b/include/linux/i2c-algo-pca.h
@@ -1,7 +1,14 @@
#ifndef _LINUX_I2C_ALGO_PCA_H
#define _LINUX_I2C_ALGO_PCA_H
-/* Clock speeds for the bus */
+/* Chips known to the pca algo */
+#define I2C_PCA_CHIP_9564 0x00
+#define I2C_PCA_CHIP_9665 0x01
+
+/* Internal period for PCA9665 oscilator */
+#define I2C_PCA_OSC_PER 3 /* e10-8s */
+
+/* Clock speeds for the bus for PCA9564*/
#define I2C_PCA_CON_330kHz 0x00
#define I2C_PCA_CON_288kHz 0x01
#define I2C_PCA_CON_217kHz 0x02
@@ -18,6 +25,26 @@
#define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */
#define I2C_PCA_CON 0x03 /* CONTROL Read/Write */
+/* PCA9665 registers */
+#define I2C_PCA_INDPTR 0x00 /* INDIRECT Pointer Write Only */
+#define I2C_PCA_IND 0x02 /* INDIRECT Read/Write */
+
+/* PCA9665 indirect registers */
+#define I2C_PCA_ICOUNT 0x00 /* Byte Count for buffered mode */
+#define I2C_PCA_IADR 0x01 /* OWN ADR */
+#define I2C_PCA_ISCLL 0x02 /* SCL LOW period */
+#define I2C_PCA_ISCLH 0x03 /* SCL HIGH period */
+#define I2C_PCA_ITO 0x04 /* TIMEOUT */
+#define I2C_PCA_IPRESET 0x05 /* Parallel bus reset */
+#define I2C_PCA_IMODE 0x06 /* I2C Bus mode */
+
+/* PCA9665 I2C bus mode */
+#define I2C_PCA_MODE_STD 0x00 /* Standard mode */
+#define I2C_PCA_MODE_FAST 0x01 /* Fast mode */
+#define I2C_PCA_MODE_FASTP 0x02 /* Fast Plus mode */
+#define I2C_PCA_MODE_TURBO 0x03 /* Turbo mode */
+
+
#define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */
#define I2C_PCA_CON_ENSIO 0x40 /* Enable */
#define I2C_PCA_CON_STA 0x20 /* Start */
@@ -31,7 +58,9 @@ struct i2c_algo_pca_data {
int (*read_byte) (void *data, int reg);
int (*wait_for_completion) (void *data);
void (*reset_chip) (void *data);
- /* i2c_clock values are defined in linux/i2c-algo-pca.h */
+ /* For PCA9564, use one of the predefined frequencies:
+ * 330000, 288000, 217000, 146000, 88000, 59000, 44000, 36000
+ * For PCA9665, use the frequency you want here. */
unsigned int i2c_clock;
};
diff --git a/include/linux/i2c-pca-platform.h b/include/linux/i2c-pca-platform.h
index 3d191873f2d1..aba33759dec4 100644
--- a/include/linux/i2c-pca-platform.h
+++ b/include/linux/i2c-pca-platform.h
@@ -6,7 +6,7 @@ struct i2c_pca9564_pf_platform_data {
* not supplied (negative value), but it
* cannot exit some error conditions then */
int i2c_clock_speed; /* values are defined in linux/i2c-algo-pca.h */
- int timeout; /* timeout = this value * 10us */
+ int timeout; /* timeout in jiffies */
};
#endif /* I2C_PCA9564_PLATFORM_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 05dfa7c4fb64..2c9e8080da5e 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1237,6 +1237,7 @@
#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451
#define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452
#define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS 0x0542
#define PCI_DEVICE_ID_NVIDIA_NVENET_24 0x054C
#define PCI_DEVICE_ID_NVIDIA_NVENET_25 0x054D
#define PCI_DEVICE_ID_NVIDIA_NVENET_26 0x054E
@@ -1247,11 +1248,14 @@
#define PCI_DEVICE_ID_NVIDIA_NVENET_31 0x07DF
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759
#define PCI_DEVICE_ID_NVIDIA_NVENET_32 0x0760
#define PCI_DEVICE_ID_NVIDIA_NVENET_33 0x0761
#define PCI_DEVICE_ID_NVIDIA_NVENET_34 0x0762
#define PCI_DEVICE_ID_NVIDIA_NVENET_35 0x0763
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2
#define PCI_DEVICE_ID_NVIDIA_NVENET_36 0x0AB0
#define PCI_DEVICE_ID_NVIDIA_NVENET_37 0x0AB1
#define PCI_DEVICE_ID_NVIDIA_NVENET_38 0x0AB2
@@ -1475,6 +1479,7 @@
#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
+#define PCI_DEVICE_ID_SERVERWORKS_HT1100LD 0x0408
#define PCI_VENDOR_ID_SBE 0x1176
#define PCI_DEVICE_ID_SBE_WANXL100 0x0301