浏览代码

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: Fix platform driver hotplug/coldplug
  i2c: New driver for the SuperH Mobile I2C bus controller
  i2c/scx200_acb: Don't use 0 as NULL pointer
  i2c-bfin-twi: Fix mismatch in add timer and delete timer
  i2c-bfin-twi: Just let i2c-bfin-twi driver depends on BLACKFIN
  i2c-bfin-twi: Use simpler comment headers and strip out information that is maintained in the scm's log
  i2c-bfin-twi: Cleanup driver descriptions, versions and some module useful information
  i2c-bfin-twi: Add missing pin mux operation
  i2c-bfin-twi: Add platform_resource interface to support multi-port TWI controllers
  i2c-bfin-twi: Add repeat start feature to avoid break of a bundle of i2c master xfer operation
  i2c: Remove trailing whitespaces in busses/Kconfig
  i2c: Replace remaining __FUNCTION__ occurrences
  i2c: Renesas SH7760 I2C master driver
  i2c-dev: Split i2cdev_ioctl
  i2c-ibm_iic: Support building as an of_platform driver
  i2c-ibm_iic: Change the log levels
  i2c: Add platform driver on top of the new pca-algorithm
  i2c-algo-pca: Extend for future drivers
  i2c-algo-pca: Remove trailing whitespaces and unnecessary UTF
  i2c: Remove the algorithm drivers from the config menu
Linus Torvalds 17 年之前
父节点
当前提交
b24a31442e

+ 5 - 34
drivers/i2c/algos/Kconfig

@@ -1,45 +1,16 @@
 #
 #
-# Character device configuration
+# I2C algorithm drivers configuration
 #
 #
 
 
-menu "I2C Algorithms"
-
 config I2C_ALGOBIT
 config I2C_ALGOBIT
-	tristate "I2C bit-banging interfaces"
-	help
-	  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
-	  and then say Y to the specific driver for you adapter below.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-algo-bit.
+	tristate
 
 
 config I2C_ALGOPCF
 config I2C_ALGOPCF
-	tristate "I2C PCF 8584 interfaces"
-	help
-	  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
-	  Y to the specific driver for you adapter below.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-algo-pcf.
+	tristate
 
 
 config I2C_ALGOPCA
 config I2C_ALGOPCA
-	tristate "I2C PCA 9564 interfaces"
-	help
-	  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
-	  Y to the specific driver for you adapter below.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-algo-pca.
+	tristate
 
 
 config I2C_ALGO_SGI
 config I2C_ALGO_SGI
-	tristate "I2C SGI interfaces"
+	tristate
 	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
 	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-	help
-	  Supports the SGI interfaces like the ones found on SGI Indy VINO
-	  or SGI O2 MACE.
-
-endmenu
-

+ 63 - 63
drivers/i2c/algos/i2c-algo-pca.c

@@ -1,6 +1,7 @@
 /*
 /*
- *  i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters                
+ *  i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters
  *    Copyright (C) 2004 Arcom Control Systems
  *    Copyright (C) 2004 Arcom Control Systems
+ *    Copyright (C) 2008 Pengutronix
  *
  *
  *  This program is free software; you can redistribute it and/or modify
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -21,14 +22,10 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-pca.h>
 #include <linux/i2c-algo-pca.h>
-#include "i2c-algo-pca.h"
-
-#define DRIVER "i2c-algo-pca"
 
 
 #define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
 #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 DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
@@ -36,15 +33,15 @@
 
 
 static int i2c_debug;
 static int i2c_debug;
 
 
-#define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val)
-#define pca_inw(adap, reg) adap->read_byte(adap, reg)
+#define pca_outw(adap, reg, val) adap->write_byte(adap->data, reg, val)
+#define pca_inw(adap, reg) adap->read_byte(adap->data, reg)
 
 
 #define pca_status(adap) pca_inw(adap, I2C_PCA_STA)
 #define pca_status(adap) pca_inw(adap, I2C_PCA_STA)
-#define pca_clock(adap) adap->get_clock(adap)
-#define pca_own(adap) adap->get_own(adap)
+#define pca_clock(adap) adap->i2c_clock
 #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
 #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
 #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
 #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
-#define pca_wait(adap) adap->wait_for_interrupt(adap)
+#define pca_wait(adap) adap->wait_for_completion(adap->data)
+#define pca_reset(adap) adap->reset_chip(adap->data)
 
 
 /*
 /*
  * Generate a start condition on the i2c bus.
  * Generate a start condition on the i2c bus.
@@ -99,7 +96,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap)
  *
  *
  * returns after the address has been sent
  * returns after the address has been sent
  */
  */
-static void pca_address(struct i2c_algo_pca_data *adap, 
+static void pca_address(struct i2c_algo_pca_data *adap,
 			struct i2c_msg *msg)
 			struct i2c_msg *msg)
 {
 {
 	int sta = pca_get_con(adap);
 	int sta = pca_get_con(adap);
@@ -108,9 +105,9 @@ static void pca_address(struct i2c_algo_pca_data *adap,
 	addr = ( (0x7f & msg->addr) << 1 );
 	addr = ( (0x7f & msg->addr) << 1 );
 	if (msg->flags & I2C_M_RD )
 	if (msg->flags & I2C_M_RD )
 		addr |= 1;
 		addr |= 1;
-	DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", 
+	DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
 	     msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
 	     msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
-	
+
 	pca_outw(adap, I2C_PCA_DAT, addr);
 	pca_outw(adap, I2C_PCA_DAT, addr);
 
 
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
@@ -124,7 +121,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
  *
  *
  * Returns after the byte has been transmitted
  * Returns after the byte has been transmitted
  */
  */
-static void pca_tx_byte(struct i2c_algo_pca_data *adap, 
+static void pca_tx_byte(struct i2c_algo_pca_data *adap,
 			__u8 b)
 			__u8 b)
 {
 {
 	int sta = pca_get_con(adap);
 	int sta = pca_get_con(adap);
@@ -142,19 +139,19 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap,
  *
  *
  * returns immediately.
  * returns immediately.
  */
  */
-static void pca_rx_byte(struct i2c_algo_pca_data *adap, 
+static void pca_rx_byte(struct i2c_algo_pca_data *adap,
 			__u8 *b, int ack)
 			__u8 *b, int ack)
 {
 {
 	*b = pca_inw(adap, I2C_PCA_DAT);
 	*b = pca_inw(adap, I2C_PCA_DAT);
 	DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
 	DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
 }
 }
 
 
-/* 
+/*
  * Setup ACK or NACK for next received byte and wait for it to arrive.
  * Setup ACK or NACK for next received byte and wait for it to arrive.
  *
  *
  * Returns after next byte has arrived.
  * Returns after next byte has arrived.
  */
  */
-static void pca_rx_ack(struct i2c_algo_pca_data *adap, 
+static void pca_rx_ack(struct i2c_algo_pca_data *adap,
 		       int ack)
 		       int ack)
 {
 {
 	int sta = pca_get_con(adap);
 	int sta = pca_get_con(adap);
@@ -168,15 +165,6 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap,
 	pca_wait(adap);
 	pca_wait(adap);
 }
 }
 
 
-/* 
- * Reset the i2c bus / SIO 
- */
-static void pca_reset(struct i2c_algo_pca_data *adap)
-{
-	/* apparently only an external reset will do it. not a lot can be done */
-	printk(KERN_ERR DRIVER ": Haven't figured out how to do a reset yet\n");
-}
-
 static int pca_xfer(struct i2c_adapter *i2c_adap,
 static int pca_xfer(struct i2c_adapter *i2c_adap,
                     struct i2c_msg *msgs,
                     struct i2c_msg *msgs,
                     int num)
                     int num)
@@ -187,7 +175,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 	int numbytes = 0;
 	int numbytes = 0;
 	int state;
 	int state;
 	int ret;
 	int ret;
-	int timeout = 100;
+	int timeout = i2c_adap->timeout;
 
 
 	while ((state = pca_status(adap)) != 0xf8 && timeout--) {
 	while ((state = pca_status(adap)) != 0xf8 && timeout--) {
 		msleep(10);
 		msleep(10);
@@ -203,14 +191,14 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 		for (curmsg = 0; curmsg < num; curmsg++) {
 		for (curmsg = 0; curmsg < num; curmsg++) {
 			int addr, i;
 			int addr, i;
 			msg = &msgs[curmsg];
 			msg = &msgs[curmsg];
-			
+
 			addr = (0x7f & msg->addr) ;
 			addr = (0x7f & msg->addr) ;
-		
+
 			if (msg->flags & I2C_M_RD )
 			if (msg->flags & I2C_M_RD )
-				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n", 
+				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
 				       curmsg, msg->len, addr, (addr<<1) | 1);
 				       curmsg, msg->len, addr, (addr<<1) | 1);
 			else {
 			else {
-				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s", 
+				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s",
 				       curmsg, msg->len, addr, addr<<1,
 				       curmsg, msg->len, addr, addr<<1,
 				       msg->len == 0 ? "" : ", ");
 				       msg->len == 0 ? "" : ", ");
 				for(i=0; i < msg->len; i++)
 				for(i=0; i < msg->len; i++)
@@ -237,7 +225,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 		case 0x10: /* A repeated start condition has been transmitted */
 		case 0x10: /* A repeated start condition has been transmitted */
 			pca_address(adap, msg);
 			pca_address(adap, msg);
 			break;
 			break;
-			
+
 		case 0x18: /* SLA+W has been transmitted; ACK has been received */
 		case 0x18: /* SLA+W has been transmitted; ACK has been received */
 		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
 		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
 			if (numbytes < msg->len) {
 			if (numbytes < msg->len) {
@@ -287,7 +275,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
 		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
 			DEB2("Arbitration lost\n");
 			DEB2("Arbitration lost\n");
 			goto out;
 			goto out;
-			
+
 		case 0x58: /* Data byte has been received; NOT ACK has been returned */
 		case 0x58: /* Data byte has been received; NOT ACK has been returned */
 			if ( numbytes == msg->len - 1 ) {
 			if ( numbytes == msg->len - 1 ) {
 				pca_rx_byte(adap, &msg->buf[numbytes], 0);
 				pca_rx_byte(adap, &msg->buf[numbytes], 0);
@@ -317,16 +305,16 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 			pca_reset(adap);
 			pca_reset(adap);
 			goto out;
 			goto out;
 		default:
 		default:
-			printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state);
+			dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state);
 			break;
 			break;
 		}
 		}
-		
+
 	}
 	}
 
 
 	ret = curmsg;
 	ret = curmsg;
  out:
  out:
 	DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
 	DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
-	     "status is %#04x. control is %#04x\n", 
+	     "status is %#04x. control is %#04x\n",
 	     curmsg, num, pca_status(adap),
 	     curmsg, num, pca_status(adap),
 	     pca_get_con(adap));
 	     pca_get_con(adap));
 	return ret;
 	return ret;
@@ -337,53 +325,65 @@ static u32 pca_func(struct i2c_adapter *adap)
         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 }
 
 
-static int pca_init(struct i2c_algo_pca_data *adap)
+static const struct i2c_algorithm pca_algo = {
+	.master_xfer	= pca_xfer,
+	.functionality	= pca_func,
+};
+
+static int pca_init(struct i2c_adapter *adap)
 {
 {
 	static int freqs[] = {330,288,217,146,88,59,44,36};
 	static int freqs[] = {330,288,217,146,88,59,44,36};
-	int own, clock;
+	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;
+	}
+
+	adap->algo = &pca_algo;
 
 
-	own = pca_own(adap);
-	clock = pca_clock(adap);
-	DEB1(KERN_INFO DRIVER ": own address is %#04x\n", own);
-	DEB1(KERN_INFO DRIVER ": clock freqeuncy is %dkHz\n", freqs[clock]);
+	pca_reset(pca_data);
 
 
-	pca_outw(adap, I2C_PCA_ADR, own << 1);
+	clock = pca_clock(pca_data);
+	DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
 
 
-	pca_set_con(adap, I2C_PCA_CON_ENSIO | clock);
-	udelay(500); /* 500 µs for oscilator to stabilise */
+	pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+	udelay(500); /* 500 us for oscilator to stabilise */
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static const struct i2c_algorithm pca_algo = {
-	.master_xfer	= pca_xfer,
-	.functionality	= pca_func,
-};
-
-/* 
- * registering functions to load algorithms at runtime 
+/*
+ * registering functions to load algorithms at runtime
  */
  */
 int i2c_pca_add_bus(struct i2c_adapter *adap)
 int i2c_pca_add_bus(struct i2c_adapter *adap)
 {
 {
-	struct i2c_algo_pca_data *pca_adap = adap->algo_data;
 	int rval;
 	int rval;
 
 
-	/* register new adapter to i2c module... */
-	adap->algo = &pca_algo;
+	rval = pca_init(adap);
+	if (rval)
+		return rval;
 
 
-	adap->timeout = 100;		/* default values, should	*/
-	adap->retries = 3;		/* be replaced by defines	*/
+	return i2c_add_adapter(adap);
+}
+EXPORT_SYMBOL(i2c_pca_add_bus);
 
 
-	if ((rval = pca_init(pca_adap)))
-		return rval;
+int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
+{
+	int rval;
 
 
-	rval = i2c_add_adapter(adap);
+	rval = pca_init(adap);
+	if (rval)
+		return rval;
 
 
-	return rval;
+	return i2c_add_numbered_adapter(adap);
 }
 }
-EXPORT_SYMBOL(i2c_pca_add_bus);
+EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
 
 
-MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
+MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
+	"Wolfram Sang <w.sang@pengutronix.de>");
 MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
 MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 

+ 0 - 26
drivers/i2c/algos/i2c-algo-pca.h

@@ -1,26 +0,0 @@
-#ifndef I2C_PCA9564_H
-#define I2C_PCA9564_H 1
-
-#define I2C_PCA_STA		0x00 /* STATUS  Read Only  */
-#define I2C_PCA_TO		0x00 /* TIMEOUT Write Only */
-#define I2C_PCA_DAT		0x01 /* DATA    Read/Write */
-#define I2C_PCA_ADR		0x02 /* OWN ADR Read/Write */
-#define I2C_PCA_CON		0x03 /* CONTROL Read/Write */
-
-#define I2C_PCA_CON_AA		0x80 /* Assert Acknowledge */
-#define I2C_PCA_CON_ENSIO	0x40 /* Enable */
-#define I2C_PCA_CON_STA		0x20 /* Start */
-#define I2C_PCA_CON_STO		0x10 /* Stop */
-#define I2C_PCA_CON_SI		0x08 /* Serial Interrupt */
-#define I2C_PCA_CON_CR		0x07 /* Clock Rate (MASK) */
-
-#define I2C_PCA_CON_330kHz	0x00
-#define I2C_PCA_CON_288kHz	0x01
-#define I2C_PCA_CON_217kHz	0x02
-#define I2C_PCA_CON_146kHz	0x03
-#define I2C_PCA_CON_88kHz	0x04
-#define I2C_PCA_CON_59kHz	0x05
-#define I2C_PCA_CON_44kHz	0x06
-#define I2C_PCA_CON_36kHz	0x07
-
-#endif /* I2C_PCA9564_H */

+ 53 - 20
drivers/i2c/busses/Kconfig

@@ -100,9 +100,12 @@ config I2C_AU1550
 
 
 config I2C_BLACKFIN_TWI
 config I2C_BLACKFIN_TWI
 	tristate "Blackfin TWI I2C support"
 	tristate "Blackfin TWI I2C support"
-	depends on BF534 || BF536 || BF537
+	depends on BLACKFIN
 	help
 	help
-	  This is the TWI I2C device driver for Blackfin 534/536/537/54x.
+	  This is the TWI I2C device driver for Blackfin BF522, BF525,
+	  BF527, BF534, BF536, BF537 and BF54x. For other Blackfin processors,
+	  please don't use this driver.
+
 	  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-bfin-twi.
 	  will be called i2c-bfin-twi.
 
 
@@ -135,7 +138,7 @@ config I2C_ELEKTOR
 	  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
 	  such an adapter.
 	  such an adapter.
 
 
-	  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
 config I2C_GPIO
@@ -190,7 +193,7 @@ config I2C_I810
 	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
-	  810/815 family of mainboard I2C interfaces.  Specifically, the 
+	  810/815 family of mainboard I2C interfaces.  Specifically, the
 	  following versions of the chipset are supported:
 	  following versions of the chipset are supported:
 	    i810AA
 	    i810AA
 	    i810AB
 	    i810AB
@@ -246,10 +249,10 @@ 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
+	depends on 4xx
 	help
 	help
-	  Say Y here if you want to use IIC peripheral found on 
-	  embedded IBM PPC 4xx based systems. 
+	  Say Y here if you want to use IIC peripheral found on
+	  embedded IBM PPC 4xx based systems.
 
 
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-ibm_iic.
 	  will be called i2c-ibm_iic.
@@ -269,7 +272,7 @@ config I2C_IXP2000
 	depends on 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
 	  system and are using GPIO lines for an I2C bus.
 	  system and are using GPIO lines for an I2C bus.
 
 
 	  This support is also available as a module. If so, the module
 	  This support is also available as a module. If so, the module
@@ -354,7 +357,7 @@ config I2C_PARPORT
 	  on the parport driver.  This is meant for embedded systems. Don't say
 	  on the parport driver.  This is meant for embedded systems. Don't say
 	  Y here if you intend to say Y or M there.
 	  Y here if you intend to say Y or M there.
 
 
-	  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-parport.
 	  will be called i2c-parport.
 
 
 config I2C_PARPORT_LIGHT
 config I2C_PARPORT_LIGHT
@@ -372,12 +375,12 @@ config I2C_PARPORT_LIGHT
 	  the clean but heavy parport handling is not an option.  The
 	  the clean but heavy parport handling is not an option.  The
 	  drawback is a reduced portability and the impossibility to
 	  drawback is a reduced portability and the impossibility to
 	  daisy-chain other parallel port devices.
 	  daisy-chain other parallel port devices.
-	  
+
 	  Don't say Y here if you said Y or M to i2c-parport.  Saying M to
 	  Don't say Y here if you said Y or M to i2c-parport.  Saying M to
 	  both is possible but both modules should not be loaded at the same
 	  both is possible but both modules should not be loaded at the same
 	  time.
 	  time.
 
 
-	  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-parport-light.
 	  will be called i2c-parport-light.
 
 
 config I2C_PASEMI
 config I2C_PASEMI
@@ -401,7 +404,7 @@ config I2C_PROSAVAGE
 
 
 	  This driver is deprecated in favor of the savagefb driver.
 	  This driver is deprecated in favor of the savagefb driver.
 
 
-	  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-prosavage.
 	  will be called i2c-prosavage.
 
 
 config I2C_S3C2410
 config I2C_S3C2410
@@ -417,7 +420,7 @@ config I2C_SAVAGE4
 	depends on 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
 	  S3 Savage 4 I2C interface.
 	  S3 Savage 4 I2C interface.
 
 
 	  This driver is deprecated in favor of the savagefb driver.
 	  This driver is deprecated in favor of the savagefb driver.
@@ -452,7 +455,7 @@ config SCx200_I2C
 
 
 	  If you don't know what to do here, say N.
 	  If you don't know what to do here, say N.
 
 
-	  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
 	  This driver is deprecated and will be dropped soon. Use i2c-gpio
@@ -483,14 +486,14 @@ config SCx200_ACB
 
 
 	  If you don't know what to do here, say N.
 	  If you don't know what to do here, say N.
 
 
-	  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_acb.
 	  will be called scx200_acb.
 
 
 config I2C_SIS5595
 config I2C_SIS5595
 	tristate "SiS 5595"
 	tristate "SiS 5595"
 	depends on 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.
 
 
 	  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
@@ -500,7 +503,7 @@ config I2C_SIS630
 	tristate "SiS 630/730"
 	tristate "SiS 630/730"
 	depends on 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.
 
 
 	  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
@@ -632,9 +635,9 @@ config I2C_PCA_ISA
 	select I2C_ALGOPCA
 	select I2C_ALGOPCA
 	default n
 	default n
 	help
 	help
-	  This driver supports ISA boards using the Philips PCA 9564
-	  Parallel bus to I2C bus controller
-	  
+	  This driver supports ISA boards using the Philips PCA9564
+	  parallel bus to I2C bus controller.
+
 	  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-pca-isa.
 	  will be called i2c-pca-isa.
 
 
@@ -643,6 +646,17 @@ config I2C_PCA_ISA
 	  delays when I2C/SMBus chip drivers are loaded (e.g. at boot
 	  delays when I2C/SMBus chip drivers are loaded (e.g. at boot
 	  time).  If unsure, say N.
 	  time).  If unsure, say N.
 
 
+config I2C_PCA_PLATFORM
+	tristate "PCA9564 as platform device"
+	select I2C_ALGOPCA
+	default n
+	help
+	  This driver supports a memory mapped Philips PCA9564
+	  parallel bus to I2C bus controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-pca-platform.
+
 config I2C_MV64XXX
 config I2C_MV64XXX
 	tristate "Marvell mv64xxx I2C Controller"
 	tristate "Marvell mv64xxx I2C Controller"
 	depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
 	depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
@@ -672,4 +686,23 @@ config I2C_PMCMSP
 	  This driver can also be built as module. If so, the module
 	  This driver can also be built as module. If so, the module
 	  will be called i2c-pmcmsp.
 	  will be called i2c-pmcmsp.
 
 
+config I2C_SH7760
+	tristate "Renesas SH7760 I2C Controller"
+	depends on CPU_SUBTYPE_SH7760
+	help
+	  This driver supports the 2 I2C interfaces on the Renesas SH7760.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sh7760.
+
+config I2C_SH_MOBILE
+	tristate "SuperH Mobile I2C Controller"
+	depends on SUPERH
+	help
+	  If you say yes to this option, support will be included for the
+	  built-in I2C interface on the Renesas SH-Mobile processor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sh_mobile.
+
 endmenu
 endmenu

+ 3 - 0
drivers/i2c/busses/Makefile

@@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
 obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
 obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
+obj-$(CONFIG_I2C_PCA_PLATFORM)	+= i2c-pca-platform.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_PMCMSP)	+= i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PMCMSP)	+= i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
@@ -37,6 +38,8 @@ obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.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_SH7760)	+= i2c-sh7760.o
+obj-$(CONFIG_I2C_SH_MOBILE)	+= i2c-sh_mobile.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_SIMTEC)	+= i2c-simtec.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o

+ 1 - 1
drivers/i2c/busses/i2c-at91.c

@@ -298,7 +298,7 @@ static int at91_i2c_resume(struct platform_device *pdev)
 #endif
 #endif
 
 
 /* work with "modprobe at91_i2c" from hotplugging or coldplugging */
 /* work with "modprobe at91_i2c" from hotplugging or coldplugging */
-MODULE_ALIAS("at91_i2c");
+MODULE_ALIAS("platform:at91_i2c");
 
 
 static struct platform_driver at91_i2c_driver = {
 static struct platform_driver at91_i2c_driver = {
 	.probe		= at91_i2c_probe,
 	.probe		= at91_i2c_probe,

+ 1 - 0
drivers/i2c/busses/i2c-au1550.c

@@ -472,6 +472,7 @@ i2c_au1550_exit(void)
 MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
 MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
 MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
 MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:au1xpsc_smbus");
 
 
 module_init (i2c_au1550_init);
 module_init (i2c_au1550_init);
 module_exit (i2c_au1550_exit);
 module_exit (i2c_au1550_exit);

+ 295 - 180
drivers/i2c/busses/i2c-bfin-twi.c

@@ -1,25 +1,11 @@
 /*
 /*
- * drivers/i2c/busses/i2c-bfin-twi.c
+ * Blackfin On-Chip Two Wire Interface Driver
  *
  *
- * Description: Driver for Blackfin Two Wire Interface
+ * Copyright 2005-2007 Analog Devices Inc.
  *
  *
- * Author:      sonicz  <sonic.zhang@analog.com>
+ * Enter bugs at http://blackfin.uclinux.org/
  *
  *
- * 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
+ * Licensed under the GPL-2 or later.
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
@@ -34,14 +20,16 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 
 
 #include <asm/blackfin.h>
 #include <asm/blackfin.h>
+#include <asm/portmux.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
 
 
 #define POLL_TIMEOUT       (2 * HZ)
 #define POLL_TIMEOUT       (2 * HZ)
 
 
 /* SMBus mode*/
 /* SMBus mode*/
-#define TWI_I2C_MODE_STANDARD		0x01
-#define TWI_I2C_MODE_STANDARDSUB	0x02
-#define TWI_I2C_MODE_COMBINED		0x04
+#define TWI_I2C_MODE_STANDARD		1
+#define TWI_I2C_MODE_STANDARDSUB	2
+#define TWI_I2C_MODE_COMBINED		3
+#define TWI_I2C_MODE_REPEAT		4
 
 
 struct bfin_twi_iface {
 struct bfin_twi_iface {
 	int			irq;
 	int			irq;
@@ -58,39 +46,74 @@ struct bfin_twi_iface {
 	struct timer_list	timeout_timer;
 	struct timer_list	timeout_timer;
 	struct i2c_adapter	adap;
 	struct i2c_adapter	adap;
 	struct completion	complete;
 	struct completion	complete;
+	struct i2c_msg 		*pmsg;
+	int			msg_num;
+	int			cur_msg;
+	void __iomem		*regs_base;
 };
 };
 
 
-static struct bfin_twi_iface twi_iface;
+
+#define DEFINE_TWI_REG(reg, off) \
+static inline u16 read_##reg(struct bfin_twi_iface *iface) \
+	{ return bfin_read16(iface->regs_base + (off)); } \
+static inline void write_##reg(struct bfin_twi_iface *iface, u16 v) \
+	{ bfin_write16(iface->regs_base + (off), v); }
+
+DEFINE_TWI_REG(CLKDIV, 0x00)
+DEFINE_TWI_REG(CONTROL, 0x04)
+DEFINE_TWI_REG(SLAVE_CTL, 0x08)
+DEFINE_TWI_REG(SLAVE_STAT, 0x0C)
+DEFINE_TWI_REG(SLAVE_ADDR, 0x10)
+DEFINE_TWI_REG(MASTER_CTL, 0x14)
+DEFINE_TWI_REG(MASTER_STAT, 0x18)
+DEFINE_TWI_REG(MASTER_ADDR, 0x1C)
+DEFINE_TWI_REG(INT_STAT, 0x20)
+DEFINE_TWI_REG(INT_MASK, 0x24)
+DEFINE_TWI_REG(FIFO_CTL, 0x28)
+DEFINE_TWI_REG(FIFO_STAT, 0x2C)
+DEFINE_TWI_REG(XMT_DATA8, 0x80)
+DEFINE_TWI_REG(XMT_DATA16, 0x84)
+DEFINE_TWI_REG(RCV_DATA8, 0x88)
+DEFINE_TWI_REG(RCV_DATA16, 0x8C)
+
+static const u16 pin_req[2][3] = {
+	{P_TWI0_SCL, P_TWI0_SDA, 0},
+	{P_TWI1_SCL, P_TWI1_SDA, 0},
+};
 
 
 static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 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();
+	unsigned short twi_int_status = read_INT_STAT(iface);
+	unsigned short mast_stat = read_MASTER_STAT(iface);
 
 
 	if (twi_int_status & XMTSERV) {
 	if (twi_int_status & XMTSERV) {
 		/* Transmit next data */
 		/* Transmit next data */
 		if (iface->writeNum > 0) {
 		if (iface->writeNum > 0) {
-			bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+			write_XMT_DATA8(iface, *(iface->transPtr++));
 			iface->writeNum--;
 			iface->writeNum--;
 		}
 		}
 		/* start receive immediately after complete sending in
 		/* start receive immediately after complete sending in
 		 * combine mode.
 		 * 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);
+		else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | MDIR | RSTART);
+		else if (iface->manual_stop)
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | STOP);
+		else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg+1 < iface->msg_num)
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | RSTART);
 		SSYNC();
 		SSYNC();
 		/* Clear status */
 		/* Clear status */
-		bfin_write_TWI_INT_STAT(XMTSERV);
+		write_INT_STAT(iface, XMTSERV);
 		SSYNC();
 		SSYNC();
 	}
 	}
 	if (twi_int_status & RCVSERV) {
 	if (twi_int_status & RCVSERV) {
 		if (iface->readNum > 0) {
 		if (iface->readNum > 0) {
 			/* Receive next data */
 			/* Receive next data */
-			*(iface->transPtr) = bfin_read_TWI_RCV_DATA8();
+			*(iface->transPtr) = read_RCV_DATA8(iface);
 			if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 			if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 				/* Change combine mode into sub mode after
 				/* Change combine mode into sub mode after
 				 * read first data.
 				 * read first data.
@@ -105,28 +128,33 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 			iface->transPtr++;
 			iface->transPtr++;
 			iface->readNum--;
 			iface->readNum--;
 		} else if (iface->manual_stop) {
 		} else if (iface->manual_stop) {
-			bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
-				| STOP);
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | STOP);
+			SSYNC();
+		} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg+1 < iface->msg_num) {
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | RSTART);
 			SSYNC();
 			SSYNC();
 		}
 		}
 		/* Clear interrupt source */
 		/* Clear interrupt source */
-		bfin_write_TWI_INT_STAT(RCVSERV);
+		write_INT_STAT(iface, RCVSERV);
 		SSYNC();
 		SSYNC();
 	}
 	}
 	if (twi_int_status & MERR) {
 	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);
+		write_INT_STAT(iface, MERR);
+		write_INT_MASK(iface, 0);
+		write_MASTER_STAT(iface, 0x3e);
+		write_MASTER_CTL(iface, 0);
 		SSYNC();
 		SSYNC();
-		iface->result = -1;
+		iface->result = -EIO;
 		/* if both err and complete int stats are set, return proper
 		/* if both err and complete int stats are set, return proper
 		 * results.
 		 * results.
 		 */
 		 */
 		if (twi_int_status & MCOMP) {
 		if (twi_int_status & MCOMP) {
-			bfin_write_TWI_INT_STAT(MCOMP);
-			bfin_write_TWI_INT_MASK(0);
-			bfin_write_TWI_MASTER_CTL(0);
+			write_INT_STAT(iface, MCOMP);
+			write_INT_MASK(iface, 0);
+			write_MASTER_CTL(iface, 0);
 			SSYNC();
 			SSYNC();
 			/* If it is a quick transfer, only address bug no data,
 			/* If it is a quick transfer, only address bug no data,
 			 * not an err, return 1.
 			 * not an err, return 1.
@@ -143,7 +171,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 		return;
 		return;
 	}
 	}
 	if (twi_int_status & MCOMP) {
 	if (twi_int_status & MCOMP) {
-		bfin_write_TWI_INT_STAT(MCOMP);
+		write_INT_STAT(iface, MCOMP);
 		SSYNC();
 		SSYNC();
 		if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 		if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 			if (iface->readNum == 0) {
 			if (iface->readNum == 0) {
@@ -152,28 +180,63 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 				 */
 				 */
 				iface->readNum = 1;
 				iface->readNum = 1;
 				iface->manual_stop = 1;
 				iface->manual_stop = 1;
-				bfin_write_TWI_MASTER_CTL(
-					bfin_read_TWI_MASTER_CTL()
-					| (0xff << 6));
+				write_MASTER_CTL(iface,
+					read_MASTER_CTL(iface) | (0xff << 6));
 			} else {
 			} else {
 				/* set the readd number in other
 				/* set the readd number in other
 				 * combine mode.
 				 * combine mode.
 				 */
 				 */
-				bfin_write_TWI_MASTER_CTL(
-					(bfin_read_TWI_MASTER_CTL() &
+				write_MASTER_CTL(iface,
+					(read_MASTER_CTL(iface) &
 					(~(0xff << 6))) |
 					(~(0xff << 6))) |
-					( iface->readNum << 6));
+					(iface->readNum << 6));
+			}
+			/* remove restart bit and enable master receive */
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) & ~RSTART);
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | MEN | MDIR);
+			SSYNC();
+		} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg+1 < iface->msg_num) {
+			iface->cur_msg++;
+			iface->transPtr = iface->pmsg[iface->cur_msg].buf;
+			iface->writeNum = iface->readNum =
+				iface->pmsg[iface->cur_msg].len;
+			/* Set Transmit device address */
+			write_MASTER_ADDR(iface,
+				iface->pmsg[iface->cur_msg].addr);
+			if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD)
+				iface->read_write = I2C_SMBUS_READ;
+			else {
+				iface->read_write = I2C_SMBUS_WRITE;
+				/* Transmit first data */
+				if (iface->writeNum > 0) {
+					write_XMT_DATA8(iface,
+						*(iface->transPtr++));
+					iface->writeNum--;
+					SSYNC();
+				}
+			}
+
+			if (iface->pmsg[iface->cur_msg].len <= 255)
+				write_MASTER_CTL(iface,
+				iface->pmsg[iface->cur_msg].len << 6);
+			else {
+				write_MASTER_CTL(iface, 0xff << 6);
+				iface->manual_stop = 1;
 			}
 			}
 			/* remove restart bit and enable master receive */
 			/* 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);
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) & ~RSTART);
+			write_MASTER_CTL(iface, read_MASTER_CTL(iface) |
+				MEN | ((iface->read_write == I2C_SMBUS_READ) ?
+				MDIR : 0));
 			SSYNC();
 			SSYNC();
 		} else {
 		} else {
 			iface->result = 1;
 			iface->result = 1;
-			bfin_write_TWI_INT_MASK(0);
-			bfin_write_TWI_MASTER_CTL(0);
+			write_INT_MASK(iface, 0);
+			write_MASTER_CTL(iface, 0);
 			SSYNC();
 			SSYNC();
 			complete(&iface->complete);
 			complete(&iface->complete);
 		}
 		}
@@ -221,91 +284,85 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
 {
 {
 	struct bfin_twi_iface *iface = adap->algo_data;
 	struct bfin_twi_iface *iface = adap->algo_data;
 	struct i2c_msg *pmsg;
 	struct i2c_msg *pmsg;
-	int i, ret;
 	int rc = 0;
 	int rc = 0;
 
 
-	if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
+	if (!(read_CONTROL(iface) & TWI_ENA))
 		return -ENXIO;
 		return -ENXIO;
 
 
-	while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
+	while (read_MASTER_STAT(iface) & BUSBUSY)
 		yield();
 		yield();
+
+	iface->pmsg = msgs;
+	iface->msg_num = num;
+	iface->cur_msg = 0;
+
+	pmsg = &msgs[0];
+	if (pmsg->flags & I2C_M_TEN) {
+		dev_err(&adap->dev, "10 bits addr not supported!\n");
+		return -EINVAL;
 	}
 	}
 
 
-	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_REPEAT;
+	iface->manual_stop = 0;
+	iface->transPtr = pmsg->buf;
+	iface->writeNum = iface->readNum = pmsg->len;
+	iface->result = 0;
+	iface->timeout_count = 10;
+	init_completion(&(iface->complete));
+	/* Set Transmit device address */
+	write_MASTER_ADDR(iface, pmsg->addr);
 
 
-		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();
+	/* FIFO Initiation. Data in FIFO should be
+	 *  discarded before start a new operation.
+	 */
+	write_FIFO_CTL(iface, 0x3);
+	SSYNC();
+	write_FIFO_CTL(iface, 0);
+	SSYNC();
 
 
-		if (pmsg->flags & I2C_M_RD)
-			iface->read_write = I2C_SMBUS_READ;
-		else {
-			iface->read_write = I2C_SMBUS_WRITE;
-			/* Transmit first data */
-			if (iface->writeNum > 0) {
-				bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
-				iface->writeNum--;
-				SSYNC();
-			}
+	if (pmsg->flags & I2C_M_RD)
+		iface->read_write = I2C_SMBUS_READ;
+	else {
+		iface->read_write = I2C_SMBUS_WRITE;
+		/* Transmit first data */
+		if (iface->writeNum > 0) {
+			write_XMT_DATA8(iface, *(iface->transPtr++));
+			iface->writeNum--;
+			SSYNC();
 		}
 		}
+	}
 
 
-		/* clear int stat */
-		bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
+	/* clear int stat */
+	write_INT_STAT(iface, 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();
+	/* Interrupt mask . Enable XMT, RCV interrupt */
+	write_INT_MASK(iface, MCOMP | MERR | 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;
+	if (pmsg->len <= 255)
+		write_MASTER_CTL(iface, pmsg->len << 6);
+	else {
+		write_MASTER_CTL(iface, 0xff << 6);
+		iface->manual_stop = 1;
+	}
 
 
-		iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
-		add_timer(&iface->timeout_timer);
+	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();
+	/* Master enable */
+	write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
+		((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
+		((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
+	SSYNC();
 
 
-		wait_for_completion(&iface->complete);
+	wait_for_completion(&iface->complete);
 
 
-		rc = iface->result;
-		if (rc == 1)
-			ret++;
-		else if (rc == -1)
-			break;
-	}
+	rc = iface->result;
 
 
-	return ret;
+	if (rc == 1)
+		return num;
+	else
+		return rc;
 }
 }
 
 
 /*
 /*
@@ -319,12 +376,11 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	struct bfin_twi_iface *iface = adap->algo_data;
 	struct bfin_twi_iface *iface = adap->algo_data;
 	int rc = 0;
 	int rc = 0;
 
 
-	if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
+	if (!(read_CONTROL(iface) & TWI_ENA))
 		return -ENXIO;
 		return -ENXIO;
 
 
-	while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
+	while (read_MASTER_STAT(iface) & BUSBUSY)
 		yield();
 		yield();
-	}
 
 
 	iface->writeNum = 0;
 	iface->writeNum = 0;
 	iface->readNum = 0;
 	iface->readNum = 0;
@@ -392,19 +448,20 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	iface->read_write = read_write;
 	iface->read_write = read_write;
 	iface->command = command;
 	iface->command = command;
 	iface->timeout_count = 10;
 	iface->timeout_count = 10;
+	init_completion(&(iface->complete));
 
 
 	/* FIFO Initiation. Data in FIFO should be discarded before
 	/* FIFO Initiation. Data in FIFO should be discarded before
 	 * start a new operation.
 	 * start a new operation.
 	 */
 	 */
-	bfin_write_TWI_FIFO_CTL(0x3);
+	write_FIFO_CTL(iface, 0x3);
 	SSYNC();
 	SSYNC();
-	bfin_write_TWI_FIFO_CTL(0);
+	write_FIFO_CTL(iface, 0);
 
 
 	/* clear int stat */
 	/* clear int stat */
-	bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
+	write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
 
 
 	/* Set Transmit device address */
 	/* Set Transmit device address */
-	bfin_write_TWI_MASTER_ADDR(addr);
+	write_MASTER_ADDR(iface, addr);
 	SSYNC();
 	SSYNC();
 
 
 	iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
 	iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
@@ -412,60 +469,64 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 
 
 	switch (iface->cur_mode) {
 	switch (iface->cur_mode) {
 	case TWI_I2C_MODE_STANDARDSUB:
 	case TWI_I2C_MODE_STANDARDSUB:
-		bfin_write_TWI_XMT_DATA8(iface->command);
-		bfin_write_TWI_INT_MASK(MCOMP | MERR |
+		write_XMT_DATA8(iface, iface->command);
+		write_INT_MASK(iface, MCOMP | MERR |
 			((iface->read_write == I2C_SMBUS_READ) ?
 			((iface->read_write == I2C_SMBUS_READ) ?
 			RCVSERV : XMTSERV));
 			RCVSERV : XMTSERV));
 		SSYNC();
 		SSYNC();
 
 
 		if (iface->writeNum + 1 <= 255)
 		if (iface->writeNum + 1 <= 255)
-			bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
+			write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
 		else {
 		else {
-			bfin_write_TWI_MASTER_CTL(0xff << 6);
+			write_MASTER_CTL(iface, 0xff << 6);
 			iface->manual_stop = 1;
 			iface->manual_stop = 1;
 		}
 		}
 		/* Master enable */
 		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
 		break;
 		break;
 	case TWI_I2C_MODE_COMBINED:
 	case TWI_I2C_MODE_COMBINED:
-		bfin_write_TWI_XMT_DATA8(iface->command);
-		bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV);
+		write_XMT_DATA8(iface, iface->command);
+		write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
 		SSYNC();
 		SSYNC();
 
 
 		if (iface->writeNum > 0)
 		if (iface->writeNum > 0)
-			bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
+			write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
 		else
 		else
-			bfin_write_TWI_MASTER_CTL(0x1 << 6);
+			write_MASTER_CTL(iface, 0x1 << 6);
 		/* Master enable */
 		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
 		break;
 		break;
 	default:
 	default:
-		bfin_write_TWI_MASTER_CTL(0);
+		write_MASTER_CTL(iface, 0);
 		if (size != I2C_SMBUS_QUICK) {
 		if (size != I2C_SMBUS_QUICK) {
 			/* Don't access xmit data register when this is a
 			/* Don't access xmit data register when this is a
 			 * read operation.
 			 * read operation.
 			 */
 			 */
 			if (iface->read_write != I2C_SMBUS_READ) {
 			if (iface->read_write != I2C_SMBUS_READ) {
 				if (iface->writeNum > 0) {
 				if (iface->writeNum > 0) {
-					bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+					write_XMT_DATA8(iface,
+						*(iface->transPtr++));
 					if (iface->writeNum <= 255)
 					if (iface->writeNum <= 255)
-						bfin_write_TWI_MASTER_CTL(iface->writeNum << 6);
+						write_MASTER_CTL(iface,
+							iface->writeNum << 6);
 					else {
 					else {
-						bfin_write_TWI_MASTER_CTL(0xff << 6);
+						write_MASTER_CTL(iface,
+							0xff << 6);
 						iface->manual_stop = 1;
 						iface->manual_stop = 1;
 					}
 					}
 					iface->writeNum--;
 					iface->writeNum--;
 				} else {
 				} else {
-					bfin_write_TWI_XMT_DATA8(iface->command);
-					bfin_write_TWI_MASTER_CTL(1 << 6);
+					write_XMT_DATA8(iface, iface->command);
+					write_MASTER_CTL(iface, 1 << 6);
 				}
 				}
 			} else {
 			} else {
 				if (iface->readNum > 0 && iface->readNum <= 255)
 				if (iface->readNum > 0 && iface->readNum <= 255)
-					bfin_write_TWI_MASTER_CTL(iface->readNum << 6);
+					write_MASTER_CTL(iface,
+						iface->readNum << 6);
 				else if (iface->readNum > 255) {
 				else if (iface->readNum > 255) {
-					bfin_write_TWI_MASTER_CTL(0xff << 6);
+					write_MASTER_CTL(iface, 0xff << 6);
 					iface->manual_stop = 1;
 					iface->manual_stop = 1;
 				} else {
 				} else {
 					del_timer(&iface->timeout_timer);
 					del_timer(&iface->timeout_timer);
@@ -473,13 +534,13 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 				}
 				}
 			}
 			}
 		}
 		}
-		bfin_write_TWI_INT_MASK(MCOMP | MERR |
+		write_INT_MASK(iface, MCOMP | MERR |
 			((iface->read_write == I2C_SMBUS_READ) ?
 			((iface->read_write == I2C_SMBUS_READ) ?
 			RCVSERV : XMTSERV));
 			RCVSERV : XMTSERV));
 		SSYNC();
 		SSYNC();
 
 
 		/* Master enable */
 		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
 			((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
 			((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
 		break;
 		break;
@@ -514,10 +575,10 @@ static struct i2c_algorithm bfin_twi_algorithm = {
 
 
 static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
 static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
 {
 {
-/*	struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
+	struct bfin_twi_iface *iface = platform_get_drvdata(dev);
 
 
 	/* Disable TWI */
 	/* Disable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA);
+	write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA);
 	SSYNC();
 	SSYNC();
 
 
 	return 0;
 	return 0;
@@ -525,24 +586,52 @@ static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
 
 
 static int i2c_bfin_twi_resume(struct platform_device *dev)
 static int i2c_bfin_twi_resume(struct platform_device *dev)
 {
 {
-/*	struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
+	struct bfin_twi_iface *iface = platform_get_drvdata(dev);
 
 
 	/* Enable TWI */
 	/* Enable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+	write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
 	SSYNC();
 	SSYNC();
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int i2c_bfin_twi_probe(struct platform_device *dev)
+static int i2c_bfin_twi_probe(struct platform_device *pdev)
 {
 {
-	struct bfin_twi_iface *iface = &twi_iface;
+	struct bfin_twi_iface *iface;
 	struct i2c_adapter *p_adap;
 	struct i2c_adapter *p_adap;
+	struct resource *res;
 	int rc;
 	int rc;
 
 
+	iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL);
+	if (!iface) {
+		dev_err(&pdev->dev, "Cannot allocate memory\n");
+		rc = -ENOMEM;
+		goto out_error_nomem;
+	}
+
 	spin_lock_init(&(iface->lock));
 	spin_lock_init(&(iface->lock));
-	init_completion(&(iface->complete));
-	iface->irq = IRQ_TWI;
+
+	/* Find and map our resources */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
+		rc = -ENOENT;
+		goto out_error_get_res;
+	}
+
+	iface->regs_base = ioremap(res->start, res->end - res->start + 1);
+	if (iface->regs_base == NULL) {
+		dev_err(&pdev->dev, "Cannot map IO\n");
+		rc = -ENXIO;
+		goto out_error_ioremap;
+	}
+
+	iface->irq = platform_get_irq(pdev, 0);
+	if (iface->irq < 0) {
+		dev_err(&pdev->dev, "No IRQ specified\n");
+		rc = -ENOENT;
+		goto out_error_no_irq;
+	}
 
 
 	init_timer(&(iface->timeout_timer));
 	init_timer(&(iface->timeout_timer));
 	iface->timeout_timer.function = bfin_twi_timeout;
 	iface->timeout_timer.function = bfin_twi_timeout;
@@ -550,39 +639,63 @@ static int i2c_bfin_twi_probe(struct platform_device *dev)
 
 
 	p_adap = &iface->adap;
 	p_adap = &iface->adap;
 	p_adap->id = I2C_HW_BLACKFIN;
 	p_adap->id = I2C_HW_BLACKFIN;
-	p_adap->nr = dev->id;
-	strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
+	p_adap->nr = pdev->id;
+	strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
 	p_adap->algo = &bfin_twi_algorithm;
 	p_adap->algo = &bfin_twi_algorithm;
 	p_adap->algo_data = iface;
 	p_adap->algo_data = iface;
 	p_adap->class = I2C_CLASS_ALL;
 	p_adap->class = I2C_CLASS_ALL;
-	p_adap->dev.parent = &dev->dev;
+	p_adap->dev.parent = &pdev->dev;
+
+	rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
+	if (rc) {
+		dev_err(&pdev->dev, "Can't setup pin mux!\n");
+		goto out_error_pin_mux;
+	}
 
 
 	rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
 	rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
-		IRQF_DISABLED, dev->name, iface);
+		IRQF_DISABLED, pdev->name, iface);
 	if (rc) {
 	if (rc) {
-		dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n",
-			iface->irq);
-		return -ENODEV;
+		dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
+		rc = -ENODEV;
+		goto out_error_req_irq;
 	}
 	}
 
 
 	/* Set TWI internal clock as 10MHz */
 	/* Set TWI internal clock as 10MHz */
-	bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
+	write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
 
 
 	/* Set Twi interface clock as specified */
 	/* 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 )
+	write_CLKDIV(iface, ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
+			<< 8) | ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
 			& 0xFF));
 			& 0xFF));
 
 
 	/* Enable TWI */
 	/* Enable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+	write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
 	SSYNC();
 	SSYNC();
 
 
 	rc = i2c_add_numbered_adapter(p_adap);
 	rc = i2c_add_numbered_adapter(p_adap);
-	if (rc < 0)
-		free_irq(iface->irq, iface);
-	else
-		platform_set_drvdata(dev, iface);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "Can't add i2c adapter!\n");
+		goto out_error_add_adapter;
+	}
+
+	platform_set_drvdata(pdev, iface);
 
 
+	dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, "
+		"regs_base@%p\n", iface->regs_base);
+
+	return 0;
+
+out_error_add_adapter:
+	free_irq(iface->irq, iface);
+out_error_req_irq:
+out_error_no_irq:
+	peripheral_free_list(pin_req[pdev->id]);
+out_error_pin_mux:
+	iounmap(iface->regs_base);
+out_error_ioremap:
+out_error_get_res:
+	kfree(iface);
+out_error_nomem:
 	return rc;
 	return rc;
 }
 }
 
 
@@ -594,6 +707,9 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
 
 
 	i2c_del_adapter(&(iface->adap));
 	i2c_del_adapter(&(iface->adap));
 	free_irq(iface->irq, iface);
 	free_irq(iface->irq, iface);
+	peripheral_free_list(pin_req[pdev->id]);
+	iounmap(iface->regs_base);
+	kfree(iface);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -611,8 +727,6 @@ static struct platform_driver i2c_bfin_twi_driver = {
 
 
 static int __init i2c_bfin_twi_init(void)
 static int __init i2c_bfin_twi_init(void)
 {
 {
-	pr_info("I2C: Blackfin I2C TWI driver\n");
-
 	return platform_driver_register(&i2c_bfin_twi_driver);
 	return platform_driver_register(&i2c_bfin_twi_driver);
 }
 }
 
 
@@ -621,9 +735,10 @@ static void __exit i2c_bfin_twi_exit(void)
 	platform_driver_unregister(&i2c_bfin_twi_driver);
 	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_init(i2c_bfin_twi_init);
 module_exit(i2c_bfin_twi_exit);
 module_exit(i2c_bfin_twi_exit);
+
+MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
+MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:i2c-bfin-twi");

+ 6 - 3
drivers/i2c/busses/i2c-davinci.c

@@ -328,7 +328,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	int i;
 	int i;
 	int ret;
 	int ret;
 
 
-	dev_dbg(dev->dev, "%s: msgs: %d\n", __FUNCTION__, num);
+	dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
 
 
 	ret = i2c_davinci_wait_bus_not_busy(dev, 1);
 	ret = i2c_davinci_wait_bus_not_busy(dev, 1);
 	if (ret < 0) {
 	if (ret < 0) {
@@ -342,7 +342,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 			return ret;
 			return ret;
 	}
 	}
 
 
-	dev_dbg(dev->dev, "%s:%d ret: %d\n", __FUNCTION__, __LINE__, ret);
+	dev_dbg(dev->dev, "%s:%d ret: %d\n", __func__, __LINE__, ret);
 
 
 	return num;
 	return num;
 }
 }
@@ -364,7 +364,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
 	u16 w;
 	u16 w;
 
 
 	while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
 	while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
-		dev_dbg(dev->dev, "%s: stat=0x%x\n", __FUNCTION__, stat);
+		dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
 		if (count++ == 100) {
 		if (count++ == 100) {
 			dev_warn(dev->dev, "Too much work in one IRQ\n");
 			dev_warn(dev->dev, "Too much work in one IRQ\n");
 			break;
 			break;
@@ -553,6 +553,9 @@ static int davinci_i2c_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:i2c_davinci");
+
 static struct platform_driver davinci_i2c_driver = {
 static struct platform_driver davinci_i2c_driver = {
 	.probe		= davinci_i2c_probe,
 	.probe		= davinci_i2c_probe,
 	.remove		= davinci_i2c_remove,
 	.remove		= davinci_i2c_remove,

+ 1 - 0
drivers/i2c/busses/i2c-gpio.c

@@ -220,3 +220,4 @@ module_exit(i2c_gpio_exit);
 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
 MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
 MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:i2c-gpio");

+ 191 - 6
drivers/i2c/busses/i2c-ibm_iic.c

@@ -6,6 +6,9 @@
  * Copyright (c) 2003, 2004 Zultys Technologies.
  * Copyright (c) 2003, 2004 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
  *
+ * Copyright (c) 2008 PIKA Technologies
+ * Sean MacLennan <smaclennan@pikatech.com>
+ *
  * Based on original work by
  * Based on original work by
  * 	Ian DaSilva  <idasilva@mvista.com>
  * 	Ian DaSilva  <idasilva@mvista.com>
  *      Armin Kuster <akuster@mvista.com>
  *      Armin Kuster <akuster@mvista.com>
@@ -39,12 +42,17 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-id.h>
+
+#ifdef CONFIG_IBM_OCP
 #include <asm/ocp.h>
 #include <asm/ocp.h>
 #include <asm/ibm4xx.h>
 #include <asm/ibm4xx.h>
+#else
+#include <linux/of_platform.h>
+#endif
 
 
 #include "i2c-ibm_iic.h"
 #include "i2c-ibm_iic.h"
 
 
-#define DRIVER_VERSION "2.1"
+#define DRIVER_VERSION "2.2"
 
 
 MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
 MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
@@ -650,13 +658,14 @@ static inline u8 iic_clckdiv(unsigned int opb)
 	opb /= 1000000;
 	opb /= 1000000;
 
 
 	if (opb < 20 || opb > 150){
 	if (opb < 20 || opb > 150){
-		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
+		printk(KERN_WARNING "ibm-iic: invalid OPB clock frequency %u MHz\n",
 			opb);
 			opb);
 		opb = opb < 20 ? 20 : 150;
 		opb = opb < 20 ? 20 : 150;
 	}
 	}
 	return (u8)((opb + 9) / 10 - 1);
 	return (u8)((opb + 9) / 10 - 1);
 }
 }
 
 
+#ifdef CONFIG_IBM_OCP
 /*
 /*
  * Register single IIC interface
  * Register single IIC interface
  */
  */
@@ -672,7 +681,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
 			ocp->def->index);
 			ocp->def->index);
 
 
 	if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
 	if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
-		printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n",
+		printk(KERN_ERR "ibm-iic%d: failed to allocate device data\n",
 			ocp->def->index);
 			ocp->def->index);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
@@ -687,7 +696,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
 	}
 	}
 
 
 	if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
 	if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
-		printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
+		printk(KERN_ERR "ibm-iic%d: failed to ioremap device registers\n",
 			dev->idx);
 			dev->idx);
 		ret = -ENXIO;
 		ret = -ENXIO;
 		goto fail2;
 		goto fail2;
@@ -745,7 +754,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
 	adap->nr = dev->idx >= 0 ? dev->idx : 0;
 	adap->nr = dev->idx >= 0 ? dev->idx : 0;
 
 
 	if ((ret = i2c_add_numbered_adapter(adap)) < 0) {
 	if ((ret = i2c_add_numbered_adapter(adap)) < 0) {
-		printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n",
+		printk(KERN_ERR "ibm-iic%d: failed to register i2c adapter\n",
 			dev->idx);
 			dev->idx);
 		goto fail;
 		goto fail;
 	}
 	}
@@ -778,7 +787,7 @@ static void __devexit iic_remove(struct ocp_device *ocp)
 	struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
 	struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
 	BUG_ON(dev == NULL);
 	BUG_ON(dev == NULL);
 	if (i2c_del_adapter(&dev->adap)){
 	if (i2c_del_adapter(&dev->adap)){
-		printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n",
+		printk(KERN_ERR "ibm-iic%d: failed to delete i2c adapter :(\n",
 			dev->idx);
 			dev->idx);
 		/* That's *very* bad, just shutdown IRQ ... */
 		/* That's *very* bad, just shutdown IRQ ... */
 		if (dev->irq >= 0){
 		if (dev->irq >= 0){
@@ -828,5 +837,181 @@ static void __exit iic_exit(void)
 	ocp_unregister_driver(&ibm_iic_driver);
 	ocp_unregister_driver(&ibm_iic_driver);
 }
 }
 
 
+#else  /* !CONFIG_IBM_OCP */
+
+static int __devinit iic_request_irq(struct of_device *ofdev,
+				     struct ibm_iic_private *dev)
+{
+	struct device_node *np = ofdev->node;
+	int irq;
+
+	if (iic_force_poll)
+		return NO_IRQ;
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
+		return NO_IRQ;
+	}
+
+	/* Disable interrupts until we finish initialization, assumes
+	 *  level-sensitive IRQ setup...
+	 */
+	iic_interrupt_mode(dev, 0);
+	if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) {
+		dev_err(&ofdev->dev, "request_irq %d failed\n", irq);
+		/* Fallback to the polling mode */
+		return NO_IRQ;
+	}
+
+	return irq;
+}
+
+/*
+ * Register single IIC interface
+ */
+static int __devinit iic_probe(struct of_device *ofdev,
+			       const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct ibm_iic_private *dev;
+	struct i2c_adapter *adap;
+	const u32 *indexp, *freq;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		dev_err(&ofdev->dev, "failed to allocate device data\n");
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	indexp = of_get_property(np, "index", NULL);
+	if (!indexp) {
+		dev_err(&ofdev->dev, "no index specified\n");
+		ret = -EINVAL;
+		goto error_cleanup;
+	}
+	dev->idx = *indexp;
+
+	dev->vaddr = of_iomap(np, 0);
+	if (dev->vaddr == NULL) {
+		dev_err(&ofdev->dev, "failed to iomap device\n");
+		ret = -ENXIO;
+		goto error_cleanup;
+	}
+
+	init_waitqueue_head(&dev->wq);
+
+	dev->irq = iic_request_irq(ofdev, dev);
+	if (dev->irq == NO_IRQ)
+		dev_warn(&ofdev->dev, "using polling mode\n");
+
+	/* Board specific settings */
+	if (iic_force_fast || of_get_property(np, "fast-mode", NULL))
+		dev->fast_mode = 1;
+
+	freq = of_get_property(np, "clock-frequency", NULL);
+	if (freq == NULL) {
+		freq = of_get_property(np->parent, "clock-frequency", NULL);
+		if (freq == NULL) {
+			dev_err(&ofdev->dev, "Unable to get bus frequency\n");
+			ret = -EINVAL;
+			goto error_cleanup;
+		}
+	}
+
+	dev->clckdiv = iic_clckdiv(*freq);
+	dev_dbg(&ofdev->dev, "clckdiv = %d\n", dev->clckdiv);
+
+	/* Initialize IIC interface */
+	iic_dev_init(dev);
+
+	/* Register it with i2c layer */
+	adap = &dev->adap;
+	adap->dev.parent = &ofdev->dev;
+	strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
+	i2c_set_adapdata(adap, dev);
+	adap->id = I2C_HW_OCP;
+	adap->class = I2C_CLASS_HWMON;
+	adap->algo = &iic_algo;
+	adap->timeout = 1;
+	adap->nr = dev->idx;
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret  < 0) {
+		dev_err(&ofdev->dev, "failed to register i2c adapter\n");
+		goto error_cleanup;
+	}
+
+	dev_info(&ofdev->dev, "using %s mode\n",
+		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
+
+	return 0;
+
+error_cleanup:
+	if (dev->irq != NO_IRQ) {
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}
+
+	if (dev->vaddr)
+		iounmap(dev->vaddr);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(dev);
+	return ret;
+}
+
+/*
+ * Cleanup initialized IIC interface
+ */
+static int __devexit iic_remove(struct of_device *ofdev)
+{
+	struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+
+	i2c_del_adapter(&dev->adap);
+
+	if (dev->irq != NO_IRQ) {
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}
+
+	iounmap(dev->vaddr);
+	kfree(dev);
+
+	return 0;
+}
+
+static const struct of_device_id ibm_iic_match[] = {
+	{ .compatible = "ibm,iic-405ex", },
+	{ .compatible = "ibm,iic-405gp", },
+	{ .compatible = "ibm,iic-440gp", },
+	{ .compatible = "ibm,iic-440gpx", },
+	{ .compatible = "ibm,iic-440grx", },
+	{}
+};
+
+static struct of_platform_driver ibm_iic_driver = {
+	.name	= "ibm-iic",
+	.match_table = ibm_iic_match,
+	.probe	= iic_probe,
+	.remove	= __devexit_p(iic_remove),
+};
+
+static int __init iic_init(void)
+{
+	return of_register_platform_driver(&ibm_iic_driver);
+}
+
+static void __exit iic_exit(void)
+{
+	of_unregister_platform_driver(&ibm_iic_driver);
+}
+#endif /* CONFIG_IBM_OCP */
+
 module_init(iic_init);
 module_init(iic_init);
 module_exit(iic_exit);
 module_exit(iic_exit);

+ 1 - 0
drivers/i2c/busses/i2c-iop3xx.c

@@ -550,3 +550,4 @@ module_exit (i2c_iop3xx_exit);
 MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
 MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
 MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
 MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:IOP3xx-I2C");

+ 1 - 0
drivers/i2c/busses/i2c-ixp2000.c

@@ -164,4 +164,5 @@ module_exit(ixp2000_i2c_exit);
 MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>");
 MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>");
 MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
 MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:IXP2000-I2C");
 
 

+ 3 - 0
drivers/i2c/busses/i2c-mpc.c

@@ -392,6 +392,9 @@ static int fsl_i2c_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 };
 };
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:fsl-i2c");
+
 /* Structure for a device driver */
 /* Structure for a device driver */
 static struct platform_driver fsl_i2c_driver = {
 static struct platform_driver fsl_i2c_driver = {
 	.probe = fsl_i2c_probe,
 	.probe = fsl_i2c_probe,

+ 3 - 0
drivers/i2c/busses/i2c-ocores.c

@@ -312,6 +312,9 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev)
 	return 0;
 	return 0;
 }
 }
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:ocores-i2c");
+
 static struct platform_driver ocores_i2c_driver = {
 static struct platform_driver ocores_i2c_driver = {
 	.probe  = ocores_i2c_probe,
 	.probe  = ocores_i2c_probe,
 	.remove = __devexit_p(ocores_i2c_remove),
 	.remove = __devexit_p(ocores_i2c_remove),

+ 1 - 0
drivers/i2c/busses/i2c-omap.c

@@ -693,3 +693,4 @@ module_exit(omap_i2c_exit_driver);
 MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
 MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
 MODULE_DESCRIPTION("TI OMAP I2C bus adapter");
 MODULE_DESCRIPTION("TI OMAP I2C bus adapter");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:i2c_omap");

+ 20 - 33
drivers/i2c/busses/i2c-pca-isa.c

@@ -1,6 +1,7 @@
 /*
 /*
  *  i2c-pca-isa.c driver for PCA9564 on ISA boards
  *  i2c-pca-isa.c driver for PCA9564 on ISA boards
  *    Copyright (C) 2004 Arcom Control Systems
  *    Copyright (C) 2004 Arcom Control Systems
+ *    Copyright (C) 2008 Pengutronix
  *
  *
  *  This program is free software; you can redistribute it and/or modify
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -22,11 +23,9 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
-
 #include <linux/isa.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>
@@ -34,13 +33,9 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
 
 
-#include "../algos/i2c-algo-pca.h"
-
+#define DRIVER "i2c-pca-isa"
 #define IO_SIZE 4
 #define IO_SIZE 4
 
 
-#undef DEBUG_IO
-//#define DEBUG_IO
-
 static unsigned long base   = 0x330;
 static unsigned long base   = 0x330;
 static int irq 	  = 10;
 static int irq 	  = 10;
 
 
@@ -48,22 +43,9 @@ static int irq 	  = 10;
  * in the actual clock rate */
  * in the actual clock rate */
 static int clock  = I2C_PCA_CON_59kHz;
 static int clock  = I2C_PCA_CON_59kHz;
 
 
-static int own    = 0x55;
-
 static wait_queue_head_t pca_wait;
 static wait_queue_head_t pca_wait;
 
 
-static int pca_isa_getown(struct i2c_algo_pca_data *adap)
-{
-	return (own);
-}
-
-static int pca_isa_getclock(struct i2c_algo_pca_data *adap)
-{
-	return (clock);
-}
-
-static void
-pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)
+static void pca_isa_writebyte(void *pd, int reg, int val)
 {
 {
 #ifdef DEBUG_IO
 #ifdef DEBUG_IO
 	static char *names[] = { "T/O", "DAT", "ADR", "CON" };
 	static char *names[] = { "T/O", "DAT", "ADR", "CON" };
@@ -72,44 +54,49 @@ pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)
 	outb(val, base+reg);
 	outb(val, base+reg);
 }
 }
 
 
-static int
-pca_isa_readbyte(struct i2c_algo_pca_data *adap, int reg)
+static int pca_isa_readbyte(void *pd, int reg)
 {
 {
 	int res = inb(base+reg);
 	int res = inb(base+reg);
 #ifdef DEBUG_IO
 #ifdef DEBUG_IO
 	{
 	{
-		static char *names[] = { "STA", "DAT", "ADR", "CON" };	
+		static char *names[] = { "STA", "DAT", "ADR", "CON" };
 		printk("*** read  %s => %#04x\n", names[reg], res);
 		printk("*** read  %s => %#04x\n", names[reg], res);
 	}
 	}
 #endif
 #endif
 	return res;
 	return res;
 }
 }
 
 
-static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap)
+static int pca_isa_waitforcompletion(void *pd)
 {
 {
 	int ret = 0;
 	int ret = 0;
 
 
 	if (irq > -1) {
 	if (irq > -1) {
 		ret = wait_event_interruptible(pca_wait,
 		ret = wait_event_interruptible(pca_wait,
-					       pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI);
+					       pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI);
 	} else {
 	} else {
-		while ((pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) 
+		while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
 			udelay(100);
 			udelay(100);
 	}
 	}
 	return ret;
 	return ret;
 }
 }
 
 
+static void pca_isa_resetchip(void *pd)
+{
+	/* apparently only an external reset will do it. not a lot can be done */
+	printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n");
+}
+
 static irqreturn_t pca_handler(int this_irq, void *dev_id) {
 static irqreturn_t pca_handler(int this_irq, void *dev_id) {
 	wake_up_interruptible(&pca_wait);
 	wake_up_interruptible(&pca_wait);
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
 static struct i2c_algo_pca_data pca_isa_data = {
 static struct i2c_algo_pca_data pca_isa_data = {
-	.get_own		= pca_isa_getown,
-	.get_clock		= pca_isa_getclock,
+	/* .data intentionally left NULL, not needed with ISA */
 	.write_byte		= pca_isa_writebyte,
 	.write_byte		= pca_isa_writebyte,
 	.read_byte		= pca_isa_readbyte,
 	.read_byte		= pca_isa_readbyte,
-	.wait_for_interrupt	= pca_isa_waitforinterrupt,
+	.wait_for_completion	= pca_isa_waitforcompletion,
+	.reset_chip		= pca_isa_resetchip,
 };
 };
 
 
 static struct i2c_adapter pca_isa_ops = {
 static struct i2c_adapter pca_isa_ops = {
@@ -117,6 +104,7 @@ static struct i2c_adapter pca_isa_ops = {
 	.id		= I2C_HW_A_ISA,
 	.id		= I2C_HW_A_ISA,
 	.algo_data	= &pca_isa_data,
 	.algo_data	= &pca_isa_data,
 	.name		= "PCA9564 ISA Adapter",
 	.name		= "PCA9564 ISA Adapter",
+	.timeout	= 100,
 };
 };
 
 
 static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
 static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
@@ -144,6 +132,7 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
 		}
 		}
 	}
 	}
 
 
+	pca_isa_data.i2c_clock = clock;
 	if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
 	if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
 		dev_err(dev, "Failed to add i2c bus\n");
 		dev_err(dev, "Failed to add i2c bus\n");
 		goto out_irq;
 		goto out_irq;
@@ -178,7 +167,7 @@ static struct isa_driver pca_isa_driver = {
 	.remove		= __devexit_p(pca_isa_remove),
 	.remove		= __devexit_p(pca_isa_remove),
 	.driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
-		.name	= "i2c-pca-isa",
+		.name	= DRIVER,
 	}
 	}
 };
 };
 
 
@@ -204,7 +193,5 @@ MODULE_PARM_DESC(irq, "IRQ");
 module_param(clock, int, 0);
 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 as described in table 1 of PCA9564 datasheet");
 
 
-module_param(own, int, 0); /* the driver can't do slave mode, so there's no real point in this */
-
 module_init(pca_isa_init);
 module_init(pca_isa_init);
 module_exit(pca_isa_exit);
 module_exit(pca_isa_exit);

+ 298 - 0
drivers/i2c/busses/i2c-pca-platform.c

@@ -0,0 +1,298 @@
+/*
+ *  i2c_pca_platform.c
+ *
+ *  Platform driver for the PCA9564 I2C controller.
+ *
+ *  Copyright (C) 2008 Pengutronix
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-algo-pca.h>
+#include <linux/i2c-pca-platform.h>
+#include <linux/gpio.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define res_len(r)		((r)->end - (r)->start + 1)
+
+struct i2c_pca_pf_data {
+	void __iomem			*reg_base;
+	int				irq;	/* if 0, use polling */
+	int				gpio;
+	wait_queue_head_t		wait;
+	struct i2c_adapter		adap;
+	struct i2c_algo_pca_data	algo_data;
+	unsigned long			io_base;
+	unsigned long			io_size;
+};
+
+/* Read/Write functions for different register alignments */
+
+static int i2c_pca_pf_readbyte8(void *pd, int reg)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	return ioread8(i2c->reg_base + reg);
+}
+
+static int i2c_pca_pf_readbyte16(void *pd, int reg)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	return ioread8(i2c->reg_base + reg * 2);
+}
+
+static int i2c_pca_pf_readbyte32(void *pd, int reg)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	return ioread8(i2c->reg_base + reg * 4);
+}
+
+static void i2c_pca_pf_writebyte8(void *pd, int reg, int val)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	iowrite8(val, i2c->reg_base + reg);
+}
+
+static void i2c_pca_pf_writebyte16(void *pd, int reg, int val)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	iowrite8(val, i2c->reg_base + reg * 2);
+}
+
+static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	iowrite8(val, i2c->reg_base + reg * 4);
+}
+
+
+static int i2c_pca_pf_waitforcompletion(void *pd)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	int ret = 0;
+
+	if (i2c->irq) {
+		ret = wait_event_interruptible(i2c->wait,
+			i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+			& I2C_PCA_CON_SI);
+	} 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)
+				& I2C_PCA_CON_SI) == 0)
+			udelay(100);
+	}
+
+	return ret;
+}
+
+static void i2c_pca_pf_dummyreset(void *pd)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n",
+		i2c->adap.name);
+}
+
+static void i2c_pca_pf_resetchip(void *pd)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+
+	gpio_set_value(i2c->gpio, 0);
+	ndelay(100);
+	gpio_set_value(i2c->gpio, 1);
+}
+
+static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
+{
+	struct i2c_pca_pf_data *i2c = dev_id;
+
+	if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+		return IRQ_NONE;
+
+	wake_up_interruptible(&i2c->wait);
+
+	return IRQ_HANDLED;
+}
+
+
+static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
+{
+	struct i2c_pca_pf_data *i2c;
+	struct resource *res;
+	struct i2c_pca9564_pf_platform_data *platform_data =
+				pdev->dev.platform_data;
+	int ret = 0;
+	int irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	/* If irq is 0, we do polling. */
+
+	if (res == NULL) {
+		ret = -ENODEV;
+		goto e_print;
+	}
+
+	if (!request_mem_region(res->start, res_len(res), res->name)) {
+		ret = -ENOMEM;
+		goto e_print;
+	}
+
+	i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL);
+	if (!i2c) {
+		ret = -ENOMEM;
+		goto e_alloc;
+	}
+
+	init_waitqueue_head(&i2c->wait);
+
+	i2c->reg_base = ioremap(res->start, res_len(res));
+	if (!i2c->reg_base) {
+		ret = -EIO;
+		goto e_remap;
+	}
+	i2c->io_base = res->start;
+	i2c->io_size = res_len(res);
+	i2c->irq = irq;
+
+	i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
+	i2c->adap.owner = THIS_MODULE;
+	snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 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;
+	i2c->algo_data.data = i2c;
+
+	switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
+	case IORESOURCE_MEM_32BIT:
+		i2c->algo_data.write_byte = i2c_pca_pf_writebyte32;
+		i2c->algo_data.read_byte = i2c_pca_pf_readbyte32;
+		break;
+	case IORESOURCE_MEM_16BIT:
+		i2c->algo_data.write_byte = i2c_pca_pf_writebyte16;
+		i2c->algo_data.read_byte = i2c_pca_pf_readbyte16;
+		break;
+	case IORESOURCE_MEM_8BIT:
+	default:
+		i2c->algo_data.write_byte = i2c_pca_pf_writebyte8;
+		i2c->algo_data.read_byte = i2c_pca_pf_readbyte8;
+		break;
+	}
+
+	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);
+		if (ret == 0) {
+			gpio_direction_output(i2c->gpio, 1);
+			i2c->algo_data.reset_chip = i2c_pca_pf_resetchip;
+		} else {
+			printk(KERN_WARNING "%s: Registering gpio failed!\n",
+				i2c->adap.name);
+			i2c->gpio = ret;
+		}
+	}
+
+	if (irq) {
+		ret = request_irq(irq, i2c_pca_pf_handler,
+			IRQF_TRIGGER_FALLING, i2c->adap.name, i2c);
+		if (ret)
+			goto e_reqirq;
+	}
+
+	if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) {
+		ret = -ENODEV;
+		goto e_adapt;
+	}
+
+	platform_set_drvdata(pdev, i2c);
+
+	printk(KERN_INFO "%s registered.\n", i2c->adap.name);
+
+	return 0;
+
+e_adapt:
+	if (irq)
+		free_irq(irq, i2c);
+e_reqirq:
+	if (i2c->gpio > -1)
+		gpio_free(i2c->gpio);
+
+	iounmap(i2c->reg_base);
+e_remap:
+	kfree(i2c);
+e_alloc:
+	release_mem_region(res->start, res_len(res));
+e_print:
+	printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
+	return ret;
+}
+
+static int __devexit i2c_pca_pf_remove(struct platform_device *pdev)
+{
+	struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
+	platform_set_drvdata(pdev, NULL);
+
+	i2c_del_adapter(&i2c->adap);
+
+	if (i2c->irq)
+		free_irq(i2c->irq, i2c);
+
+	if (i2c->gpio > -1)
+		gpio_free(i2c->gpio);
+
+	iounmap(i2c->reg_base);
+	release_mem_region(i2c->io_base, i2c->io_size);
+	kfree(i2c);
+
+	return 0;
+}
+
+static struct platform_driver i2c_pca_pf_driver = {
+	.probe = i2c_pca_pf_probe,
+	.remove = __devexit_p(i2c_pca_pf_remove),
+	.driver = {
+		.name = "i2c-pca-platform",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init i2c_pca_pf_init(void)
+{
+	return platform_driver_register(&i2c_pca_pf_driver);
+}
+
+static void __exit i2c_pca_pf_exit(void)
+{
+	platform_driver_unregister(&i2c_pca_pf_driver);
+}
+
+MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_pca_pf_init);
+module_exit(i2c_pca_pf_exit);
+

+ 5 - 2
drivers/i2c/busses/i2c-pmcmsp.c

@@ -467,7 +467,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
 	    (cmd->read_len == 0 || cmd->write_len == 0))) {
 	    (cmd->read_len == 0 || cmd->write_len == 0))) {
 		dev_err(&pmcmsptwi_adapter.dev,
 		dev_err(&pmcmsptwi_adapter.dev,
 			"%s: Cannot transfer less than 1 byte\n",
 			"%s: Cannot transfer less than 1 byte\n",
-			__FUNCTION__);
+			__func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -475,7 +475,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
 	    cmd->write_len > MSP_MAX_BYTES_PER_RW) {
 	    cmd->write_len > MSP_MAX_BYTES_PER_RW) {
 		dev_err(&pmcmsptwi_adapter.dev,
 		dev_err(&pmcmsptwi_adapter.dev,
 			"%s: Cannot transfer more than %d bytes\n",
 			"%s: Cannot transfer more than %d bytes\n",
-			__FUNCTION__, MSP_MAX_BYTES_PER_RW);
+			__func__, MSP_MAX_BYTES_PER_RW);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -627,6 +627,9 @@ static struct i2c_adapter pmcmsptwi_adapter = {
 	.name		= DRV_NAME,
 	.name		= DRV_NAME,
 };
 };
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:" DRV_NAME);
+
 static struct platform_driver pmcmsptwi_driver = {
 static struct platform_driver pmcmsptwi_driver = {
 	.probe  = pmcmsptwi_probe,
 	.probe  = pmcmsptwi_probe,
 	.remove	= __devexit_p(pmcmsptwi_remove),
 	.remove	= __devexit_p(pmcmsptwi_remove),

+ 23 - 22
drivers/i2c/busses/i2c-pnx.c

@@ -76,7 +76,7 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
 {
 {
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
 
-	dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __FUNCTION__,
+	dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__,
 		slave_addr, alg_data->mif.mode);
 		slave_addr, alg_data->mif.mode);
 
 
 	/* Check for 7 bit slave addresses only */
 	/* Check for 7 bit slave addresses only */
@@ -110,14 +110,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
 	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
 	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
 		  I2C_REG_STS(alg_data));
 		  I2C_REG_STS(alg_data));
 
 
-	dev_dbg(&adap->dev, "%s(): sending %#x\n", __FUNCTION__,
+	dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__,
 		(slave_addr << 1) | start_bit | alg_data->mif.mode);
 		(slave_addr << 1) | start_bit | alg_data->mif.mode);
 
 
 	/* Write the slave address, START bit and R/W bit */
 	/* Write the slave address, START bit and R/W bit */
 	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
 	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
 		  I2C_REG_TX(alg_data));
 		  I2C_REG_TX(alg_data));
 
 
-	dev_dbg(&adap->dev, "%s(): exit\n", __FUNCTION__);
+	dev_dbg(&adap->dev, "%s(): exit\n", __func__);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -135,7 +135,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
 	long timeout = 1000;
 	long timeout = 1000;
 
 
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 
 	/* Write a STOP bit to TX FIFO */
 	/* Write a STOP bit to TX FIFO */
 	iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
 	iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
@@ -149,7 +149,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
 	}
 	}
 
 
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 }
 }
 
 
 /**
 /**
@@ -164,7 +164,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 	u32 val;
 	u32 val;
 
 
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 
 	if (alg_data->mif.len > 0) {
 	if (alg_data->mif.len > 0) {
 		/* We still have something to talk about... */
 		/* We still have something to talk about... */
@@ -179,7 +179,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 		alg_data->mif.len--;
 		alg_data->mif.len--;
 		iowrite32(val, I2C_REG_TX(alg_data));
 		iowrite32(val, I2C_REG_TX(alg_data));
 
 
-		dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __FUNCTION__,
+		dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__,
 			val, alg_data->mif.len + 1);
 			val, alg_data->mif.len + 1);
 
 
 		if (alg_data->mif.len == 0) {
 		if (alg_data->mif.len == 0) {
@@ -197,7 +197,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 			del_timer_sync(&alg_data->mif.timer);
 			del_timer_sync(&alg_data->mif.timer);
 
 
 			dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
 			dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
-				__FUNCTION__);
+				__func__);
 
 
 			complete(&alg_data->mif.complete);
 			complete(&alg_data->mif.complete);
 		}
 		}
@@ -213,13 +213,13 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 		/* Stop timer. */
 		/* Stop timer. */
 		del_timer_sync(&alg_data->mif.timer);
 		del_timer_sync(&alg_data->mif.timer);
 		dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
 		dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
-			"zero-xfer.\n", __FUNCTION__);
+			"zero-xfer.\n", __func__);
 
 
 		complete(&alg_data->mif.complete);
 		complete(&alg_data->mif.complete);
 	}
 	}
 
 
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 
 	return 0;
 	return 0;
 }
 }
@@ -237,14 +237,14 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 	u32 ctl = 0;
 	u32 ctl = 0;
 
 
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 
 	/* Check, whether there is already data,
 	/* Check, whether there is already data,
 	 * or we didn't 'ask' for it yet.
 	 * or we didn't 'ask' for it yet.
 	 */
 	 */
 	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
 	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
 		dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
 		dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
-			"Rx-fifo...\n", __FUNCTION__);
+			"Rx-fifo...\n", __func__);
 
 
 		if (alg_data->mif.len == 1) {
 		if (alg_data->mif.len == 1) {
 			/* Last byte, do not acknowledge next rcv. */
 			/* Last byte, do not acknowledge next rcv. */
@@ -276,7 +276,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 	if (alg_data->mif.len > 0) {
 	if (alg_data->mif.len > 0) {
 		val = ioread32(I2C_REG_RX(alg_data));
 		val = ioread32(I2C_REG_RX(alg_data));
 		*alg_data->mif.buf++ = (u8) (val & 0xff);
 		*alg_data->mif.buf++ = (u8) (val & 0xff);
-		dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __FUNCTION__, val,
+		dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val,
 			alg_data->mif.len);
 			alg_data->mif.len);
 
 
 		alg_data->mif.len--;
 		alg_data->mif.len--;
@@ -300,7 +300,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 	}
 	}
 
 
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 
 	return 0;
 	return 0;
 }
 }
@@ -312,7 +312,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
 
 	dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
 	dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
-		__FUNCTION__,
+		__func__,
 		ioread32(I2C_REG_STS(alg_data)),
 		ioread32(I2C_REG_STS(alg_data)),
 		ioread32(I2C_REG_CTL(alg_data)),
 		ioread32(I2C_REG_CTL(alg_data)),
 		alg_data->mif.mode);
 		alg_data->mif.mode);
@@ -336,7 +336,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 		/* Slave did not acknowledge, generate a STOP */
 		/* Slave did not acknowledge, generate a STOP */
 		dev_dbg(&adap->dev, "%s(): "
 		dev_dbg(&adap->dev, "%s(): "
 			"Slave did not acknowledge, generating a STOP.\n",
 			"Slave did not acknowledge, generating a STOP.\n",
-			__FUNCTION__);
+			__func__);
 		i2c_pnx_stop(adap);
 		i2c_pnx_stop(adap);
 
 
 		/* Disable master interrupts. */
 		/* Disable master interrupts. */
@@ -375,7 +375,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
 	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
 
 
 	dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
 	dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
-		 __FUNCTION__, ioread32(I2C_REG_STS(alg_data)),
+		 __func__, ioread32(I2C_REG_STS(alg_data)),
 		 ioread32(I2C_REG_CTL(alg_data)));
 		 ioread32(I2C_REG_CTL(alg_data)));
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
@@ -447,7 +447,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 	u32 stat = ioread32(I2C_REG_STS(alg_data));
 	u32 stat = ioread32(I2C_REG_STS(alg_data));
 
 
 	dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
 	dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
-		__FUNCTION__, num, ioread32(I2C_REG_STS(alg_data)));
+		__func__, num, ioread32(I2C_REG_STS(alg_data)));
 
 
 	bus_reset_if_active(adap);
 	bus_reset_if_active(adap);
 
 
@@ -473,7 +473,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 		alg_data->mif.ret = 0;
 		alg_data->mif.ret = 0;
 		alg_data->last = (i == num - 1);
 		alg_data->last = (i == num - 1);
 
 
-		dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __FUNCTION__,
+		dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__,
 			alg_data->mif.mode,
 			alg_data->mif.mode,
 			alg_data->mif.len);
 			alg_data->mif.len);
 
 
@@ -498,7 +498,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 		if (!(rc = alg_data->mif.ret))
 		if (!(rc = alg_data->mif.ret))
 			completed++;
 			completed++;
 		dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
 		dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
-			__FUNCTION__, rc);
+			__func__, rc);
 
 
 		/* Clear TDI and AFI bits in case they are set. */
 		/* Clear TDI and AFI bits in case they are set. */
 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
@@ -522,7 +522,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 	alg_data->mif.len = 0;
 	alg_data->mif.len = 0;
 
 
 	dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
 	dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 
 	if (completed != num)
 	if (completed != num)
 		return ((rc < 0) ? rc : -EREMOTEIO);
 		return ((rc < 0) ? rc : -EREMOTEIO);
@@ -563,7 +563,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
 
 
 	if (!i2c_pnx || !i2c_pnx->adapter) {
 	if (!i2c_pnx || !i2c_pnx->adapter) {
 		dev_err(&pdev->dev, "%s: no platform data supplied\n",
 		dev_err(&pdev->dev, "%s: no platform data supplied\n",
-		       __FUNCTION__);
+		       __func__);
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
@@ -697,6 +697,7 @@ static void __exit i2c_adap_pnx_exit(void)
 MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
 MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
 MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
 MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pnx-i2c");
 
 
 /* We need to make sure I2C is initialized before USB */
 /* We need to make sure I2C is initialized before USB */
 subsys_initcall(i2c_adap_pnx_init);
 subsys_initcall(i2c_adap_pnx_init);

+ 3 - 0
drivers/i2c/busses/i2c-powermac.c

@@ -263,6 +263,9 @@ static int __devexit i2c_powermac_probe(struct platform_device *dev)
 }
 }
 
 
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:i2c-powermac");
+
 static struct platform_driver i2c_powermac_driver = {
 static struct platform_driver i2c_powermac_driver = {
 	.probe = i2c_powermac_probe,
 	.probe = i2c_powermac_probe,
 	.remove = __devexit_p(i2c_powermac_remove),
 	.remove = __devexit_p(i2c_powermac_remove),

+ 2 - 1
drivers/i2c/busses/i2c-pxa.c

@@ -155,7 +155,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
 		readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 		readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 }
 }
 
 
-#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
+#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __func__)
 #else
 #else
 #define i2c_debug	0
 #define i2c_debug	0
 
 
@@ -1132,6 +1132,7 @@ static void __exit i2c_adap_pxa_exit(void)
 }
 }
 
 
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-i2c");
 
 
 module_init(i2c_adap_pxa_init);
 module_init(i2c_adap_pxa_init);
 module_exit(i2c_adap_pxa_exit);
 module_exit(i2c_adap_pxa_exit);

+ 3 - 2
drivers/i2c/busses/i2c-s3c2410.c

@@ -276,12 +276,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
 	switch (i2c->state) {
 	switch (i2c->state) {
 
 
 	case STATE_IDLE:
 	case STATE_IDLE:
-		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __FUNCTION__);
+		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
 		goto out;
 		goto out;
 		break;
 		break;
 
 
 	case STATE_STOP:
 	case STATE_STOP:
-		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __FUNCTION__);
+		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
 		s3c24xx_i2c_disable_irq(i2c);		
 		s3c24xx_i2c_disable_irq(i2c);		
 		goto out_ack;
 		goto out_ack;
 
 
@@ -948,3 +948,4 @@ module_exit(i2c_adap_s3c_exit);
 MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
 MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c2410-i2c");

+ 577 - 0
drivers/i2c/busses/i2c-sh7760.c

@@ -0,0 +1,577 @@
+/*
+ * I2C bus driver for the SH7760 I2C Interfaces.
+ *
+ * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
+ *
+ * licensed under the terms outlined in the file COPYING.
+ *
+ */
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <asm/clock.h>
+#include <asm/i2c-sh7760.h>
+#include <asm/io.h>
+
+/* register offsets */
+#define I2CSCR		0x0		/* slave ctrl		*/
+#define I2CMCR		0x4		/* master ctrl		*/
+#define I2CSSR		0x8		/* slave status		*/
+#define I2CMSR		0xC		/* master status	*/
+#define I2CSIER		0x10		/* slave irq enable	*/
+#define I2CMIER		0x14		/* master irq enable	*/
+#define I2CCCR		0x18		/* clock dividers	*/
+#define I2CSAR		0x1c		/* slave address	*/
+#define I2CMAR		0x20		/* master address	*/
+#define I2CRXTX		0x24		/* data port		*/
+#define I2CFCR		0x28		/* fifo control		*/
+#define I2CFSR		0x2C		/* fifo status		*/
+#define I2CFIER		0x30		/* fifo irq enable	*/
+#define I2CRFDR		0x34		/* rx fifo count	*/
+#define I2CTFDR		0x38		/* tx fifo count	*/
+
+#define REGSIZE		0x3C
+
+#define MCR_MDBS	0x80		/* non-fifo mode switch	*/
+#define MCR_FSCL	0x40		/* override SCL pin	*/
+#define MCR_FSDA	0x20		/* override SDA pin	*/
+#define MCR_OBPC	0x10		/* override pins	*/
+#define MCR_MIE		0x08		/* master if enable	*/
+#define MCR_TSBE	0x04
+#define MCR_FSB		0x02		/* force stop bit	*/
+#define MCR_ESG		0x01		/* en startbit gen.	*/
+
+#define MSR_MNR		0x40		/* nack received	*/
+#define MSR_MAL		0x20		/* arbitration lost	*/
+#define MSR_MST		0x10		/* sent a stop		*/
+#define MSR_MDE		0x08
+#define MSR_MDT		0x04
+#define MSR_MDR		0x02
+#define MSR_MAT		0x01		/* slave addr xfer done	*/
+
+#define MIE_MNRE	0x40		/* nack irq en		*/
+#define MIE_MALE	0x20		/* arblos irq en	*/
+#define MIE_MSTE	0x10		/* stop irq en		*/
+#define MIE_MDEE	0x08
+#define MIE_MDTE	0x04
+#define MIE_MDRE	0x02
+#define MIE_MATE	0x01		/* address sent irq en	*/
+
+#define FCR_RFRST	0x02		/* reset rx fifo	*/
+#define FCR_TFRST	0x01		/* reset tx fifo	*/
+
+#define FSR_TEND	0x04		/* last byte sent	*/
+#define FSR_RDF		0x02		/* rx fifo trigger	*/
+#define FSR_TDFE	0x01		/* tx fifo empty	*/
+
+#define FIER_TEIE	0x04		/* tx fifo empty irq en	*/
+#define FIER_RXIE	0x02		/* rx fifo trig irq en	*/
+#define FIER_TXIE	0x01		/* tx fifo trig irq en	*/
+
+#define FIFO_SIZE	16
+
+struct cami2c {
+	void __iomem *iobase;
+	struct i2c_adapter adap;
+
+	/* message processing */
+	struct i2c_msg	*msg;
+#define IDF_SEND	1
+#define IDF_RECV	2
+#define IDF_STOP	4
+	int		flags;
+
+#define IDS_DONE	1
+#define IDS_ARBLOST	2
+#define IDS_NACK	4
+	int		status;
+	struct completion xfer_done;
+
+	int irq;
+	struct resource *ioarea;
+};
+
+static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
+{
+	ctrl_outl(val, (unsigned long)cam->iobase + reg);
+}
+
+static inline unsigned long IN32(struct cami2c *cam, int reg)
+{
+	return ctrl_inl((unsigned long)cam->iobase + reg);
+}
+
+static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
+{
+	struct cami2c *id = ptr;
+	struct i2c_msg *msg = id->msg;
+	char *data = msg->buf;
+	unsigned long msr, fsr, fier, len;
+
+	msr = IN32(id, I2CMSR);
+	fsr = IN32(id, I2CFSR);
+
+	/* arbitration lost */
+	if (msr & MSR_MAL) {
+		OUT32(id, I2CMCR, 0);
+		OUT32(id, I2CSCR, 0);
+		OUT32(id, I2CSAR, 0);
+		id->status |= IDS_DONE | IDS_ARBLOST;
+		goto out;
+	}
+
+	if (msr & MSR_MNR) {
+		/* NACK handling is very screwed up.  After receiving a
+		 * NAK IRQ one has to wait a bit  before writing to any
+		 * registers, or the ctl will lock up. After that delay
+		 * do a normal i2c stop. Then wait at least 1 ms before
+		 * attempting another transfer or ctl will stop working
+		 */
+		udelay(100);	/* wait or risk ctl hang */
+		OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+		OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
+		OUT32(id, I2CFIER, 0);
+		OUT32(id, I2CMIER, MIE_MSTE);
+		OUT32(id, I2CSCR, 0);
+		OUT32(id, I2CSAR, 0);
+		id->status |= IDS_NACK;
+		msr &= ~MSR_MAT;
+		fsr = 0;
+		/* In some cases the MST bit is also set. */
+	}
+
+	/* i2c-stop was sent */
+	if (msr & MSR_MST) {
+		id->status |= IDS_DONE;
+		goto out;
+	}
+
+	/* i2c slave addr was sent; set to "normal" operation */
+	if (msr & MSR_MAT)
+		OUT32(id, I2CMCR, MCR_MIE);
+
+	fier = IN32(id, I2CFIER);
+
+	if (fsr & FSR_RDF) {
+		len = IN32(id, I2CRFDR);
+		if (msg->len <= len) {
+			if (id->flags & IDF_STOP) {
+				OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
+				OUT32(id, I2CFIER, 0);
+				/* manual says: wait >= 0.5 SCL times */
+				udelay(5);
+				/* next int should be MST */
+			} else {
+				id->status |= IDS_DONE;
+				/* keep the RDF bit: ctrl holds SCL low
+				 * until the setup for the next i2c_msg
+				 * clears this bit.
+				 */
+				fsr &= ~FSR_RDF;
+			}
+		}
+		while (msg->len && len) {
+			*data++ = IN32(id, I2CRXTX);
+			msg->len--;
+			len--;
+		}
+
+		if (msg->len) {
+			len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1
+						      : msg->len - 1;
+
+			OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4));
+		}
+
+	} else if (id->flags & IDF_SEND) {
+		if ((fsr & FSR_TEND) && (msg->len < 1)) {
+			if (id->flags & IDF_STOP) {
+				OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
+			} else {
+				id->status |= IDS_DONE;
+				/* keep the TEND bit: ctl holds SCL low
+				 * until the setup for the next i2c_msg
+				 * clears this bit.
+				 */
+				fsr &= ~FSR_TEND;
+			}
+		}
+		if (fsr & FSR_TDFE) {
+			while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) {
+				OUT32(id, I2CRXTX, *data++);
+				msg->len--;
+			}
+
+			if (msg->len < 1) {
+				fier &= ~FIER_TXIE;
+				OUT32(id, I2CFIER, fier);
+			} else {
+				len = (msg->len >= FIFO_SIZE) ? 2 : 0;
+				OUT32(id, I2CFCR,
+					  FCR_RFRST | ((len & 3) << 2));
+			}
+		}
+	}
+out:
+	if (id->status & IDS_DONE) {
+		OUT32(id, I2CMIER, 0);
+		OUT32(id, I2CFIER, 0);
+		id->msg = NULL;
+		complete(&id->xfer_done);
+	}
+	/* clear status flags and ctrl resumes work */
+	OUT32(id, I2CMSR, ~msr);
+	OUT32(id, I2CFSR, ~fsr);
+	OUT32(id, I2CSSR, 0);
+
+	return IRQ_HANDLED;
+}
+
+
+/* prepare and start a master receive operation */
+static void sh7760_i2c_mrecv(struct cami2c *id)
+{
+	int len;
+
+	id->flags |= IDF_RECV;
+
+	/* set the slave addr reg; otherwise rcv wont work! */
+	OUT32(id, I2CSAR, 0xfe);
+	OUT32(id, I2CMAR, (id->msg->addr << 1) | 1);
+
+	/* adjust rx fifo trigger */
+	if (id->msg->len >= FIFO_SIZE)
+		len = FIFO_SIZE - 1;	/* trigger at fifo full */
+	else
+		len = id->msg->len - 1;	/* trigger before all received */
+
+	OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+	OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4));
+
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
+	OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
+	OUT32(id, I2CFIER, FIER_RXIE);
+}
+
+/* prepare and start a master send operation */
+static void sh7760_i2c_msend(struct cami2c *id)
+{
+	int len;
+
+	id->flags |= IDF_SEND;
+
+	/* set the slave addr reg; otherwise xmit wont work! */
+	OUT32(id, I2CSAR, 0xfe);
+	OUT32(id, I2CMAR, (id->msg->addr << 1) | 0);
+
+	/* adjust tx fifo trigger */
+	if (id->msg->len >= FIFO_SIZE)
+		len = 2;	/* trig: 2 bytes left in TX fifo */
+	else
+		len = 0;	/* trig: 8 bytes left in TX fifo */
+
+	OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+	OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2));
+
+	while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) {
+		OUT32(id, I2CRXTX, *(id->msg->buf));
+		(id->msg->len)--;
+		(id->msg->buf)++;
+	}
+
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
+	OUT32(id, I2CFSR, 0);
+	OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
+	OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0));
+}
+
+static inline int sh7760_i2c_busy_check(struct cami2c *id)
+{
+	return (IN32(id, I2CMCR) & MCR_FSDA);
+}
+
+static int sh7760_i2c_master_xfer(struct i2c_adapter *adap,
+				  struct i2c_msg *msgs,
+				  int num)
+{
+	struct cami2c *id = adap->algo_data;
+	int i, retr;
+
+	if (sh7760_i2c_busy_check(id)) {
+		dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr);
+		return -EBUSY;
+	}
+
+	i = 0;
+	while (i < num) {
+		retr = adap->retries;
+retry:
+		id->flags = ((i == (num-1)) ? IDF_STOP : 0);
+		id->status = 0;
+		id->msg = msgs;
+		init_completion(&id->xfer_done);
+
+		if (msgs->flags & I2C_M_RD)
+			sh7760_i2c_mrecv(id);
+		else
+			sh7760_i2c_msend(id);
+
+		wait_for_completion(&id->xfer_done);
+
+		if (id->status == 0) {
+			num = -EIO;
+			break;
+		}
+
+		if (id->status & IDS_NACK) {
+			/* wait a bit or i2c module stops working */
+			mdelay(1);
+			num = -EREMOTEIO;
+			break;
+		}
+
+		if (id->status & IDS_ARBLOST) {
+			if (retr--) {
+				mdelay(2);
+				goto retry;
+			}
+			num = -EREMOTEIO;
+			break;
+		}
+
+		msgs++;
+		i++;
+	}
+
+	id->msg = NULL;
+	id->flags = 0;
+	id->status = 0;
+
+	OUT32(id, I2CMCR, 0);
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMIER, 0);
+	OUT32(id, I2CFIER, 0);
+
+	/* reset slave module registers too: master mode enables slave
+	 * module for receive ops (ack, data). Without this reset,
+	 * eternal bus activity might be reported after NACK / ARBLOST.
+	 */
+	OUT32(id, I2CSCR, 0);
+	OUT32(id, I2CSAR, 0);
+	OUT32(id, I2CSSR, 0);
+
+	return num;
+}
+
+static u32 sh7760_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+static const struct i2c_algorithm sh7760_i2c_algo = {
+	.master_xfer	= sh7760_i2c_master_xfer,
+	.functionality	= sh7760_i2c_func,
+};
+
+/* calculate CCR register setting for a desired scl clock.  SCL clock is
+ * derived from I2C module clock  (iclk)  which in turn is derived from
+ * peripheral module clock (mclk, usually around 33MHz):
+ * iclk = mclk/(CDF + 1).  iclk must be < 20MHz.
+ * scl = iclk/(SCGD*8 + 20).
+ */
+static int __devinit calc_CCR(unsigned long scl_hz)
+{
+	struct clk *mclk;
+	unsigned long mck, m1, dff, odff, iclk;
+	signed char cdf, cdfm;
+	int scgd, scgdm, scgds;
+
+	mclk = clk_get(NULL, "module_clk");
+	if (IS_ERR(mclk)) {
+		return PTR_ERR(mclk);
+	} else {
+		mck = mclk->rate;
+		clk_put(mclk);
+	}
+
+	odff = scl_hz;
+	scgdm = cdfm = m1 = 0;
+	for (cdf = 3; cdf >= 0; cdf--) {
+		iclk = mck / (1 + cdf);
+		if (iclk >= 20000000)
+			continue;
+		scgds = ((iclk / scl_hz) - 20) >> 3;
+		for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) {
+			m1 = iclk / (20 + (scgd << 3));
+			dff = abs(scl_hz - m1);
+			if (dff < odff) {
+				odff = dff;
+				cdfm = cdf;
+				scgdm = scgd;
+			}
+		}
+	}
+	/* fail if more than 25% off of requested SCL */
+	if (odff > (scl_hz >> 2))
+		return -EINVAL;
+
+	/* create a CCR register value */
+	return ((scgdm << 2) | cdfm);
+}
+
+static int __devinit sh7760_i2c_probe(struct platform_device *pdev)
+{
+	struct sh7760_i2c_platdata *pd;
+	struct resource *res;
+	struct cami2c *id;
+	int ret;
+
+	pd = pdev->dev.platform_data;
+	if (!pd) {
+		dev_err(&pdev->dev, "no platform_data!\n");
+		ret = -ENODEV;
+		goto out0;
+	}
+
+	id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
+	if (!id) {
+		dev_err(&pdev->dev, "no mem for private data\n");
+		ret = -ENOMEM;
+		goto out0;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no mmio resources\n");
+		ret = -ENODEV;
+		goto out1;
+	}
+
+	id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name);
+	if (!id->ioarea) {
+		dev_err(&pdev->dev, "mmio already reserved\n");
+		ret = -EBUSY;
+		goto out1;
+	}
+
+	id->iobase = ioremap(res->start, REGSIZE);
+	if (!id->iobase) {
+		dev_err(&pdev->dev, "cannot ioremap\n");
+		ret = -ENODEV;
+		goto out2;
+	}
+
+	id->irq = platform_get_irq(pdev, 0);
+
+	id->adap.nr = pdev->id;
+	id->adap.algo = &sh7760_i2c_algo;
+	id->adap.class = I2C_CLASS_ALL;
+	id->adap.retries = 3;
+	id->adap.algo_data = id;
+	id->adap.dev.parent = &pdev->dev;
+	snprintf(id->adap.name, sizeof(id->adap.name),
+		"SH7760 I2C at %08lx", (unsigned long)res->start);
+
+	OUT32(id, I2CMCR, 0);
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMIER, 0);
+	OUT32(id, I2CMAR, 0);
+	OUT32(id, I2CSIER, 0);
+	OUT32(id, I2CSAR, 0);
+	OUT32(id, I2CSCR, 0);
+	OUT32(id, I2CSSR, 0);
+	OUT32(id, I2CFIER, 0);
+	OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+	OUT32(id, I2CFSR, 0);
+
+	ret = calc_CCR(pd->speed_khz * 1000);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n",
+			pd->speed_khz);
+		goto out3;
+	}
+	OUT32(id, I2CCCR, ret);
+
+	if (request_irq(id->irq, sh7760_i2c_irq, IRQF_DISABLED,
+			SH7760_I2C_DEVNAME, id)) {
+		dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
+		ret = -EBUSY;
+		goto out3;
+	}
+
+	ret = i2c_add_numbered_adapter(&id->adap);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
+		goto out4;
+	}
+
+	platform_set_drvdata(pdev, id);
+
+	dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n",
+		 pd->speed_khz, res->start, id->irq);
+
+	return 0;
+
+out4:
+	free_irq(id->irq, id);
+out3:
+	iounmap(id->iobase);
+out2:
+	release_resource(id->ioarea);
+	kfree(id->ioarea);
+out1:
+	kfree(id);
+out0:
+	return ret;
+}
+
+static int __devexit sh7760_i2c_remove(struct platform_device *pdev)
+{
+	struct cami2c *id = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&id->adap);
+	free_irq(id->irq, id);
+	iounmap(id->iobase);
+	release_resource(id->ioarea);
+	kfree(id->ioarea);
+	kfree(id);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver sh7760_i2c_drv = {
+	.driver	= {
+		.name	= SH7760_I2C_DEVNAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sh7760_i2c_probe,
+	.remove		= __devexit_p(sh7760_i2c_remove),
+};
+
+static int __init sh7760_i2c_init(void)
+{
+	return platform_driver_register(&sh7760_i2c_drv);
+}
+
+static void __exit sh7760_i2c_exit(void)
+{
+	platform_driver_unregister(&sh7760_i2c_drv);
+}
+
+module_init(sh7760_i2c_init);
+module_exit(sh7760_i2c_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SH7760 I2C bus driver");
+MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");

+ 500 - 0
drivers/i2c/busses/i2c-sh_mobile.c

@@ -0,0 +1,500 @@
+/*
+ * SuperH Mobile I2C Controller
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Portions of the code based on out-of-tree driver i2c-sh7343.c
+ * Copyright (c) 2006 Carlos Munoz <carlos@kenati.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+enum sh_mobile_i2c_op {
+	OP_START = 0,
+	OP_TX_ONLY,
+	OP_TX_STOP,
+	OP_TX_TO_RX,
+	OP_RX_ONLY,
+	OP_RX_STOP,
+};
+
+struct sh_mobile_i2c_data {
+	struct device *dev;
+	void __iomem *reg;
+	struct i2c_adapter adap;
+
+	struct clk *clk;
+	u_int8_t iccl;
+	u_int8_t icch;
+
+	spinlock_t lock;
+	wait_queue_head_t wait;
+	struct i2c_msg *msg;
+	int pos;
+	int sr;
+};
+
+#define NORMAL_SPEED		100000 /* FAST_SPEED 400000 */
+
+/* Register offsets */
+#define ICDR(pd)		(pd->reg + 0x00)
+#define ICCR(pd)		(pd->reg + 0x04)
+#define ICSR(pd)		(pd->reg + 0x08)
+#define ICIC(pd)		(pd->reg + 0x0c)
+#define ICCL(pd)		(pd->reg + 0x10)
+#define ICCH(pd)		(pd->reg + 0x14)
+
+/* Register bits */
+#define ICCR_ICE		0x80
+#define ICCR_RACK		0x40
+#define ICCR_TRS		0x10
+#define ICCR_BBSY		0x04
+#define ICCR_SCP		0x01
+
+#define ICSR_SCLM		0x80
+#define ICSR_SDAM		0x40
+#define SW_DONE			0x20
+#define ICSR_BUSY		0x10
+#define ICSR_AL			0x08
+#define ICSR_TACK		0x04
+#define ICSR_WAIT		0x02
+#define ICSR_DTE		0x01
+
+#define ICIC_ALE		0x08
+#define ICIC_TACKE		0x04
+#define ICIC_WAITE		0x02
+#define ICIC_DTEE		0x01
+
+static void activate_ch(struct sh_mobile_i2c_data *pd)
+{
+	/* Make sure the clock is enabled */
+	clk_enable(pd->clk);
+
+	/* Enable channel and configure rx ack */
+	iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
+
+	/* Mask all interrupts */
+	iowrite8(0, ICIC(pd));
+
+	/* Set the clock */
+	iowrite8(pd->iccl, ICCL(pd));
+	iowrite8(pd->icch, ICCH(pd));
+}
+
+static void deactivate_ch(struct sh_mobile_i2c_data *pd)
+{
+	/* Clear/disable interrupts */
+	iowrite8(0, ICSR(pd));
+	iowrite8(0, ICIC(pd));
+
+	/* Disable channel */
+	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
+
+	/* Disable clock */
+	clk_disable(pd->clk);
+}
+
+static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
+			    enum sh_mobile_i2c_op op, unsigned char data)
+{
+	unsigned char ret = 0;
+	unsigned long flags;
+
+	dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data);
+
+	spin_lock_irqsave(&pd->lock, flags);
+
+	switch (op) {
+	case OP_START:
+		iowrite8(0x94, ICCR(pd));
+		break;
+	case OP_TX_ONLY:
+		iowrite8(data, ICDR(pd));
+		break;
+	case OP_TX_STOP:
+		iowrite8(data, ICDR(pd));
+		iowrite8(0x90, ICCR(pd));
+		iowrite8(ICIC_ALE | ICIC_TACKE, ICIC(pd));
+		break;
+	case OP_TX_TO_RX:
+		iowrite8(data, ICDR(pd));
+		iowrite8(0x81, ICCR(pd));
+		break;
+	case OP_RX_ONLY:
+		ret = ioread8(ICDR(pd));
+		break;
+	case OP_RX_STOP:
+		ret = ioread8(ICDR(pd));
+		iowrite8(0xc0, ICCR(pd));
+		break;
+	}
+
+	spin_unlock_irqrestore(&pd->lock, flags);
+
+	dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret);
+	return ret;
+}
+
+static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
+{
+	struct platform_device *dev = dev_id;
+	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+	struct i2c_msg *msg = pd->msg;
+	unsigned char data, sr;
+	int wakeup = 0;
+
+	sr = ioread8(ICSR(pd));
+	pd->sr |= sr;
+
+	dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
+	       (msg->flags & I2C_M_RD) ? "read" : "write",
+	       pd->pos, msg->len);
+
+	if (sr & (ICSR_AL | ICSR_TACK)) {
+		iowrite8(0, ICIC(pd)); /* disable interrupts */
+		wakeup = 1;
+		goto do_wakeup;
+	}
+
+	if (pd->pos == msg->len) {
+		i2c_op(pd, OP_RX_ONLY, 0);
+		wakeup = 1;
+		goto do_wakeup;
+	}
+
+	if (pd->pos == -1) {
+		data = (msg->addr & 0x7f) << 1;
+		data |= (msg->flags & I2C_M_RD) ? 1 : 0;
+	} else
+		data = msg->buf[pd->pos];
+
+	if ((pd->pos == -1) || !(msg->flags & I2C_M_RD)) {
+		if (msg->flags & I2C_M_RD)
+			i2c_op(pd, OP_TX_TO_RX, data);
+		else if (pd->pos == (msg->len - 1)) {
+			i2c_op(pd, OP_TX_STOP, data);
+			wakeup = 1;
+		} else
+			i2c_op(pd, OP_TX_ONLY, data);
+	} else {
+		if (pd->pos == (msg->len - 1))
+			data = i2c_op(pd, OP_RX_STOP, 0);
+		else
+			data = i2c_op(pd, OP_RX_ONLY, 0);
+
+		msg->buf[pd->pos] = data;
+	}
+	pd->pos++;
+
+ do_wakeup:
+	if (wakeup) {
+		pd->sr |= SW_DONE;
+		wake_up(&pd->wait);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
+{
+	/* Initialize channel registers */
+	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
+
+	/* Enable channel and configure rx ack */
+	iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
+
+	/* Set the clock */
+	iowrite8(pd->iccl, ICCL(pd));
+	iowrite8(pd->icch, ICCH(pd));
+
+	pd->msg = usr_msg;
+	pd->pos = -1;
+	pd->sr = 0;
+
+	/* Enable all interrupts except wait */
+	iowrite8(ioread8(ICIC(pd)) | ICIC_ALE | ICIC_TACKE | ICIC_DTEE,
+		 ICIC(pd));
+	return 0;
+}
+
+static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
+			      struct i2c_msg *msgs,
+			      int num)
+{
+	struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
+	struct i2c_msg	*msg;
+	int err = 0;
+	u_int8_t val;
+	int i, k, retry_count;
+
+	activate_ch(pd);
+
+	/* Process all messages */
+	for (i = 0; i < num; i++) {
+		msg = &msgs[i];
+
+		err = start_ch(pd, msg);
+		if (err)
+			break;
+
+		i2c_op(pd, OP_START, 0);
+
+		/* The interrupt handler takes care of the rest... */
+		k = wait_event_timeout(pd->wait,
+				       pd->sr & (ICSR_TACK | SW_DONE),
+				       5 * HZ);
+		if (!k)
+			dev_err(pd->dev, "Transfer request timed out\n");
+
+		retry_count = 10;
+again:
+		val = ioread8(ICSR(pd));
+
+		dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
+
+		if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
+			err = -EIO;
+			break;
+		}
+
+		/* the interrupt handler may wake us up before the
+		 * transfer is finished, so poll the hardware
+		 * until we're done.
+		 */
+
+		if (!(!(val & ICSR_BUSY) && (val & ICSR_SCLM) &&
+		      (val & ICSR_SDAM))) {
+			msleep(1);
+			if (retry_count--)
+				goto again;
+
+			err = -EIO;
+			dev_err(pd->dev, "Polling timed out\n");
+			break;
+		}
+	}
+
+	deactivate_ch(pd);
+
+	if (!err)
+		err = num;
+	return err;
+}
+
+static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm sh_mobile_i2c_algorithm = {
+	.functionality	= sh_mobile_i2c_func,
+	.master_xfer	= sh_mobile_i2c_xfer,
+};
+
+static void sh_mobile_i2c_setup_channel(struct platform_device *dev)
+{
+	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+	unsigned long peripheral_clk = clk_get_rate(pd->clk);
+	u_int32_t num;
+	u_int32_t denom;
+	u_int32_t tmp;
+
+	spin_lock_init(&pd->lock);
+	init_waitqueue_head(&pd->wait);
+
+	/* Calculate the value for iccl. From the data sheet:
+	 * iccl = (p clock / transfer rate) * (L / (L + H))
+	 * where L and H are the SCL low/high ratio (5/4 in this case).
+	 * We also round off the result.
+	 */
+	num = peripheral_clk * 5;
+	denom = NORMAL_SPEED * 9;
+	tmp = num * 10 / denom;
+	if (tmp % 10 >= 5)
+		pd->iccl = (u_int8_t)((num/denom) + 1);
+	else
+		pd->iccl = (u_int8_t)(num/denom);
+
+	/* Calculate the value for icch. From the data sheet:
+	   icch = (p clock / transfer rate) * (H / (L + H)) */
+	num = peripheral_clk * 4;
+	tmp = num * 10 / denom;
+	if (tmp % 10 >= 5)
+		pd->icch = (u_int8_t)((num/denom) + 1);
+	else
+		pd->icch = (u_int8_t)(num/denom);
+}
+
+static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
+{
+	struct resource *res;
+	int ret = -ENXIO;
+	int q, m;
+	int k = 0;
+	int n = 0;
+
+	while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
+		for (n = res->start; hook && n <= res->end; n++) {
+			if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED,
+					dev->dev.bus_id, dev))
+				goto rollback;
+		}
+		k++;
+	}
+
+	if (hook)
+		return k > 0 ? 0 : -ENOENT;
+
+	k--;
+	ret = 0;
+
+ rollback:
+	for (q = k; k >= 0; k--) {
+		for (m = n; m >= res->start; m--)
+			free_irq(m, dev);
+
+		res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1);
+		m = res->end;
+	}
+
+	return ret;
+}
+
+static int sh_mobile_i2c_probe(struct platform_device *dev)
+{
+	struct sh_mobile_i2c_data *pd;
+	struct i2c_adapter *adap;
+	struct resource *res;
+	int size;
+	int ret;
+
+	pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL);
+	if (pd == NULL) {
+		dev_err(&dev->dev, "cannot allocate private data\n");
+		return -ENOMEM;
+	}
+
+	pd->clk = clk_get(&dev->dev, "peripheral_clk");
+	if (IS_ERR(pd->clk)) {
+		dev_err(&dev->dev, "cannot get peripheral clock\n");
+		ret = PTR_ERR(pd->clk);
+		goto err;
+	}
+
+	ret = sh_mobile_i2c_hook_irqs(dev, 1);
+	if (ret) {
+		dev_err(&dev->dev, "cannot request IRQ\n");
+		goto err_clk;
+	}
+
+	pd->dev = &dev->dev;
+	platform_set_drvdata(dev, pd);
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&dev->dev, "cannot find IO resource\n");
+		ret = -ENOENT;
+		goto err_irq;
+	}
+
+	size = (res->end - res->start) + 1;
+
+	pd->reg = ioremap(res->start, size);
+	if (pd->reg == NULL) {
+		dev_err(&dev->dev, "cannot map IO\n");
+		ret = -ENXIO;
+		goto err_irq;
+	}
+
+	/* setup the private data */
+	adap = &pd->adap;
+	i2c_set_adapdata(adap, pd);
+
+	adap->owner = THIS_MODULE;
+	adap->algo = &sh_mobile_i2c_algorithm;
+	adap->dev.parent = &dev->dev;
+	adap->retries = 5;
+	adap->nr = dev->id;
+
+	strlcpy(adap->name, dev->name, sizeof(adap->name));
+
+	sh_mobile_i2c_setup_channel(dev);
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret < 0) {
+		dev_err(&dev->dev, "cannot add numbered adapter\n");
+		goto err_all;
+	}
+
+	return 0;
+
+ err_all:
+	iounmap(pd->reg);
+ err_irq:
+	sh_mobile_i2c_hook_irqs(dev, 0);
+ err_clk:
+	clk_put(pd->clk);
+ err:
+	kfree(pd);
+	return ret;
+}
+
+static int sh_mobile_i2c_remove(struct platform_device *dev)
+{
+	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+
+	i2c_del_adapter(&pd->adap);
+	iounmap(pd->reg);
+	sh_mobile_i2c_hook_irqs(dev, 0);
+	clk_put(pd->clk);
+	kfree(pd);
+	return 0;
+}
+
+static struct platform_driver sh_mobile_i2c_driver = {
+	.driver		= {
+		.name		= "i2c-sh_mobile",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= sh_mobile_i2c_probe,
+	.remove		= sh_mobile_i2c_remove,
+};
+
+static int __init sh_mobile_i2c_adap_init(void)
+{
+	return platform_driver_register(&sh_mobile_i2c_driver);
+}
+
+static void __exit sh_mobile_i2c_adap_exit(void)
+{
+	platform_driver_unregister(&sh_mobile_i2c_driver);
+}
+
+module_init(sh_mobile_i2c_adap_init);
+module_exit(sh_mobile_i2c_adap_exit);
+
+MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL v2");

+ 3 - 0
drivers/i2c/busses/i2c-simtec.c

@@ -159,6 +159,9 @@ static int simtec_i2c_remove(struct platform_device *dev)
 
 
 /* device driver */
 /* device driver */
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:simtec-i2c");
+
 static struct platform_driver simtec_i2c_driver = {
 static struct platform_driver simtec_i2c_driver = {
 	.driver		= {
 	.driver		= {
 		.name		= "simtec-i2c",
 		.name		= "simtec-i2c",

+ 1 - 0
drivers/i2c/busses/i2c-versatile.c

@@ -151,3 +151,4 @@ module_exit(i2c_versatile_exit);
 
 
 MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
 MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:versatile-i2c");

+ 1 - 1
drivers/i2c/busses/scx200_acb.c

@@ -527,7 +527,7 @@ static int __init scx200_create_isa(const char *text, unsigned long base,
 	if (iface == NULL)
 	if (iface == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	if (request_region(base, 8, iface->adapter.name) == 0) {
+	if (!request_region(base, 8, iface->adapter.name)) {
 		printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
 		printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
 		       base, base + 8 - 1);
 		       base, base + 8 - 1);
 		rc = -EBUSY;
 		rc = -EBUSY;

+ 14 - 14
drivers/i2c/chips/isp1301_omap.c

@@ -658,7 +658,7 @@ pulldown:
 		OTG_CTRL_REG |= OTG_PULLUP;
 		OTG_CTRL_REG |= OTG_PULLUP;
 	}
 	}
 
 
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	dump_regs(isp, "otg->isp1301");
 	dump_regs(isp, "otg->isp1301");
 }
 }
 
 
@@ -782,7 +782,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
 		if (otg_ctrl & OTG_DRIVER_SEL) {
 		if (otg_ctrl & OTG_DRIVER_SEL) {
 			switch (isp->otg.state) {
 			switch (isp->otg.state) {
 			case OTG_STATE_A_IDLE:
 			case OTG_STATE_A_IDLE:
-				b_idle(isp, __FUNCTION__);
+				b_idle(isp, __func__);
 				break;
 				break;
 			default:
 			default:
 				break;
 				break;
@@ -826,7 +826,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
 						isp->otg.host->otg_port);
 						isp->otg.host->otg_port);
 	}
 	}
 
 
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -837,7 +837,7 @@ static int otg_init(struct isp1301 *isp)
 	if (!otg_dev)
 	if (!otg_dev)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 	/* some of these values are board-specific... */
 	/* some of these values are board-specific... */
 	OTG_SYSCON_2_REG |= OTG_EN
 	OTG_SYSCON_2_REG |= OTG_EN
 		/* for B-device: */
 		/* for B-device: */
@@ -853,9 +853,9 @@ static int otg_init(struct isp1301 *isp)
 	update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
 	update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
 	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
 	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
 
 
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	pr_debug("otg: %s, %s %06x\n",
 	pr_debug("otg: %s, %s %06x\n",
-			state_name(isp), __FUNCTION__, OTG_CTRL_REG);
+			state_name(isp), __func__, OTG_CTRL_REG);
 
 
 	OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
 	OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
 			| B_SRP_TMROUT | B_HNP_FAIL
 			| B_SRP_TMROUT | B_HNP_FAIL
@@ -1041,11 +1041,11 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
 						OTG1_DP_PULLDOWN);
 						OTG1_DP_PULLDOWN);
 			isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
 			isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
 						OTG1_DP_PULLUP);
 						OTG1_DP_PULLUP);
-			dump_regs(isp, __FUNCTION__);
+			dump_regs(isp, __func__);
 #endif
 #endif
 			/* FALLTHROUGH */
 			/* FALLTHROUGH */
 		case OTG_STATE_B_SRP_INIT:
 		case OTG_STATE_B_SRP_INIT:
-			b_idle(isp, __FUNCTION__);
+			b_idle(isp, __func__);
 			OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
 			OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
 			/* FALLTHROUGH */
 			/* FALLTHROUGH */
 		case OTG_STATE_B_IDLE:
 		case OTG_STATE_B_IDLE:
@@ -1077,7 +1077,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
 	 */
 	 */
 	update_otg1(isp, isp_stat);
 	update_otg1(isp, isp_stat);
 	update_otg2(isp, isp_bstat);
 	update_otg2(isp, isp_bstat);
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 #endif
 #endif
 
 
 	dump_regs(isp, "isp1301->otg");
 	dump_regs(isp, "isp1301->otg");
@@ -1310,7 +1310,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
 	 */
 	 */
 	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV);
 	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV);
 
 
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 
 
 	return 0;
 	return 0;
 
 
@@ -1365,7 +1365,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
 	isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
 	isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
 		INTR_VBUS_VLD);
 		INTR_VBUS_VLD);
 	dev_info(&isp->client.dev, "B-Peripheral sessions ok\n");
 	dev_info(&isp->client.dev, "B-Peripheral sessions ok\n");
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 
 
 	/* If this has a Mini-AB connector, this mode is highly
 	/* If this has a Mini-AB connector, this mode is highly
 	 * nonstandard ... but can be handy for testing, so long
 	 * nonstandard ... but can be handy for testing, so long
@@ -1416,7 +1416,7 @@ isp1301_start_srp(struct otg_transceiver *dev)
 
 
 	pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG);
 	pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG);
 #ifdef	CONFIG_USB_OTG
 #ifdef	CONFIG_USB_OTG
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 #endif
 #endif
 	return 0;
 	return 0;
 }
 }
@@ -1463,7 +1463,7 @@ isp1301_start_hnp(struct otg_transceiver *dev)
 	}
 	}
 	pr_debug("otg: HNP %s, %06x ...\n",
 	pr_debug("otg: HNP %s, %06x ...\n",
 		state_name(isp), OTG_CTRL_REG);
 		state_name(isp), OTG_CTRL_REG);
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	return 0;
 	return 0;
 #else
 #else
 	/* srp-only */
 	/* srp-only */
@@ -1601,7 +1601,7 @@ fail2:
 	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
 	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
 #endif
 #endif
 
 
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 
 
 #ifdef	VERBOSE
 #ifdef	VERBOSE
 	mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
 	mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);

+ 1 - 1
drivers/i2c/i2c-core.c

@@ -1506,7 +1506,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
 		read_write = I2C_SMBUS_READ;
 		read_write = I2C_SMBUS_READ;
 		if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
 		if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
 			dev_err(&adapter->dev, "%s called with invalid "
 			dev_err(&adapter->dev, "%s called with invalid "
-				"block proc call size (%d)\n", __FUNCTION__,
+				"block proc call size (%d)\n", __func__,
 				data->block[0]);
 				data->block[0]);
 			return -1;
 			return -1;
 		}
 		}

+ 168 - 161
drivers/i2c/i2c-dev.c

@@ -200,16 +200,176 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
 	return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
 	return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
 }
 }
 
 
-static int i2cdev_ioctl(struct inode *inode, struct file *file,
-		unsigned int cmd, unsigned long arg)
+static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+		unsigned long arg)
 {
 {
-	struct i2c_client *client = (struct i2c_client *)file->private_data;
 	struct i2c_rdwr_ioctl_data rdwr_arg;
 	struct i2c_rdwr_ioctl_data rdwr_arg;
-	struct i2c_smbus_ioctl_data data_arg;
-	union i2c_smbus_data temp;
 	struct i2c_msg *rdwr_pa;
 	struct i2c_msg *rdwr_pa;
 	u8 __user **data_ptrs;
 	u8 __user **data_ptrs;
-	int i,datasize,res;
+	int i, res;
+
+	if (copy_from_user(&rdwr_arg,
+			   (struct i2c_rdwr_ioctl_data __user *)arg,
+			   sizeof(rdwr_arg)))
+		return -EFAULT;
+
+	/* Put an arbitrary limit on the number of messages that can
+	 * be sent at once */
+	if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
+		return -EINVAL;
+
+	rdwr_pa = (struct i2c_msg *)
+		kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
+		GFP_KERNEL);
+	if (!rdwr_pa)
+		return -ENOMEM;
+
+	if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
+			   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
+		kfree(rdwr_pa);
+		return -EFAULT;
+	}
+
+	data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
+	if (data_ptrs == NULL) {
+		kfree(rdwr_pa);
+		return -ENOMEM;
+	}
+
+	res = 0;
+	for (i = 0; i < rdwr_arg.nmsgs; i++) {
+		/* Limit the size of the message to a sane amount;
+		 * and don't let length change either. */
+		if ((rdwr_pa[i].len > 8192) ||
+		    (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
+			res = -EINVAL;
+			break;
+		}
+		data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
+		rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
+		if (rdwr_pa[i].buf == NULL) {
+			res = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
+				   rdwr_pa[i].len)) {
+				++i; /* Needs to be kfreed too */
+				res = -EFAULT;
+			break;
+		}
+	}
+	if (res < 0) {
+		int j;
+		for (j = 0; j < i; ++j)
+			kfree(rdwr_pa[j].buf);
+		kfree(data_ptrs);
+		kfree(rdwr_pa);
+		return res;
+	}
+
+	res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
+	while (i-- > 0) {
+		if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
+			if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
+					 rdwr_pa[i].len))
+				res = -EFAULT;
+		}
+		kfree(rdwr_pa[i].buf);
+	}
+	kfree(data_ptrs);
+	kfree(rdwr_pa);
+	return res;
+}
+
+static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+		unsigned long arg)
+{
+	struct i2c_smbus_ioctl_data data_arg;
+	union i2c_smbus_data temp;
+	int datasize, res;
+
+	if (copy_from_user(&data_arg,
+			   (struct i2c_smbus_ioctl_data __user *) arg,
+			   sizeof(struct i2c_smbus_ioctl_data)))
+		return -EFAULT;
+	if ((data_arg.size != I2C_SMBUS_BYTE) &&
+	    (data_arg.size != I2C_SMBUS_QUICK) &&
+	    (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
+	    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
+	    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
+	    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
+	    (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
+	    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
+	    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
+		dev_dbg(&client->adapter->dev,
+			"size out of range (%x) in ioctl I2C_SMBUS.\n",
+			data_arg.size);
+		return -EINVAL;
+	}
+	/* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
+	   so the check is valid if size==I2C_SMBUS_QUICK too. */
+	if ((data_arg.read_write != I2C_SMBUS_READ) &&
+	    (data_arg.read_write != I2C_SMBUS_WRITE)) {
+		dev_dbg(&client->adapter->dev,
+			"read_write out of range (%x) in ioctl I2C_SMBUS.\n",
+			data_arg.read_write);
+		return -EINVAL;
+	}
+
+	/* Note that command values are always valid! */
+
+	if ((data_arg.size == I2C_SMBUS_QUICK) ||
+	    ((data_arg.size == I2C_SMBUS_BYTE) &&
+	    (data_arg.read_write == I2C_SMBUS_WRITE)))
+		/* These are special: we do not use data */
+		return i2c_smbus_xfer(client->adapter, client->addr,
+				      client->flags, data_arg.read_write,
+				      data_arg.command, data_arg.size, NULL);
+
+	if (data_arg.data == NULL) {
+		dev_dbg(&client->adapter->dev,
+			"data is NULL pointer in ioctl I2C_SMBUS.\n");
+		return -EINVAL;
+	}
+
+	if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
+	    (data_arg.size == I2C_SMBUS_BYTE))
+		datasize = sizeof(data_arg.data->byte);
+	else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
+		 (data_arg.size == I2C_SMBUS_PROC_CALL))
+		datasize = sizeof(data_arg.data->word);
+	else /* size == smbus block, i2c block, or block proc. call */
+		datasize = sizeof(data_arg.data->block);
+
+	if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+	    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+	    (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
+	    (data_arg.read_write == I2C_SMBUS_WRITE)) {
+		if (copy_from_user(&temp, data_arg.data, datasize))
+			return -EFAULT;
+	}
+	if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
+		/* Convert old I2C block commands to the new
+		   convention. This preserves binary compatibility. */
+		data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
+		if (data_arg.read_write == I2C_SMBUS_READ)
+			temp.block[0] = I2C_SMBUS_BLOCK_MAX;
+	}
+	res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+	      data_arg.read_write, data_arg.command, data_arg.size, &temp);
+	if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+		     (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+		     (data_arg.read_write == I2C_SMBUS_READ))) {
+		if (copy_to_user(data_arg.data, &temp, datasize))
+			return -EFAULT;
+	}
+	return res;
+}
+
+static int i2cdev_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	struct i2c_client *client = (struct i2c_client *)file->private_data;
 	unsigned long funcs;
 	unsigned long funcs;
 
 
 	dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
 	dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
@@ -253,164 +413,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
 		return put_user(funcs, (unsigned long __user *)arg);
 		return put_user(funcs, (unsigned long __user *)arg);
 
 
 	case I2C_RDWR:
 	case I2C_RDWR:
-		if (copy_from_user(&rdwr_arg,
-				   (struct i2c_rdwr_ioctl_data __user *)arg,
-				   sizeof(rdwr_arg)))
-			return -EFAULT;
-
-		/* Put an arbitrary limit on the number of messages that can
-		 * be sent at once */
-		if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
-			return -EINVAL;
-
-		rdwr_pa = (struct i2c_msg *)
-			kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
-			GFP_KERNEL);
-
-		if (rdwr_pa == NULL) return -ENOMEM;
-
-		if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
-				   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
-			kfree(rdwr_pa);
-			return -EFAULT;
-		}
-
-		data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
-		if (data_ptrs == NULL) {
-			kfree(rdwr_pa);
-			return -ENOMEM;
-		}
-
-		res = 0;
-		for( i=0; i<rdwr_arg.nmsgs; i++ ) {
-			/* Limit the size of the message to a sane amount;
-			 * and don't let length change either. */
-			if ((rdwr_pa[i].len > 8192) ||
-			    (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
-				res = -EINVAL;
-				break;
-			}
-			data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
-			rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
-			if(rdwr_pa[i].buf == NULL) {
-				res = -ENOMEM;
-				break;
-			}
-			if(copy_from_user(rdwr_pa[i].buf,
-				data_ptrs[i],
-				rdwr_pa[i].len)) {
-					++i; /* Needs to be kfreed too */
-					res = -EFAULT;
-				break;
-			}
-		}
-		if (res < 0) {
-			int j;
-			for (j = 0; j < i; ++j)
-				kfree(rdwr_pa[j].buf);
-			kfree(data_ptrs);
-			kfree(rdwr_pa);
-			return res;
-		}
-
-		res = i2c_transfer(client->adapter,
-			rdwr_pa,
-			rdwr_arg.nmsgs);
-		while(i-- > 0) {
-			if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
-				if(copy_to_user(
-					data_ptrs[i],
-					rdwr_pa[i].buf,
-					rdwr_pa[i].len)) {
-					res = -EFAULT;
-				}
-			}
-			kfree(rdwr_pa[i].buf);
-		}
-		kfree(data_ptrs);
-		kfree(rdwr_pa);
-		return res;
+		return i2cdev_ioctl_rdrw(client, arg);
 
 
 	case I2C_SMBUS:
 	case I2C_SMBUS:
-		if (copy_from_user(&data_arg,
-		                   (struct i2c_smbus_ioctl_data __user *) arg,
-		                   sizeof(struct i2c_smbus_ioctl_data)))
-			return -EFAULT;
-		if ((data_arg.size != I2C_SMBUS_BYTE) &&
-		    (data_arg.size != I2C_SMBUS_QUICK) &&
-		    (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
-		    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
-		    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
-		    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
-		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
-		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
-		    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
-			dev_dbg(&client->adapter->dev,
-				"size out of range (%x) in ioctl I2C_SMBUS.\n",
-				data_arg.size);
-			return -EINVAL;
-		}
-		/* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
-		   so the check is valid if size==I2C_SMBUS_QUICK too. */
-		if ((data_arg.read_write != I2C_SMBUS_READ) &&
-		    (data_arg.read_write != I2C_SMBUS_WRITE)) {
-			dev_dbg(&client->adapter->dev,
-				"read_write out of range (%x) in ioctl I2C_SMBUS.\n",
-				data_arg.read_write);
-			return -EINVAL;
-		}
-
-		/* Note that command values are always valid! */
-
-		if ((data_arg.size == I2C_SMBUS_QUICK) ||
-		    ((data_arg.size == I2C_SMBUS_BYTE) &&
-		    (data_arg.read_write == I2C_SMBUS_WRITE)))
-			/* These are special: we do not use data */
-			return i2c_smbus_xfer(client->adapter, client->addr,
-					      client->flags,
-					      data_arg.read_write,
-					      data_arg.command,
-					      data_arg.size, NULL);
-
-		if (data_arg.data == NULL) {
-			dev_dbg(&client->adapter->dev,
-				"data is NULL pointer in ioctl I2C_SMBUS.\n");
-			return -EINVAL;
-		}
+		return i2cdev_ioctl_smbus(client, arg);
 
 
-		if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
-		    (data_arg.size == I2C_SMBUS_BYTE))
-			datasize = sizeof(data_arg.data->byte);
-		else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
-		         (data_arg.size == I2C_SMBUS_PROC_CALL))
-			datasize = sizeof(data_arg.data->word);
-		else /* size == smbus block, i2c block, or block proc. call */
-			datasize = sizeof(data_arg.data->block);
-
-		if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-		    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
-		    (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
-		    (data_arg.read_write == I2C_SMBUS_WRITE)) {
-			if (copy_from_user(&temp, data_arg.data, datasize))
-				return -EFAULT;
-		}
-		if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
-			/* Convert old I2C block commands to the new
-			   convention. This preserves binary compatibility. */
-			data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
-			if (data_arg.read_write == I2C_SMBUS_READ)
-				temp.block[0] = I2C_SMBUS_BLOCK_MAX;
-		}
-		res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-		      data_arg.read_write,
-		      data_arg.command,data_arg.size,&temp);
-		if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-		              (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
-			      (data_arg.read_write == I2C_SMBUS_READ))) {
-			if (copy_to_user(data_arg.data, &temp, datasize))
-				return -EFAULT;
-		}
-		return res;
 	case I2C_RETRIES:
 	case I2C_RETRIES:
 		client->adapter->retries = arg;
 		client->adapter->retries = arg;
 		break;
 		break;

+ 22 - 0
include/asm-sh/i2c-sh7760.h

@@ -0,0 +1,22 @@
+/*
+ * MMIO/IRQ and platform data for SH7760 I2C channels
+ */
+
+#ifndef _I2C_SH7760_H_
+#define _I2C_SH7760_H_
+
+#define SH7760_I2C_DEVNAME	"sh7760-i2c"
+
+#define SH7760_I2C0_MMIO	0xFE140000
+#define SH7760_I2C0_MMIOEND	0xFE14003B
+#define SH7760_I2C0_IRQ		62
+
+#define SH7760_I2C1_MMIO	0xFE150000
+#define SH7760_I2C1_MMIOEND	0xFE15003B
+#define SH7760_I2C1_IRQ		63
+
+struct sh7760_i2c_platdata {
+	unsigned int speed_khz;
+};
+
+#endif

+ 32 - 5
include/linux/i2c-algo-pca.h

@@ -1,14 +1,41 @@
 #ifndef _LINUX_I2C_ALGO_PCA_H
 #ifndef _LINUX_I2C_ALGO_PCA_H
 #define _LINUX_I2C_ALGO_PCA_H
 #define _LINUX_I2C_ALGO_PCA_H
 
 
+/* Clock speeds for the bus */
+#define I2C_PCA_CON_330kHz	0x00
+#define I2C_PCA_CON_288kHz	0x01
+#define I2C_PCA_CON_217kHz	0x02
+#define I2C_PCA_CON_146kHz	0x03
+#define I2C_PCA_CON_88kHz	0x04
+#define I2C_PCA_CON_59kHz	0x05
+#define I2C_PCA_CON_44kHz	0x06
+#define I2C_PCA_CON_36kHz	0x07
+
+/* PCA9564 registers */
+#define I2C_PCA_STA		0x00 /* STATUS  Read Only  */
+#define I2C_PCA_TO		0x00 /* TIMEOUT Write Only */
+#define I2C_PCA_DAT		0x01 /* DATA    Read/Write */
+#define I2C_PCA_ADR		0x02 /* OWN ADR Read/Write */
+#define I2C_PCA_CON		0x03 /* CONTROL Read/Write */
+
+#define I2C_PCA_CON_AA		0x80 /* Assert Acknowledge */
+#define I2C_PCA_CON_ENSIO	0x40 /* Enable */
+#define I2C_PCA_CON_STA		0x20 /* Start */
+#define I2C_PCA_CON_STO		0x10 /* Stop */
+#define I2C_PCA_CON_SI		0x08 /* Serial Interrupt */
+#define I2C_PCA_CON_CR		0x07 /* Clock Rate (MASK) */
+
 struct i2c_algo_pca_data {
 struct i2c_algo_pca_data {
-	int  (*get_own)			(struct i2c_algo_pca_data *adap); /* Obtain own address */
-	int  (*get_clock)		(struct i2c_algo_pca_data *adap);
-	void (*write_byte)		(struct i2c_algo_pca_data *adap, int reg, int val);
-	int  (*read_byte)		(struct i2c_algo_pca_data *adap, int reg);
-	int  (*wait_for_interrupt)	(struct i2c_algo_pca_data *adap);
+	void 				*data;	/* private low level data */
+	void (*write_byte)		(void *data, int reg, int val);
+	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 */
+	unsigned int			i2c_clock;
 };
 };
 
 
 int i2c_pca_add_bus(struct i2c_adapter *);
 int i2c_pca_add_bus(struct i2c_adapter *);
+int i2c_pca_add_numbered_bus(struct i2c_adapter *);
 
 
 #endif /* _LINUX_I2C_ALGO_PCA_H */
 #endif /* _LINUX_I2C_ALGO_PCA_H */

+ 12 - 0
include/linux/i2c-pca-platform.h

@@ -0,0 +1,12 @@
+#ifndef I2C_PCA9564_PLATFORM_H
+#define I2C_PCA9564_PLATFORM_H
+
+struct i2c_pca9564_pf_platform_data {
+	int gpio;		/* pin to reset chip. driver will work when
+				 * 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 */
+};
+
+#endif /* I2C_PCA9564_PLATFORM_H */