Parcourir la source

Merge branch 'for-linus/2639/i2c-2' of git://git.fluff.org/bjdooks/linux

* 'for-linus/2639/i2c-2' of git://git.fluff.org/bjdooks/linux:
  i2c-pxa2xx: Don't clear isr bits too early
  i2c-pxa2xx: Fix register offsets
  i2c-pxa2xx: pass of_node from platform driver to adapter and publish
  i2c-pxa2xx: check timeout correctly
  i2c-pxa2xx: add support for shared IRQ handler
  i2c-pxa2xx: Add PCI support for PXA I2C controller
  ARM: pxa2xx: reorganize I2C files
  i2c-pxa2xx: use dynamic register layout
  i2c-mxs: set controller to pio queue mode after reset
  i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
  i2c/busses: Add support for Diolan U2C-12 USB-I2C adapter
Linus Torvalds il y a 14 ans
Parent
commit
75ea6358bc
48 fichiers modifiés avec 997 ajouts et 148 suppressions
  1. 26 0
      Documentation/i2c/busses/i2c-diolan-u2c
  2. 6 0
      MAINTAINERS
  3. 1 1
      arch/arm/mach-mmp/include/mach/mmp2.h
  4. 1 1
      arch/arm/mach-mmp/include/mach/pxa168.h
  5. 1 1
      arch/arm/mach-mmp/include/mach/pxa910.h
  6. 1 2
      arch/arm/mach-pxa/balloon3.c
  7. 1 1
      arch/arm/mach-pxa/cm-x300.c
  8. 1 2
      arch/arm/mach-pxa/colibri-evalboard.c
  9. 1 2
      arch/arm/mach-pxa/colibri-pxa270-income.c
  10. 1 1
      arch/arm/mach-pxa/corgi.c
  11. 1 1
      arch/arm/mach-pxa/csb726.c
  12. 1 1
      arch/arm/mach-pxa/devices.c
  13. 1 1
      arch/arm/mach-pxa/em-x270.c
  14. 1 1
      arch/arm/mach-pxa/ezx.c
  15. 1 1
      arch/arm/mach-pxa/hx4700.c
  16. 1 1
      arch/arm/mach-pxa/littleton.c
  17. 1 1
      arch/arm/mach-pxa/magician.c
  18. 1 1
      arch/arm/mach-pxa/mainstone.c
  19. 1 1
      arch/arm/mach-pxa/mioa701.c
  20. 1 1
      arch/arm/mach-pxa/mxm8x10.c
  21. 1 2
      arch/arm/mach-pxa/palm27x.c
  22. 1 1
      arch/arm/mach-pxa/pcm990-baseboard.c
  23. 1 1
      arch/arm/mach-pxa/poodle.c
  24. 1 2
      arch/arm/mach-pxa/pxa27x.c
  25. 1 1
      arch/arm/mach-pxa/pxa3xx.c
  26. 1 1
      arch/arm/mach-pxa/pxa95x.c
  27. 1 1
      arch/arm/mach-pxa/raumfeld.c
  28. 1 1
      arch/arm/mach-pxa/saar.c
  29. 1 2
      arch/arm/mach-pxa/saarb.c
  30. 1 2
      arch/arm/mach-pxa/spitz.c
  31. 1 1
      arch/arm/mach-pxa/stargate2.c
  32. 1 2
      arch/arm/mach-pxa/tavorevb3.c
  33. 1 1
      arch/arm/mach-pxa/tosa.c
  34. 1 1
      arch/arm/mach-pxa/trizeps4.c
  35. 1 1
      arch/arm/mach-pxa/viper.c
  36. 1 2
      arch/arm/mach-pxa/vpac270.c
  37. 1 2
      arch/arm/mach-pxa/xcep.c
  38. 1 2
      arch/arm/mach-pxa/z2.c
  39. 1 2
      arch/arm/mach-pxa/zeus.c
  40. 1 1
      arch/arm/mach-pxa/zylonite_pxa300.c
  41. 24 8
      drivers/i2c/busses/Kconfig
  42. 2 0
      drivers/i2c/busses/Makefile
  43. 535 0
      drivers/i2c/busses/i2c-diolan-u2c.c
  44. 99 62
      drivers/i2c/busses/i2c-eg20t.c
  45. 2 2
      drivers/i2c/busses/i2c-mxs.c
  46. 176 0
      drivers/i2c/busses/i2c-pxa-pci.c
  47. 89 26
      drivers/i2c/busses/i2c-pxa.c
  48. 0 0
      include/linux/i2c/pxa-i2c.h

+ 26 - 0
Documentation/i2c/busses/i2c-diolan-u2c

@@ -0,0 +1,26 @@
+Kernel driver i2c-diolan-u2c
+
+Supported adapters:
+  * Diolan U2C-12 I2C-USB adapter
+    Documentation:
+	http://www.diolan.com/i2c/u2c12.html
+
+Author: Guenter Roeck <guenter.roeck@ericsson.com>
+
+Description
+-----------
+
+This is the driver for the Diolan U2C-12 USB-I2C adapter.
+
+The Diolan U2C-12 I2C-USB Adapter provides a low cost solution to connect
+a computer to I2C slave devices using a USB interface. It also supports
+connectivity to SPI devices.
+
+This driver only supports the I2C interface of U2C-12. The driver does not use
+interrupts.
+
+
+Module parameters
+-----------------
+
+* frequency: I2C bus frequency

+ 6 - 0
MAINTAINERS

@@ -2138,6 +2138,12 @@ F:	Documentation/serial/digiepca.txt
 F:	drivers/char/epca*
 F:	drivers/char/epca*
 F:	drivers/char/digi*
 F:	drivers/char/digi*
 
 
+DIOLAN U2C-12 I2C DRIVER
+M:	Guenter Roeck <guenter.roeck@ericsson.com>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	drivers/i2c/busses/i2c-diolan-u2c.c
+
 DIRECTORY NOTIFICATION (DNOTIFY)
 DIRECTORY NOTIFICATION (DNOTIFY)
 M:	Eric Paris <eparis@parisplace.org>
 M:	Eric Paris <eparis@parisplace.org>
 S:	Maintained
 S:	Maintained

+ 1 - 1
arch/arm/mach-mmp/include/mach/mmp2.h

@@ -11,8 +11,8 @@ extern void __init mmp2_init_irq(void);
 extern void mmp2_clear_pmic_int(void);
 extern void mmp2_clear_pmic_int(void);
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <mach/devices.h>
 #include <mach/devices.h>
-#include <plat/i2c.h>
 
 
 extern struct pxa_device_desc mmp2_device_uart1;
 extern struct pxa_device_desc mmp2_device_uart1;
 extern struct pxa_device_desc mmp2_device_uart2;
 extern struct pxa_device_desc mmp2_device_uart2;

+ 1 - 1
arch/arm/mach-mmp/include/mach/pxa168.h

@@ -8,8 +8,8 @@ extern void __init pxa168_init_irq(void);
 extern void pxa168_clear_keypad_wakeup(void);
 extern void pxa168_clear_keypad_wakeup(void);
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <mach/devices.h>
 #include <mach/devices.h>
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 #include <video/pxa168fb.h>
 #include <video/pxa168fb.h>
 #include <plat/pxa27x_keypad.h>
 #include <plat/pxa27x_keypad.h>

+ 1 - 1
arch/arm/mach-mmp/include/mach/pxa910.h

@@ -7,8 +7,8 @@ extern struct sys_timer pxa910_timer;
 extern void __init pxa910_init_irq(void);
 extern void __init pxa910_init_irq(void);
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <mach/devices.h>
 #include <mach/devices.h>
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 
 
 extern struct pxa_device_desc pxa910_device_uart1;
 extern struct pxa_device_desc pxa910_device_uart1;

+ 1 - 2
arch/arm/mach-pxa/balloon3.c

@@ -27,6 +27,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/i2c/pcf857x.h>
 #include <linux/i2c/pcf857x.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/physmap.h>
 #include <linux/regulator/max1586.h>
 #include <linux/regulator/max1586.h>
@@ -51,8 +52,6 @@
 #include <mach/irda.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 
 

+ 1 - 1
arch/arm/mach-pxa/cm-x300.c

@@ -29,6 +29,7 @@
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/i2c/pca953x.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <linux/mfd/da903x.h>
 #include <linux/mfd/da903x.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/machine.h>
@@ -48,7 +49,6 @@
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 #include <mach/audio.h>
 #include <mach/audio.h>
 #include <mach/pxa3xx-u2d.h>
 #include <mach/pxa3xx-u2d.h>

+ 1 - 2
arch/arm/mach-pxa/colibri-evalboard.c

@@ -20,6 +20,7 @@
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <mach/pxa27x.h>
 #include <mach/pxa27x.h>
 #include <mach/colibri.h>
 #include <mach/colibri.h>
@@ -27,8 +28,6 @@
 #include <mach/ohci.h>
 #include <mach/ohci.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/pxa27x-udc.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 
 

+ 1 - 2
arch/arm/mach-pxa/colibri-pxa270-income.c

@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm_backlight.h>
 #include <linux/pwm_backlight.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/sysdev.h>
 #include <linux/sysdev.h>
 
 
 #include <asm/irq.h>
 #include <asm/irq.h>
@@ -33,8 +34,6 @@
 #include <mach/pxa27x-udc.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
 
 
-#include <plat/i2c.h>
-
 #include "devices.h"
 #include "devices.h"
 #include "generic.h"
 #include "generic.h"
 
 

+ 1 - 1
arch/arm/mach-pxa/corgi.c

@@ -24,6 +24,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/backlight.h>
 #include <linux/backlight.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/spi/ads7846.h>
@@ -45,7 +46,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/irq.h>
 
 
 #include <mach/pxa25x.h>
 #include <mach/pxa25x.h>
-#include <plat/i2c.h>
 #include <mach/irda.h>
 #include <mach/irda.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/udc.h>

+ 1 - 1
arch/arm/mach-pxa/csb726.c

@@ -17,12 +17,12 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
 #include <linux/sm501.h>
 #include <linux/sm501.h>
 #include <linux/smsc911x.h>
 #include <linux/smsc911x.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
 #include <mach/csb726.h>
 #include <mach/csb726.h>
 #include <mach/mfp-pxa27x.h>
 #include <mach/mfp-pxa27x.h>
-#include <plat/i2c.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/pxa2xx-regs.h>

+ 1 - 1
arch/arm/mach-pxa/devices.c

@@ -4,6 +4,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/pxa2xx_spi.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/pmu.h>
 #include <asm/pmu.h>
 #include <mach/udc.h>
 #include <mach/udc.h>
@@ -16,7 +17,6 @@
 #include <mach/camera.h>
 #include <mach/camera.h>
 #include <mach/audio.h>
 #include <mach/audio.h>
 #include <mach/hardware.h>
 #include <mach/hardware.h>
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 
 
 #include "devices.h"
 #include "devices.h"

+ 1 - 1
arch/arm/mach-pxa/em-x270.c

@@ -31,6 +31,7 @@
 #include <linux/apm-emulation.h>
 #include <linux/apm-emulation.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/i2c/pca953x.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/regulator/userspace-consumer.h>
 #include <linux/regulator/userspace-consumer.h>
 
 
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>
@@ -45,7 +46,6 @@
 #include <mach/ohci.h>
 #include <mach/ohci.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <plat/pxa27x_keypad.h>
 #include <plat/pxa27x_keypad.h>
-#include <plat/i2c.h>
 #include <mach/camera.h>
 #include <mach/camera.h>
 
 
 #include "generic.h"
 #include "generic.h"

+ 1 - 1
arch/arm/mach-pxa/ezx.c

@@ -20,6 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/gpio_keys.h>
 #include <linux/leds-lp3944.h>
 #include <linux/leds-lp3944.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>
 
 
@@ -30,7 +31,6 @@
 #include <mach/pxa27x.h>
 #include <mach/pxa27x.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>
-#include <plat/i2c.h>
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <plat/pxa27x_keypad.h>
 #include <plat/pxa27x_keypad.h>
 #include <mach/camera.h>
 #include <mach/camera.h>

+ 1 - 1
arch/arm/mach-pxa/hx4700.c

@@ -35,6 +35,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -42,7 +43,6 @@
 
 
 #include <mach/pxa27x.h>
 #include <mach/pxa27x.h>
 #include <mach/hx4700.h>
 #include <mach/hx4700.h>
-#include <plat/i2c.h>
 #include <mach/irda.h>
 #include <mach/irda.h>
 
 
 #include <video/platform_lcd.h>
 #include <video/platform_lcd.h>

+ 1 - 1
arch/arm/mach-pxa/littleton.c

@@ -28,6 +28,7 @@
 #include <linux/leds.h>
 #include <linux/leds.h>
 #include <linux/mfd/da903x.h>
 #include <linux/mfd/da903x.h>
 #include <linux/i2c/max732x.h>
 #include <linux/i2c/max732x.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/types.h>
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
@@ -45,7 +46,6 @@
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <plat/pxa27x_keypad.h>
 #include <plat/pxa27x_keypad.h>
 #include <mach/littleton.h>
 #include <mach/littleton.h>
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 
 
 #include "generic.h"
 #include "generic.h"

+ 1 - 1
arch/arm/mach-pxa/magician.c

@@ -28,6 +28,7 @@
 #include <linux/regulator/bq24022.h>
 #include <linux/regulator/bq24022.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/machine.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -36,7 +37,6 @@
 #include <mach/pxa27x.h>
 #include <mach/pxa27x.h>
 #include <mach/magician.h>
 #include <mach/magician.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
-#include <plat/i2c.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/irda.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>

+ 1 - 1
arch/arm/mach-pxa/mainstone.c

@@ -27,6 +27,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/gpio_keys.h>
 #include <linux/pwm_backlight.h>
 #include <linux/pwm_backlight.h>
 #include <linux/smc91x.h>
 #include <linux/smc91x.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/types.h>
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
@@ -46,7 +47,6 @@
 #include <mach/mainstone.h>
 #include <mach/mainstone.h>
 #include <mach/audio.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
-#include <plat/i2c.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/irda.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>

+ 1 - 1
arch/arm/mach-pxa/mioa701.c

@@ -39,6 +39,7 @@
 #include <linux/usb/gpio_vbus.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/regulator/max1586.h>
 #include <linux/regulator/max1586.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
@@ -50,7 +51,6 @@
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/udc.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/pxa27x-udc.h>
-#include <plat/i2c.h>
 #include <mach/camera.h>
 #include <mach/camera.h>
 #include <mach/audio.h>
 #include <mach/audio.h>
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>

+ 1 - 1
arch/arm/mach-pxa/mxm8x10.c

@@ -22,8 +22,8 @@
 #include <linux/serial_8250.h>
 #include <linux/serial_8250.h>
 #include <linux/dm9000.h>
 #include <linux/dm9000.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 
 
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>

+ 1 - 2
arch/arm/mach-pxa/palm27x.c

@@ -22,6 +22,7 @@
 #include <linux/power_supply.h>
 #include <linux/power_supply.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/regulator/max1586.h>
 #include <linux/regulator/max1586.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
@@ -36,8 +37,6 @@
 #include <mach/palmasoc.h>
 #include <mach/palmasoc.h>
 #include <mach/palm27x.h>
 #include <mach/palm27x.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 
 

+ 1 - 1
arch/arm/mach-pxa/pcm990-baseboard.c

@@ -23,12 +23,12 @@
 #include <linux/irq.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/pwm_backlight.h>
 #include <linux/pwm_backlight.h>
 
 
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>
 
 
 #include <asm/gpio.h>
 #include <asm/gpio.h>
-#include <plat/i2c.h>
 #include <mach/camera.h>
 #include <mach/camera.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <mach/pxa27x.h>
 #include <mach/pxa27x.h>

+ 1 - 1
arch/arm/mach-pxa/poodle.c

@@ -23,6 +23,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/spi/ads7846.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/pxa2xx_spi.h>
@@ -44,7 +45,6 @@
 #include <mach/irda.h>
 #include <mach/irda.h>
 #include <mach/poodle.h>
 #include <mach/poodle.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
-#include <plat/i2c.h>
 
 
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
 #include <asm/hardware/locomo.h>

+ 1 - 2
arch/arm/mach-pxa/pxa27x.c

@@ -19,6 +19,7 @@
 #include <linux/sysdev.h>
 #include <linux/sysdev.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
 #include <mach/hardware.h>
@@ -32,8 +33,6 @@
 #include <mach/dma.h>
 #include <mach/dma.h>
 #include <mach/smemc.h>
 #include <mach/smemc.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 #include "clock.h"
 #include "clock.h"

+ 1 - 1
arch/arm/mach-pxa/pxa3xx.c

@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/sysdev.h>
 #include <linux/sysdev.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
 #include <mach/hardware.h>
@@ -32,7 +33,6 @@
 #include <mach/dma.h>
 #include <mach/dma.h>
 #include <mach/regs-intc.h>
 #include <mach/regs-intc.h>
 #include <mach/smemc.h>
 #include <mach/smemc.h>
-#include <plat/i2c.h>
 
 
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"

+ 1 - 1
arch/arm/mach-pxa/pxa95x.c

@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/sysdev.h>
 #include <linux/sysdev.h>
@@ -27,7 +28,6 @@
 #include <mach/pm.h>
 #include <mach/pm.h>
 #include <mach/dma.h>
 #include <mach/dma.h>
 #include <mach/regs-intc.h>
 #include <mach/regs-intc.h>
-#include <plat/i2c.h>
 
 
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"

+ 1 - 1
arch/arm/mach-pxa/raumfeld.c

@@ -32,6 +32,7 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/pwm_backlight.h>
 #include <linux/pwm_backlight.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
 #include <linux/spi/spi_gpio.h>
 #include <linux/lis3lv02d.h>
 #include <linux/lis3lv02d.h>
@@ -53,7 +54,6 @@
 #include <mach/ohci.h>
 #include <mach/ohci.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
-#include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <plat/pxa3xx_nand.h>
 
 
 #include "generic.h"
 #include "generic.h"

+ 1 - 1
arch/arm/mach-pxa/saar.c

@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/fb.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/smc91x.h>
 #include <linux/smc91x.h>
 #include <linux/mfd/da903x.h>
 #include <linux/mfd/da903x.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
@@ -31,7 +32,6 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/flash.h>
 
 
 #include <mach/pxa930.h>
 #include <mach/pxa930.h>
-#include <plat/i2c.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
 
 
 #include "devices.h"
 #include "devices.h"

+ 1 - 2
arch/arm/mach-pxa/saarb.c

@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/mfd/88pm860x.h>
 #include <linux/mfd/88pm860x.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -24,8 +25,6 @@
 #include <mach/mfp-pxa930.h>
 #include <mach/mfp-pxa930.h>
 #include <mach/gpio.h>
 #include <mach/gpio.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 
 
 #define SAARB_NR_IRQS	(IRQ_BOARD_START + 40)
 #define SAARB_NR_IRQS	(IRQ_BOARD_START + 40)

+ 1 - 2
arch/arm/mach-pxa/spitz.c

@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/leds.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/spi/ads7846.h>
@@ -47,8 +48,6 @@
 #include <mach/sharpsl_pm.h>
 #include <mach/sharpsl_pm.h>
 #include <mach/smemc.h>
 #include <mach/smemc.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 
 

+ 1 - 1
arch/arm/mach-pxa/stargate2.c

@@ -25,6 +25,7 @@
 #include <linux/mtd/plat-ram.h>
 #include <linux/mtd/plat-ram.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
 
 
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/i2c/pcf857x.h>
 #include <linux/i2c/pcf857x.h>
 #include <linux/i2c/at24.h>
 #include <linux/i2c/at24.h>
 #include <linux/smc91x.h>
 #include <linux/smc91x.h>
@@ -43,7 +44,6 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/flash.h>
 
 
 #include <mach/pxa27x.h>
 #include <mach/pxa27x.h>
-#include <plat/i2c.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/udc.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/pxa27x-udc.h>

+ 1 - 2
arch/arm/mach-pxa/tavorevb3.c

@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/mfd/88pm860x.h>
 #include <linux/mfd/88pm860x.h>
 
 
@@ -23,8 +24,6 @@
 
 
 #include <mach/pxa930.h>
 #include <mach/pxa930.h>
 
 
-#include <plat/i2c.h>
-
 #include "devices.h"
 #include "devices.h"
 #include "generic.h"
 #include "generic.h"
 
 

+ 1 - 1
arch/arm/mach-pxa/tosa.c

@@ -34,6 +34,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -41,7 +42,6 @@
 #include <mach/pxa25x.h>
 #include <mach/pxa25x.h>
 #include <mach/reset.h>
 #include <mach/reset.h>
 #include <mach/irda.h>
 #include <mach/irda.h>
-#include <plat/i2c.h>
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/udc.h>
 #include <mach/tosa_bt.h>
 #include <mach/tosa_bt.h>

+ 1 - 1
arch/arm/mach-pxa/trizeps4.c

@@ -26,6 +26,7 @@
 #include <linux/dm9000.h>
 #include <linux/dm9000.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/types.h>
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
@@ -47,7 +48,6 @@
 #include <mach/irda.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>
 #include <mach/smemc.h>
 #include <mach/smemc.h>
-#include <plat/i2c.h>
 
 
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"

+ 1 - 1
arch/arm/mach-pxa/viper.c

@@ -36,6 +36,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
 #include <linux/i2c-gpio.h>
 #include <linux/i2c-gpio.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_8250.h>
 #include <linux/smc91x.h>
 #include <linux/smc91x.h>
 #include <linux/pwm_backlight.h>
 #include <linux/pwm_backlight.h>
@@ -47,7 +48,6 @@
 #include <mach/pxa25x.h>
 #include <mach/pxa25x.h>
 #include <mach/audio.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
 #include <mach/pxafb.h>
-#include <plat/i2c.h>
 #include <mach/regs-uart.h>
 #include <mach/regs-uart.h>
 #include <mach/arcom-pcmcia.h>
 #include <mach/arcom-pcmcia.h>
 #include <mach/viper.h>
 #include <mach/viper.h>

+ 1 - 2
arch/arm/mach-pxa/vpac270.c

@@ -26,6 +26,7 @@
 #include <linux/ucb1400.h>
 #include <linux/ucb1400.h>
 #include <linux/ata_platform.h>
 #include <linux/ata_platform.h>
 #include <linux/regulator/max1586.h>
 #include <linux/regulator/max1586.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
@@ -40,8 +41,6 @@
 #include <mach/udc.h>
 #include <mach/udc.h>
 #include <mach/pata_pxa.h>
 #include <mach/pata_pxa.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 
 

+ 1 - 2
arch/arm/mach-pxa/xcep.c

@@ -16,6 +16,7 @@
 
 
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/smc91x.h>
 #include <linux/smc91x.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
@@ -26,8 +27,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 
 
-#include <plat/i2c.h>
-
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/mfp-pxa25x.h>
 #include <mach/mfp-pxa25x.h>

+ 1 - 2
arch/arm/mach-pxa/z2.c

@@ -29,6 +29,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/gpio_keys.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/machine.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
@@ -40,8 +41,6 @@
 #include <mach/mmc.h>
 #include <mach/mmc.h>
 #include <plat/pxa27x_keypad.h>
 #include <plat/pxa27x_keypad.h>
 
 
-#include <plat/i2c.h>
-
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
 
 

+ 1 - 2
arch/arm/mach-pxa/zeus.c

@@ -25,6 +25,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/apm-emulation.h>
 #include <linux/apm-emulation.h>
 #include <linux/can/platform/mcp251x.h>
 #include <linux/can/platform/mcp251x.h>
@@ -33,8 +34,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 
 
-#include <plat/i2c.h>
-
 #include <mach/pxa2xx-regs.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/regs-uart.h>
 #include <mach/regs-uart.h>
 #include <mach/ohci.h>
 #include <mach/ohci.h>

+ 1 - 1
arch/arm/mach-pxa/zylonite_pxa300.c

@@ -17,11 +17,11 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 
 
 #include <mach/pxa300.h>
 #include <mach/pxa300.h>
-#include <plat/i2c.h>
 #include <mach/zylonite.h>
 #include <mach/zylonite.h>
 
 
 #include "generic.h"
 #include "generic.h"

+ 24 - 8
drivers/i2c/busses/Kconfig

@@ -547,15 +547,18 @@ config I2C_PUV3
 
 
 config I2C_PXA
 config I2C_PXA
 	tristate "Intel PXA2XX I2C adapter"
 	tristate "Intel PXA2XX I2C adapter"
-	depends on ARCH_PXA || ARCH_MMP
+	depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF)
 	help
 	help
 	  If you have devices in the PXA I2C bus, say yes to this option.
 	  If you have devices in the PXA I2C bus, say yes to this option.
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-pxa.
 	  will be called i2c-pxa.
 
 
+config I2C_PXA_PCI
+	def_bool I2C_PXA && X86_32 && PCI && OF
+
 config I2C_PXA_SLAVE
 config I2C_PXA_SLAVE
 	bool "Intel PXA2XX I2C Slave comms support"
 	bool "Intel PXA2XX I2C Slave comms support"
-	depends on I2C_PXA
+	depends on I2C_PXA && !X86_32
 	help
 	help
 	  Support I2C slave mode communications on the PXA I2C bus.  This
 	  Support I2C slave mode communications on the PXA I2C bus.  This
 	  is necessary for systems where the PXA may be a target on the
 	  is necessary for systems where the PXA may be a target on the
@@ -668,15 +671,28 @@ config I2C_XILINX
 	  will be called xilinx_i2c.
 	  will be called xilinx_i2c.
 
 
 config I2C_EG20T
 config I2C_EG20T
-        tristate "PCH I2C of Intel EG20T"
-        depends on PCI
-        help
-          This driver is for PCH(Platform controller Hub) I2C of EG20T which
-          is an IOH(Input/Output Hub) for x86 embedded processor.
-          This driver can access PCH I2C bus device.
+	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH"
+	depends on PCI
+	help
+	  This driver is for PCH(Platform controller Hub) I2C of EG20T which
+	  is an IOH(Input/Output Hub) for x86 embedded processor.
+	  This driver can access PCH I2C bus device.
+
+	  This driver also supports the ML7213, a companion chip for the
+	  Atom E6xx series and compatible with the Intel EG20T PCH.
 
 
 comment "External I2C/SMBus adapter drivers"
 comment "External I2C/SMBus adapter drivers"
 
 
+config I2C_DIOLAN_U2C
+	tristate "Diolan U2C-12 USB adapter"
+	depends on USB
+	help
+	  If you say yes to this option, support will be included for Diolan
+	  U2C-12, a USB to I2C interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-diolan-u2c.
+
 config I2C_PARPORT
 config I2C_PARPORT
 	tristate "Parallel port adapter"
 	tristate "Parallel port adapter"
 	depends on PARPORT
 	depends on PARPORT

+ 2 - 0
drivers/i2c/busses/Makefile

@@ -54,6 +54,7 @@ obj-$(CONFIG_I2C_PMCMSP)	+= i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PUV3)		+= i2c-puv3.o
 obj-$(CONFIG_I2C_PUV3)		+= i2c-puv3.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
+obj-$(CONFIG_I2C_PXA_PCI)	+= i2c-pxa-pci.o
 obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
 obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
 obj-$(CONFIG_I2C_S6000)		+= i2c-s6000.o
 obj-$(CONFIG_I2C_S6000)		+= i2c-s6000.o
 obj-$(CONFIG_I2C_SH7760)	+= i2c-sh7760.o
 obj-$(CONFIG_I2C_SH7760)	+= i2c-sh7760.o
@@ -67,6 +68,7 @@ obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_EG20T)         += i2c-eg20t.o
 obj-$(CONFIG_I2C_EG20T)         += i2c-eg20t.o
 
 
 # External I2C/SMBus adapter drivers
 # External I2C/SMBus adapter drivers
+obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
 obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
 obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o
 obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o

+ 535 - 0
drivers/i2c/busses/i2c-diolan-u2c.c

@@ -0,0 +1,535 @@
+/*
+ * Driver for the Diolan u2c-12 USB-I2C adapter
+ *
+ * Copyright (c) 2010-2011 Ericsson AB
+ *
+ * Derived from:
+ *  i2c-tiny-usb.c
+ *  Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+
+#define DRIVER_NAME		"i2c-diolan-u2c"
+
+#define USB_VENDOR_ID_DIOLAN		0x0abf
+#define USB_DEVICE_ID_DIOLAN_U2C	0x3370
+
+#define DIOLAN_OUT_EP		0x02
+#define DIOLAN_IN_EP		0x84
+
+/* commands via USB, must match command ids in the firmware */
+#define CMD_I2C_READ		0x01
+#define CMD_I2C_WRITE		0x02
+#define CMD_I2C_SCAN		0x03	/* Returns list of detected devices */
+#define CMD_I2C_RELEASE_SDA	0x04
+#define CMD_I2C_RELEASE_SCL	0x05
+#define CMD_I2C_DROP_SDA	0x06
+#define CMD_I2C_DROP_SCL	0x07
+#define CMD_I2C_READ_SDA	0x08
+#define CMD_I2C_READ_SCL	0x09
+#define CMD_GET_FW_VERSION	0x0a
+#define CMD_GET_SERIAL		0x0b
+#define CMD_I2C_START		0x0c
+#define CMD_I2C_STOP		0x0d
+#define CMD_I2C_REPEATED_START	0x0e
+#define CMD_I2C_PUT_BYTE	0x0f
+#define CMD_I2C_GET_BYTE	0x10
+#define CMD_I2C_PUT_ACK		0x11
+#define CMD_I2C_GET_ACK		0x12
+#define CMD_I2C_PUT_BYTE_ACK	0x13
+#define CMD_I2C_GET_BYTE_ACK	0x14
+#define CMD_I2C_SET_SPEED	0x1b
+#define CMD_I2C_GET_SPEED	0x1c
+#define CMD_I2C_SET_CLK_SYNC	0x24
+#define CMD_I2C_GET_CLK_SYNC	0x25
+#define CMD_I2C_SET_CLK_SYNC_TO	0x26
+#define CMD_I2C_GET_CLK_SYNC_TO	0x27
+
+#define RESP_OK			0x00
+#define RESP_FAILED		0x01
+#define RESP_BAD_MEMADDR	0x04
+#define RESP_DATA_ERR		0x05
+#define RESP_NOT_IMPLEMENTED	0x06
+#define RESP_NACK		0x07
+#define RESP_TIMEOUT		0x09
+
+#define U2C_I2C_SPEED_FAST	0	/* 400 kHz */
+#define U2C_I2C_SPEED_STD	1	/* 100 kHz */
+#define U2C_I2C_SPEED_2KHZ	242	/* 2 kHz, minimum speed */
+#define U2C_I2C_SPEED(f)	((DIV_ROUND_UP(1000000, (f)) - 10) / 2 + 1)
+
+#define U2C_I2C_FREQ_FAST	400000
+#define U2C_I2C_FREQ_STD	100000
+#define U2C_I2C_FREQ(s)		(1000000 / (2 * (s - 1) + 10))
+
+#define DIOLAN_USB_TIMEOUT	100	/* in ms */
+#define DIOLAN_SYNC_TIMEOUT	20	/* in ms */
+
+#define DIOLAN_OUTBUF_LEN	128
+#define DIOLAN_FLUSH_LEN	(DIOLAN_OUTBUF_LEN - 4)
+#define DIOLAN_INBUF_LEN	256	/* Maximum supported receive length */
+
+/* Structure to hold all of our device specific stuff */
+struct i2c_diolan_u2c {
+	u8 obuffer[DIOLAN_OUTBUF_LEN];	/* output buffer */
+	u8 ibuffer[DIOLAN_INBUF_LEN];	/* input buffer */
+	struct usb_device *usb_dev;	/* the usb device for this device */
+	struct usb_interface *interface;/* the interface for this device */
+	struct i2c_adapter adapter;	/* i2c related things */
+	int olen;			/* Output buffer length */
+	int ocount;			/* Number of enqueued messages */
+};
+
+static uint frequency = U2C_I2C_FREQ_STD;	/* I2C clock frequency in Hz */
+
+module_param(frequency, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(frequency, "I2C clock frequency in hertz");
+
+/* usb layer */
+
+/* Send command to device, and get response. */
+static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)
+{
+	int ret = 0;
+	int actual;
+	int i;
+
+	if (!dev->olen || !dev->ocount)
+		return -EINVAL;
+
+	ret = usb_bulk_msg(dev->usb_dev,
+			   usb_sndbulkpipe(dev->usb_dev, DIOLAN_OUT_EP),
+			   dev->obuffer, dev->olen, &actual,
+			   DIOLAN_USB_TIMEOUT);
+	if (!ret) {
+		for (i = 0; i < dev->ocount; i++) {
+			int tmpret;
+
+			tmpret = usb_bulk_msg(dev->usb_dev,
+					      usb_rcvbulkpipe(dev->usb_dev,
+							      DIOLAN_IN_EP),
+					      dev->ibuffer,
+					      sizeof(dev->ibuffer), &actual,
+					      DIOLAN_USB_TIMEOUT);
+			/*
+			 * Stop command processing if a previous command
+			 * returned an error.
+			 * Note that we still need to retrieve all messages.
+			 */
+			if (ret < 0)
+				continue;
+			ret = tmpret;
+			if (ret == 0 && actual > 0) {
+				switch (dev->ibuffer[actual - 1]) {
+				case RESP_NACK:
+					/*
+					 * Return ENXIO if NACK was received as
+					 * response to the address phase,
+					 * EIO otherwise
+					 */
+					ret = i == 1 ? -ENXIO : -EIO;
+					break;
+				case RESP_TIMEOUT:
+					ret = -ETIMEDOUT;
+					break;
+				case RESP_OK:
+					/* strip off return code */
+					ret = actual - 1;
+					break;
+				default:
+					ret = -EIO;
+					break;
+				}
+			}
+		}
+	}
+	dev->olen = 0;
+	dev->ocount = 0;
+	return ret;
+}
+
+static int diolan_write_cmd(struct i2c_diolan_u2c *dev, bool flush)
+{
+	if (flush || dev->olen >= DIOLAN_FLUSH_LEN)
+		return diolan_usb_transfer(dev);
+	return 0;
+}
+
+/* Send command (no data) */
+static int diolan_usb_cmd(struct i2c_diolan_u2c *dev, u8 command, bool flush)
+{
+	dev->obuffer[dev->olen++] = command;
+	dev->ocount++;
+	return diolan_write_cmd(dev, flush);
+}
+
+/* Send command with one byte of data */
+static int diolan_usb_cmd_data(struct i2c_diolan_u2c *dev, u8 command, u8 data,
+			       bool flush)
+{
+	dev->obuffer[dev->olen++] = command;
+	dev->obuffer[dev->olen++] = data;
+	dev->ocount++;
+	return diolan_write_cmd(dev, flush);
+}
+
+/* Send command with two bytes of data */
+static int diolan_usb_cmd_data2(struct i2c_diolan_u2c *dev, u8 command, u8 d1,
+				u8 d2, bool flush)
+{
+	dev->obuffer[dev->olen++] = command;
+	dev->obuffer[dev->olen++] = d1;
+	dev->obuffer[dev->olen++] = d2;
+	dev->ocount++;
+	return diolan_write_cmd(dev, flush);
+}
+
+/*
+ * Flush input queue.
+ * If we don't do this at startup and the controller has queued up
+ * messages which were not retrieved, it will stop responding
+ * at some point.
+ */
+static void diolan_flush_input(struct i2c_diolan_u2c *dev)
+{
+	int i;
+
+	for (i = 0; i < 10; i++) {
+		int actual = 0;
+		int ret;
+
+		ret = usb_bulk_msg(dev->usb_dev,
+				   usb_rcvbulkpipe(dev->usb_dev, DIOLAN_IN_EP),
+				   dev->ibuffer, sizeof(dev->ibuffer), &actual,
+				   DIOLAN_USB_TIMEOUT);
+		if (ret < 0 || actual == 0)
+			break;
+	}
+	if (i == 10)
+		dev_err(&dev->interface->dev, "Failed to flush input buffer\n");
+}
+
+static int diolan_i2c_start(struct i2c_diolan_u2c *dev)
+{
+	return diolan_usb_cmd(dev, CMD_I2C_START, false);
+}
+
+static int diolan_i2c_repeated_start(struct i2c_diolan_u2c *dev)
+{
+	return diolan_usb_cmd(dev, CMD_I2C_REPEATED_START, false);
+}
+
+static int diolan_i2c_stop(struct i2c_diolan_u2c *dev)
+{
+	return diolan_usb_cmd(dev, CMD_I2C_STOP, true);
+}
+
+static int diolan_i2c_get_byte_ack(struct i2c_diolan_u2c *dev, bool ack,
+				   u8 *byte)
+{
+	int ret;
+
+	ret = diolan_usb_cmd_data(dev, CMD_I2C_GET_BYTE_ACK, ack, true);
+	if (ret > 0)
+		*byte = dev->ibuffer[0];
+	else if (ret == 0)
+		ret = -EIO;
+
+	return ret;
+}
+
+static int diolan_i2c_put_byte_ack(struct i2c_diolan_u2c *dev, u8 byte)
+{
+	return diolan_usb_cmd_data(dev, CMD_I2C_PUT_BYTE_ACK, byte, false);
+}
+
+static int diolan_set_speed(struct i2c_diolan_u2c *dev, u8 speed)
+{
+	return diolan_usb_cmd_data(dev, CMD_I2C_SET_SPEED, speed, true);
+}
+
+/* Enable or disable clock synchronization (stretching) */
+static int diolan_set_clock_synch(struct i2c_diolan_u2c *dev, bool enable)
+{
+	return diolan_usb_cmd_data(dev, CMD_I2C_SET_CLK_SYNC, enable, true);
+}
+
+/* Set clock synchronization timeout in ms */
+static int diolan_set_clock_synch_timeout(struct i2c_diolan_u2c *dev, int ms)
+{
+	int to_val = ms * 10;
+
+	return diolan_usb_cmd_data2(dev, CMD_I2C_SET_CLK_SYNC_TO,
+				    to_val & 0xff, (to_val >> 8) & 0xff, true);
+}
+
+static void diolan_fw_version(struct i2c_diolan_u2c *dev)
+{
+	int ret;
+
+	ret = diolan_usb_cmd(dev, CMD_GET_FW_VERSION, true);
+	if (ret >= 2)
+		dev_info(&dev->interface->dev,
+			 "Diolan U2C firmware version %u.%u\n",
+			 (unsigned int)dev->ibuffer[0],
+			 (unsigned int)dev->ibuffer[1]);
+}
+
+static void diolan_get_serial(struct i2c_diolan_u2c *dev)
+{
+	int ret;
+	u32 serial;
+
+	ret = diolan_usb_cmd(dev, CMD_GET_SERIAL, true);
+	if (ret >= 4) {
+		serial = le32_to_cpu(*(u32 *)dev->ibuffer);
+		dev_info(&dev->interface->dev,
+			 "Diolan U2C serial number %u\n", serial);
+	}
+}
+
+static int diolan_init(struct i2c_diolan_u2c *dev)
+{
+	int speed, ret;
+
+	if (frequency >= 200000) {
+		speed = U2C_I2C_SPEED_FAST;
+		frequency = U2C_I2C_FREQ_FAST;
+	} else if (frequency >= 100000 || frequency == 0) {
+		speed = U2C_I2C_SPEED_STD;
+		frequency = U2C_I2C_FREQ_STD;
+	} else {
+		speed = U2C_I2C_SPEED(frequency);
+		if (speed > U2C_I2C_SPEED_2KHZ)
+			speed = U2C_I2C_SPEED_2KHZ;
+		frequency = U2C_I2C_FREQ(speed);
+	}
+
+	dev_info(&dev->interface->dev,
+		 "Diolan U2C at USB bus %03d address %03d speed %d Hz\n",
+		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum, frequency);
+
+	diolan_flush_input(dev);
+	diolan_fw_version(dev);
+	diolan_get_serial(dev);
+
+	/* Set I2C speed */
+	ret = diolan_set_speed(dev, speed);
+	if (ret < 0)
+		return ret;
+
+	/* Configure I2C clock synchronization */
+	ret = diolan_set_clock_synch(dev, speed != U2C_I2C_SPEED_FAST);
+	if (ret < 0)
+		return ret;
+
+	if (speed != U2C_I2C_SPEED_FAST)
+		ret = diolan_set_clock_synch_timeout(dev, DIOLAN_SYNC_TIMEOUT);
+
+	return ret;
+}
+
+/* i2c layer */
+
+static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
+			   int num)
+{
+	struct i2c_diolan_u2c *dev = i2c_get_adapdata(adapter);
+	struct i2c_msg *pmsg;
+	int i, j;
+	int ret, sret;
+
+	ret = diolan_i2c_start(dev);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		if (i) {
+			ret = diolan_i2c_repeated_start(dev);
+			if (ret < 0)
+				goto abort;
+		}
+		if (pmsg->flags & I2C_M_RD) {
+			ret =
+			    diolan_i2c_put_byte_ack(dev, (pmsg->addr << 1) | 1);
+			if (ret < 0)
+				goto abort;
+			for (j = 0; j < pmsg->len; j++) {
+				u8 byte;
+				bool ack = j < pmsg->len - 1;
+
+				/*
+				 * Don't send NACK if this is the first byte
+				 * of a SMBUS_BLOCK message.
+				 */
+				if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN))
+					ack = true;
+
+				ret = diolan_i2c_get_byte_ack(dev, ack, &byte);
+				if (ret < 0)
+					goto abort;
+				/*
+				 * Adjust count if first received byte is length
+				 */
+				if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN)) {
+					if (byte == 0
+					    || byte > I2C_SMBUS_BLOCK_MAX) {
+						ret = -EPROTO;
+						goto abort;
+					}
+					pmsg->len += byte;
+				}
+				pmsg->buf[j] = byte;
+			}
+		} else {
+			ret = diolan_i2c_put_byte_ack(dev, pmsg->addr << 1);
+			if (ret < 0)
+				goto abort;
+			for (j = 0; j < pmsg->len; j++) {
+				ret = diolan_i2c_put_byte_ack(dev,
+							      pmsg->buf[j]);
+				if (ret < 0)
+					goto abort;
+			}
+		}
+	}
+abort:
+	sret = diolan_i2c_stop(dev);
+	if (sret < 0 && ret >= 0)
+		ret = sret;
+	return ret;
+}
+
+/*
+ * Return list of supported functionality.
+ */
+static u32 diolan_usb_func(struct i2c_adapter *a)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+	       I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
+}
+
+static const struct i2c_algorithm diolan_usb_algorithm = {
+	.master_xfer = diolan_usb_xfer,
+	.functionality = diolan_usb_func,
+};
+
+/* device layer */
+
+static const struct usb_device_id diolan_u2c_table[] = {
+	{ USB_DEVICE(USB_VENDOR_ID_DIOLAN, USB_DEVICE_ID_DIOLAN_U2C) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, diolan_u2c_table);
+
+static void diolan_u2c_free(struct i2c_diolan_u2c *dev)
+{
+	usb_put_dev(dev->usb_dev);
+	kfree(dev);
+}
+
+static int diolan_u2c_probe(struct usb_interface *interface,
+			    const struct usb_device_id *id)
+{
+	struct i2c_diolan_u2c *dev;
+	int ret;
+
+	/* allocate memory for our device state and initialize it */
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&interface->dev, "no memory for device state\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
+	dev->interface = interface;
+
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(interface, dev);
+
+	/* setup i2c adapter description */
+	dev->adapter.owner = THIS_MODULE;
+	dev->adapter.class = I2C_CLASS_HWMON;
+	dev->adapter.algo = &diolan_usb_algorithm;
+	i2c_set_adapdata(&dev->adapter, dev);
+	snprintf(dev->adapter.name, sizeof(dev->adapter.name),
+		 DRIVER_NAME " at bus %03d device %03d",
+		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
+
+	dev->adapter.dev.parent = &dev->interface->dev;
+
+	/* initialize diolan i2c interface */
+	ret = diolan_init(dev);
+	if (ret < 0) {
+		dev_err(&interface->dev, "failed to initialize adapter\n");
+		goto error_free;
+	}
+
+	/* and finally attach to i2c layer */
+	ret = i2c_add_adapter(&dev->adapter);
+	if (ret < 0) {
+		dev_err(&interface->dev, "failed to add I2C adapter\n");
+		goto error_free;
+	}
+
+	dev_dbg(&interface->dev, "connected " DRIVER_NAME "\n");
+
+	return 0;
+
+error_free:
+	usb_set_intfdata(interface, NULL);
+	diolan_u2c_free(dev);
+error:
+	return ret;
+}
+
+static void diolan_u2c_disconnect(struct usb_interface *interface)
+{
+	struct i2c_diolan_u2c *dev = usb_get_intfdata(interface);
+
+	i2c_del_adapter(&dev->adapter);
+	usb_set_intfdata(interface, NULL);
+	diolan_u2c_free(dev);
+
+	dev_dbg(&interface->dev, "disconnected\n");
+}
+
+static struct usb_driver diolan_u2c_driver = {
+	.name = DRIVER_NAME,
+	.probe = diolan_u2c_probe,
+	.disconnect = diolan_u2c_disconnect,
+	.id_table = diolan_u2c_table,
+};
+
+static int __init diolan_u2c_init(void)
+{
+	/* register this driver with the USB subsystem */
+	return usb_register(&diolan_u2c_driver);
+}
+
+static void __exit diolan_u2c_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&diolan_u2c_driver);
+}
+
+module_init(diolan_u2c_init);
+module_exit(diolan_u2c_exit);
+
+MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
+MODULE_DESCRIPTION(DRIVER_NAME " driver");
+MODULE_LICENSE("GPL");

+ 99 - 62
drivers/i2c/busses/i2c-eg20t.c

@@ -132,6 +132,13 @@
 #define pch_pci_dbg(pdev, fmt, arg...)  \
 #define pch_pci_dbg(pdev, fmt, arg...)  \
 	dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
 	dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
 
 
+/*
+Set the number of I2C instance max
+Intel EG20T PCH :		1ch
+OKI SEMICONDUCTOR ML7213 IOH :	2ch
+*/
+#define PCH_I2C_MAX_DEV			2
+
 /**
 /**
  * struct i2c_algo_pch_data - for I2C driver functionalities
  * struct i2c_algo_pch_data - for I2C driver functionalities
  * @pch_adapter:		stores the reference to i2c_adapter structure
  * @pch_adapter:		stores the reference to i2c_adapter structure
@@ -156,12 +163,14 @@ struct i2c_algo_pch_data {
  * @pch_data:		stores a list of i2c_algo_pch_data
  * @pch_data:		stores a list of i2c_algo_pch_data
  * @pch_i2c_suspended:	specifies whether the system is suspended or not
  * @pch_i2c_suspended:	specifies whether the system is suspended or not
  *			perhaps with more lines and words.
  *			perhaps with more lines and words.
+ * @ch_num:		specifies the number of i2c instance
  *
  *
  * pch_data has as many elements as maximum I2C channels
  * pch_data has as many elements as maximum I2C channels
  */
  */
 struct adapter_info {
 struct adapter_info {
-	struct i2c_algo_pch_data pch_data;
+	struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
 	bool pch_i2c_suspended;
 	bool pch_i2c_suspended;
+	int ch_num;
 };
 };
 
 
 
 
@@ -170,8 +179,13 @@ static int pch_clk = 50000;	/* specifies I2C clock speed in KHz */
 static wait_queue_head_t pch_event;
 static wait_queue_head_t pch_event;
 static DEFINE_MUTEX(pch_mutex);
 static DEFINE_MUTEX(pch_mutex);
 
 
+/* Definition for ML7213 by OKI SEMICONDUCTOR */
+#define PCI_VENDOR_ID_ROHM		0x10DB
+#define PCI_DEVICE_ID_ML7213_I2C	0x802D
+
 static struct pci_device_id __devinitdata pch_pcidev_id[] = {
 static struct pci_device_id __devinitdata pch_pcidev_id[] = {
-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_I2C)},
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C),   1, },
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
 	{0,}
 	{0,}
 };
 };
 
 
@@ -212,8 +226,7 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap)
 	/* Initialize I2C registers */
 	/* Initialize I2C registers */
 	iowrite32(0x21, p + PCH_I2CNF);
 	iowrite32(0x21, p + PCH_I2CNF);
 
 
-	pch_setbit(adap->pch_base_address, PCH_I2CCTL,
-			  PCH_I2CCTL_I2CMEN);
+	pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_I2CCTL_I2CMEN);
 
 
 	if (pch_i2c_speed != 400)
 	if (pch_i2c_speed != 400)
 		pch_i2c_speed = 100;
 		pch_i2c_speed = 100;
@@ -255,7 +268,7 @@ static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
  * @timeout:	waiting time counter (us).
  * @timeout:	waiting time counter (us).
  */
  */
 static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
 static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
-				 s32 timeout)
+				     s32 timeout)
 {
 {
 	void __iomem *p = adap->pch_base_address;
 	void __iomem *p = adap->pch_base_address;
 
 
@@ -475,8 +488,8 @@ static void pch_i2c_sendnack(struct i2c_algo_pch_data *adap)
  * @last:	specifies whether last message or not.
  * @last:	specifies whether last message or not.
  * @first:	specifies whether first message or not.
  * @first:	specifies whether first message or not.
  */
  */
-s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
-		  u32 last, u32 first)
+static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+			     u32 last, u32 first)
 {
 {
 	struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
 	struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
 
 
@@ -569,10 +582,10 @@ s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
 }
 }
 
 
 /**
 /**
- * pch_i2c_cb_ch0() - Interrupt handler Call back function
+ * pch_i2c_cb() - Interrupt handler Call back function
  * @adap:	Pointer to struct i2c_algo_pch_data.
  * @adap:	Pointer to struct i2c_algo_pch_data.
  */
  */
-static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
+static void pch_i2c_cb(struct i2c_algo_pch_data *adap)
 {
 {
 	u32 sts;
 	u32 sts;
 	void __iomem *p = adap->pch_base_address;
 	void __iomem *p = adap->pch_base_address;
@@ -600,24 +613,30 @@ static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
  */
  */
 static irqreturn_t pch_i2c_handler(int irq, void *pData)
 static irqreturn_t pch_i2c_handler(int irq, void *pData)
 {
 {
-	s32 reg_val;
-
-	struct i2c_algo_pch_data *adap_data = (struct i2c_algo_pch_data *)pData;
-	void __iomem *p = adap_data->pch_base_address;
-	u32 mode = ioread32(p + PCH_I2CMOD) & (BUFFER_MODE | EEPROM_SR_MODE);
-
-	if (mode != NORMAL_MODE) {
-		pch_err(adap_data, "I2C mode is not supported\n");
-		return IRQ_NONE;
+	u32 reg_val;
+	int flag;
+	int i;
+	struct adapter_info *adap_info = pData;
+	void __iomem *p;
+	u32 mode;
+
+	for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
+		p = adap_info->pch_data[i].pch_base_address;
+		mode = ioread32(p + PCH_I2CMOD);
+		mode &= BUFFER_MODE | EEPROM_SR_MODE;
+		if (mode != NORMAL_MODE) {
+			pch_err(adap_info->pch_data,
+				"I2C-%d mode(%d) is not supported\n", mode, i);
+			continue;
+		}
+		reg_val = ioread32(p + PCH_I2CSR);
+		if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT)) {
+			pch_i2c_cb(&adap_info->pch_data[i]);
+			flag = 1;
+		}
 	}
 	}
 
 
-	reg_val = ioread32(p + PCH_I2CSR);
-	if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT))
-		pch_i2c_cb_ch0(adap_data);
-	else
-		return IRQ_NONE;
-
-	return IRQ_HANDLED;
+	return flag ? IRQ_HANDLED : IRQ_NONE;
 }
 }
 
 
 /**
 /**
@@ -627,7 +646,7 @@ static irqreturn_t pch_i2c_handler(int irq, void *pData)
  * @num:	number of messages.
  * @num:	number of messages.
  */
  */
 static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
 static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
-		    struct i2c_msg *msgs, s32 num)
+			struct i2c_msg *msgs, s32 num)
 {
 {
 	struct i2c_msg *pmsg;
 	struct i2c_msg *pmsg;
 	u32 i = 0;
 	u32 i = 0;
@@ -710,11 +729,13 @@ static void pch_i2c_disbl_int(struct i2c_algo_pch_data *adap)
 }
 }
 
 
 static int __devinit pch_i2c_probe(struct pci_dev *pdev,
 static int __devinit pch_i2c_probe(struct pci_dev *pdev,
-			       const struct pci_device_id *id)
+				   const struct pci_device_id *id)
 {
 {
 	void __iomem *base_addr;
 	void __iomem *base_addr;
-	s32 ret;
+	int ret;
+	int i, j;
 	struct adapter_info *adap_info;
 	struct adapter_info *adap_info;
+	struct i2c_adapter *pch_adap;
 
 
 	pch_pci_dbg(pdev, "Entered.\n");
 	pch_pci_dbg(pdev, "Entered.\n");
 
 
@@ -744,44 +765,48 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev,
 		goto err_pci_iomap;
 		goto err_pci_iomap;
 	}
 	}
 
 
-	adap_info->pch_i2c_suspended = false;
+	/* Set the number of I2C channel instance */
+	adap_info->ch_num = id->driver_data;
 
 
-	adap_info->pch_data.p_adapter_info = adap_info;
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
+		adap_info->pch_i2c_suspended = false;
 
 
-	adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
-	adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
-	strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
-	adap_info->pch_data.pch_adapter.algo = &pch_algorithm;
-	adap_info->pch_data.pch_adapter.algo_data =
-						&adap_info->pch_data;
+		adap_info->pch_data[i].p_adapter_info = adap_info;
 
 
-	/* (i * 0x80) + base_addr; */
-	adap_info->pch_data.pch_base_address = base_addr;
+		pch_adap->owner = THIS_MODULE;
+		pch_adap->class = I2C_CLASS_HWMON;
+		strcpy(pch_adap->name, KBUILD_MODNAME);
+		pch_adap->algo = &pch_algorithm;
+		pch_adap->algo_data = &adap_info->pch_data[i];
 
 
-	adap_info->pch_data.pch_adapter.dev.parent = &pdev->dev;
+		/* base_addr + offset; */
+		adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
 
 
-	ret = i2c_add_adapter(&(adap_info->pch_data.pch_adapter));
+		pch_adap->dev.parent = &pdev->dev;
 
 
-	if (ret) {
-		pch_pci_err(pdev, "i2c_add_adapter FAILED\n");
-		goto err_i2c_add_adapter;
-	}
+		ret = i2c_add_adapter(pch_adap);
+		if (ret) {
+			pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
+			goto err_i2c_add_adapter;
+		}
 
 
-	pch_i2c_init(&adap_info->pch_data);
+		pch_i2c_init(&adap_info->pch_data[i]);
+	}
 	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
 	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, &adap_info->pch_data);
+		  KBUILD_MODNAME, adap_info);
 	if (ret) {
 	if (ret) {
 		pch_pci_err(pdev, "request_irq FAILED\n");
 		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
+		goto err_i2c_add_adapter;
 	}
 	}
 
 
 	pci_set_drvdata(pdev, adap_info);
 	pci_set_drvdata(pdev, adap_info);
 	pch_pci_dbg(pdev, "returns %d.\n", ret);
 	pch_pci_dbg(pdev, "returns %d.\n", ret);
 	return 0;
 	return 0;
 
 
-err_request_irq:
-	i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
 err_i2c_add_adapter:
 err_i2c_add_adapter:
+	for (j = 0; j < i; j++)
+		i2c_del_adapter(&adap_info->pch_data[j].pch_adapter);
 	pci_iounmap(pdev, base_addr);
 	pci_iounmap(pdev, base_addr);
 err_pci_iomap:
 err_pci_iomap:
 	pci_release_regions(pdev);
 	pci_release_regions(pdev);
@@ -794,17 +819,22 @@ err_pci_enable:
 
 
 static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 {
 {
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 
 
-	pch_i2c_disbl_int(&adap_info->pch_data);
-	free_irq(pdev->irq, &adap_info->pch_data);
-	i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
+	free_irq(pdev->irq, adap_info);
 
 
-	if (adap_info->pch_data.pch_base_address) {
-		pci_iounmap(pdev, adap_info->pch_data.pch_base_address);
-		adap_info->pch_data.pch_base_address = 0;
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_i2c_disbl_int(&adap_info->pch_data[i]);
+		i2c_del_adapter(&adap_info->pch_data[i].pch_adapter);
 	}
 	}
 
 
+	if (adap_info->pch_data[0].pch_base_address)
+		pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
+
+	for (i = 0; i < adap_info->ch_num; i++)
+		adap_info->pch_data[i].pch_base_address = 0;
+
 	pci_set_drvdata(pdev, NULL);
 	pci_set_drvdata(pdev, NULL);
 
 
 	pci_release_regions(pdev);
 	pci_release_regions(pdev);
@@ -817,17 +847,22 @@ static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 {
 	int ret;
 	int ret;
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
-	void __iomem *p = adap_info->pch_data.pch_base_address;
+	void __iomem *p = adap_info->pch_data[0].pch_base_address;
 
 
 	adap_info->pch_i2c_suspended = true;
 	adap_info->pch_i2c_suspended = true;
 
 
-	while ((adap_info->pch_data.pch_i2c_xfer_in_progress)) {
-		/* Wait until all channel transfers are completed */
-		msleep(20);
+	for (i = 0; i < adap_info->ch_num; i++) {
+		while ((adap_info->pch_data[i].pch_i2c_xfer_in_progress)) {
+			/* Wait until all channel transfers are completed */
+			msleep(20);
+		}
 	}
 	}
+
 	/* Disable the i2c interrupts */
 	/* Disable the i2c interrupts */
-	pch_i2c_disbl_int(&adap_info->pch_data);
+	for (i = 0; i < adap_info->ch_num; i++)
+		pch_i2c_disbl_int(&adap_info->pch_data[i]);
 
 
 	pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
 	pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
 		"invoked function pch_i2c_disbl_int successfully\n",
 		"invoked function pch_i2c_disbl_int successfully\n",
@@ -850,6 +885,7 @@ static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 
 
 static int pch_i2c_resume(struct pci_dev *pdev)
 static int pch_i2c_resume(struct pci_dev *pdev)
 {
 {
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_set_power_state(pdev, PCI_D0);
@@ -862,7 +898,8 @@ static int pch_i2c_resume(struct pci_dev *pdev)
 
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 
 
-	pch_i2c_init(&adap_info->pch_data);
+	for (i = 0; i < adap_info->ch_num; i++)
+		pch_i2c_init(&adap_info->pch_data[i]);
 
 
 	adap_info->pch_i2c_suspended = false;
 	adap_info->pch_i2c_suspended = false;
 
 
@@ -894,7 +931,7 @@ static void __exit pch_pci_exit(void)
 }
 }
 module_exit(pch_pci_exit);
 module_exit(pch_pci_exit);
 
 
-MODULE_DESCRIPTION("PCH I2C PCI Driver");
+MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH I2C Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>");
 MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>");
 module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
 module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));

+ 2 - 2
drivers/i2c/busses/i2c-mxs.c

@@ -118,6 +118,8 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
 {
 {
 	mxs_reset_block(i2c->regs);
 	mxs_reset_block(i2c->regs);
 	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
 	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
+	writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
+			i2c->regs + MXS_I2C_QUEUECTRL_SET);
 }
 }
 
 
 static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len,
 static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len,
@@ -347,8 +349,6 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
 
 
 	/* Do reset to enforce correct startup after pinmuxing */
 	/* Do reset to enforce correct startup after pinmuxing */
 	mxs_i2c_reset(i2c);
 	mxs_i2c_reset(i2c);
-	writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
-			i2c->regs + MXS_I2C_QUEUECTRL_SET);
 
 
 	adap = &i2c->adapter;
 	adap = &i2c->adapter;
 	strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
 	strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));

+ 176 - 0
drivers/i2c/busses/i2c-pxa-pci.c

@@ -0,0 +1,176 @@
+/*
+ * The CE4100's I2C device is more or less the same one as found on PXA.
+ * It does not support slave mode, the register slightly moved. This PCI
+ * device provides three bars, every contains a single I2C controller.
+ */
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+
+#define CE4100_PCI_I2C_DEVS	3
+
+struct ce4100_devices {
+	struct platform_device *pdev[CE4100_PCI_I2C_DEVS];
+};
+
+static struct platform_device *add_i2c_device(struct pci_dev *dev, int bar)
+{
+	struct platform_device *pdev;
+	struct i2c_pxa_platform_data pdata;
+	struct resource res[2];
+	struct device_node *child;
+	static int devnum;
+	int ret;
+
+	memset(&pdata, 0, sizeof(struct i2c_pxa_platform_data));
+	memset(&res, 0, sizeof(res));
+
+	res[0].flags = IORESOURCE_MEM;
+	res[0].start = pci_resource_start(dev, bar);
+	res[0].end = pci_resource_end(dev, bar);
+
+	res[1].flags = IORESOURCE_IRQ;
+	res[1].start = dev->irq;
+	res[1].end = dev->irq;
+
+	for_each_child_of_node(dev->dev.of_node, child) {
+		const void *prop;
+		struct resource r;
+		int ret;
+
+		ret = of_address_to_resource(child, 0, &r);
+		if (ret < 0)
+			continue;
+		if (r.start != res[0].start)
+			continue;
+		if (r.end != res[0].end)
+			continue;
+		if (r.flags != res[0].flags)
+			continue;
+
+		prop = of_get_property(child, "fast-mode", NULL);
+		if (prop)
+			pdata.fast_mode = 1;
+
+		break;
+	}
+
+	if (!child) {
+		dev_err(&dev->dev, "failed to match a DT node for bar %d.\n",
+				bar);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	pdev = platform_device_alloc("ce4100-i2c", devnum);
+	if (!pdev) {
+		of_node_put(child);
+		ret = -ENOMEM;
+		goto out;
+	}
+	pdev->dev.parent = &dev->dev;
+	pdev->dev.of_node = child;
+
+	ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+	if (ret)
+		goto err;
+
+	ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (ret)
+		goto err;
+
+	ret = platform_device_add(pdev);
+	if (ret)
+		goto err;
+	devnum++;
+	return pdev;
+err:
+	platform_device_put(pdev);
+out:
+	return ERR_PTR(ret);
+}
+
+static int __devinit ce4100_i2c_probe(struct pci_dev *dev,
+		const struct pci_device_id *ent)
+{
+	int ret;
+	int i;
+	struct ce4100_devices *sds;
+
+	ret = pci_enable_device_mem(dev);
+	if (ret)
+		return ret;
+
+	if (!dev->dev.of_node) {
+		dev_err(&dev->dev, "Missing device tree node.\n");
+		return -EINVAL;
+	}
+	sds = kzalloc(sizeof(*sds), GFP_KERNEL);
+	if (!sds)
+		goto err_mem;
+
+	for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
+		sds->pdev[i] = add_i2c_device(dev, i);
+		if (IS_ERR(sds->pdev[i])) {
+			while (--i >= 0)
+				platform_device_unregister(sds->pdev[i]);
+			goto err_dev_add;
+		}
+	}
+	pci_set_drvdata(dev, sds);
+	return 0;
+
+err_dev_add:
+	pci_set_drvdata(dev, NULL);
+	kfree(sds);
+err_mem:
+	pci_disable_device(dev);
+	return ret;
+}
+
+static void __devexit ce4100_i2c_remove(struct pci_dev *dev)
+{
+	struct ce4100_devices *sds;
+	unsigned int i;
+
+	sds = pci_get_drvdata(dev);
+	pci_set_drvdata(dev, NULL);
+
+	for (i = 0; i < ARRAY_SIZE(sds->pdev); i++)
+		platform_device_unregister(sds->pdev[i]);
+
+	pci_disable_device(dev);
+	kfree(sds);
+}
+
+static struct pci_device_id ce4100_i2c_devices[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
+	{ },
+};
+MODULE_DEVICE_TABLE(pci, ce4100_i2c_devices);
+
+static struct pci_driver ce4100_i2c_driver = {
+	.name           = "ce4100_i2c",
+	.id_table       = ce4100_i2c_devices,
+	.probe          = ce4100_i2c_probe,
+	.remove         = __devexit_p(ce4100_i2c_remove),
+};
+
+static int __init ce4100_i2c_init(void)
+{
+	return pci_register_driver(&ce4100_i2c_driver);
+}
+module_init(ce4100_i2c_init);
+
+static void __exit ce4100_i2c_exit(void)
+{
+	pci_unregister_driver(&ce4100_i2c_driver);
+}
+module_exit(ce4100_i2c_exit);
+
+MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");

+ 89 - 26
drivers/i2c/busses/i2c-pxa.c

@@ -29,38 +29,75 @@
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/i2c-pxa.h>
 #include <linux/i2c-pxa.h>
+#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/io.h>
+#include <linux/i2c/pxa-i2c.h>
 
 
 #include <asm/irq.h>
 #include <asm/irq.h>
-#include <plat/i2c.h>
+
+#ifndef CONFIG_HAVE_CLK
+#define clk_get(dev, id)	NULL
+#define clk_put(clk)		do { } while (0)
+#define clk_disable(clk)	do { } while (0)
+#define clk_enable(clk)		do { } while (0)
+#endif
+
+struct pxa_reg_layout {
+	u32 ibmr;
+	u32 idbr;
+	u32 icr;
+	u32 isr;
+	u32 isar;
+};
+
+enum pxa_i2c_types {
+	REGS_PXA2XX,
+	REGS_PXA3XX,
+	REGS_CE4100,
+};
 
 
 /*
 /*
- * I2C register offsets will be shifted 0 or 1 bit left, depending on
- * different SoCs
+ * I2C registers definitions
  */
  */
-#define REG_SHIFT_0	(0 << 0)
-#define REG_SHIFT_1	(1 << 0)
-#define REG_SHIFT(d)	((d) & 0x1)
+static struct pxa_reg_layout pxa_reg_layout[] = {
+	[REGS_PXA2XX] = {
+		.ibmr =	0x00,
+		.idbr =	0x08,
+		.icr =	0x10,
+		.isr =	0x18,
+		.isar =	0x20,
+	},
+	[REGS_PXA3XX] = {
+		.ibmr =	0x00,
+		.idbr =	0x04,
+		.icr =	0x08,
+		.isr =	0x0c,
+		.isar =	0x10,
+	},
+	[REGS_CE4100] = {
+		.ibmr =	0x14,
+		.idbr =	0x0c,
+		.icr =	0x00,
+		.isr =	0x04,
+		/* no isar register */
+	},
+};
 
 
 static const struct platform_device_id i2c_pxa_id_table[] = {
 static const struct platform_device_id i2c_pxa_id_table[] = {
-	{ "pxa2xx-i2c",		REG_SHIFT_1 },
-	{ "pxa3xx-pwri2c",	REG_SHIFT_0 },
+	{ "pxa2xx-i2c",		REGS_PXA2XX },
+	{ "pxa3xx-pwri2c",	REGS_PXA3XX },
+	{ "ce4100-i2c",		REGS_CE4100 },
 	{ },
 	{ },
 };
 };
 MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 
 
 /*
 /*
- * I2C registers and bit definitions
+ * I2C bit definitions
  */
  */
-#define IBMR		(0x00)
-#define IDBR		(0x08)
-#define ICR		(0x10)
-#define ISR		(0x18)
-#define ISAR		(0x20)
 
 
 #define ICR_START	(1 << 0)	   /* start bit */
 #define ICR_START	(1 << 0)	   /* start bit */
 #define ICR_STOP	(1 << 1)	   /* stop bit */
 #define ICR_STOP	(1 << 1)	   /* stop bit */
@@ -111,7 +148,11 @@ struct pxa_i2c {
 	u32			icrlog[32];
 	u32			icrlog[32];
 
 
 	void __iomem		*reg_base;
 	void __iomem		*reg_base;
-	unsigned int		reg_shift;
+	void __iomem		*reg_ibmr;
+	void __iomem		*reg_idbr;
+	void __iomem		*reg_icr;
+	void __iomem		*reg_isr;
+	void __iomem		*reg_isar;
 
 
 	unsigned long		iobase;
 	unsigned long		iobase;
 	unsigned long		iosize;
 	unsigned long		iosize;
@@ -121,11 +162,11 @@ struct pxa_i2c {
 	unsigned int		fast_mode :1;
 	unsigned int		fast_mode :1;
 };
 };
 
 
-#define _IBMR(i2c)	((i2c)->reg_base + (0x0 << (i2c)->reg_shift))
-#define _IDBR(i2c)	((i2c)->reg_base + (0x4 << (i2c)->reg_shift))
-#define _ICR(i2c)	((i2c)->reg_base + (0x8 << (i2c)->reg_shift))
-#define _ISR(i2c)	((i2c)->reg_base + (0xc << (i2c)->reg_shift))
-#define _ISAR(i2c)	((i2c)->reg_base + (0x10 << (i2c)->reg_shift))
+#define _IBMR(i2c)	((i2c)->reg_ibmr)
+#define _IDBR(i2c)	((i2c)->reg_idbr)
+#define _ICR(i2c)	((i2c)->reg_icr)
+#define _ISR(i2c)	((i2c)->reg_isr)
+#define _ISAR(i2c)	((i2c)->reg_isar)
 
 
 /*
 /*
  * I2C Slave mode address
  * I2C Slave mode address
@@ -418,7 +459,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 	writel(I2C_ISR_INIT, _ISR(i2c));
 	writel(I2C_ISR_INIT, _ISR(i2c));
 	writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
 	writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
 
 
-	writel(i2c->slave_addr, _ISAR(i2c));
+	if (i2c->reg_isar)
+		writel(i2c->slave_addr, _ISAR(i2c));
 
 
 	/* set control register values */
 	/* set control register values */
 	writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
 	writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
@@ -729,8 +771,10 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
 	 */
 	 */
 	ret = i2c->msg_idx;
 	ret = i2c->msg_idx;
 
 
-	if (timeout == 0)
+	if (!timeout && i2c->msg_num) {
 		i2c_pxa_scream_blue_murder(i2c, "timeout");
 		i2c_pxa_scream_blue_murder(i2c, "timeout");
+		ret = I2C_RETRY;
+	}
 
 
  out:
  out:
 	return ret;
 	return ret;
@@ -915,11 +959,16 @@ static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
 	writel(icr, _ICR(i2c));
 	writel(icr, _ICR(i2c));
 }
 }
 
 
+#define VALID_INT_SOURCE	(ISR_SSD | ISR_ALD | ISR_ITE | ISR_IRF | \
+				ISR_SAD | ISR_BED)
 static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
 static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
 {
 {
 	struct pxa_i2c *i2c = dev_id;
 	struct pxa_i2c *i2c = dev_id;
 	u32 isr = readl(_ISR(i2c));
 	u32 isr = readl(_ISR(i2c));
 
 
+	if (!(isr & VALID_INT_SOURCE))
+		return IRQ_NONE;
+
 	if (i2c_debug > 2 && 0) {
 	if (i2c_debug > 2 && 0) {
 		dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
 		dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
 			__func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
 			__func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
@@ -934,7 +983,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
 	/*
 	/*
 	 * Always clear all pending IRQs.
 	 * Always clear all pending IRQs.
 	 */
 	 */
-	writel(isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED), _ISR(i2c));
+	writel(isr & VALID_INT_SOURCE, _ISR(i2c));
 
 
 	if (isr & ISR_SAD)
 	if (isr & ISR_SAD)
 		i2c_pxa_slave_start(i2c, isr);
 		i2c_pxa_slave_start(i2c, isr);
@@ -1001,6 +1050,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	struct resource *res;
 	struct resource *res;
 	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
 	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
 	const struct platform_device_id *id = platform_get_device_id(dev);
 	const struct platform_device_id *id = platform_get_device_id(dev);
+	enum pxa_i2c_types i2c_type = id->driver_data;
 	int ret;
 	int ret;
 	int irq;
 	int irq;
 
 
@@ -1044,7 +1094,13 @@ static int i2c_pxa_probe(struct platform_device *dev)
 		ret = -EIO;
 		ret = -EIO;
 		goto eremap;
 		goto eremap;
 	}
 	}
-	i2c->reg_shift = REG_SHIFT(id->driver_data);
+
+	i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr;
+	i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
+	i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
+	i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
+	if (i2c_type != REGS_CE4100)
+		i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
 
 
 	i2c->iobase = res->start;
 	i2c->iobase = res->start;
 	i2c->iosize = resource_size(res);
 	i2c->iosize = resource_size(res);
@@ -1072,7 +1128,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
 		i2c->adap.algo = &i2c_pxa_pio_algorithm;
 		i2c->adap.algo = &i2c_pxa_pio_algorithm;
 	} else {
 	} else {
 		i2c->adap.algo = &i2c_pxa_algorithm;
 		i2c->adap.algo = &i2c_pxa_algorithm;
-		ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
+		ret = request_irq(irq, i2c_pxa_handler, IRQF_SHARED,
 				  i2c->adap.name, i2c);
 				  i2c->adap.name, i2c);
 		if (ret)
 		if (ret)
 			goto ereqirq;
 			goto ereqirq;
@@ -1082,12 +1138,19 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
 
 	i2c->adap.algo_data = i2c;
 	i2c->adap.algo_data = i2c;
 	i2c->adap.dev.parent = &dev->dev;
 	i2c->adap.dev.parent = &dev->dev;
+#ifdef CONFIG_OF
+	i2c->adap.dev.of_node = dev->dev.of_node;
+#endif
 
 
-	ret = i2c_add_numbered_adapter(&i2c->adap);
+	if (i2c_type == REGS_CE4100)
+		ret = i2c_add_adapter(&i2c->adap);
+	else
+		ret = i2c_add_numbered_adapter(&i2c->adap);
 	if (ret < 0) {
 	if (ret < 0) {
 		printk(KERN_INFO "I2C: Failed to add bus\n");
 		printk(KERN_INFO "I2C: Failed to add bus\n");
 		goto eadapt;
 		goto eadapt;
 	}
 	}
+	of_i2c_register_devices(&i2c->adap);
 
 
 	platform_set_drvdata(dev, i2c);
 	platform_set_drvdata(dev, i2c);
 
 

+ 0 - 0
arch/arm/plat-pxa/include/plat/i2c.h → include/linux/i2c/pxa-i2c.h