Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
authorLinus Torvalds <torvalds@woody.osdl.org>
Tue, 12 Dec 2006 17:57:55 +0000 (09:57 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Tue, 12 Dec 2006 17:57:55 +0000 (09:57 -0800)
* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
  i2c: Fix OMAP clock prescaler to match the comment
  i2c: Refactor a kfree in i2c-dev
  i2c: Fix return value check in i2c-dev
  i2c: Enable PEC on more i2c-i801 devices
  i2c: Discard the i2c algo del_bus wrappers
  i2c: New ARM Versatile/Realview bus driver
  i2c: fix broken ds1337 initialization
  i2c: i2c-i801 documentation update
  i2c: Use the __ATTR macro where possible
  i2c: Whitespace cleanups
  i2c: Use put_user instead of copy_to_user where possible
  i2c: New Atmel AT91 bus driver
  i2c: Add support for nested i2c bus locking
  i2c: Cleanups to the i2c-nforce2 bus driver
  i2c: Add request/release_mem_region to i2c-ibm_iic bus driver
  i2c: New Philips PNX bus driver
  i2c: Delete the broken i2c-ite bus driver
  i2c: Update the list of driver IDs
  i2c: Fix documentation typos

68 files changed:
Documentation/feature-removal-schedule.txt
Documentation/i2c/busses/i2c-amd8111
Documentation/i2c/busses/i2c-i801
Documentation/i2c/busses/i2c-nforce2
arch/arm/mach-pnx4008/Makefile
arch/arm/mach-pnx4008/i2c.c [new file with mode: 0644]
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.h
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-versatile/core.c
drivers/acorn/char/i2c.c
drivers/i2c/algos/Kconfig
drivers/i2c/algos/Makefile
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-ite.c [deleted file]
drivers/i2c/algos/i2c-algo-ite.h [deleted file]
drivers/i2c/algos/i2c-algo-pca.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/algos/i2c-algo-sgi.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-at91.c [new file with mode: 0644]
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-hydra.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-i810.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-ite.c [deleted file]
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-ixp4xx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-pnx.c [new file with mode: 0644]
drivers/i2c/busses/i2c-prosavage.c
drivers/i2c/busses/i2c-savage4.c
drivers/i2c/busses/i2c-versatile.c [new file with mode: 0644]
drivers/i2c/busses/i2c-via.c
drivers/i2c/busses/i2c-voodoo3.c
drivers/i2c/busses/scx200_i2c.c
drivers/i2c/chips/ds1337.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ieee1394/pcilynx.c
drivers/media/dvb/pluto2/pluto2.c
drivers/media/video/bt8xx/bttv-i2c.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/vino.c
drivers/media/video/zoran_card.c
drivers/video/aty/radeon_i2c.c
drivers/video/i810/i810-i2c.c
drivers/video/intelfb/intelfb_i2c.c
drivers/video/matrox/i2c-matroxfb.c
drivers/video/nvidia/nv_i2c.c
drivers/video/riva/rivafb-i2c.c
drivers/video/savage/savagefb-i2c.c
include/asm-arm/arch-pnx4008/i2c.h [new file with mode: 0644]
include/linux/i2c-algo-bit.h
include/linux/i2c-algo-ite.h [deleted file]
include/linux/i2c-algo-pca.h
include/linux/i2c-algo-pcf.h
include/linux/i2c-algo-sgi.h
include/linux/i2c-id.h
include/linux/i2c-pnx.h [new file with mode: 0644]
include/linux/i2c.h

index 46f2a55..031029e 100644 (file)
@@ -216,17 +216,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What:  i2c-ite and i2c-algo-ite drivers
-When:  September 2006
-Why:   These drivers never compiled since they were added to the kernel
-       tree 5 years ago. This feature removal can be reevaluated if
-       someone shows interest in the drivers, fixes them and takes over
-       maintenance.
-       http://marc.theaimsgroup.com/?l=linux-mips&m=115040510817448
-Who:   Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
 What:  Bridge netfilter deferred IPv4/IPv6 output hook calling
 When:  January 2007
 Why:   The deferred output hooks are a layering violation causing unusual
index db294ee..460dd66 100644 (file)
@@ -5,7 +5,7 @@ Supported adapters:
 
 Datasheets:
        AMD datasheet not yet available, but almost everything can be found
-       in publically available ACPI 2.0 specification, which the adapter 
+       in the publicly available ACPI 2.0 specification, which the adapter
        follows.
 
 Author: Vojtech Pavlik <vojtech@suse.cz>
index e46c234..3db69a0 100644 (file)
@@ -9,7 +9,10 @@ Supported adapters:
   * Intel 82801EB/ER (ICH5) (HW PEC supported, 32 byte buffer not supported)
   * Intel 6300ESB
   * Intel 82801FB/FR/FW/FRW (ICH6)
-  * Intel ICH7
+  * Intel 82801G (ICH7)
+  * Intel 631xESB/632xESB (ESB2)
+  * Intel 82801H (ICH8)
+  * Intel ICH9
     Datasheets: Publicly available at the Intel website
 
 Authors: 
index cd49c42..7f61fbc 100644 (file)
@@ -10,11 +10,11 @@ Supported adapters:
   * nForce4 MCP51              10de:0264
   * nForce4 MCP55              10de:0368
 
-Datasheet: not publically available, but seems to be similar to the
+Datasheet: not publicly available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
 
 Authors:
-       Hans-Frieder Vogt <hfvogt@arcor.de>, 
+       Hans-Frieder Vogt <hfvogt@gmx.net>,
        Thomas Leibold <thomas@plx.com>, 
         Patrick Dreker <patrick@dreker.de>
        
@@ -38,7 +38,7 @@ Notes
 -----
 
 The SMBus adapter in the nForce2 chipset seems to be very similar to the
-SMBus 2.0 adapter in the AMD-8111 southbridge. However, I could only get
+SMBus 2.0 adapter in the AMD-8111 south bridge. However, I could only get
 the driver to work with direct I/O access, which is different to the EC
 interface of the AMD-8111. Tested on Asus A7N8X. The ACPI DSDT table of the
 Asus A7N8X lists two SMBuses, both of which are supported by this driver.
index b457ca0..777564c 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                  := core.o irq.o time.o clock.o gpio.o serial.o dma.o
+obj-y                  := core.o irq.o time.o clock.o gpio.o serial.o dma.o i2c.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c
new file mode 100644 (file)
index 0000000..6f30882
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * I2C initialization for PNX4008.
+ *
+ * Author: Vitaly Wool <vitalywool@gmail.com>
+ *
+ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/i2c-pnx.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/i2c.h>
+
+static int set_clock_run(struct platform_device *pdev)
+{
+       struct clk *clk;
+       char name[10];
+       int retval = 0;
+
+       snprintf(name, 10, "i2c%d_ck", pdev->id);
+       clk = clk_get(&pdev->dev, name);
+       if (!IS_ERR(clk)) {
+               clk_set_rate(clk, 1);
+               clk_put(clk);
+       } else
+               retval = -ENOENT;
+
+       return retval;
+}
+
+static int set_clock_stop(struct platform_device *pdev)
+{
+       struct clk *clk;
+       char name[10];
+       int retval = 0;
+
+       snprintf(name, 10, "i2c%d_ck", pdev->id);
+       clk = clk_get(&pdev->dev, name);
+       if (!IS_ERR(clk)) {
+               clk_set_rate(clk, 0);
+               clk_put(clk);
+       } else
+               retval = -ENOENT;
+
+       return retval;
+}
+
+static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       int retval = 0;
+#ifdef CONFIG_PM
+       retval = set_clock_run(pdev);
+#endif
+       return retval;
+}
+
+static int i2c_pnx_resume(struct platform_device *pdev)
+{
+       int retval = 0;
+#ifdef CONFIG_PM
+       retval = set_clock_run(pdev);
+#endif
+       return retval;
+}
+
+static u32 calculate_input_freq(struct platform_device *pdev)
+{
+       return HCLK_MHZ;
+}
+
+
+static struct i2c_pnx_algo_data pnx_algo_data0 = {
+       .base = PNX4008_I2C1_BASE,
+       .irq = I2C_1_INT,
+};
+
+static struct i2c_pnx_algo_data pnx_algo_data1 = {
+       .base = PNX4008_I2C2_BASE,
+       .irq = I2C_2_INT,
+};
+
+static struct i2c_pnx_algo_data pnx_algo_data2 = {
+       .base = (PNX4008_USB_CONFIG_BASE + 0x300),
+       .irq = USB_I2C_INT,
+};
+
+static struct i2c_adapter pnx_adapter0 = {
+       .name = I2C_CHIP_NAME "0",
+       .algo_data = &pnx_algo_data0,
+};
+static struct i2c_adapter pnx_adapter1 = {
+       .name = I2C_CHIP_NAME "1",
+       .algo_data = &pnx_algo_data1,
+};
+
+static struct i2c_adapter pnx_adapter2 = {
+       .name = "USB-I2C",
+       .algo_data = &pnx_algo_data2,
+};
+
+static struct i2c_pnx_data i2c0_data = {
+       .suspend = i2c_pnx_suspend,
+       .resume = i2c_pnx_resume,
+       .calculate_input_freq = calculate_input_freq,
+       .set_clock_run = set_clock_run,
+       .set_clock_stop = set_clock_stop,
+       .adapter = &pnx_adapter0,
+};
+
+static struct i2c_pnx_data i2c1_data = {
+       .suspend = i2c_pnx_suspend,
+       .resume = i2c_pnx_resume,
+       .calculate_input_freq = calculate_input_freq,
+       .set_clock_run = set_clock_run,
+       .set_clock_stop = set_clock_stop,
+       .adapter = &pnx_adapter1,
+};
+
+static struct i2c_pnx_data i2c2_data = {
+       .suspend = i2c_pnx_suspend,
+       .resume = i2c_pnx_resume,
+       .calculate_input_freq = calculate_input_freq,
+       .set_clock_run = set_clock_run,
+       .set_clock_stop = set_clock_stop,
+       .adapter = &pnx_adapter2,
+};
+
+static struct platform_device i2c0_device = {
+       .name = "pnx-i2c",
+       .id = 0,
+       .dev = {
+               .platform_data = &i2c0_data,
+       },
+};
+
+static struct platform_device i2c1_device = {
+       .name = "pnx-i2c",
+       .id = 1,
+       .dev = {
+               .platform_data = &i2c1_data,
+       },
+};
+
+static struct platform_device i2c2_device = {
+       .name = "pnx-i2c",
+       .id = 2,
+       .dev = {
+               .platform_data = &i2c2_data,
+       },
+};
+
+static struct platform_device *devices[] __initdata = {
+       &i2c0_device,
+       &i2c1_device,
+       &i2c2_device,
+};
+
+void __init pnx4008_register_i2c_devices(void)
+{
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
index 68c6705..84d3fe7 100644 (file)
@@ -141,6 +141,19 @@ struct platform_device realview_smc91x_device = {
        .resource       = realview_smc91x_resources,
 };
 
+static struct resource realview_i2c_resource = {
+       .start          = REALVIEW_I2C_BASE,
+       .end            = REALVIEW_I2C_BASE + SZ_4K - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+struct platform_device realview_i2c_device = {
+       .name           = "versatile-i2c",
+       .id             = -1,
+       .num_resources  = 1,
+       .resource       = &realview_i2c_resource,
+};
+
 #define REALVIEW_SYSMCI        (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
 
 static unsigned int realview_mmc_status(struct device *dev)
index 93e86d9..2b53420 100644 (file)
@@ -108,6 +108,7 @@ static struct amba_device name##_device = {                 \
 
 extern struct platform_device realview_flash_device;
 extern struct platform_device realview_smc91x_device;
+extern struct platform_device realview_i2c_device;
 extern struct mmc_platform_data realview_mmc0_plat_data;
 extern struct mmc_platform_data realview_mmc1_plat_data;
 extern struct clk realview_clcd_clk;
index 84a9595..9741b4d 100644 (file)
@@ -155,6 +155,7 @@ static void __init realview_eb_init(void)
 
        platform_device_register(&realview_flash_device);
        platform_device_register(&realview_smc91x_device);
+       platform_device_register(&realview_i2c_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index 5719694..bf71507 100644 (file)
@@ -325,6 +325,19 @@ static struct platform_device smc91x_device = {
        .resource       = smc91x_resources,
 };
 
+static struct resource versatile_i2c_resource = {
+       .start                  = VERSATILE_I2C_BASE,
+       .end                    = VERSATILE_I2C_BASE + SZ_4K - 1,
+       .flags                  = IORESOURCE_MEM,
+};
+
+static struct platform_device versatile_i2c_device = {
+       .name                   = "versatile-i2c",
+       .id                     = -1,
+       .num_resources          = 1,
+       .resource               = &versatile_i2c_resource,
+};
+
 #define VERSATILE_SYSMCI       (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
 
 unsigned int mmc_status(struct device *dev)
@@ -775,6 +788,7 @@ void __init versatile_init(void)
        clk_register(&versatile_clcd_clk);
 
        platform_device_register(&versatile_flash_device);
+       platform_device_register(&versatile_i2c_device);
        platform_device_register(&smc91x_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
index bdb9c8b..9e584a7 100644 (file)
@@ -360,7 +360,7 @@ static int __init i2c_ioc_init(void)
        if (ret >= 0){
                ret = misc_register(&rtc_dev);
                if(ret < 0)
-                       i2c_bit_del_bus(&ioc_ops);
+                       i2c_del_adapter(&ioc_ops);
        }
 
        return ret;
index c034820..af02034 100644 (file)
@@ -38,17 +38,6 @@ config I2C_ALGOPCA
          This support is also available as a module.  If so, the module 
          will be called i2c-algo-pca.
 
-config I2C_ALGOITE
-       tristate "ITE I2C Algorithm"
-       depends on MIPS_ITE8172 && I2C
-       help
-         This supports the use of the ITE8172 I2C interface found on some MIPS
-         systems. Say Y if you have one of these. You should also say Y for
-         the ITE I2C peripheral driver support below.
-
-         This support is also available as a module.  If so, the module 
-         will be called i2c-algo-ite.
-
 config I2C_ALGO8XX
        tristate "MPC8xx CPM I2C interface"
        depends on 8xx && I2C
index 208be04..cac1051 100644 (file)
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C_ALGOBIT)      += i2c-algo-bit.o
 obj-$(CONFIG_I2C_ALGOPCF)      += i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ALGOPCA)      += i2c-algo-pca.o
-obj-$(CONFIG_I2C_ALGOITE)      += i2c-algo-ite.o
 obj-$(CONFIG_I2C_ALGO_SGI)     += i2c-algo-sgi.o
 
 ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
index 21c36bf..95aa539 100644 (file)
@@ -540,15 +540,7 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
 
        return i2c_add_adapter(adap);
 }
-
-
-int i2c_bit_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_bit_add_bus);
-EXPORT_SYMBOL(i2c_bit_del_bus);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c
deleted file mode 100644 (file)
index 70d8eef..0000000
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-algo-ite.c i2c driver algorithms for ITE adapters           
-   
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2000 MontaVista Software Inc.
-
-   ---------------------------------------------------------------------------
-   This file was highly leveraged from i2c-algo-pcf.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
-
-     Copyright (C) 1995-1997 Simon G. Vogl
-                   1998-2000 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 
-   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
-   <mbailey@littlefeet-inc.com> */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ite.h>
-#include "i2c-algo-ite.h"
-
-#define        PM_DSR          IT8172_PCI_IO_BASE + IT_PM_DSR
-#define        PM_IBSR         IT8172_PCI_IO_BASE + IT_PM_DSR + 0x04 
-#define GPIO_CCR       IT8172_PCI_IO_BASE + IT_GPCCR
-
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEF_TIMEOUT 16
-
-
-/* module parameters:
- */
-static int i2c_debug;
-static int iic_test;   /* see if the line-setting functions work       */
-
-/* --- setting states on the bus with the right timing: ---------------        */
-
-#define get_clock(adap) adap->getclock(adap->data)
-#define iic_outw(adap, reg, val) adap->setiic(adap->data, reg, val)
-#define iic_inw(adap, reg) adap->getiic(adap->data, reg)
-
-
-/* --- other auxiliary functions --------------------------------------        */
-
-static void iic_start(struct i2c_algo_iic_data *adap)
-{
-       iic_outw(adap,ITE_I2CHCR,ITE_CMD);
-}
-
-static void iic_stop(struct i2c_algo_iic_data *adap)
-{
-       iic_outw(adap,ITE_I2CHCR,0);
-       iic_outw(adap,ITE_I2CHSR,ITE_I2CHSR_TDI);
-}
-
-static void iic_reset(struct i2c_algo_iic_data *adap)
-{
-       iic_outw(adap, PM_IBSR, iic_inw(adap, PM_IBSR) | 0x80);
-}
-
-
-static int wait_for_bb(struct i2c_algo_iic_data *adap)
-{
-       int timeout = DEF_TIMEOUT;
-       short status;
-
-       status = iic_inw(adap, ITE_I2CHSR);
-#ifndef STUB_I2C
-       while (timeout-- && (status & ITE_I2CHSR_HB)) {
-               udelay(1000); /* How much is this? */
-               status = iic_inw(adap, ITE_I2CHSR);
-       }
-#endif
-       if (timeout<=0) {
-               printk(KERN_ERR "Timeout, host is busy\n");
-               iic_reset(adap);
-       }
-       return(timeout<=0);
-}
-
-/* After we issue a transaction on the IIC bus, this function
- * is called.  It puts this process to sleep until we get an interrupt from
- * from the controller telling us that the transaction we requested in complete.
- */
-static int wait_for_pin(struct i2c_algo_iic_data *adap, short *status) {
-
-       int timeout = DEF_TIMEOUT;
-       
-       timeout = wait_for_bb(adap);
-       if (timeout) {
-               DEB2(printk("Timeout waiting for host not busy\n");)
-               return -EIO;
-       }                           
-       timeout = DEF_TIMEOUT;
-
-       *status = iic_inw(adap, ITE_I2CHSR);
-#ifndef STUB_I2C
-       while (timeout-- && !(*status & ITE_I2CHSR_TDI)) {
-          adap->waitforpin();
-          *status = iic_inw(adap, ITE_I2CHSR);
-       }
-#endif
-       if (timeout <= 0)
-               return(-1);
-       else
-               return(0);
-}
-
-static int wait_for_fe(struct i2c_algo_iic_data *adap, short *status)
-{
-       int timeout = DEF_TIMEOUT;
-
-       *status = iic_inw(adap, ITE_I2CFSR);
-#ifndef STUB_I2C 
-       while (timeout-- && (*status & ITE_I2CFSR_FE)) {
-               udelay(1000);
-               iic_inw(adap, ITE_I2CFSR);
-       }
-#endif
-       if (timeout <= 0) 
-               return(-1);
-       else
-               return(0);
-}
-
-static int iic_init (struct i2c_algo_iic_data *adap)
-{
-       short i;
-
-       /* Clear bit 7 to set I2C to normal operation mode */
-       i=iic_inw(adap, PM_DSR)& 0xff7f;
-       iic_outw(adap, PM_DSR, i);
-
-       /* set IT_GPCCR port C bit 2&3 as function 2 */
-       i = iic_inw(adap, GPIO_CCR) & 0xfc0f;
-       iic_outw(adap,GPIO_CCR,i);
-
-       /* Clear slave address/sub-address */
-       iic_outw(adap,ITE_I2CSAR, 0);
-       iic_outw(adap,ITE_I2CSSAR, 0);
-
-       /* Set clock counter register */
-       iic_outw(adap,ITE_I2CCKCNT, get_clock(adap));
-
-       /* Set START/reSTART/STOP time registers */
-       iic_outw(adap,ITE_I2CSHDR, 0x0a);
-       iic_outw(adap,ITE_I2CRSUR, 0x0a);
-       iic_outw(adap,ITE_I2CPSUR, 0x0a);
-
-       /* Enable interrupts on completing the current transaction */
-       iic_outw(adap,ITE_I2CHCR, ITE_I2CHCR_IE | ITE_I2CHCR_HCE);
-
-       /* Clear transfer count */
-       iic_outw(adap,ITE_I2CFBCR, 0x0);
-
-       DEB2(printk("iic_init: Initialized IIC on ITE 0x%x\n",
-               iic_inw(adap, ITE_I2CHSR)));
-       return 0;
-}
-
-
-/*
- * Sanity check for the adapter hardware - check the reaction of
- * the bus lines only if it seems to be idle.
- */
-static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
-#if 0
-       int scl,sda;
-       sda=getsda(adap);
-       if (adap->getscl==NULL) {
-               printk("test_bus: Warning: Adapter can't read from clock line - skipping test.\n");
-               return 0;               
-       }
-       scl=getscl(adap);
-       printk("test_bus: Adapter: %s scl: %d  sda: %d -- testing...\n",
-       name,getscl(adap),getsda(adap));
-       if (!scl || !sda ) {
-               printk("test_bus: %s seems to be busy.\n",adap->name);
-               goto bailout;
-       }
-       sdalo(adap);
-       printk("test_bus:1 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 != getsda(adap) ) {
-               printk("test_bus: %s SDA stuck high!\n",name);
-               sdahi(adap);
-               goto bailout;
-       }
-       if ( 0 == getscl(adap) ) {
-               printk("test_bus: %s SCL unexpected low while pulling SDA low!\n",
-                       name);
-               goto bailout;
-       }               
-       sdahi(adap);
-       printk("test_bus:2 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 == getsda(adap) ) {
-               printk("test_bus: %s SDA stuck low!\n",name);
-               sdahi(adap);
-               goto bailout;
-       }
-       if ( 0 == getscl(adap) ) {
-               printk("test_bus: %s SCL unexpected low while SDA high!\n",
-                      adap->name);
-       goto bailout;
-       }
-       scllo(adap);
-       printk("test_bus:3 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 != getscl(adap) ) {
-
-               sclhi(adap);
-               goto bailout;
-       }
-       if ( 0 == getsda(adap) ) {
-               printk("test_bus: %s SDA unexpected low while pulling SCL low!\n",
-                       name);
-               goto bailout;
-       }
-       sclhi(adap);
-       printk("test_bus:4 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 == getscl(adap) ) {
-               printk("test_bus: %s SCL stuck low!\n",name);
-               sclhi(adap);
-               goto bailout;
-       }
-       if ( 0 == getsda(adap) ) {
-               printk("test_bus: %s SDA unexpected low while SCL high!\n",
-                       name);
-               goto bailout;
-       }
-       printk("test_bus: %s passed test.\n",name);
-       return 0;
-bailout:
-       sdahi(adap);
-       sclhi(adap);
-       return -ENODEV;
-#endif
-       return (0);
-}
-
-/* ----- Utility functions
- */
-
-
-/* Verify the device we want to talk to on the IIC bus really exists. */
-static inline int try_address(struct i2c_algo_iic_data *adap,
-                      unsigned int addr, int retries)
-{
-       int i, ret = -1;
-       short status;
-
-       for (i=0;i<retries;i++) {
-               iic_outw(adap, ITE_I2CSAR, addr);
-               iic_start(adap);
-               if (wait_for_pin(adap, &status) == 0) {
-                       if ((status & ITE_I2CHSR_DNE) == 0) { 
-                               iic_stop(adap);
-                               iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
-                               ret=1;
-                               break;  /* success! */
-                       }
-               }
-               iic_stop(adap);
-               udelay(adap->udelay);
-       }
-       DEB2(if (i) printk("try_address: needed %d retries for 0x%x\n",i,
-                          addr));
-       return ret;
-}
-
-
-static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-                         int count)
-{
-       struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-       int wrcount=0, timeout;
-       short status;
-       int loops, remainder, i, j;
-       union {
-               char byte[2];
-               unsigned short word;
-       } tmp;
-   
-       iic_outw(adap, ITE_I2CSSAR, (unsigned short)buf[wrcount++]);
-       count--;
-       if (count == 0)
-               return -EIO;
-
-       loops =  count / 32;            /* 32-byte FIFO */
-       remainder = count % 32;
-
-       if(loops) {
-               for(i=0; i<loops; i++) {
-
-                       iic_outw(adap, ITE_I2CFBCR, 32);
-                       for(j=0; j<32/2; j++) {
-                               tmp.byte[1] = buf[wrcount++];
-                               tmp.byte[0] = buf[wrcount++];
-                               iic_outw(adap, ITE_I2CFDR, tmp.word); 
-                       }
-
-                       /* status FIFO overrun */
-                       iic_inw(adap, ITE_I2CFSR);
-                       iic_inw(adap, ITE_I2CFBCR);
-
-                       iic_outw(adap, ITE_I2CHCR, ITE_WRITE);  /* Issue WRITE command */
-
-                       /* Wait for transmission to complete */
-                       timeout = wait_for_pin(adap, &status);
-                       if(timeout) {
-                               iic_stop(adap);
-                               printk("iic_sendbytes: %s write timeout.\n", i2c_adap->name);
-                               return -EREMOTEIO; /* got a better one ?? */
-       }
-                       if (status & ITE_I2CHSR_DB) {
-                               iic_stop(adap);
-                               printk("iic_sendbytes: %s write error - no ack.\n", i2c_adap->name);
-                               return -EREMOTEIO; /* got a better one ?? */
-                       }
-               }
-       }
-       if(remainder) {
-               iic_outw(adap, ITE_I2CFBCR, remainder);
-               for(i=0; i<remainder/2; i++) {
-                       tmp.byte[1] = buf[wrcount++];
-                       tmp.byte[0] = buf[wrcount++];
-                       iic_outw(adap, ITE_I2CFDR, tmp.word);
-               }
-
-               /* status FIFO overrun */
-               iic_inw(adap, ITE_I2CFSR);
-               iic_inw(adap, ITE_I2CFBCR);
-
-               iic_outw(adap, ITE_I2CHCR, ITE_WRITE);  /* Issue WRITE command */
-
-               timeout = wait_for_pin(adap, &status);
-               if(timeout) {
-                       iic_stop(adap);
-                       printk("iic_sendbytes: %s write timeout.\n", i2c_adap->name);
-                       return -EREMOTEIO; /* got a better one ?? */
-               }
-#ifndef STUB_I2C
-               if (status & ITE_I2CHSR_DB) { 
-                       iic_stop(adap);
-                       printk("iic_sendbytes: %s write error - no ack.\n", i2c_adap->name);
-                       return -EREMOTEIO; /* got a better one ?? */
-               }
-#endif
-       }
-       iic_stop(adap);
-       return wrcount;
-}
-
-
-static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count,
-       int sread)
-{
-       int rdcount=0, i, timeout;
-       short status;
-       struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-       int loops, remainder, j;
-       union {
-               char byte[2];
-               unsigned short word;
-       } tmp;
-               
-       loops = count / 32;                             /* 32-byte FIFO */
-       remainder = count % 32;
-
-       if(loops) {
-               for(i=0; i<loops; i++) {
-                       iic_outw(adap, ITE_I2CFBCR, 32);
-                       if (sread)
-                               iic_outw(adap, ITE_I2CHCR, ITE_SREAD);
-                       else
-                               iic_outw(adap, ITE_I2CHCR, ITE_READ);           /* Issue READ command */
-
-                       timeout = wait_for_pin(adap, &status);
-                       if(timeout) {
-                               iic_stop(adap);
-                               printk("iic_readbytes:  %s read timeout.\n", i2c_adap->name);
-                               return (-1);
-                       }
-#ifndef STUB_I2C
-                       if (status & ITE_I2CHSR_DB) {
-                               iic_stop(adap);
-                               printk("iic_readbytes: %s read error - no ack.\n", i2c_adap->name);
-                               return (-1);
-                       }
-#endif
-
-                       timeout = wait_for_fe(adap, &status);
-                       if(timeout) {
-                               iic_stop(adap);
-                               printk("iic_readbytes:  %s FIFO is empty\n", i2c_adap->name);
-                               return (-1); 
-                       }
-
-                       for(j=0; j<32/2; j++) {
-                               tmp.word = iic_inw(adap, ITE_I2CFDR);
-                               buf[rdcount++] = tmp.byte[1];
-                               buf[rdcount++] = tmp.byte[0];
-                       }
-
-                       /* status FIFO underrun */
-                       iic_inw(adap, ITE_I2CFSR);
-
-               }
-       }
-
-
-       if(remainder) {
-               remainder=(remainder+1)/2 * 2;
-               iic_outw(adap, ITE_I2CFBCR, remainder);
-               if (sread)
-                       iic_outw(adap, ITE_I2CHCR, ITE_SREAD);
-               else
-               iic_outw(adap, ITE_I2CHCR, ITE_READ);           /* Issue READ command */
-
-               timeout = wait_for_pin(adap, &status);
-               if(timeout) {
-                       iic_stop(adap);
-                       printk("iic_readbytes:  %s read timeout.\n", i2c_adap->name);
-                       return (-1);
-               }
-#ifndef STUB_I2C
-               if (status & ITE_I2CHSR_DB) {
-                       iic_stop(adap);
-                       printk("iic_readbytes: %s read error - no ack.\n", i2c_adap->name);
-                       return (-1);
-               }
-#endif
-               timeout = wait_for_fe(adap, &status);
-               if(timeout) {
-                       iic_stop(adap);
-                       printk("iic_readbytes:  %s FIFO is empty\n", i2c_adap->name);
-                       return (-1);
-               }         
-
-               for(i=0; i<(remainder+1)/2; i++) {
-                       tmp.word = iic_inw(adap, ITE_I2CFDR);
-                       buf[rdcount++] = tmp.byte[1];
-                       buf[rdcount++] = tmp.byte[0];
-               }
-
-               /* status FIFO underrun */
-               iic_inw(adap, ITE_I2CFSR);
-
-       }
-
-       iic_stop(adap);
-       return rdcount;
-}
-
-
-/* This function implements combined transactions.  Combined
- * transactions consist of combinations of reading and writing blocks of data.
- * Each transfer (i.e. a read or a write) is separated by a repeated start
- * condition.
- */
-#if 0
-static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 
-{
-   int i;
-   struct i2c_msg *pmsg;
-   int ret;
-
-   DEB2(printk("Beginning combined transaction\n"));
-
-   for(i=0; i<(num-1); i++) {
-      pmsg = &msgs[i];
-      if(pmsg->flags & I2C_M_RD) {
-         DEB2(printk("  This one is a read\n"));
-         ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_COMBINED_XFER);
-      }
-      else if(!(pmsg->flags & I2C_M_RD)) {
-         DEB2(printk("This one is a write\n"));
-         ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_COMBINED_XFER);
-      }
-   }
-   /* Last read or write segment needs to be terminated with a stop */
-   pmsg = &msgs[i];
-
-   if(pmsg->flags & I2C_M_RD) {
-      DEB2(printk("Doing the last read\n"));
-      ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-   }
-   else if(!(pmsg->flags & I2C_M_RD)) {
-      DEB2(printk("Doing the last write\n"));
-      ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-   }
-
-   return ret;
-}
-#endif
-
-
-/* Whenever we initiate a transaction, the first byte clocked
- * onto the bus after the start condition is the address (7 bit) of the
- * device we want to talk to.  This function manipulates the address specified
- * so that it makes sense to the hardware when written to the IIC peripheral.
- *
- * Note: 10 bit addresses are not supported in this driver, although they are
- * supported by the hardware.  This functionality needs to be implemented.
- */
-static inline int iic_doAddress(struct i2c_algo_iic_data *adap,
-                                struct i2c_msg *msg, int retries) 
-{
-       unsigned short flags = msg->flags;
-       unsigned int addr;
-       int ret;
-
-/* Ten bit addresses not supported right now */
-       if ( (flags & I2C_M_TEN)  ) { 
-#if 0
-               addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-               DEB2(printk("addr0: %d\n",addr));
-               ret = try_address(adap, addr, retries);
-               if (ret!=1) {
-                       printk("iic_doAddress: died at extended address code.\n");
-                       return -EREMOTEIO;
-               }
-               iic_outw(adap,msg->addr & 0x7f);
-               if (ret != 1) {
-                       printk("iic_doAddress: died at 2nd address code.\n");
-                       return -EREMOTEIO;
-               }
-               if ( flags & I2C_M_RD ) {
-                       i2c_repstart(adap);
-                       addr |= 0x01;
-                       ret = try_address(adap, addr, retries);
-                       if (ret!=1) {
-                               printk("iic_doAddress: died at extended address code.\n");
-                               return -EREMOTEIO;
-                       }
-               }
-#endif
-       } else {
-
-               addr = ( msg->addr << 1 );
-
-#if 0
-               if (flags & I2C_M_RD )
-                       addr |= 1;
-               if (flags & I2C_M_REV_DIR_ADDR )
-                       addr ^= 1;
-#endif
-
-               if (iic_inw(adap, ITE_I2CSAR) != addr) {
-                       iic_outw(adap, ITE_I2CSAR, addr);
-                       ret = try_address(adap, addr, retries);
-                       if (ret!=1) {
-                               printk("iic_doAddress: died at address code.\n");
-                               return -EREMOTEIO;
-                       }
-               }
-
-  }
-
-       return 0;
-}
-
-
-/* Description: Prepares the controller for a transaction (clearing status
- * registers, data buffers, etc), and then calls either iic_readbytes or
- * iic_sendbytes to do the actual transaction.
- *
- * still to be done: Before we issue a transaction, we should
- * verify that the bus is not busy or in some unknown state.
- */
-static int iic_xfer(struct i2c_adapter *i2c_adap,
-                   struct i2c_msg *msgs, 
-                   int num)
-{
-       struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-       struct i2c_msg *pmsg;
-       int i = 0;
-       int ret, timeout;
-    
-       pmsg = &msgs[i];
-
-       if(!pmsg->len) {
-               DEB2(printk("iic_xfer: read/write length is 0\n");)
-               return -EIO;
-       }
-       if(!(pmsg->flags & I2C_M_RD) && (!(pmsg->len)%2) ) {
-               DEB2(printk("iic_xfer: write buffer length is not odd\n");)
-               return -EIO; 
-       }
-
-       /* Wait for any pending transfers to complete */
-       timeout = wait_for_bb(adap);
-       if (timeout) {
-               DEB2(printk("iic_xfer: Timeout waiting for host not busy\n");)
-               return -EIO;
-       }
-
-       /* Flush FIFO */
-       iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
-
-       /* Load address */
-       ret = iic_doAddress(adap, pmsg, i2c_adap->retries);
-       if (ret)
-               return -EIO;
-
-#if 0
-       /* Combined transaction (read and write) */
-       if(num > 1) {
-           DEB2(printk("iic_xfer: Call combined transaction\n"));
-           ret = iic_combined_transaction(i2c_adap, msgs, num);
-  }
-#endif
-
-       DEB3(printk("iic_xfer: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
-               i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-
-       if(pmsg->flags & I2C_M_RD)              /* Read */
-               ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, 0);
-       else {                                                                                                  /* Write */ 
-               udelay(1000);
-               ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len);
-       }
-
-       if (ret != pmsg->len)
-               DEB3(printk("iic_xfer: error or fail on read/write %d bytes.\n",ret)); 
-       else
-               DEB3(printk("iic_xfer: read/write %d bytes.\n",ret));
-
-       return ret;
-}
-
-
-/* Implements device specific ioctls.  Higher level ioctls can
- * be found in i2c-core.c and are typical of any i2c controller (specifying
- * slave address, timeouts, etc).  These ioctls take advantage of any hardware
- * features built into the controller for which this algorithm-adapter set
- * was written.  These ioctls allow you to take control of the data and clock
- * lines and set the either high or low,
- * similar to a GPIO pin.
- */
-static int algo_control(struct i2c_adapter *adapter, 
-       unsigned int cmd, unsigned long arg)
-{
-
-  struct i2c_algo_iic_data *adap = adapter->algo_data;
-  struct i2c_iic_msg s_msg;
-  char *buf;
-       int ret;
-
-  if (cmd == I2C_SREAD) {
-               if(copy_from_user(&s_msg, (struct i2c_iic_msg *)arg, 
-                               sizeof(struct i2c_iic_msg))) 
-                       return -EFAULT;
-               buf = kmalloc(s_msg.len, GFP_KERNEL);
-               if (buf== NULL)
-                       return -ENOMEM;
-
-               /* Flush FIFO */
-               iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
-
-               /* Load address */
-               iic_outw(adap, ITE_I2CSAR,s_msg.addr<<1);
-               iic_outw(adap, ITE_I2CSSAR,s_msg.waddr & 0xff);
-
-               ret = iic_readbytes(adapter, buf, s_msg.len, 1);
-               if (ret>=0) {
-                       if(copy_to_user( s_msg.buf, buf, s_msg.len) ) 
-                               ret = -EFAULT;
-               }
-               kfree(buf);
-       }
-       return 0;
-}
-
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-              I2C_FUNC_PROTOCOL_MANGLING; 
-}
-
-/* -----exported algorithm data: ------------------------------------- */
-
-static struct i2c_algorithm iic_algo = {
-       .master_xfer    = iic_xfer,
-       .algo_control   = algo_control, /* ioctl */
-       .functionality  = iic_func,
-};
-
-
-/* 
- * registering functions to load algorithms at runtime 
- */
-int i2c_iic_add_bus(struct i2c_adapter *adap)
-{
-       struct i2c_algo_iic_data *iic_adap = adap->algo_data;
-
-       if (iic_test) {
-               int ret = test_bus(iic_adap, adap->name);
-               if (ret<0)
-                       return -ENODEV;
-       }
-
-       DEB2(printk("i2c-algo-ite: hw routines for %s registered.\n",
-                   adap->name));
-
-       /* register new adapter to i2c module... */
-       adap->algo = &iic_algo;
-
-       adap->timeout = 100;    /* default values, should       */
-       adap->retries = 3;              /* be replaced by defines       */
-       adap->flags = 0;
-
-       iic_init(iic_adap);
-       return i2c_add_adapter(adap);
-}
-
-
-int i2c_iic_del_bus(struct i2c_adapter *adap)
-{
-       int res;
-       if ((res = i2c_del_adapter(adap)) < 0)
-               return res;
-       DEB2(printk("i2c-algo-ite: adapter unregistered: %s\n",adap->name));
-
-       return 0;
-}
-
-
-int __init i2c_algo_iic_init (void)
-{
-       printk(KERN_INFO "ITE iic (i2c) algorithm module\n");
-       return 0;
-}
-
-
-void i2c_algo_iic_exit(void)
-{
-       return;
-}
-
-
-EXPORT_SYMBOL(i2c_iic_add_bus);
-EXPORT_SYMBOL(i2c_iic_del_bus);
-
-/* The MODULE_* macros resolve to nothing if MODULES is not defined
- * when this file is compiled.
- */
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("ITE iic algorithm");
-MODULE_LICENSE("GPL");
-
-module_param(iic_test, bool, 0);
-module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
-
-MODULE_PARM_DESC(iic_test, "Test if the I2C bus is available");
-MODULE_PARM_DESC(i2c_debug,
-        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
-
-
-/* This function resolves to init_module (the function invoked when a module
- * is loaded via insmod) when this file is compiled with MODULES defined.
- * Otherwise (i.e. if you want this driver statically linked to the kernel),
- * a pointer to this function is stored in a table and called
- * during the initialization of the kernel (in do_basic_setup in /init/main.c) 
- *
- * All this functionality is complements of the macros defined in linux/init.h
- */
-module_init(i2c_algo_iic_init);
-
-
-/* If MODULES is defined when this file is compiled, then this function will
- * resolved to cleanup_module.
- */
-module_exit(i2c_algo_iic_exit);
diff --git a/drivers/i2c/algos/i2c-algo-ite.h b/drivers/i2c/algos/i2c-algo-ite.h
deleted file mode 100644 (file)
index a8ca3c9..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-   --------------------------------------------------------------------
-   i2c-ite.h: Global defines for the I2C controller on board the    
-                 ITE MIPS processor.                                
-   --------------------------------------------------------------------
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2001 MontaVista Software Inc.
-
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
-#ifndef I2C_ITE_H
-#define I2C_ITE_H 1
-
-#include <asm/it8172/it8172.h>
-
-/* I2C Registers */
-#define ITE_I2CHCR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x30
-#define ITE_I2CHSR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x34
-#define ITE_I2CSAR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x38
-#define ITE_I2CSSAR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x3c
-#define ITE_I2CCKCNT   IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x48
-#define ITE_I2CSHDR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x4c
-#define ITE_I2CRSUR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x50
-#define ITE_I2CPSUR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x54
-
-#define ITE_I2CFDR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x70
-#define ITE_I2CFBCR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x74
-#define ITE_I2CFCR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x78
-#define ITE_I2CFSR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x7c
-
-
-/* Host Control Register ITE_I2CHCR */
-#define        ITE_I2CHCR_HCE  0x01    /* Enable I2C Host Controller */
-#define        ITE_I2CHCR_IE   0x02    /* Enable the interrupt after completing
-                                  the current transaction */
-#define ITE_I2CHCR_CP_W        0x00    /* bit2-4 000 - Write */
-#define        ITE_I2CHCR_CP_R 0x08    /*        010 - Current address read */
-#define        ITE_I2CHCR_CP_S 0x10    /*        100 - Sequential read */
-#define ITE_I2CHCR_ST  0x20    /* Initiates the I2C host controller to execute
-                                  the command and send the data programmed in
-                                  all required registers to I2C bus */
-#define ITE_CMD                ITE_I2CHCR_HCE | ITE_I2CHCR_IE | ITE_I2CHCR_ST
-#define ITE_WRITE      ITE_CMD | ITE_I2CHCR_CP_W
-#define ITE_READ       ITE_CMD | ITE_I2CHCR_CP_R
-#define ITE_SREAD      ITE_CMD | ITE_I2CHCR_CP_S
-
-/* Host Status Register ITE_I2CHSR */
-#define        ITE_I2CHSR_DB   0x01    /* Device is busy, receives NACK response except
-                                  in the first and last bytes */
-#define        ITE_I2CHSR_DNE  0x02    /* Target address on I2C bus does not exist */
-#define        ITE_I2CHSR_TDI  0x04    /* R/W Transaction on I2C bus was completed */
-#define        ITE_I2CHSR_HB   0x08    /* Host controller is processing transactions */
-#define        ITE_I2CHSR_FER  0x10    /* Error occurs in the FIFO */
-
-/* Slave Address Register ITE_I2CSAR */
-#define        ITE_I2CSAR_SA_MASK      0xfe    /* Target I2C device address */
-#define        ITE_I2CSAR_ASO          0x0100  /* Output 1/0 to I2CAS port when the
-                                          next slave address is addressed */
-
-/* Slave Sub-address Register ITE_I2CSSAR */
-#define        ITE_I2CSSAR_SUBA_MASK   0xff    /* Target I2C device sub-address */
-
-/* Clock Counter Register ITE_I2CCKCNT */
-#define        ITE_I2CCKCNT_STOP       0x00    /* stop I2C clock */
-#define        ITE_I2CCKCNT_HPCC_MASK  0x7f    /* SCL high period counter */
-#define        ITE_I2CCKCNT_LPCC_MASK  0x7f00  /* SCL low period counter */
-
-/* START Hold Time Register ITE_I2CSHDR */
-/* value is counted based on 16 MHz internal clock */
-#define ITE_I2CSHDR_FM 0x0a    /* START condition at fast mode */
-#define        ITE_I2CSHDR_SM  0x47    /* START contition at standard mode */
-
-/* (Repeated) START Setup Time Register ITE_I2CRSUR */
-/* value is counted based on 16 MHz internal clock */
-#define        ITE_I2CRSUR_FM  0x0a    /* repeated START condition at fast mode */
-#define        ITE_I2CRSUR_SM  0x50    /* repeated START condition at standard mode */
-
-/* STOP setup Time Register ITE_I2CPSUR */
-
-/* FIFO Data Register ITE_I2CFDR */
-#define        ITE_I2CFDR_MASK         0xff
-
-/* FIFO Byte Count Register ITE_I2CFBCR */
-#define ITE_I2CFBCR_MASK       0x3f
-
-/* FIFO Control Register ITE_I2CFCR */
-#define        ITE_I2CFCR_FLUSH        0x01    /* Flush FIFO and reset the FIFO point
-                                          and I2CFSR */
-/* FIFO Status Register ITE_I2CFSR */
-#define        ITE_I2CFSR_FO   0x01    /* FIFO is overrun when write */
-#define        ITE_I2CFSR_FU   0x02    /* FIFO is underrun when read */
-#define        ITE_I2CFSR_FF   0x04    /* FIFO is full when write */
-#define        ITE_I2CFSR_FE   0x08    /* FIFO is empty when read */
-
-#endif  /* I2C_ITE_H */
index 9081c9f..36fdf97 100644 (file)
@@ -381,14 +381,7 @@ int i2c_pca_add_bus(struct i2c_adapter *adap)
 
        return rval;
 }
-
-int i2c_pca_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_pca_add_bus);
-EXPORT_SYMBOL(i2c_pca_del_bus);
 
 MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
 MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
index 3b20033..ecb2c2d 100644 (file)
@@ -486,15 +486,7 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
 
        return rval;
 }
-
-
-int i2c_pcf_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_pcf_add_bus);
-EXPORT_SYMBOL(i2c_pcf_del_bus);
 
 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
 MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
index 490d999..ac2d505 100644 (file)
@@ -171,15 +171,7 @@ int i2c_sgi_add_bus(struct i2c_adapter *adap)
 
        return i2c_add_adapter(adap);
 }
-
-
-int i2c_sgi_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_sgi_add_bus);
-EXPORT_SYMBOL(i2c_sgi_del_bus);
 
 MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
 MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
index 90f91d0..e1989f3 100644 (file)
@@ -74,6 +74,13 @@ config I2C_AMD8111
          This driver can also be built as a module.  If so, the module
          will be called i2c-amd8111.
 
+config I2C_AT91
+       tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
+       depends on I2C && ARCH_AT91 && EXPERIMENTAL
+       help
+         This supports the use of the I2C interface on Atmel AT91
+         processors.
+
 config I2C_AU1550
        tristate "Au1550/Au1200 SMBus interface"
        depends on I2C && (SOC_AU1550 || SOC_AU1200)
@@ -209,18 +216,6 @@ config I2C_ISA
        tristate
        depends on I2C
 
-config I2C_ITE
-       tristate "ITE I2C Adapter"
-       depends on I2C && MIPS_ITE8172
-       select I2C_ALGOITE
-       help
-         This supports the ITE8172 I2C peripheral found on some MIPS
-         systems. Say Y if you have one of these. You should also say Y for
-         the ITE I2C driver algorithm support above.
-
-         This support is also available as a module.  If so, the module 
-         will be called i2c-ite.
-
 config I2C_IXP4XX
        tristate "IXP4xx GPIO-Based I2C Interface"
        depends on I2C && ARCH_IXP4XX
@@ -481,6 +476,17 @@ config I2C_STUB
 
          If you don't know what to do here, definitely say N.
 
+config I2C_VERSATILE
+       tristate "ARM Versatile/Realview I2C bus support"
+       depends on I2C && (ARCH_VERSATILE || ARCH_REALVIEW)
+       select I2C_ALGOBIT
+       help
+         Say yes if you want to support the I2C serial bus on ARMs Versatile
+         range of platforms.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-versatile.
+
 config I2C_VIA
        tristate "VIA 82C586B"
        depends on I2C && PCI && EXPERIMENTAL
@@ -548,4 +554,23 @@ config I2C_MV64XXX
          This driver can also be built as a module.  If so, the module
          will be called i2c-mv64xxx.
 
+config I2C_PNX
+       tristate "I2C bus support for Philips PNX targets"
+       depends on ARCH_PNX4008 && I2C
+       help
+         This driver supports the Philips IP3204 I2C IP block master and/or
+         slave controller
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-pnx.
+
+config I2C_PNX_EARLY
+       bool "Early initialization for I2C on PNXxxxx"
+       depends on I2C_PNX=y
+       help
+         Under certain circumstances one may need to make sure I2C on PNXxxxx
+         is initialized earlier than some other driver that depends on it
+         (for instance, that might be USB in case of PNX4008). With this
+         option turned on you can guarantee that.
+
 endmenu
index 493c872..37196c1 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_I2C_ALI15X3)       += i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)       += i2c-amd756.o
 obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
 obj-$(CONFIG_I2C_AMD8111)      += i2c-amd8111.o
+obj-$(CONFIG_I2C_AT91)         += i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)       += i2c-au1550.o
 obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
 obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
@@ -16,7 +17,6 @@ obj-$(CONFIG_I2C_I810)                += i2c-i810.o
 obj-$(CONFIG_I2C_IBM_IIC)      += i2c-ibm_iic.o
 obj-$(CONFIG_I2C_IOP3XX)       += i2c-iop3xx.o
 obj-$(CONFIG_I2C_ISA)          += i2c-isa.o
-obj-$(CONFIG_I2C_ITE)          += i2c-ite.o
 obj-$(CONFIG_I2C_IXP2000)      += i2c-ixp2000.o
 obj-$(CONFIG_I2C_IXP4XX)       += i2c-ixp4xx.o
 obj-$(CONFIG_I2C_POWERMAC)     += i2c-powermac.o
@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_PARPORT)     += i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)        += i2c-parport-light.o
 obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
 obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
+obj-$(CONFIG_I2C_PNX)          += i2c-pnx.o
 obj-$(CONFIG_I2C_PROSAVAGE)    += i2c-prosavage.o
 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
 obj-$(CONFIG_I2C_RPXLITE)      += i2c-rpx.o
@@ -39,6 +40,7 @@ obj-$(CONFIG_I2C_SIS5595)     += i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
 obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
+obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
 obj-$(CONFIG_I2C_VIA)          += i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)       += i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)      += i2c-voodoo3.o
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
new file mode 100644 (file)
index 0000000..67f91bd
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+    i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
+
+    Copyright (C) 2004 Rick Bronson
+    Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
+
+    Borrowed heavily from original work by:
+    Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+*/
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/at91_twi.h>
+#include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
+
+#define TWI_CLOCK              100000          /* Hz. max 400 Kbits/sec */
+
+
+static struct clk *twi_clk;
+static void __iomem *twi_base;
+
+#define at91_twi_read(reg)             __raw_readl(twi_base + (reg))
+#define at91_twi_write(reg, val)       __raw_writel((val), twi_base + (reg))
+
+
+/*
+ * Initialize the TWI hardware registers.
+ */
+static void __devinit at91_twi_hwinit(void)
+{
+       unsigned long cdiv, ckdiv;
+
+       at91_twi_write(AT91_TWI_IDR, 0xffffffff);       /* Disable all interrupts */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST);    /* Reset peripheral */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);     /* Set Master mode */
+
+       /* Calcuate clock dividers */
+       cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3;
+       cdiv = cdiv + 1;        /* round up */
+       ckdiv = 0;
+       while (cdiv > 255) {
+               ckdiv++;
+               cdiv = cdiv >> 1;
+       }
+
+       if (cpu_is_at91rm9200()) {                      /* AT91RM9200 Errata #22 */
+               if (ckdiv > 5) {
+                       printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n");
+                       ckdiv = 5;
+               }
+       }
+
+       at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv);
+}
+
+/*
+ * Poll the i2c status register until the specified bit is set.
+ * Returns 0 if timed out (100 msec).
+ */
+static short at91_poll_status(unsigned long bit)
+{
+       int loop_cntr = 10000;
+
+       do {
+               udelay(10);
+       } while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0));
+
+       return (loop_cntr > 0);
+}
+
+static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
+{
+       /* Send Start */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
+
+       /* Read data */
+       while (length--) {
+               if (!length)    /* need to send Stop before reading last byte */
+                       at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
+               if (!at91_poll_status(AT91_TWI_RXRDY)) {
+                       dev_dbg(&adap->dev, "RXRDY timeout\n");
+                       return -ETIMEDOUT;
+               }
+               *buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff);
+       }
+
+       return 0;
+}
+
+static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
+{
+       /* Load first byte into transmitter */
+       at91_twi_write(AT91_TWI_THR, *buf++);
+
+       /* Send Start */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
+
+       do {
+               if (!at91_poll_status(AT91_TWI_TXRDY)) {
+                       dev_dbg(&adap->dev, "TXRDY timeout\n");
+                       return -ETIMEDOUT;
+               }
+
+               length--;       /* byte was transmitted */
+
+               if (length > 0)         /* more data to send? */
+                       at91_twi_write(AT91_TWI_THR, *buf++);
+       } while (length);
+
+       /* Send Stop */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
+
+       return 0;
+}
+
+/*
+ * Generic i2c master transfer entrypoint.
+ *
+ * Note: We do not use Atmel's feature of storing the "internal device address".
+ * Instead the "internal device address" has to be written using a seperate
+ * i2c message.
+ * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
+ */
+static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
+{
+       int i, ret;
+
+       dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
+
+       for (i = 0; i < num; i++) {
+               dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
+                       pmsg->flags & I2C_M_RD ? "read" : "writ",
+                       pmsg->len, pmsg->len > 1 ? "s" : "",
+                       pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr);
+
+               at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16)
+                       | ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
+
+               if (pmsg->len && pmsg->buf) {   /* sanity check */
+                       if (pmsg->flags & I2C_M_RD)
+                               ret = xfer_read(adap, pmsg->buf, pmsg->len);
+                       else
+                               ret = xfer_write(adap, pmsg->buf, pmsg->len);
+
+                       if (ret)
+                               return ret;
+
+                       /* Wait until transfer is finished */
+                       if (!at91_poll_status(AT91_TWI_TXCOMP)) {
+                               dev_dbg(&adap->dev, "TXCOMP timeout\n");
+                               return -ETIMEDOUT;
+                       }
+               }
+               dev_dbg(&adap->dev, "transfer complete\n");
+               pmsg++;         /* next message */
+       }
+       return i;
+}
+
+/*
+ * Return list of supported functionality.
+ */
+static u32 at91_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm at91_algorithm = {
+       .master_xfer    = at91_xfer,
+       .functionality  = at91_func,
+};
+
+/*
+ * Main initialization routine.
+ */
+static int __devinit at91_i2c_probe(struct platform_device *pdev)
+{
+       struct i2c_adapter *adapter;
+       struct resource *res;
+       int rc;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
+
+       if (!request_mem_region(res->start, res->end - res->start + 1, "at91_i2c"))
+               return -EBUSY;
+
+       twi_base = ioremap(res->start, res->end - res->start + 1);
+       if (!twi_base) {
+               rc = -ENOMEM;
+               goto fail0;
+       }
+
+       twi_clk = clk_get(NULL, "twi_clk");
+       if (IS_ERR(twi_clk)) {
+               dev_err(&pdev->dev, "no clock defined\n");
+               rc = -ENODEV;
+               goto fail1;
+       }
+
+       adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+       if (adapter == NULL) {
+               dev_err(&pdev->dev, "can't allocate inteface!\n");
+               rc = -ENOMEM;
+               goto fail2;
+       }
+       sprintf(adapter->name, "AT91");
+       adapter->algo = &at91_algorithm;
+       adapter->class = I2C_CLASS_HWMON;
+       adapter->dev.parent = &pdev->dev;
+
+       platform_set_drvdata(pdev, adapter);
+
+       clk_enable(twi_clk);            /* enable peripheral clock */
+       at91_twi_hwinit();              /* initialize TWI controller */
+
+       rc = i2c_add_adapter(adapter);
+       if (rc) {
+               dev_err(&pdev->dev, "Adapter %s registration failed\n",
+                               adapter->name);
+               goto fail3;
+       }
+
+       dev_info(&pdev->dev, "AT91 i2c bus driver.\n");
+       return 0;
+
+fail3:
+       platform_set_drvdata(pdev, NULL);
+       kfree(adapter);
+       clk_disable(twi_clk);
+fail2:
+       clk_put(twi_clk);
+fail1:
+       iounmap(twi_base);
+fail0:
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       return rc;
+}
+
+static int __devexit at91_i2c_remove(struct platform_device *pdev)
+{
+       struct i2c_adapter *adapter = platform_get_drvdata(pdev);
+       struct resource *res;
+       int rc;
+
+       rc = i2c_del_adapter(adapter);
+       platform_set_drvdata(pdev, NULL);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       iounmap(twi_base);
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       clk_disable(twi_clk);           /* disable peripheral clock */
+       clk_put(twi_clk);
+
+       return rc;
+}
+
+#ifdef CONFIG_PM
+
+/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
+
+static int at91_i2c_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+       clk_disable(twi_clk);
+       return 0;
+}
+
+static int at91_i2c_resume(struct platform_device *pdev)
+{
+       return clk_enable(twi_clk);
+}
+
+#else
+#define at91_i2c_suspend       NULL
+#define at91_i2c_resume                NULL
+#endif
+
+static struct platform_driver at91_i2c_driver = {
+       .probe          = at91_i2c_probe,
+       .remove         = __devexit_p(at91_i2c_remove),
+       .suspend        = at91_i2c_suspend,
+       .resume         = at91_i2c_resume,
+       .driver         = {
+               .name   = "at91_i2c",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init at91_i2c_init(void)
+{
+       return platform_driver_register(&at91_i2c_driver);
+}
+
+static void __exit at91_i2c_exit(void)
+{
+       platform_driver_unregister(&at91_i2c_driver);
+}
+
+module_init(at91_i2c_init);
+module_exit(at91_i2c_exit);
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
+MODULE_LICENSE("GPL");
index a591fe6..8349674 100644 (file)
@@ -293,7 +293,7 @@ static int __init i2c_pcfisa_init(void)
 
 static void i2c_pcfisa_exit(void)
 {
-       i2c_pcf_del_bus(&pcf_isa_ops);
+       i2c_del_adapter(&pcf_isa_ops);
 
        if (irq > 0) {
                disable_irq(irq);
index 457d48a..9832f77 100644 (file)
@@ -146,7 +146,7 @@ static int __devinit hydra_probe(struct pci_dev *dev,
 static void __devexit hydra_remove(struct pci_dev *dev)
 {
        pdregw(hydra_bit_data.data, 0);         /* clear SCLK_OE and SDAT_OE */
-       i2c_bit_del_bus(&hydra_adap);
+       i2c_del_adapter(&hydra_adap);
        iounmap(hydra_bit_data.data);
        release_mem_region(pci_resource_start(dev, 0)+
                           offsetof(struct Hydra, CachePD), 4);
index c7be2fd..ae625b8 100644 (file)
@@ -470,12 +470,20 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        int err;
 
        I801_dev = dev;
-       if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
-           (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
-           (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
+       switch (dev->device) {
+       case PCI_DEVICE_ID_INTEL_82801DB_3:
+       case PCI_DEVICE_ID_INTEL_82801EB_3:
+       case PCI_DEVICE_ID_INTEL_ESB_4:
+       case PCI_DEVICE_ID_INTEL_ICH6_16:
+       case PCI_DEVICE_ID_INTEL_ICH7_17:
+       case PCI_DEVICE_ID_INTEL_ESB2_17:
+       case PCI_DEVICE_ID_INTEL_ICH8_5:
+       case PCI_DEVICE_ID_INTEL_ICH9_6:
                isich4 = 1;
-       else
+               break;
+       default:
                isich4 = 0;
+       }
 
        err = pci_enable_device(dev);
        if (err) {
index b66fb6b..10c98bc 100644 (file)
@@ -219,14 +219,14 @@ static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id
                return retval;
        retval = i2c_bit_add_bus(&i810_ddc_adapter);
        if (retval)
-               i2c_bit_del_bus(&i810_i2c_adapter);
+               i2c_del_adapter(&i810_i2c_adapter);
        return retval;
 }
 
 static void __devexit i810_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&i810_ddc_adapter);
-       i2c_bit_del_bus(&i810_i2c_adapter);
+       i2c_del_adapter(&i810_ddc_adapter);
+       i2c_del_adapter(&i810_i2c_adapter);
        iounmap(ioaddr);
 }
 
index 781a99c..1898e99 100644 (file)
@@ -680,6 +680,12 @@ static int __devinit iic_probe(struct ocp_device *ocp){
        dev->idx = ocp->def->index;
        ocp_set_drvdata(ocp, dev);
        
+       if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs),
+                               "ibm_iic")) {
+               ret = -EBUSY;
+               goto fail1;
+       }
+
        if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
                printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
                        dev->idx);
@@ -750,6 +756,8 @@ fail:
 
        iounmap(dev->vaddr);
 fail2: 
+       release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
+fail1:
        ocp_set_drvdata(ocp, NULL);
        kfree(dev);     
        return ret;
@@ -777,6 +785,7 @@ static void __devexit iic_remove(struct ocp_device *ocp)
                    free_irq(dev->irq, dev);
                }
                iounmap(dev->vaddr);
+               release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
                kfree(dev);
        }
 }
diff --git a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c
deleted file mode 100644 (file)
index f7d7186..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-adap-ite.c i2c-hw access for the IIC peripheral on the ITE MIPS system
-   -------------------------------------------------------------------------
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2001 MontaVista Software Inc.
-
-   ----------------------------------------------------------------------------
-   This file was highly leveraged from i2c-elektor.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
-     Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ite.h>
-#include <linux/i2c-adap-ite.h>
-#include "../i2c-ite.h"
-
-#define DEFAULT_BASE  0x14014030
-#define ITE_IIC_IO_SIZE        0x40
-#define DEFAULT_IRQ   0
-#define DEFAULT_CLOCK 0x1b0e   /* default 16MHz/(27+14) = 400KHz */
-#define DEFAULT_OWN   0x55
-
-static int base;
-static int irq;
-static int clock;
-static int own;
-
-static struct iic_ite gpi;
-static wait_queue_head_t iic_wait;
-static int iic_pending;
-static spinlock_t lock;
-
-/* ----- local functions ----------------------------------------------        */
-
-static void iic_ite_setiic(void *data, int ctl, short val)
-{
-        unsigned long j = jiffies + 10;
-
-       pr_debug(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff);
-#ifdef DEBUG
-       while (time_before(jiffies, j))
-               schedule();
-#endif
-       outw(val,ctl);
-}
-
-static short iic_ite_getiic(void *data, int ctl)
-{
-       short val;
-
-       val = inw(ctl);
-       pr_debug("Read 0x%02x from 0x%x\n",(unsigned short)val, ctl&0xff);
-       return (val);
-}
-
-/* Return our slave address.  This is the address
- * put on the I2C bus when another master on the bus wants to address us
- * as a slave
- */
-static int iic_ite_getown(void *data)
-{
-       return (gpi.iic_own);
-}
-
-
-static int iic_ite_getclock(void *data)
-{
-       return (gpi.iic_clock);
-}
-
-
-/* Put this process to sleep.  We will wake up when the
- * IIC controller interrupts.
- */
-static void iic_ite_waitforpin(void) {
-   DEFINE_WAIT(wait);
-   int timeout = 2;
-   unsigned long flags;
-
-   /* If interrupts are enabled (which they are), then put the process to
-    * sleep.  This process will be awakened by two events -- either the
-    * the IIC peripheral interrupts or the timeout expires. 
-    * If interrupts are not enabled then delay for a reasonable amount 
-    * of time and return.
-    */
-   if (gpi.iic_irq > 0) {
-       spin_lock_irqsave(&lock, flags);
-       if (iic_pending == 0) {
-               spin_unlock_irqrestore(&lock, flags);
-               prepare_to_wait(&iic_wait, &wait, TASK_INTERRUPTIBLE);
-               if (schedule_timeout(timeout*HZ)) {
-                       spin_lock_irqsave(&lock, flags);
-                       if (iic_pending == 1) {
-                               iic_pending = 0;
-                       }
-                       spin_unlock_irqrestore(&lock, flags);
-               }
-               finish_wait(&iic_wait, &wait);
-       } else {
-               iic_pending = 0;
-               spin_unlock_irqrestore(&lock, flags);
-       }
-   } else {
-      udelay(100);
-   }
-}
-
-
-static irqreturn_t iic_ite_handler(int this_irq, void *dev_id)
-{
-       spin_lock(&lock);
-       iic_pending = 1;
-       spin_unlock(&lock);
-
-       wake_up_interruptible(&iic_wait);
-
-       return IRQ_HANDLED;
-}
-
-
-/* Lock the region of memory where I/O registers exist.  Request our
- * interrupt line and register its associated handler.
- */
-static int iic_hw_resrc_init(void)
-{
-       if (!request_region(gpi.iic_base, ITE_IIC_IO_SIZE, "i2c"))
-               return -ENODEV;
-  
-       if (gpi.iic_irq <= 0)
-               return 0;
-
-       if (request_irq(gpi.iic_irq, iic_ite_handler, 0, "ITE IIC", 0) < 0)
-               gpi.iic_irq = 0;
-       else
-               enable_irq(gpi.iic_irq);
-
-       return 0;
-}
-
-
-static void iic_ite_release(void)
-{
-       if (gpi.iic_irq > 0) {
-               disable_irq(gpi.iic_irq);
-               free_irq(gpi.iic_irq, 0);
-       }
-       release_region(gpi.iic_base , 2);
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_iic_data iic_ite_data = {
-       NULL,
-       iic_ite_setiic,
-       iic_ite_getiic,
-       iic_ite_getown,
-       iic_ite_getclock,
-       iic_ite_waitforpin,
-       80, 80, 100,            /*      waits, timeout */
-};
-
-static struct i2c_adapter iic_ite_ops = {
-       .owner          = THIS_MODULE,
-       .id             = I2C_HW_I_IIC,
-       .algo_data      = &iic_ite_data,
-       .name           = "ITE IIC adapter",
-};
-
-/* Called when the module is loaded.  This function starts the
- * cascade of calls up through the hierarchy of i2c modules (i.e. up to the
- *  algorithm layer and into to the core layer)
- */
-static int __init iic_ite_init(void) 
-{
-
-       struct iic_ite *piic = &gpi;
-
-       printk(KERN_INFO "Initialize ITE IIC adapter module\n");
-       if (base == 0)
-               piic->iic_base = DEFAULT_BASE;
-       else
-               piic->iic_base = base;
-
-       if (irq == 0)
-               piic->iic_irq = DEFAULT_IRQ;
-       else
-               piic->iic_irq = irq;
-
-       if (clock == 0)
-               piic->iic_clock = DEFAULT_CLOCK;
-       else
-               piic->iic_clock = clock;
-
-       if (own == 0)
-               piic->iic_own = DEFAULT_OWN;
-       else
-               piic->iic_own = own;
-
-       iic_ite_data.data = (void *)piic;
-       init_waitqueue_head(&iic_wait);
-       spin_lock_init(&lock);
-       if (iic_hw_resrc_init() == 0) {
-               if (i2c_iic_add_bus(&iic_ite_ops) < 0)
-                       return -ENODEV;
-       } else {
-               return -ENODEV;
-       }
-       printk(KERN_INFO " found device at %#x irq %d.\n", 
-               piic->iic_base, piic->iic_irq);
-       return 0;
-}
-
-
-static void iic_ite_exit(void)
-{
-       i2c_iic_del_bus(&iic_ite_ops);
-        iic_ite_release();
-}
-
-/* If modules is NOT defined when this file is compiled, then the MODULE_*
- * macros will resolve to nothing
- */
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
-MODULE_LICENSE("GPL");
-
-module_param(base, int, 0);
-module_param(irq, int, 0);
-module_param(clock, int, 0);
-module_param(own, int, 0);
-
-
-/* Called when module is loaded or when kernel is initialized.
- * If MODULES is defined when this file is compiled, then this function will
- * resolve to init_module (the function called when insmod is invoked for a
- * module).  Otherwise, this function is called early in the boot, when the
- * kernel is intialized.  Check out /include/init.h to see how this works.
- */
-module_init(iic_ite_init);
-
-/* Resolves to module_cleanup when MODULES is defined. */
-module_exit(iic_ite_exit); 
index dd3f4cd..efa3ecc 100644 (file)
@@ -90,7 +90,7 @@ static int ixp2000_i2c_remove(struct platform_device *plat_dev)
 
        platform_set_drvdata(plat_dev, NULL);
 
-       i2c_bit_del_bus(&drv_data->adapter);
+       i2c_del_adapter(&drv_data->adapter);
 
        kfree(drv_data);
 
index 68fe863..08e89b8 100644 (file)
@@ -91,7 +91,7 @@ static int ixp4xx_i2c_remove(struct platform_device *plat_dev)
 
        platform_set_drvdata(plat_dev, NULL);
 
-       i2c_bit_del_bus(&drv_data->adapter);
+       i2c_del_adapter(&drv_data->adapter);
 
        kfree(drv_data);
 
index e0292e4..ad37c10 100644 (file)
@@ -35,7 +35,7 @@
     nForce4 MCP55              0368
 
     This driver supports the 2 SMBuses that are included in the MCP of the
-    nForce2/3/4 chipsets.
+    nForce2/3/4/5xx chipsets.
 */
 
 /* Note: we assume there can only be one nForce2, with two SMBus interfaces */
@@ -52,8 +52,8 @@
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@arcor.de>");
-MODULE_DESCRIPTION("nForce2 SMBus driver");
+MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
+MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
 
 
 struct nforce2_smbus {
@@ -80,9 +80,6 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_ADDR                (smbus->base + 0x02)    /* address */
 #define NVIDIA_SMB_CMD         (smbus->base + 0x03)    /* command */
 #define NVIDIA_SMB_DATA                (smbus->base + 0x04)    /* 32 data registers */
-#define NVIDIA_SMB_BCNT                (smbus->base + 0x24)    /* number of data bytes */
-#define NVIDIA_SMB_ALRM_A      (smbus->base + 0x25)    /* alarm address */
-#define NVIDIA_SMB_ALRM_D      (smbus->base + 0x26)    /* 2 bytes alarm data */
 
 #define NVIDIA_SMB_STS_DONE    0x80
 #define NVIDIA_SMB_STS_ALRM    0x40
@@ -95,40 +92,17 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_PRTCL_BYTE                  0x04
 #define NVIDIA_SMB_PRTCL_BYTE_DATA             0x06
 #define NVIDIA_SMB_PRTCL_WORD_DATA             0x08
-#define NVIDIA_SMB_PRTCL_BLOCK_DATA            0x0a
-#define NVIDIA_SMB_PRTCL_PROC_CALL             0x0c
-#define NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL       0x0d
-#define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA                0x4a
 #define NVIDIA_SMB_PRTCL_PEC                   0x80
 
 static struct pci_driver nforce2_driver;
 
-static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
-                      unsigned short flags, char read_write,
-                      u8 command, int size, union i2c_smbus_data *data);
-static u32 nforce2_func(struct i2c_adapter *adapter);
-
-
-static const struct i2c_algorithm smbus_algorithm = {
-       .smbus_xfer = nforce2_access,
-       .functionality = nforce2_func,
-};
-
-static struct i2c_adapter nforce2_adapter = {
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
-       .algo           = &smbus_algorithm,
-};
-
-/* Return -1 on error. See smbus.h for more information */
+/* Return -1 on error */
 static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                unsigned short flags, char read_write,
                u8 command, int size, union i2c_smbus_data * data)
 {
        struct nforce2_smbus *smbus = adap->algo_data;
        unsigned char protocol, pec, temp;
-       unsigned char len = 0; /* to keep the compiler quiet */
-       int i;
 
        protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
                NVIDIA_SMB_PRTCL_WRITE;
@@ -163,35 +137,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                        protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
                        break;
 
-               case I2C_SMBUS_BLOCK_DATA:
-                       outb_p(command, NVIDIA_SMB_CMD);
-                       if (read_write == I2C_SMBUS_WRITE) {
-                               len = min_t(u8, data->block[0], 32);
-                               outb_p(len, NVIDIA_SMB_BCNT);
-                               for (i = 0; i < len; i++)
-                                       outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);
-                       }
-                       protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
-                       break;
-
-               case I2C_SMBUS_I2C_BLOCK_DATA:
-                       len = min_t(u8, data->block[0], 32);
-                       outb_p(command, NVIDIA_SMB_CMD);
-                       outb_p(len, NVIDIA_SMB_BCNT);
-                       if (read_write == I2C_SMBUS_WRITE)
-                               for (i = 0; i < len; i++)
-                                       outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);
-                       protocol |= NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA;
-                       break;
-
-               case I2C_SMBUS_PROC_CALL:
-                       dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-                       return -1;
-
-               case I2C_SMBUS_BLOCK_PROC_CALL:
-                       dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
-                       return -1;
-
                default:
                        dev_err(&adap->dev, "Unsupported transaction %d\n", size);
                        return -1;
@@ -227,19 +172,8 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                        break;
 
                case I2C_SMBUS_WORD_DATA:
-               /* case I2C_SMBUS_PROC_CALL: not supported */
                        data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
                        break;
-
-               case I2C_SMBUS_BLOCK_DATA:
-               /* case I2C_SMBUS_BLOCK_PROC_CALL: not supported */
-                       len = inb_p(NVIDIA_SMB_BCNT);
-                       len = min_t(u8, len, 32);
-               case I2C_SMBUS_I2C_BLOCK_DATA:
-                       for (i = 0; i < len; i++)
-                               data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
-                       data->block[0] = len;
-                       break;
        }
 
        return 0;
@@ -250,10 +184,14 @@ static u32 nforce2_func(struct i2c_adapter *adapter)
 {
        /* other functionality might be possible, but is not tested */
        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-           I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA /* |
-           I2C_FUNC_SMBUS_BLOCK_DATA */;
+           I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
 }
 
+static struct i2c_algorithm smbus_algorithm = {
+       .smbus_xfer     = nforce2_access,
+       .functionality  = nforce2_func,
+};
+
 
 static struct pci_device_id nforce2_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
@@ -267,7 +205,6 @@ static struct pci_device_id nforce2_ids[] = {
        { 0 }
 };
 
-
 MODULE_DEVICE_TABLE (pci, nforce2_ids);
 
 
@@ -291,7 +228,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                }
 
                smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
-               smbus->size = 8;
+               smbus->size = 64;
        }
        smbus->dev = dev;
 
@@ -300,7 +237,9 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                        smbus->base, smbus->base+smbus->size-1, name);
                return -1;
        }
-       smbus->adapter = nforce2_adapter;
+       smbus->adapter.owner = THIS_MODULE;
+       smbus->adapter.class = I2C_CLASS_HWMON;
+       smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
        smbus->adapter.dev.parent = &dev->dev;
        snprintf(smbus->adapter.name, I2C_NAME_SIZE,
index dec04da..bcd8367 100644 (file)
@@ -231,8 +231,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
                 * 13           2               1
                 * 19.2         2               1
                 */
-               if (fclk_rate > 16000000)
-                       psc = (fclk_rate + 8000000) / 12000000;
+               if (fclk_rate > 12000000)
+                       psc = fclk_rate / 12000000;
        }
 
        /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
index 5eb2bd2..4bc4281 100644 (file)
@@ -163,7 +163,7 @@ static void __exit i2c_parport_exit(void)
        if (adapter_parm[type].init.val)
                line_set(0, &adapter_parm[type].init);
 
-       i2c_bit_del_bus(&parport_adapter);
+       i2c_del_adapter(&parport_adapter);
        release_region(base, 3);
 }
 
index 48a8294..66696a4 100644 (file)
@@ -218,7 +218,7 @@ static void i2c_parport_detach (struct parport *port)
                        if (adapter_parm[type].init.val)
                                line_set(port, 0, &adapter_parm[type].init);
                                
-                       i2c_bit_del_bus(&adapter->adapter);
+                       i2c_del_adapter(&adapter->adapter);
                        parport_unregister_device(adapter->pdev);
                        if (prev)
                                prev->next = adapter->next;
index 407840b..cc6536a 100644 (file)
@@ -156,7 +156,7 @@ static int __init pca_isa_init(void)
 
 static void pca_isa_exit(void)
 {
-       i2c_pca_del_bus(&pca_isa_ops);
+       i2c_del_adapter(&pca_isa_ops);
 
        if (irq > 0) {
                disable_irq(irq);
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
new file mode 100644 (file)
index 0000000..de0bca7
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Provides I2C support for Philips PNX010x/PNX4008 boards.
+ *
+ * Authors: Dennis Kovalev <dkovalev@ru.mvista.com>
+ *         Vitaly Wool <vwool@ru.mvista.com>
+ *
+ * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-pnx.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#define I2C_PNX_TIMEOUT                10 /* msec */
+#define I2C_PNX_SPEED_KHZ      100
+#define I2C_PNX_REGION_SIZE    0x100
+#define PNX_DEFAULT_FREQ       13 /* MHz */
+
+static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)
+{
+       while (timeout > 0 &&
+                       (ioread32(I2C_REG_STS(data)) & mstatus_active)) {
+               mdelay(1);
+               timeout--;
+       }
+       return (timeout <= 0);
+}
+
+static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data)
+{
+       while (timeout > 0 &&
+                       (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
+               mdelay(1);
+               timeout--;
+       }
+       return (timeout <= 0);
+}
+
+static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *data = adap->algo_data;
+       struct timer_list *timer = &data->mif.timer;
+       int expires = I2C_PNX_TIMEOUT / (1000 / HZ);
+
+       del_timer_sync(timer);
+
+       dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n",
+               jiffies, expires);
+
+       timer->expires = jiffies + expires;
+       timer->data = (unsigned long)adap;
+
+       add_timer(timer);
+}
+
+/**
+ * i2c_pnx_start - start a device
+ * @slave_addr:                slave address
+ * @adap:              pointer to adapter structure
+ *
+ * Generate a START signal in the desired mode.
+ */
+static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+
+       dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __FUNCTION__,
+               slave_addr, alg_data->mif.mode);
+
+       /* Check for 7 bit slave addresses only */
+       if (slave_addr & ~0x7f) {
+               dev_err(&adap->dev, "%s: Invalid slave address %x. "
+                      "Only 7-bit addresses are supported\n",
+                      adap->name, slave_addr);
+               return -EINVAL;
+       }
+
+       /* First, make sure bus is idle */
+       if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {
+               /* Somebody else is monopolizing the bus */
+               dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, "
+                      "cntrl = %x, stat = %x\n",
+                      adap->name, slave_addr,
+                      ioread32(I2C_REG_CTL(alg_data)),
+                      ioread32(I2C_REG_STS(alg_data)));
+               return -EBUSY;
+       } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
+               /* Sorry, we lost the bus */
+               dev_err(&adap->dev, "%s: Arbitration failure. "
+                      "Slave addr = %02x\n", adap->name, slave_addr);
+               return -EIO;
+       }
+
+       /*
+        * OK, I2C is enabled and we have the bus.
+        * Clear the current TDI and AFI status flags.
+        */
+       iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
+                 I2C_REG_STS(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): sending %#x\n", __FUNCTION__,
+               (slave_addr << 1) | start_bit | alg_data->mif.mode);
+
+       /* Write the slave address, START bit and R/W bit */
+       iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
+                 I2C_REG_TX(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): exit\n", __FUNCTION__);
+
+       return 0;
+}
+
+/**
+ * i2c_pnx_stop - stop a device
+ * @adap:              pointer to I2C adapter structure
+ *
+ * Generate a STOP signal to terminate the master transaction.
+ */
+static void i2c_pnx_stop(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       /* Only 1 msec max timeout due to interrupt context */
+       long timeout = 1000;
+
+       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       /* Write a STOP bit to TX FIFO */
+       iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
+
+       /* Wait until the STOP is seen. */
+       while (timeout > 0 &&
+              (ioread32(I2C_REG_STS(alg_data)) & mstatus_active)) {
+               /* may be called from interrupt context */
+               udelay(1);
+               timeout--;
+       }
+
+       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+}
+
+/**
+ * i2c_pnx_master_xmit - transmit data to slave
+ * @adap:              pointer to I2C adapter structure
+ *
+ * Sends one byte of data to the slave
+ */
+static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 val;
+
+       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       if (alg_data->mif.len > 0) {
+               /* We still have something to talk about... */
+               val = *alg_data->mif.buf++;
+
+               if (alg_data->mif.len == 1) {
+                       val |= stop_bit;
+                       if (!alg_data->last)
+                               val |= start_bit;
+               }
+
+               alg_data->mif.len--;
+               iowrite32(val, I2C_REG_TX(alg_data));
+
+               dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __FUNCTION__,
+                       val, alg_data->mif.len + 1);
+
+               if (alg_data->mif.len == 0) {
+                       if (alg_data->last) {
+                               /* Wait until the STOP is seen. */
+                               if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
+                                       dev_err(&adap->dev, "The bus is still "
+                                               "active after timeout\n");
+                       }
+                       /* Disable master interrupts */
+                       iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
+                               ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
+                                 I2C_REG_CTL(alg_data));
+
+                       del_timer_sync(&alg_data->mif.timer);
+
+                       dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
+                               __FUNCTION__);
+
+                       complete(&alg_data->mif.complete);
+               }
+       } else if (alg_data->mif.len == 0) {
+               /* zero-sized transfer */
+               i2c_pnx_stop(adap);
+
+               /* Disable master interrupts. */
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
+                       ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
+                         I2C_REG_CTL(alg_data));
+
+               /* Stop timer. */
+               del_timer_sync(&alg_data->mif.timer);
+               dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
+                       "zero-xfer.\n", __FUNCTION__);
+
+               complete(&alg_data->mif.complete);
+       }
+
+       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       return 0;
+}
+
+/**
+ * i2c_pnx_master_rcv - receive data from slave
+ * @adap:              pointer to I2C adapter structure
+ *
+ * Reads one byte data from the slave
+ */
+static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       unsigned int val = 0;
+       u32 ctl = 0;
+
+       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       /* Check, whether there is already data,
+        * or we didn't 'ask' for it yet.
+        */
+       if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
+               dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
+                       "Rx-fifo...\n", __FUNCTION__);
+
+               if (alg_data->mif.len == 1) {
+                       /* Last byte, do not acknowledge next rcv. */
+                       val |= stop_bit;
+                       if (!alg_data->last)
+                               val |= start_bit;
+
+                       /*
+                        * Enable interrupt RFDAIE (data in Rx fifo),
+                        * and disable DRMIE (need data for Tx)
+                        */
+                       ctl = ioread32(I2C_REG_CTL(alg_data));
+                       ctl |= mcntrl_rffie | mcntrl_daie;
+                       ctl &= ~mcntrl_drmie;
+                       iowrite32(ctl, I2C_REG_CTL(alg_data));
+               }
+
+               /*
+                * Now we'll 'ask' for data:
+                * For each byte we want to receive, we must
+                * write a (dummy) byte to the Tx-FIFO.
+                */
+               iowrite32(val, I2C_REG_TX(alg_data));
+
+               return 0;
+       }
+
+       /* Handle data. */
+       if (alg_data->mif.len > 0) {
+               val = ioread32(I2C_REG_RX(alg_data));
+               *alg_data->mif.buf++ = (u8) (val & 0xff);
+               dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __FUNCTION__, val,
+                       alg_data->mif.len);
+
+               alg_data->mif.len--;
+               if (alg_data->mif.len == 0) {
+                       if (alg_data->last)
+                               /* Wait until the STOP is seen. */
+                               if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
+                                       dev_err(&adap->dev, "The bus is still "
+                                               "active after timeout\n");
+
+                       /* Disable master interrupts */
+                       ctl = ioread32(I2C_REG_CTL(alg_data));
+                       ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
+                                mcntrl_drmie | mcntrl_daie);
+                       iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+                       /* Kill timer. */
+                       del_timer_sync(&alg_data->mif.timer);
+                       complete(&alg_data->mif.complete);
+               }
+       }
+
+       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       return 0;
+}
+
+static irqreturn_t
+i2c_pnx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       u32 stat, ctl;
+       struct i2c_adapter *adap = dev_id;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+
+       dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
+               __FUNCTION__,
+               ioread32(I2C_REG_STS(alg_data)),
+               ioread32(I2C_REG_CTL(alg_data)),
+               alg_data->mif.mode);
+       stat = ioread32(I2C_REG_STS(alg_data));
+
+       /* let's see what kind of event this is */
+       if (stat & mstatus_afi) {
+               /* We lost arbitration in the midst of a transfer */
+               alg_data->mif.ret = -EIO;
+
+               /* Disable master interrupts. */
+               ctl = ioread32(I2C_REG_CTL(alg_data));
+               ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
+                        mcntrl_drmie);
+               iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+               /* Stop timer, to prevent timeout. */
+               del_timer_sync(&alg_data->mif.timer);
+               complete(&alg_data->mif.complete);
+       } else if (stat & mstatus_nai) {
+               /* Slave did not acknowledge, generate a STOP */
+               dev_dbg(&adap->dev, "%s(): "
+                       "Slave did not acknowledge, generating a STOP.\n",
+                       __FUNCTION__);
+               i2c_pnx_stop(adap);
+
+               /* Disable master interrupts. */
+               ctl = ioread32(I2C_REG_CTL(alg_data));
+               ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
+                        mcntrl_drmie);
+               iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+               /* Our return value. */
+               alg_data->mif.ret = -EIO;
+
+               /* Stop timer, to prevent timeout. */
+               del_timer_sync(&alg_data->mif.timer);
+               complete(&alg_data->mif.complete);
+       } else {
+               /*
+                * Two options:
+                * - Master Tx needs data.
+                * - There is data in the Rx-fifo
+                * The latter is only the case if we have requested for data,
+                * via a dummy write. (See 'i2c_pnx_master_rcv'.)
+                * We therefore check, as a sanity check, whether that interrupt
+                * has been enabled.
+                */
+               if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
+                       if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
+                               i2c_pnx_master_xmit(adap);
+                       } else if (alg_data->mif.mode == I2C_SMBUS_READ) {
+                               i2c_pnx_master_rcv(adap);
+                       }
+               }
+       }
+
+       /* Clear TDI and AFI bits */
+       stat = ioread32(I2C_REG_STS(alg_data));
+       iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
+                __FUNCTION__, ioread32(I2C_REG_STS(alg_data)),
+                ioread32(I2C_REG_CTL(alg_data)));
+
+       return IRQ_HANDLED;
+}
+
+static void i2c_pnx_timeout(unsigned long data)
+{
+       struct i2c_adapter *adap = (struct i2c_adapter *)data;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 ctl;
+
+       dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. "
+              "Resetting master...\n",
+              ioread32(I2C_REG_STS(alg_data)),
+              ioread32(I2C_REG_CTL(alg_data)));
+
+       /* Reset master and disable interrupts */
+       ctl = ioread32(I2C_REG_CTL(alg_data));
+       ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie);
+       iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+       ctl |= mcntrl_reset;
+       iowrite32(ctl, I2C_REG_CTL(alg_data));
+       wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       alg_data->mif.ret = -EIO;
+       complete(&alg_data->mif.complete);
+}
+
+static inline void bus_reset_if_active(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 stat;
+
+       if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
+               dev_err(&adap->dev,
+                       "%s: Bus is still active after xfer. Reset it...\n",
+                      adap->name);
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
+                         I2C_REG_CTL(alg_data));
+               wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) {
+               /* If there is data in the fifo's after transfer,
+                * flush fifo's by reset.
+                */
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
+                         I2C_REG_CTL(alg_data));
+               wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       } else if (stat & mstatus_nai) {
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
+                         I2C_REG_CTL(alg_data));
+               wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       }
+}
+
+/**
+ * i2c_pnx_xfer - generic transfer entry point
+ * @adap:              pointer to I2C adapter structure
+ * @msgs:              array of messages
+ * @num:               number of messages
+ *
+ * Initiates the transfer
+ */
+static int
+i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       struct i2c_msg *pmsg;
+       int rc = 0, completed = 0, i;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 stat = ioread32(I2C_REG_STS(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
+               __FUNCTION__, num, ioread32(I2C_REG_STS(alg_data)));
+
+       bus_reset_if_active(adap);
+
+       /* Process transactions in a loop. */
+       for (i = 0; rc >= 0 && i < num; i++) {
+               u8 addr;
+
+               pmsg = &msgs[i];
+               addr = pmsg->addr;
+
+               if (pmsg->flags & I2C_M_TEN) {
+                       dev_err(&adap->dev,
+                               "%s: 10 bits addr not supported!\n",
+                               adap->name);
+                       rc = -EINVAL;
+                       break;
+               }
+
+               alg_data->mif.buf = pmsg->buf;
+               alg_data->mif.len = pmsg->len;
+               alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
+                       I2C_SMBUS_READ : I2C_SMBUS_WRITE;
+               alg_data->mif.ret = 0;
+               alg_data->last = (i == num - 1);
+
+               dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __FUNCTION__,
+                       alg_data->mif.mode,
+                       alg_data->mif.len);
+
+               i2c_pnx_arm_timer(adap);
+
+               /* initialize the completion var */
+               init_completion(&alg_data->mif.complete);
+
+               /* Enable master interrupt */
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie |
+                               mcntrl_naie | mcntrl_drmie,
+                         I2C_REG_CTL(alg_data));
+
+               /* Put start-code and slave-address on the bus. */
+               rc = i2c_pnx_start(addr, adap);
+               if (rc < 0)
+                       break;
+
+               /* Wait for completion */
+               wait_for_completion(&alg_data->mif.complete);
+
+               if (!(rc = alg_data->mif.ret))
+                       completed++;
+               dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
+                       __FUNCTION__, rc);
+
+               /* Clear TDI and AFI bits in case they are set. */
+               if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
+                       dev_dbg(&adap->dev,
+                               "%s: TDI still set... clearing now.\n",
+                              adap->name);
+                       iowrite32(stat, I2C_REG_STS(alg_data));
+               }
+               if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
+                       dev_dbg(&adap->dev,
+                               "%s: AFI still set... clearing now.\n",
+                              adap->name);
+                       iowrite32(stat, I2C_REG_STS(alg_data));
+               }
+       }
+
+       bus_reset_if_active(adap);
+
+       /* Cleanup to be sure... */
+       alg_data->mif.buf = NULL;
+       alg_data->mif.len = 0;
+
+       dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       if (completed != num)
+               return ((rc < 0) ? rc : -EREMOTEIO);
+
+       return num;
+}
+
+static u32 i2c_pnx_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm pnx_algorithm = {
+       .master_xfer = i2c_pnx_xfer,
+       .functionality = i2c_pnx_func,
+};
+
+static int i2c_pnx_controller_suspend(struct platform_device *pdev,
+                                     pm_message_t state)
+{
+       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
+       return i2c_pnx->suspend(pdev, state);
+}
+
+static int i2c_pnx_controller_resume(struct platform_device *pdev)
+{
+       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
+       return i2c_pnx->resume(pdev);
+}
+
+static int __devinit i2c_pnx_probe(struct platform_device *pdev)
+{
+       unsigned long tmp;
+       int ret = 0;
+       struct i2c_pnx_algo_data *alg_data;
+       int freq_mhz;
+       struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;
+
+       if (!i2c_pnx || !i2c_pnx->adapter) {
+               dev_err(&pdev->dev, "%s: no platform data supplied\n",
+                      __FUNCTION__);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       platform_set_drvdata(pdev, i2c_pnx);
+
+       if (i2c_pnx->calculate_input_freq)
+               freq_mhz = i2c_pnx->calculate_input_freq(pdev);
+       else {
+               freq_mhz = PNX_DEFAULT_FREQ;
+               dev_info(&pdev->dev, "Setting bus frequency to default value: "
+                      "%d MHz", freq_mhz);
+       }
+
+       i2c_pnx->adapter->algo = &pnx_algorithm;
+
+       alg_data = i2c_pnx->adapter->algo_data;
+       init_timer(&alg_data->mif.timer);
+       alg_data->mif.timer.function = i2c_pnx_timeout;
+       alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter;
+
+       /* Register I/O resource */
+       if (!request_region(alg_data->base, I2C_PNX_REGION_SIZE, pdev->name)) {
+               dev_err(&pdev->dev,
+                      "I/O region 0x%08x for I2C already in use.\n",
+                      alg_data->base);
+               ret = -ENODEV;
+               goto out_drvdata;
+       }
+
+       if (!(alg_data->ioaddr =
+                       (u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) {
+               dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
+       i2c_pnx->set_clock_run(pdev);
+
+       /*
+        * Clock Divisor High This value is the number of system clocks
+        * the serial clock (SCL) will be high.
+        * For example, if the system clock period is 50 ns and the maximum
+        * desired serial period is 10000 ns (100 kHz), then CLKHI would be
+        * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
+        * programmed into CLKHI will vary from this slightly due to
+        * variations in the output pad's rise and fall times as well as
+        * the deglitching filter length.
+        */
+
+       tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+       iowrite32(tmp, I2C_REG_CKH(alg_data));
+       iowrite32(tmp, I2C_REG_CKL(alg_data));
+
+       iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
+       if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
+               ret = -ENODEV;
+               goto out_unmap;
+       }
+       init_completion(&alg_data->mif.complete);
+
+       ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
+                       0, pdev->name, i2c_pnx->adapter);
+       if (ret)
+               goto out_clock;
+
+       /* Register this adapter with the I2C subsystem */
+       i2c_pnx->adapter->dev.parent = &pdev->dev;
+       ret = i2c_add_adapter(i2c_pnx->adapter);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "I2C: Failed to add bus\n");
+               goto out_irq;
+       }
+
+       dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
+              i2c_pnx->adapter->name, alg_data->base, alg_data->irq);
+
+       return 0;
+
+out_irq:
+       free_irq(alg_data->irq, alg_data);
+out_clock:
+       i2c_pnx->set_clock_stop(pdev);
+out_unmap:
+       iounmap((void *)alg_data->ioaddr);
+out_release:
+       release_region(alg_data->base, I2C_PNX_REGION_SIZE);
+out_drvdata:
+       platform_set_drvdata(pdev, NULL);
+out:
+       return ret;
+}
+
+static int __devexit i2c_pnx_remove(struct platform_device *pdev)
+{
+       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
+       struct i2c_adapter *adap = i2c_pnx->adapter;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+
+       free_irq(alg_data->irq, alg_data);
+       i2c_del_adapter(adap);
+       i2c_pnx->set_clock_stop(pdev);
+       iounmap((void *)alg_data->ioaddr);
+       release_region(alg_data->base, I2C_PNX_REGION_SIZE);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver i2c_pnx_driver = {
+       .driver = {
+               .name = "pnx-i2c",
+               .owner = THIS_MODULE,
+       },
+       .probe = i2c_pnx_probe,
+       .remove = __devexit_p(i2c_pnx_remove),
+       .suspend = i2c_pnx_controller_suspend,
+       .resume = i2c_pnx_controller_resume,
+};
+
+static int __init i2c_adap_pnx_init(void)
+{
+       return platform_driver_register(&i2c_pnx_driver);
+}
+
+static void __exit i2c_adap_pnx_exit(void)
+{
+       platform_driver_unregister(&i2c_pnx_driver);
+}
+
+MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
+MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
+MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_I2C_PNX_EARLY
+/* We need to make sure I2C is initialized before USB */
+subsys_initcall(i2c_adap_pnx_init);
+#else
+mudule_init(i2c_adap_pnx_init);
+#endif
+module_exit(i2c_adap_pnx_exit);
index 7745e21..07c1f1e 100644 (file)
@@ -212,7 +212,7 @@ static void prosavage_remove(struct pci_dev *dev)
                if (chip->i2c_bus[i].adap_ok == 0)
                        continue;
 
-               ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
+               ret = i2c_del_adapter(&chip->i2c_bus[i].adap);
                if (ret) {
                        dev_err(&dev->dev, "%s not removed\n",
                                chip->i2c_bus[i].adap.name);
index 209f47e..844b4ff 100644 (file)
@@ -173,7 +173,7 @@ static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_
 
 static void __devexit savage4_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&savage4_i2c_adapter);
+       i2c_del_adapter(&savage4_i2c_adapter);
        iounmap(ioaddr);
 }
 
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
new file mode 100644 (file)
index 0000000..081d957
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  i2c-versatile.c
+ *
+ *  Copyright (C) 2006 ARM Ltd.
+ *  written by Russell King, Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#define I2C_CONTROL    0x00
+#define I2C_CONTROLS   0x00
+#define I2C_CONTROLC   0x04
+#define SCL            (1 << 0)
+#define SDA            (1 << 1)
+
+struct i2c_versatile {
+       struct i2c_adapter       adap;
+       struct i2c_algo_bit_data algo;
+       void __iomem             *base;
+};
+
+static void i2c_versatile_setsda(void *data, int state)
+{
+       struct i2c_versatile *i2c = data;
+
+       writel(SDA, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC));
+}
+
+static void i2c_versatile_setscl(void *data, int state)
+{
+       struct i2c_versatile *i2c = data;
+
+       writel(SCL, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC));
+}
+
+static int i2c_versatile_getsda(void *data)
+{
+       struct i2c_versatile *i2c = data;
+       return !!(readl(i2c->base + I2C_CONTROL) & SDA);
+}
+
+static int i2c_versatile_getscl(void *data)
+{
+       struct i2c_versatile *i2c = data;
+       return !!(readl(i2c->base + I2C_CONTROL) & SCL);
+}
+
+static struct i2c_algo_bit_data i2c_versatile_algo = {
+       .setsda = i2c_versatile_setsda,
+       .setscl = i2c_versatile_setscl,
+       .getsda = i2c_versatile_getsda,
+       .getscl = i2c_versatile_getscl,
+       .udelay = 30,
+       .timeout = HZ,
+};
+
+static int i2c_versatile_probe(struct platform_device *dev)
+{
+       struct i2c_versatile *i2c;
+       struct resource *r;
+       int ret;
+
+       r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!r) {
+               ret = -EINVAL;
+               goto err_out;
+       }
+
+       if (!request_mem_region(r->start, r->end - r->start + 1, "versatile-i2c")) {
+               ret = -EBUSY;
+               goto err_out;
+       }
+
+       i2c = kzalloc(sizeof(struct i2c_versatile), GFP_KERNEL);
+       if (!i2c) {
+               ret = -ENOMEM;
+               goto err_release;
+       }
+
+       i2c->base = ioremap(r->start, r->end - r->start + 1);
+       if (!i2c->base) {
+               ret = -ENOMEM;
+               goto err_free;
+       }
+
+       writel(SCL | SDA, i2c->base + I2C_CONTROLS);
+
+       i2c->adap.owner = THIS_MODULE;
+       strlcpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name));
+       i2c->adap.algo_data = &i2c->algo;
+       i2c->adap.dev.parent = &dev->dev;
+       i2c->algo = i2c_versatile_algo;
+       i2c->algo.data = i2c;
+
+       ret = i2c_bit_add_bus(&i2c->adap);
+       if (ret >= 0) {
+               platform_set_drvdata(dev, i2c);
+               return 0;
+       }
+
+       iounmap(i2c->base);
+ err_free:
+       kfree(i2c);
+ err_release:
+       release_mem_region(r->start, r->end - r->start + 1);
+ err_out:
+       return ret;
+}
+
+static int i2c_versatile_remove(struct platform_device *dev)
+{
+       struct i2c_versatile *i2c = platform_get_drvdata(dev);
+
+       platform_set_drvdata(dev, NULL);
+
+       i2c_del_adapter(&i2c->adap);
+       return 0;
+}
+
+static struct platform_driver i2c_versatile_driver = {
+       .probe          = i2c_versatile_probe,
+       .remove         = i2c_versatile_remove,
+       .driver         = {
+               .name   = "versatile-i2c",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init i2c_versatile_init(void)
+{
+       return platform_driver_register(&i2c_versatile_driver);
+}
+
+static void __exit i2c_versatile_exit(void)
+{
+       platform_driver_unregister(&i2c_versatile_driver);
+}
+
+module_init(i2c_versatile_init);
+module_exit(i2c_versatile_exit);
+
+MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
+MODULE_LICENSE("GPL");
index 910e200..15d7e00 100644 (file)
@@ -151,7 +151,7 @@ static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_i
 
 static void __devexit vt586b_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&vt586b_adapter);
+       i2c_del_adapter(&vt586b_adapter);
        release_region(I2C_DIR, IOSPACE);
        pm_io_base = 0;
 }
index 6c8d251..b0377b8 100644 (file)
@@ -211,14 +211,14 @@ static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_
                return retval;
        retval = i2c_bit_add_bus(&voodoo3_ddc_adapter);
        if (retval)
-               i2c_bit_del_bus(&voodoo3_i2c_adapter);
+               i2c_del_adapter(&voodoo3_i2c_adapter);
        return retval;
 }
 
 static void __devexit voodoo3_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&voodoo3_i2c_adapter);
-       i2c_bit_del_bus(&voodoo3_ddc_adapter);
+       i2c_del_adapter(&voodoo3_i2c_adapter);
+       i2c_del_adapter(&voodoo3_ddc_adapter);
        iounmap(ioaddr);
 }
 
index 8ddbae4..6cd96e4 100644 (file)
@@ -116,7 +116,7 @@ static int scx200_i2c_init(void)
 
 static void scx200_i2c_cleanup(void)
 {
-       i2c_bit_del_bus(&scx200_i2c_ops);
+       i2c_del_adapter(&scx200_i2c_ops);
 }
 
 module_init(scx200_i2c_init);
index 93d483b..ec17d6b 100644 (file)
@@ -347,13 +347,19 @@ static void ds1337_init_client(struct i2c_client *client)
 
        if ((status & 0x80) || (control & 0x80)) {
                /* RTC not running */
-               u8 buf[16];
+               u8 buf[1+16];   /* First byte is interpreted as address */
                struct i2c_msg msg[1];
 
                dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
 
                /* Initialize all, including STATUS and CONTROL to zero */
                memset(buf, 0, sizeof(buf));
+
+               /* Write valid values in the date/time registers */
+               buf[1+DS1337_REG_DAY] = 1;
+               buf[1+DS1337_REG_DATE] = 1;
+               buf[1+DS1337_REG_MONTH] = 1;
+
                msg[0].addr = client->addr;
                msg[0].flags = 0;
                msg[0].len = sizeof(buf);
index 7ca81f4..3e31f1d 100644 (file)
@@ -127,20 +127,17 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att
        return sprintf(buf, "%s\n", client->name);
 }
 
-/* 
- * We can't use the DEVICE_ATTR() macro here as we want the same filename for a
- * different type of a device.  So beware if the DEVICE_ATTR() macro ever
- * changes, this definition will also have to change.
+/*
+ * We can't use the DEVICE_ATTR() macro here, as we used the same name for
+ * an i2c adapter attribute (above).
  */
-static struct device_attribute dev_attr_client_name = {
-       .attr   = {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE },
-       .show   = &show_client_name,
-};
+static struct device_attribute dev_attr_client_name =
+       __ATTR(name, S_IRUGO, &show_client_name, NULL);
 
 
 /* ---------------------------------------------------
- * registering functions 
- * --------------------------------------------------- 
+ * registering functions
+ * ---------------------------------------------------
  */
 
 /* -----
@@ -314,7 +311,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
        res = driver_register(&driver->driver);
        if (res)
                return res;
-       
+
        mutex_lock(&core_lists);
 
        list_add_tail(&driver->list,&drivers);
@@ -338,13 +335,13 @@ int i2c_del_driver(struct i2c_driver *driver)
        struct list_head   *item1, *item2, *_n;
        struct i2c_client  *client;
        struct i2c_adapter *adap;
-       
+
        int res = 0;
 
        mutex_lock(&core_lists);
 
        /* Have a look at each adapter, if clients of this driver are still
-        * attached. If so, detach them to be able to kill the driver 
+        * attached. If so, detach them to be able to kill the driver
         * afterwards.
         */
        list_for_each(item1,&adapters) {
@@ -419,14 +416,14 @@ int i2c_attach_client(struct i2c_client *client)
                goto out_unlock;
        }
        list_add_tail(&client->list,&adapter->clients);
-       
+
        client->usage_count = 0;
 
        client->dev.parent = &client->adapter->dev;
        client->dev.driver = &client->driver->driver;
        client->dev.bus = &i2c_bus_type;
        client->dev.release = &i2c_client_release;
-       
+
        snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
                "%d-%04x", i2c_adapter_id(adapter), client->addr);
        dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
@@ -467,7 +464,7 @@ int i2c_detach_client(struct i2c_client *client)
 {
        struct i2c_adapter *adapter = client->adapter;
        int res = 0;
-       
+
        if (client->usage_count > 0) {
                dev_warn(&client->dev, "Client [%s] still busy, "
                         "can't detach\n", client->name);
@@ -535,10 +532,10 @@ int i2c_release_client(struct i2c_client *client)
                         __FUNCTION__);
                return -EPERM;
        }
-       
+
        client->usage_count--;
        i2c_dec_use_client(client);
-       
+
        return 0;
 }
 
@@ -603,7 +600,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
                }
 #endif
 
-               mutex_lock(&adap->bus_lock);
+               mutex_lock_nested(&adap->bus_lock, adap->level);
                ret = adap->algo->master_xfer(adap,msgs,num);
                mutex_unlock(&adap->bus_lock);
 
@@ -624,7 +621,7 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
        msg.flags = client->flags & I2C_M_TEN;
        msg.len = count;
        msg.buf = (char *)buf;
-       
+
        ret = i2c_transfer(adap, &msg, 1);
 
        /* If everything went ok (i.e. 1 msg transmitted), return #bytes
@@ -757,7 +754,7 @@ int i2c_probe(struct i2c_adapter *adapter,
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
                if (address_data->probe[0] == I2C_CLIENT_END
                 && address_data->normal_i2c[0] == I2C_CLIENT_END)
-                       return 0;
+                       return 0;
 
                dev_warn(&adapter->dev, "SMBus Quick command not supported, "
                         "can't probe for chips\n");
@@ -817,7 +814,7 @@ int i2c_probe(struct i2c_adapter *adapter,
 struct i2c_adapter* i2c_get_adapter(int id)
 {
        struct i2c_adapter *adapter;
-       
+
        mutex_lock(&core_lists);
        adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
        if (adapter && !try_module_get(adapter->owner))
@@ -834,14 +831,14 @@ void i2c_put_adapter(struct i2c_adapter *adap)
 
 /* The SMBus parts */
 
-#define POLY    (0x1070U << 3) 
+#define POLY    (0x1070U << 3)
 static u8
 crc8(u16 data)
 {
        int i;
-  
+
        for(i = 0; i < 8; i++) {
-               if (data & 0x8000) 
+               if (data & 0x8000)
                        data = data ^ POLY;
                data = data << 1;
        }
@@ -891,13 +888,13 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
                        rpec, cpec);
                return -1;
        }
-       return 0;       
+       return 0;
 }
 
 s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value)
 {
        return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-                             value,0,I2C_SMBUS_QUICK,NULL);
+                             value,0,I2C_SMBUS_QUICK,NULL);
 }
 
 s32 i2c_smbus_read_byte(struct i2c_client *client)
@@ -996,11 +993,11 @@ s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
                              I2C_SMBUS_I2C_BLOCK_DATA, &data);
 }
 
-/* Simulate a SMBus command using the i2c protocol 
+/* Simulate a SMBus command using the i2c protocol
    No checking of parameters is done!  */
-static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, 
+static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                                    unsigned short flags,
-                                   char read_write, u8 command, int size, 
+                                   char read_write, u8 command, int size,
                                    union i2c_smbus_data * data)
 {
        /* So we need to generate a series of msgs. In the case of writing, we
@@ -1010,7 +1007,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
        unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
        unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
        int num = read_write == I2C_SMBUS_READ?2:1;
-       struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, 
+       struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
                                  { addr, flags | I2C_M_RD, 0, msgbuf1 }
                                };
        int i;
@@ -1103,14 +1100,14 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
        if (i) {
                /* Compute PEC if first message is a write */
                if (!(msg[0].flags & I2C_M_RD)) {
-                       if (num == 1) /* Write only */
+                       if (num == 1) /* Write only */
                                i2c_smbus_add_pec(&msg[0]);
                        else /* Write followed by read */
                                partial_pec = i2c_smbus_msg_pec(0, &msg[0]);
                }
                /* Ask for PEC if last message is a read */
                if (msg[num-1].flags & I2C_M_RD)
-                       msg[num-1].len++;
+                       msg[num-1].len++;
        }
 
        if (i2c_transfer(adapter, msg, num) < 0)
@@ -1130,7 +1127,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                        case I2C_SMBUS_BYTE_DATA:
                                data->byte = msgbuf1[0];
                                break;
-                       case I2C_SMBUS_WORD_DATA: 
+                       case I2C_SMBUS_WORD_DATA:
                        case I2C_SMBUS_PROC_CALL:
                                data->word = msgbuf1[0] | (msgbuf1[1] << 8);
                                break;
@@ -1146,7 +1143,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
 
 
 s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
-                   char read_write, u8 command, int size, 
+                   char read_write, u8 command, int size,
                    union i2c_smbus_data * data)
 {
        s32 res;
index 2e22a2f..ac5bd2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    i2c-dev.c - i2c-bus driver, char device interface  
+    i2c-dev.c - i2c-bus driver, char device interface
 
     Copyright (C) 1995-97 Simon G. Vogl
     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
@@ -90,6 +90,7 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
        spin_lock(&i2c_dev_list_lock);
        list_del(&i2c_dev->list);
        spin_unlock(&i2c_dev_list_lock);
+       kfree(i2c_dev);
 }
 
 static ssize_t show_adapter_name(struct device *dev,
@@ -172,7 +173,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
        switch ( cmd ) {
        case I2C_SLAVE:
        case I2C_SLAVE_FORCE:
-               if ((arg > 0x3ff) || 
+               if ((arg > 0x3ff) ||
                    (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
                        return -EINVAL;
                if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
@@ -193,12 +194,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                return 0;
        case I2C_FUNCS:
                funcs = i2c_get_functionality(client->adapter);
-               return (copy_to_user((unsigned long __user *)arg, &funcs,
-                                    sizeof(unsigned long)))?-EFAULT:0;
+               return put_user(funcs, (unsigned long __user *)arg);
 
        case I2C_RDWR:
-               if (copy_from_user(&rdwr_arg, 
-                                  (struct i2c_rdwr_ioctl_data __user *)arg, 
+               if (copy_from_user(&rdwr_arg,
+                                  (struct i2c_rdwr_ioctl_data __user *)arg,
                                   sizeof(rdwr_arg)))
                        return -EFAULT;
 
@@ -206,9 +206,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                 * 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), 
+                       kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
                        GFP_KERNEL);
 
                if (rdwr_pa == NULL) return -ENOMEM;
@@ -278,9 +278,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                                   (struct i2c_smbus_ioctl_data __user *) arg,
                                   sizeof(struct i2c_smbus_ioctl_data)))
                        return -EFAULT;
-               if ((data_arg.size != I2C_SMBUS_BYTE) && 
+               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_BYTE_DATA) &&
                    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
                    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
                    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
@@ -291,11 +291,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                                data_arg.size);
                        return -EINVAL;
                }
-               /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, 
+               /* 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) && 
+               if ((data_arg.read_write != I2C_SMBUS_READ) &&
                    (data_arg.read_write != I2C_SMBUS_WRITE)) {
-                       dev_dbg(&client->adapter->dev, 
+                       dev_dbg(&client->adapter->dev,
                                "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
                                data_arg.read_write);
                        return -EINVAL;
@@ -304,7 +304,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                /* Note that command values are always valid! */
 
                if ((data_arg.size == I2C_SMBUS_QUICK) ||
-                   ((data_arg.size == I2C_SMBUS_BYTE) && 
+                   ((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,
@@ -322,14 +322,14 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                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) || 
+               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) || 
+               if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+                   (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
                    (data_arg.read_write == I2C_SMBUS_WRITE)) {
                        if (copy_from_user(&temp, data_arg.data, datasize))
                                return -EFAULT;
@@ -337,8 +337,8 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                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) || 
+               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;
@@ -417,8 +417,8 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
        i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
                                     MKDEV(I2C_MAJOR, adap->nr),
                                     "i2c-%d", adap->nr);
-       if (!i2c_dev->dev) {
-               res = -ENODEV;
+       if (IS_ERR(i2c_dev->dev)) {
+               res = PTR_ERR(i2c_dev->dev);
                goto error;
        }
        res = device_create_file(i2c_dev->dev, &dev_attr_name);
@@ -432,7 +432,6 @@ error_destroy:
        device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
 error:
        return_i2c_dev(i2c_dev);
-       kfree(i2c_dev);
        return res;
 }
 
@@ -447,7 +446,6 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap)
        device_remove_file(i2c_dev->dev, &dev_attr_name);
        return_i2c_dev(i2c_dev);
        device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
-       kfree(i2c_dev);
 
        pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
        return 0;
index 13a6179..fbb7f14 100644 (file)
@@ -1485,7 +1485,7 @@ static int __devinit add_card(struct pci_dev *dev,
 
                         }
 
-                        i2c_bit_del_bus(i2c_ad);
+                       i2c_del_adapter(i2c_ad);
                        kfree(i2c_ad);
                 }
         }
index 8e4ce10..ffda71d 100644 (file)
@@ -650,7 +650,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
        /* dvb */
        ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev);
        if (ret < 0)
-               goto err_i2c_bit_del_bus;
+               goto err_i2c_del_adapter;
 
        dvb_adapter = &pluto->dvb_adapter;
 
@@ -712,8 +712,8 @@ err_dvb_dmx_release:
        dvb_dmx_release(dvbdemux);
 err_dvb_unregister_adapter:
        dvb_unregister_adapter(dvb_adapter);
-err_i2c_bit_del_bus:
-       i2c_bit_del_bus(&pluto->i2c_adap);
+err_i2c_del_adapter:
+       i2c_del_adapter(&pluto->i2c_adap);
 err_pluto_hw_exit:
        pluto_hw_exit(pluto);
 err_free_irq:
@@ -748,7 +748,7 @@ static void __devexit pluto2_remove(struct pci_dev *pdev)
        dvb_dmxdev_release(&pluto->dmxdev);
        dvb_dmx_release(dvbdemux);
        dvb_unregister_adapter(dvb_adapter);
-       i2c_bit_del_bus(&pluto->i2c_adap);
+       i2c_del_adapter(&pluto->i2c_adap);
        pluto_hw_exit(pluto);
        free_irq(pdev->irq, pluto);
        pci_iounmap(pdev, pluto->io_mem);
index 70de6c9..62b8730 100644 (file)
@@ -479,11 +479,7 @@ int __devexit fini_bttv_i2c(struct bttv *btv)
        if (0 != btv->i2c_rc)
                return 0;
 
-       if (btv->use_i2c_hw) {
-               return i2c_del_adapter(&btv->c.i2c_adap);
-       } else {
-               return i2c_bit_del_bus(&btv->c.i2c_adap);
-       }
+       return i2c_del_adapter(&btv->c.i2c_adap);
 }
 
 /*
index 4b655f2..453af5e 100644 (file)
@@ -1153,7 +1153,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
        mutex_lock(&devlist);
        cx88_ir_fini(core);
        if (0 == core->i2c_rc)
-               i2c_bit_del_bus(&core->i2c_adap);
+               i2c_del_adapter(&core->i2c_adap);
        list_del(&core->devlist);
        iounmap(core->lmmio);
        cx88_devcount--;
index 2b4f197..6068c9b 100644 (file)
@@ -168,7 +168,7 @@ void vp3054_i2c_remove(struct cx8802_dev *dev)
            dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
                return;
 
-       i2c_bit_del_bus(&vp3054_i2c->adap);
+       i2c_del_adapter(&vp3054_i2c->adap);
        kfree(vp3054_i2c);
 }
 
index 6b6dff4..a373c14 100644 (file)
@@ -782,7 +782,7 @@ static int vino_i2c_add_bus(void)
 
 static int vino_i2c_del_bus(void)
 {
-       return i2c_sgi_del_bus(&vino_i2c_adapter);
+       return i2c_del_adapter(&vino_i2c_adapter);
 }
 
 static int i2c_camera_command(unsigned int cmd, void *arg)
index 653822c..4d1eb2f 100644 (file)
@@ -849,7 +849,7 @@ zoran_register_i2c (struct zoran *zr)
 static void
 zoran_unregister_i2c (struct zoran *zr)
 {
-       i2c_bit_del_bus((&zr->i2c_adapter));
+       i2c_del_adapter(&zr->i2c_adapter);
 }
 
 /* Check a zoran_params struct for correctness, insert default params */
index 869725a..e7c5b21 100644 (file)
@@ -120,19 +120,19 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
 void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
 {
        if (rinfo->i2c[0].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[0].adapter);
+               i2c_del_adapter(&rinfo->i2c[0].adapter);
        rinfo->i2c[0].rinfo = NULL;
 
        if (rinfo->i2c[1].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[1].adapter);
+               i2c_del_adapter(&rinfo->i2c[1].adapter);
        rinfo->i2c[1].rinfo = NULL;
 
        if (rinfo->i2c[2].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[2].adapter);
+               i2c_del_adapter(&rinfo->i2c[2].adapter);
        rinfo->i2c[2].rinfo = NULL;
 
        if (rinfo->i2c[3].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[3].adapter);
+               i2c_del_adapter(&rinfo->i2c[3].adapter);
        rinfo->i2c[3].rinfo = NULL;
 }
 
index b952e45..961f4d4 100644 (file)
@@ -137,15 +137,15 @@ void i810_create_i2c_busses(struct i810fb_par *par)
 void i810_delete_i2c_busses(struct i810fb_par *par)
 {
         if (par->chan[0].par)
-                i2c_bit_del_bus(&par->chan[0].adapter);
+               i2c_del_adapter(&par->chan[0].adapter);
         par->chan[0].par = NULL;
 
        if (par->chan[1].par)
-               i2c_bit_del_bus(&par->chan[1].adapter);
+               i2c_del_adapter(&par->chan[1].adapter);
        par->chan[1].par = NULL;
 
        if (par->chan[2].par)
-               i2c_bit_del_bus(&par->chan[2].adapter);
+               i2c_del_adapter(&par->chan[2].adapter);
        par->chan[2].par = NULL;
 }
 
index 5686e21..33bc41f 100644 (file)
@@ -188,11 +188,11 @@ void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
 
        for (i = 0; i < MAX_OUTPUTS; i++) {
                if (dinfo->output[i].i2c_bus.dinfo) {
-                       i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter);
+                       i2c_del_adapter(&dinfo->output[i].i2c_bus.adapter);
                        dinfo->output[i].i2c_bus.dinfo = NULL;
                }
                if (dinfo->output[i].ddc_bus.dinfo) {
-                       i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter);
+                       i2c_del_adapter(&dinfo->output[i].ddc_bus.adapter);
                        dinfo->output[i].ddc_bus.dinfo = NULL;
                }
        }
index 795c1a9..797b423 100644 (file)
@@ -124,7 +124,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
 
 static void i2c_bit_bus_del(struct i2c_bit_adapter* b) {
        if (b->initialized) {
-               i2c_bit_del_bus(&b->adapter);
+               i2c_del_adapter(&b->adapter);
                b->initialized = 0;
        }
 }
index 442e853..8454adf 100644 (file)
@@ -147,15 +147,15 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
 void nvidia_delete_i2c_busses(struct nvidia_par *par)
 {
        if (par->chan[0].par)
-               i2c_bit_del_bus(&par->chan[0].adapter);
+               i2c_del_adapter(&par->chan[0].adapter);
        par->chan[0].par = NULL;
 
        if (par->chan[1].par)
-               i2c_bit_del_bus(&par->chan[1].adapter);
+               i2c_del_adapter(&par->chan[1].adapter);
        par->chan[1].par = NULL;
 
        if (par->chan[2].par)
-               i2c_bit_del_bus(&par->chan[2].adapter);
+               i2c_del_adapter(&par->chan[2].adapter);
        par->chan[2].par = NULL;
 
 }
index c15b259..01b85e3 100644 (file)
@@ -144,15 +144,15 @@ void riva_create_i2c_busses(struct riva_par *par)
 void riva_delete_i2c_busses(struct riva_par *par)
 {
        if (par->chan[0].par)
-               i2c_bit_del_bus(&par->chan[0].adapter);
+               i2c_del_adapter(&par->chan[0].adapter);
        par->chan[0].par = NULL;
 
        if (par->chan[1].par)
-               i2c_bit_del_bus(&par->chan[1].adapter);
+               i2c_del_adapter(&par->chan[1].adapter);
        par->chan[1].par = NULL;
 
        if (par->chan[2].par)
-               i2c_bit_del_bus(&par->chan[2].adapter);
+               i2c_del_adapter(&par->chan[2].adapter);
        par->chan[2].par = NULL;
 }
 
index cef5bf5..1411f3b 100644 (file)
@@ -208,7 +208,7 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
        struct savagefb_par *par = info->par;
 
        if (par->chan.par)
-               i2c_bit_del_bus(&par->chan.adapter);
+               i2c_del_adapter(&par->chan.adapter);
 
        par->chan.par = NULL;
 }
diff --git a/include/asm-arm/arch-pnx4008/i2c.h b/include/asm-arm/arch-pnx4008/i2c.h
new file mode 100644 (file)
index 0000000..92e8d65
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * PNX4008-specific tweaks for I2C IP3204 block
+ *
+ * Author: Vitaly Wool <vwool@ru.mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_ARCH_I2C_H__
+#define __ASM_ARCH_I2C_H__
+
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+
+enum {
+       mstatus_tdi = 0x00000001,
+       mstatus_afi = 0x00000002,
+       mstatus_nai = 0x00000004,
+       mstatus_drmi = 0x00000008,
+       mstatus_active = 0x00000020,
+       mstatus_scl = 0x00000040,
+       mstatus_sda = 0x00000080,
+       mstatus_rff = 0x00000100,
+       mstatus_rfe = 0x00000200,
+       mstatus_tff = 0x00000400,
+       mstatus_tfe = 0x00000800,
+};
+
+enum {
+       mcntrl_tdie = 0x00000001,
+       mcntrl_afie = 0x00000002,
+       mcntrl_naie = 0x00000004,
+       mcntrl_drmie = 0x00000008,
+       mcntrl_daie = 0x00000020,
+       mcntrl_rffie = 0x00000040,
+       mcntrl_tffie = 0x00000080,
+       mcntrl_reset = 0x00000100,
+       mcntrl_cdbmode = 0x00000400,
+};
+
+enum {
+       rw_bit = 1 << 0,
+       start_bit = 1 << 8,
+       stop_bit = 1 << 9,
+};
+
+#define I2C_REG_RX(a)  ((a)->ioaddr)           /* Rx FIFO reg (RO) */
+#define I2C_REG_TX(a)  ((a)->ioaddr)           /* Tx FIFO reg (WO) */
+#define I2C_REG_STS(a) ((a)->ioaddr + 0x04)    /* Status reg (RO) */
+#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08)    /* Ctl reg */
+#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c)    /* Clock divider low */
+#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10)    /* Clock divider high */
+#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14)    /* I2C address */
+#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18)    /* Rx FIFO level (RO) */
+#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c)    /* Tx FIFO level (RO) */
+#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20)    /* Num of bytes Rx-ed (RO) */
+#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24)    /* Num of bytes Tx-ed (RO) */
+#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28)    /* Tx slave FIFO (RO) */
+#define I2C_REG_STFL(a)        ((a)->ioaddr + 0x2c)    /* Tx slave FIFO level (RO) */
+
+#define HCLK_MHZ               13
+#define I2C_CHIP_NAME          "PNX4008-I2C"
+
+#endif                         /* __ASM_ARCH_I2C_H___ */
index c8f8df2..937da70 100644 (file)
@@ -26,9 +26,9 @@
 
 /* --- Defines for bit-adapters ---------------------------------------        */
 /*
- * This struct contains the hw-dependent functions of bit-style adapters to 
+ * This struct contains the hw-dependent functions of bit-style adapters to
  * manipulate the line states, and to init any hw-specific features. This is
- * only used if you have more than one hw-type of adapter running. 
+ * only used if you have more than one hw-type of adapter running.
  */
 struct i2c_algo_bit_data {
        void *data;             /* private data for lowlevel routines */
@@ -44,6 +44,5 @@ struct i2c_algo_bit_data {
 };
 
 int i2c_bit_add_bus(struct i2c_adapter *);
-int i2c_bit_del_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_BIT_H */
diff --git a/include/linux/i2c-algo-ite.h b/include/linux/i2c-algo-ite.h
deleted file mode 100644 (file)
index 0073fe9..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-ite.h i2c driver algorithms for ITE IIC adapters                 */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* Modifications by MontaVista Software, 2001
-   Changes made to support the ITE IIC peripheral */
-
-
-#ifndef I2C_ALGO_ITE_H
-#define I2C_ALGO_ITE_H 1
-
-#include <linux/types.h>
-
-/* Example of a sequential read request:
-       struct i2c_iic_msg s_msg; 
-
-       s_msg.addr=device_address;
-       s_msg.len=length;
-       s_msg.buf=buffer;
-       s_msg.waddr=word_address;
-       ioctl(file,I2C_SREAD, &s_msg);
- */
-#define I2C_SREAD      0x780   /* SREAD ioctl command */
-
-struct i2c_iic_msg {
-       __u16 addr;     /* device address */
-       __u16 waddr;    /* word address */
-       short len;      /* msg length */
-       char *buf;      /* pointer to msg data */
-};
-
-#ifdef __KERNEL__
-struct i2c_adapter;
-
-struct i2c_algo_iic_data {
-       void *data;             /* private data for lolevel routines    */
-       void (*setiic) (void *data, int ctl, int val);
-       int  (*getiic) (void *data, int ctl);
-       int  (*getown) (void *data);
-       int  (*getclock) (void *data);
-       void (*waitforpin) (void);     
-
-       /* local settings */
-       int udelay;
-       int mdelay;
-       int timeout;
-};
-
-int i2c_iic_add_bus(struct i2c_adapter *);
-int i2c_iic_del_bus(struct i2c_adapter *);
-#endif /* __KERNEL__ */
-#endif /* I2C_ALGO_ITE_H */
index 226693e..fce47c0 100644 (file)
@@ -10,6 +10,5 @@ struct i2c_algo_pca_data {
 };
 
 int i2c_pca_add_bus(struct i2c_adapter *);
-int i2c_pca_del_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_PCA_H */
index 9908f3f..994eb86 100644 (file)
@@ -31,7 +31,7 @@ struct i2c_algo_pcf_data {
        int  (*getpcf) (void *data, int ctl);
        int  (*getown) (void *data);
        int  (*getclock) (void *data);
-       void (*waitforpin) (void);     
+       void (*waitforpin) (void);
 
        /* local settings */
        int udelay;
@@ -39,6 +39,5 @@ struct i2c_algo_pcf_data {
 };
 
 int i2c_pcf_add_bus(struct i2c_adapter *);
-int i2c_pcf_del_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_PCF_H */
index 4a0113d..3b77150 100644 (file)
@@ -22,6 +22,5 @@ struct i2c_algo_sgi_data {
 };
 
 int i2c_sgi_add_bus(struct i2c_adapter *);
-int i2c_sgi_del_bus(struct i2c_adapter *);
 
 #endif /* I2C_ALGO_SGI_H */
index 0f4cf34..7ae3c33 100644 (file)
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------- */
-/*                                                                          */
+/*                                                                          */
 /* i2c-id.h - identifier values for i2c drivers and adapters                */
-/*                                                                          */
+/*                                                                          */
 /* ------------------------------------------------------------------------- */
 /*   Copyright (C) 1995-1999 Simon G. Vogl
 
 #define I2C_DRIVERID_SAA7120   11      /* video encoder                */
 #define I2C_DRIVERID_SAA7121   12      /* video encoder                */
 #define I2C_DRIVERID_SAA7185B  13      /* video encoder                */
-#define I2C_DRIVERID_CH7003    14      /* digital pc to tv encoder     */
+#define I2C_DRIVERID_CH7003    14      /* digital pc to tv encoder     */
 #define I2C_DRIVERID_PCF8574A  15      /* i2c expander - 8 bit in/out  */
 #define I2C_DRIVERID_PCF8582C  16      /* eeprom                       */
-#define I2C_DRIVERID_AT24Cxx   17      /* eeprom 1/2/4/8/16 K          */
+#define I2C_DRIVERID_AT24Cxx   17      /* eeprom 1/2/4/8/16 K          */
 #define I2C_DRIVERID_TEA6300   18      /* audio mixer                  */
 #define I2C_DRIVERID_BT829     19      /* pc to tv encoder             */
 #define I2C_DRIVERID_TDA9850   20      /* audio mixer                  */
@@ -82,9 +82,8 @@
 #define I2C_DRIVERID_STM41T00  52      /* real time clock              */
 #define I2C_DRIVERID_UDA1342   53      /* UDA1342 audio codec          */
 #define I2C_DRIVERID_ADV7170   54      /* video encoder                */
-#define I2C_DRIVERID_RADEON    55      /* I2C bus on Radeon boards     */
 #define I2C_DRIVERID_MAX1617   56      /* temp sensor                  */
-#define I2C_DRIVERID_SAA7191   57      /* video encoder                */
+#define I2C_DRIVERID_SAA7191   57      /* video decoder                */
 #define I2C_DRIVERID_INDYCAM   58      /* SGI IndyCam                  */
 #define I2C_DRIVERID_BT832     59      /* CMOS camera video processor  */
 #define I2C_DRIVERID_TDA9887   60      /* TDA988x IF-PLL demodulator   */
 #define I2C_DRIVERID_ADM1021 1008
 #define I2C_DRIVERID_ADM9240 1009
 #define I2C_DRIVERID_LTC1710 1010
-#define I2C_DRIVERID_ICSPLL 1012
 #define I2C_DRIVERID_BT869 1013
 #define I2C_DRIVERID_MAXILIFE 1014
 #define I2C_DRIVERID_MATORB 1015
  * ---- Adapter types ----------------------------------------------------
  */
 
-/* --- Bit algorithm adapters                                          */
+/* --- Bit algorithm adapters                                          */
 #define I2C_HW_B_LP            0x010000 /* Parallel port Philips style */
 #define I2C_HW_B_SER           0x010002 /* Serial line interface */
 #define I2C_HW_B_BT848         0x010005 /* BT848 video boards */
 /* --- MPC8xx PowerPC adapters                                         */
 #define I2C_HW_MPC8XX_EPON     0x110000 /* Eponymous MPC8xx I2C adapter */
 
-/* --- ITE based algorithms                                            */
-#define I2C_HW_I_IIC           0x080000 /* controller on the ITE */
-
 /* --- PowerPC on-chip adapters                                                */
 #define I2C_HW_OCP             0x120000 /* IBM on-chip I2C adapter */
 
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h
new file mode 100644 (file)
index 0000000..e6e9c81
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Header file for I2C support on PNX010x/4008.
+ *
+ * Author: Dennis Kovalev <dkovalev@ru.mvista.com>
+ *
+ * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __I2C_PNX_H__
+#define __I2C_PNX_H__
+
+#include <asm/arch/i2c.h>
+
+struct i2c_pnx_mif {
+       int                     ret;            /* Return value */
+       int                     mode;           /* Interface mode */
+       struct completion       complete;       /* I/O completion */
+       struct timer_list       timer;          /* Timeout */
+       char *                  buf;            /* Data buffer */
+       int                     len;            /* Length of data buffer */
+};
+
+struct i2c_pnx_algo_data {
+       u32                     base;
+       u32                     ioaddr;
+       int                     irq;
+       struct i2c_pnx_mif      mif;
+       int                     last;
+};
+
+struct i2c_pnx_data {
+       int (*suspend) (struct platform_device *pdev, pm_message_t state);
+       int (*resume) (struct platform_device *pdev);
+       u32 (*calculate_input_freq) (struct platform_device *pdev);
+       int (*set_clock_run) (struct platform_device *pdev);
+       int (*set_clock_stop) (struct platform_device *pdev);
+       struct i2c_adapter *adapter;
+};
+
+#endif /* __I2C_PNX_H__ */
index 9b5d047..71e50d3 100644 (file)
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------- */
-/*                                                                          */
+/*                                                                          */
 /* i2c.h - definitions for the i2c-bus interface                            */
-/*                                                                          */
+/*                                                                          */
 /* ------------------------------------------------------------------------- */
 /*   Copyright (C) 1995-2000 Simon G. Vogl
 
@@ -27,7 +27,7 @@
 #define _LINUX_I2C_H
 
 #include <linux/types.h>
-#ifdef __KERNEL__ 
+#ifdef __KERNEL__
 #include <linux/module.h>
 #include <linux/i2c-id.h>
 #include <linux/mod_devicetable.h>
@@ -53,8 +53,8 @@ union i2c_smbus_data;
 
 /*
  * The master routines are the ones normally used to transmit data to devices
- * on a bus (or read from them). Apart from two basic transfer functions to 
- * transmit one message at a time, a more complex version can be used to 
+ * on a bus (or read from them). Apart from two basic transfer functions to
+ * transmit one message at a time, a more complex version can be used to
  * transmit an arbitrary number of messages without interruption.
  */
 extern int i2c_master_send(struct i2c_client *,const char* ,int);
@@ -67,10 +67,10 @@ extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 
 /* This is the very generalized SMBus access routine. You probably do not
    want to use this, though; one of the functions below may be much easier,
-   and probably just as fast. 
+   and probably just as fast.
    Note that we use i2c_adapter here, because you do not need a specific
    smbus adapter to call this function. */
-extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, 
+extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr,
                            unsigned short flags,
                            char read_write, u8 command, int size,
                            union i2c_smbus_data * data);
@@ -112,14 +112,14 @@ struct i2c_driver {
 
        /* Notifies the driver that a new bus has appeared. This routine
         * can be used by the driver to test if the bus meets its conditions
-        * & seek for the presence of the chip(s) it supports. If found, it 
+        * & seek for the presence of the chip(s) it supports. If found, it
         * registers the client(s) that are on the bus to the i2c admin. via
         * i2c_attach_client.
         */
        int (*attach_adapter)(struct i2c_adapter *);
        int (*detach_adapter)(struct i2c_adapter *);
 
-       /* tells the driver that a client is about to be deleted & gives it 
+       /* tells the driver that a client is about to be deleted & gives it
         * the chance to remove its private data. Also, if the client struct
         * has been dynamically allocated by the driver in the function above,
         * it must be freed here.
@@ -139,13 +139,13 @@ struct i2c_driver {
 #define I2C_NAME_SIZE  50
 
 /*
- * i2c_client identifies a single device (i.e. chip) that is connected to an 
+ * i2c_client identifies a single device (i.e. chip) that is connected to an
  * i2c bus. The behaviour is defined by the routines of the driver. This
  * function is mainly used for lookup & other admin. functions.
  */
 struct i2c_client {
        unsigned int flags;             /* div., see below              */
-       unsigned short addr;            /* chip address - NOTE: 7bit    */
+       unsigned short addr;            /* chip address - NOTE: 7bit    */
                                        /* addresses are stored in the  */
                                        /* _LOWER_ 7 bits               */
        struct i2c_adapter *adapter;    /* the adapter we sit on        */
@@ -182,14 +182,14 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
  */
 struct i2c_algorithm {
        /* If an adapter algorithm can't do I2C-level access, set master_xfer
-          to NULL. If an adapter algorithm can do SMBus access, set 
+          to NULL. If an adapter algorithm can do SMBus access, set
           smbus_xfer. If set to NULL, the SMBus protocol is simulated
           using common I2C messages */
        /* master_xfer should return the number of messages successfully
           processed, or a negative value on error */
-       int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs, 
+       int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
                           int num);
-       int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, 
+       int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
                           unsigned short flags, char read_write,
                           u8 command, int size, union i2c_smbus_data * data);
 
@@ -216,6 +216,7 @@ struct i2c_adapter {
        int (*client_unregister)(struct i2c_client *);
 
        /* data fields that are valid for all devices   */
+       u8 level;                       /* nesting level for lockdep */
        struct mutex bus_lock;
        struct mutex clist_lock;
 
@@ -316,7 +317,7 @@ extern int i2c_check_addr (struct i2c_adapter *adapter, int addr);
  * It will only call found_proc if some client is connected at the
  * specific address (unless a 'force' matched);
  */
-extern int i2c_probe(struct i2c_adapter *adapter, 
+extern int i2c_probe(struct i2c_adapter *adapter,
                struct i2c_client_address_data *address_data,
                int (*found_proc) (struct i2c_adapter *, int, int));
 
@@ -352,15 +353,15 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
  */
 struct i2c_msg {
        __u16 addr;     /* slave address                        */
-       __u16 flags;            
+       __u16 flags;
 #define I2C_M_TEN      0x10    /* we have a ten bit chip address       */
 #define I2C_M_RD       0x01
 #define I2C_M_NOSTART  0x4000
 #define I2C_M_REV_DIR_ADDR     0x2000
 #define I2C_M_IGNORE_NAK       0x1000
 #define I2C_M_NO_RD_ACK                0x0800
-       __u16 len;              /* msg length                           */
-       __u8 *buf;              /* pointer to msg data                  */
+       __u16 len;              /* msg length                           */
+       __u8 *buf;              /* pointer to msg data                  */
 };
 
 /* To determine what functionality is present */
@@ -370,16 +371,16 @@ struct i2c_msg {
 #define I2C_FUNC_PROTOCOL_MANGLING     0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
 #define I2C_FUNC_SMBUS_HWPEC_CALC      0x00000008 /* SMBus 2.0 */
 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_QUICK           0x00010000 
-#define I2C_FUNC_SMBUS_READ_BYTE       0x00020000 
-#define I2C_FUNC_SMBUS_WRITE_BYTE      0x00040000 
-#define I2C_FUNC_SMBUS_READ_BYTE_DATA  0x00080000 
-#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 
-#define I2C_FUNC_SMBUS_READ_WORD_DATA  0x00200000 
-#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 
-#define I2C_FUNC_SMBUS_PROC_CALL       0x00800000 
-#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 
-#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 
+#define I2C_FUNC_SMBUS_QUICK           0x00010000
+#define I2C_FUNC_SMBUS_READ_BYTE       0x00020000
+#define I2C_FUNC_SMBUS_WRITE_BYTE      0x00040000
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA  0x00080000
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define I2C_FUNC_SMBUS_READ_WORD_DATA  0x00200000
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define I2C_FUNC_SMBUS_PROC_CALL       0x00800000
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK  0x04000000 /* I2C-like block xfer  */
 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2         0x10000000 /* I2C-like block xfer  */
@@ -406,10 +407,10 @@ struct i2c_msg {
                              I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
                              I2C_FUNC_SMBUS_I2C_BLOCK)
 
-/* 
- * Data for SMBus Messages 
+/*
+ * Data for SMBus Messages
  */
-#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */    
+#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */
 union i2c_smbus_data {
        __u8 byte;
        __u16 word;
@@ -421,11 +422,11 @@ union i2c_smbus_data {
 #define I2C_SMBUS_READ 1
 #define I2C_SMBUS_WRITE        0
 
-/* SMBus transaction types (size parameter in the above functions) 
+/* SMBus transaction types (size parameter in the above functions)
    Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
 #define I2C_SMBUS_QUICK                    0
 #define I2C_SMBUS_BYTE             1
-#define I2C_SMBUS_BYTE_DATA        2 
+#define I2C_SMBUS_BYTE_DATA        2
 #define I2C_SMBUS_WORD_DATA        3
 #define I2C_SMBUS_PROC_CALL        4
 #define I2C_SMBUS_BLOCK_DATA       5
@@ -434,15 +435,15 @@ union i2c_smbus_data {
 
 
 /* ----- commands for the ioctl like i2c_command call:
- * note that additional calls are defined in the algorithm and hw 
- *     dependent layers - these can be listed here, or see the 
+ * note that additional calls are defined in the algorithm and hw
+ *     dependent layers - these can be listed here, or see the
  *     corresponding header files.
  */
                                /* -> bit-adapter specific ioctls       */
 #define I2C_RETRIES    0x0701  /* number of times a device address      */
                                /* should be polled when not            */
-                                /* acknowledging                       */
-#define I2C_TIMEOUT    0x0702  /* set timeout - call with int          */
+                                /* acknowledging                       */
+#define I2C_TIMEOUT    0x0702  /* set timeout - call with int          */
 
 
 /* this is for i2c-dev.c       */