summaryrefslogtreecommitdiff
path: root/packages/linux/linux-mtx-1-2.4.27/16-i2c.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/linux-mtx-1-2.4.27/16-i2c.patch')
-rw-r--r--packages/linux/linux-mtx-1-2.4.27/16-i2c.patch7482
1 files changed, 0 insertions, 7482 deletions
diff --git a/packages/linux/linux-mtx-1-2.4.27/16-i2c.patch b/packages/linux/linux-mtx-1-2.4.27/16-i2c.patch
deleted file mode 100644
index cec737bdfe..0000000000
--- a/packages/linux/linux-mtx-1-2.4.27/16-i2c.patch
+++ /dev/null
@@ -1,7482 +0,0 @@
---- linux-old/Documentation/Configure.help Mon Dec 13 16:57:33 2004
-+++ linux/Documentation/Configure.help Mon Dec 13 19:26:23 2004
-@@ -19347,6 +19347,16 @@
- <file:Documentation/modules.txt>.
- The module will be called i2c-velleman.o.
-
-+Basic I2C on Parallel Port adapter
-+CONFIG_I2C_PPORT
-+ This supports directly connecting I2C devices to the parallel port.
-+ See <file:Documentation/i2c/i2c-pport> for more information.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-pport.o.
-+
- I2C PCF 8584 interfaces
- CONFIG_I2C_ALGOPCF
- This allows you to use a range of I2C adapters called PCF adapters.
-@@ -19368,6 +19378,15 @@
- <file:Documentation/modules.txt>.
- The module will be called i2c-elektor.o.
-
-+PCF on the EPP Parallel Port
-+CONFIG_I2C_PCFEPP
-+ This supports the PCF8584 connected to the parallel port.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-pcf-epp.o.
-+
- ITE I2C Algorithm
- CONFIG_ITE_I2C_ALGO
- This supports the use the ITE8172 I2C interface found on some MIPS
-@@ -19405,6 +19424,51 @@
- Supports the SGI interfaces like the ones found on SGI Indy VINO
- or SGI O2 MACE.
-
-+Motorola 8xx I2C algorithm
-+CONFIG_I2C_ALGO8XX
-+ This is the algorithm that allows you to use Motorola 8xx I2C adapters.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-algo-8xx.o.
-+
-+Motorola 8xx I2C interface
-+CONFIG_I2C_RPXLITE
-+ This supports the Motorola 8xx I2C device.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-rpx.o.
-+
-+IBM 405 I2C algorithm
-+CONFIG_I2C_IBM_OCP_ALGO
-+ This is the algorithm that allows you to use IBM 405 I2C adapters.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-algo-ibm_ocp.o.
-+
-+IBM 405 I2C interface
-+CONFIG_I2C_IBM_OCP_ADAP
-+ This supports the IBM 405 I2C device.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-adap-ibm_ocp.o.
-+
-+StrongARM SA-1110 interface
-+CONFIG_I2C_FRODO
-+ This supports the StrongARM SA-1110 Development Board.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read
-+ <file:Documentation/modules.txt>.
-+ The module will be called i2c-frodo.o.
-+
- I2C device interface
- CONFIG_I2C_CHARDEV
- Say Y here to use i2c-* device files, usually found in the /dev
---- linux-old/Documentation/i2c/dev-interface Mon Dec 22 22:44:34 2003
-+++ linux/Documentation/i2c/dev-interface Mon Dec 13 19:26:23 2004
-@@ -89,6 +89,11 @@
- Selects ten bit addresses if select not equals 0, selects normal 7 bit
- addresses if select equals 0. Default 0.
-
-+ioctl(file,I2C_PEC,long select)
-+ Selects SMBus PEC (packet error checking) generation and verification
-+ if select not equals 0, disables if select equals 0. Default 0.
-+ Used only for SMBus transactions.
-+
- ioctl(file,I2C_FUNCS,unsigned long *funcs)
- Gets the adapter functionality and puts it in *funcs.
-
---- linux-old/Documentation/i2c/i2c-pport Thu Jan 1 00:00:00 1970
-+++ linux/Documentation/i2c/i2c-pport Mon Dec 13 19:26:24 2004
-@@ -0,0 +1,67 @@
-+Parallel Port Adapters
-+----------------------
-+If you are installing parallel port adapters it means you are probably messing
-+around with wires and IC's and the like. If you have purchased a card that
-+provides an external i2c/smbus this will require combined algorithm and
-+adapter code in a single module.
-+If you are doing it yourself by using the parallel port there
-+are basically 2 options.
-+
-+1) Using the parallel port and using the i2c-pport adapter module and the
-+i2c-algo-bit algorithm module together to enable you to wire up your parallel
-+port to act as an i2c/smbus. This provides a bus that will enable most
-+sensors to work but doesn't support the entire i2c/smbus capability.
-+
-+2) Using the parallel port to interface to a Philips PCF8584 parallel to i2c
-+adapter chip. You will need to build a bit of a circuit to do this. This
-+configuration needs the i2c-pcf-epp adapter module and the i2c-algo-pcf
-+algorithm module. This support almost all of the i2c/smbus capabilities.
-+
-+
-+i2c-pport Documentation
-+-----------------------
-+This is a primitive parallel port driver for the i2c bus, which exploits
-+features of modern bidirectional parallel ports.
-+
-+Bidirectional ports have particular bits connected in following way:
-+
-+ |
-+ /-----| R
-+ --o| |-----|
-+ read \-----| /------- Out pin
-+ |/
-+ - -|\
-+ write V
-+ |
-+ ---
-+
-+
-+It means when output is set to 1 we can read the port. Therefore
-+we can use 2 pins of parallel port as SDA and SCL for i2c bus. It
-+is not necessary to add any external - additional parts, we can
-+read and write the same port simultaneously.
-+ I only use register base+2 so it is possible to use all
-+8 data bits of parallel port for other applications (I have
-+connected EEPROM and LCD display). I do not use bit Enable Bi-directional
-+ Port. The only disadvantage is we can only support 5V chips.
-+
-+Layout:
-+
-+Cannon 25 pin
-+
-+SDA - connect to pin 14 (Auto Linefeed)
-+SCL - connect to pin 16 (Initialize Printer)
-+GND - connect to pin 18-25
-++5V - use external supply (I use 5V from 3.5" floppy connector)
-+
-+no pullups requied
-+
-+Module parameters:
-+
-+base = 0xXXX
-+XXX - 278 or 378
-+
-+That's all.
-+
-+Daniel Smolik
-+marvin@sitour.cz
---- linux-old/Documentation/i2c/i2c-protocol Mon Dec 22 22:44:34 2003
-+++ linux/Documentation/i2c/i2c-protocol Mon Dec 13 19:26:24 2004
-@@ -65,3 +65,12 @@
- need to emit an Rd instead of a Wr, or vice versa, you set this
- flag. For example:
- S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P
-+
-+ Flags I2C_M_IGNORE_NAK
-+ Normally message is interrupted immediately if there is [NA] from the
-+ client. Setting this flag treats any [NA] as [A], and all of
-+ message is sent.
-+ These messages may still fail to SCL lo->hi timeout.
-+
-+ Flags I2C_M_NO_RD_ACK
-+ In a read message, master A/NA bit is skipped.
---- linux-old/Documentation/i2c/summary Tue Jan 20 15:10:28 2004
-+++ linux/Documentation/i2c/summary Mon Dec 13 19:26:24 2004
-@@ -59,16 +59,16 @@
- i2c-algo-8xx: An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT)
- i2c-algo-bit: A bit-banging algorithm
- i2c-algo-pcf: A PCF 8584 style algorithm
--i2c-algo-ppc405: An algorithm for the I2C device in IBM 405xx processors (NOT BUILT BY DEFAULT)
-+i2c-algo-ibm_ocp: An algorithm for the I2C device in IBM 4xx processors (NOT BUILT BY DEFAULT)
-
- Adapter drivers
- ---------------
-
- i2c-elektor: Elektor ISA card (uses i2c-algo-pcf)
- i2c-elv: ELV parallel port adapter (uses i2c-algo-bit)
--i2c-pcf-epp: PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (BROKEN - missing i2c-pcf-epp.h)
-+i2c-pcf-epp: PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (NOT mkpatched)
- i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit)
--i2c-ppc405: IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT)
-+i2c-adap-ibm_ocp: IBM 4xx processor I2C device (uses i2c-algo-ibm_ocp) (NOT BUILT BY DEFAULT)
- i2c-pport: Primitive parallel port adapter (uses i2c-algo-bit)
- i2c-rpx: RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT)
- i2c-velleman: Velleman K8000 parallel port adapter (uses i2c-algo-bit)
---- linux-old/Documentation/i2c/writing-clients Mon Dec 22 22:44:34 2003
-+++ linux/Documentation/i2c/writing-clients Mon Dec 13 19:26:25 2004
-@@ -24,24 +24,24 @@
- routines, a client structure specific information like the actual I2C
- address.
-
-- struct i2c_driver foo_driver
-- {
-- /* name */ "Foo version 2.3 and later driver",
-- /* id */ I2C_DRIVERID_FOO,
-- /* flags */ I2C_DF_NOTIFY,
-- /* attach_adapter */ &foo_attach_adapter,
-- /* detach_client */ &foo_detach_client,
-- /* command */ &foo_command, /* May be NULL */
-- /* inc_use */ &foo_inc_use, /* May be NULL */
-- /* dec_use */ &foo_dec_use /* May be NULL */
-- }
-+static struct i2c_driver foo_driver = {
-+ .owner = THIS_MODULE,
-+ .name = "Foo version 2.3 driver",
-+ .id = I2C_DRIVERID_FOO, /* from i2c-id.h, optional */
-+ .flags = I2C_DF_NOTIFY,
-+ .attach_adapter = &foo_attach_adapter,
-+ .detach_client = &foo_detach_client,
-+ .command = &foo_command /* may be NULL */
-+}
-
- The name can be chosen freely, and may be upto 40 characters long. Please
- use something descriptive here.
-
--The id should be a unique ID. The range 0xf000 to 0xffff is reserved for
--local use, and you can use one of those until you start distributing the
--driver. Before you do that, contact the i2c authors to get your own ID(s).
-+If used, the id should be a unique ID. The range 0xf000 to 0xffff is
-+reserved for local use, and you can use one of those until you start
-+distributing the driver, at which time you should contact the i2c authors
-+to get your own ID(s). Note that most of the time you don't need an ID
-+at all so you can just omit it.
-
- Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
- means that your driver will be notified when new adapters are found.
-@@ -50,43 +50,8 @@
- All other fields are for call-back functions which will be explained
- below.
-
--
--Module usage count
--==================
--
--If your driver can also be compiled as a module, there are moments at
--which the module can not be removed from memory. For example, when you
--are doing a lengthy transaction, or when you create a /proc directory,
--and some process has entered that directory (this last case is the
--main reason why these call-backs were introduced).
--
--To increase or decrease the module usage count, you can use the
--MOD_{INC,DEC}_USE_COUNT macros. They must be called from the module
--which needs to get its usage count changed; that is why each driver
--module has to implement its own callback.
--
-- void foo_inc_use (struct i2c_client *client)
-- {
-- #ifdef MODULE
-- MOD_INC_USE_COUNT;
-- #endif
-- }
--
-- void foo_dec_use (struct i2c_client *client)
-- {
-- #ifdef MODULE
-- MOD_DEC_USE_COUNT;
-- #endif
-- }
--
--Do not call these call-back functions directly; instead, use one of the
--following functions defined in i2c.h:
-- void i2c_inc_use_client(struct i2c_client *);
-- void i2c_dec_use_client(struct i2c_client *);
--
--You should *not* increase the module count just because a device is
--detected and a client created. This would make it impossible to remove
--an adapter driver!
-+There use to be two additional fields in this structure, inc_use et dec_use,
-+for module usage count, but these fields were obsoleted and removed.
-
-
- Extra client data
---- linux-old/drivers/i2c/i2c-adap-ibm_ocp.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-adap-ibm_ocp.c Mon Dec 13 19:26:26 2004
-@@ -0,0 +1,346 @@
-+/*
-+ -------------------------------------------------------------------------
-+ i2c-adap-ibm_ocp.c i2c-hw access for the IIC peripheral on the IBM PPC 405
-+ -------------------------------------------------------------------------
-+
-+ Ian DaSilva, MontaVista Software, Inc.
-+ idasilva@mvista.com or source@mvista.com
-+
-+ Copyright 2000 MontaVista Software Inc.
-+
-+ Changes made to support the IIC peripheral on the IBM PPC 405
-+
-+
-+ ----------------------------------------------------------------------------
-+ 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
-+
-+ With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-+ Frodo Looijaard <frodol@dds.nl>
-+
-+
-+ 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.
-+ ----------------------------------------------------------------------------
-+
-+ History: 01/20/12 - Armin
-+ akuster@mvista.com
-+ ported up to 2.4.16+
-+
-+ Version 02/03/25 - Armin
-+ converted to ocp format
-+ removed commented out or #if 0 code
-+
-+ TODO: convert to ocp_register
-+ add PM hooks
-+
-+*/
-+
-+
-+#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/i2c.h>
-+#include <linux/i2c-algo-ibm_ocp.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/ocp.h>
-+
-+/*
-+ * This next section is configurable, and it is used to set the number
-+ * of i2c controllers in the system. The default number of instances is 1,
-+ * however, this should be changed to reflect your system's configuration.
-+ */
-+
-+/*
-+ * The STB03xxx, with a PPC405 core, has two i2c controllers.
-+ */
-+//(sizeof(IIC_ADDR)/sizeof(struct iic_regs))
-+extern iic_t *IIC_ADDR[];
-+static struct iic_ibm iic_ibmocp_adaps[IIC_NUMS][5];
-+
-+static struct i2c_algo_iic_data *iic_ibmocp_data[IIC_NUMS];
-+static struct i2c_adapter *iic_ibmocp_ops[IIC_NUMS];
-+
-+static int i2c_debug=0;
-+static wait_queue_head_t iic_wait[IIC_NUMS];
-+static int iic_pending;
-+static spinlock_t irq_driver_lock = SPIN_LOCK_UNLOCKED;
-+
-+
-+/* ----- global defines ----------------------------------------------- */
-+#define DEB(x) if (i2c_debug>=1) x
-+#define DEB2(x) if (i2c_debug>=2) x
-+#define DEB3(x) if (i2c_debug>=3) x
-+#define DEBE(x) x /* error messages */
-+
-+/* ----- local functions ---------------------------------------------- */
-+
-+//
-+// Description: Write a byte to IIC hardware
-+//
-+static void iic_ibmocp_setbyte(void *data, int ctl, int val)
-+{
-+ // writeb resolves to a write to the specified memory location
-+ // plus a call to eieio. eieio ensures that all instructions
-+ // preceding it are completed before any further stores are
-+ // completed.
-+ // Delays at this level (to protect writes) are not needed here.
-+ writeb(val, ctl);
-+}
-+
-+
-+//
-+// Description: Read a byte from IIC hardware
-+//
-+static int iic_ibmocp_getbyte(void *data, int ctl)
-+{
-+ int val;
-+
-+ val = readb(ctl);
-+ return (val);
-+}
-+
-+
-+//
-+// Description: 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_ibmocp_getown(void *data)
-+{
-+ return(((struct iic_ibm *)(data))->iic_own);
-+}
-+
-+
-+//
-+// Description: Return the clock rate
-+//
-+static int iic_ibmocp_getclock(void *data)
-+{
-+ return(((struct iic_ibm *)(data))->iic_clock);
-+}
-+
-+
-+
-+//
-+// Description: Put this process to sleep. We will wake up when the
-+// IIC controller interrupts.
-+//
-+static void iic_ibmocp_waitforpin(void *data) {
-+
-+ int timeout = 2;
-+ struct iic_ibm *priv_data = data;
-+
-+ //
-+ // 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 (priv_data->iic_irq > 0) {
-+ spin_lock_irq(&irq_driver_lock);
-+ if (iic_pending == 0) {
-+ interruptible_sleep_on_timeout(&(iic_wait[priv_data->index]), timeout*HZ );
-+ } else
-+ iic_pending = 0;
-+ spin_unlock_irq(&irq_driver_lock);
-+ } else {
-+ //
-+ // If interrupts are not enabled then delay for a reasonable amount
-+ // of time and return. We expect that by time we return to the calling
-+ // function that the IIC has finished our requested transaction and
-+ // the status bit reflects this.
-+ //
-+ // udelay is probably not the best choice for this since it is
-+ // the equivalent of a busy wait
-+ //
-+ udelay(100);
-+ }
-+ //printk("iic_ibmocp_waitforpin: exitting\n");
-+}
-+
-+
-+//
-+// Description: The registered interrupt handler
-+//
-+static void iic_ibmocp_handler(int this_irq, void *dev_id, struct pt_regs *regs)
-+{
-+ int ret;
-+ struct iic_regs *iic;
-+ struct iic_ibm *priv_data = dev_id;
-+ iic = (struct iic_regs *) priv_data->iic_base;
-+ iic_pending = 1;
-+ DEB2(printk("iic_ibmocp_handler: in interrupt handler\n"));
-+ // Read status register
-+ ret = readb((int) &(iic->sts));
-+ DEB2(printk("iic_ibmocp_handler: status = %x\n", ret));
-+ // Clear status register. See IBM PPC 405 reference manual for details
-+ writeb(0x0a, (int) &(iic->sts));
-+ wake_up_interruptible(&(iic_wait[priv_data->index]));
-+}
-+
-+
-+//
-+// Description: This function is very hardware dependent. First, we lock
-+// the region of memory where out registers exist. Next, we request our
-+// interrupt line and register its associated handler. Our IIC peripheral
-+// uses interrupt number 2, as specified by the 405 reference manual.
-+//
-+static int iic_hw_resrc_init(int instance)
-+{
-+
-+ DEB(printk("iic_hw_resrc_init: Physical Base address: 0x%x\n", (u32) IIC_ADDR[instance] ));
-+ iic_ibmocp_adaps[instance]->iic_base = (u32)ioremap((unsigned long)IIC_ADDR[instance],PAGE_SIZE);
-+
-+ DEB(printk("iic_hw_resrc_init: ioremapped base address: 0x%x\n", iic_ibmocp_adaps[instance]->iic_base));
-+
-+ if (iic_ibmocp_adaps[instance]->iic_irq > 0) {
-+
-+ if (request_irq(iic_ibmocp_adaps[instance]->iic_irq, iic_ibmocp_handler,
-+ 0, "IBM OCP IIC", iic_ibmocp_adaps[instance]) < 0) {
-+ printk(KERN_ERR "iic_hw_resrc_init: Request irq%d failed\n",
-+ iic_ibmocp_adaps[instance]->iic_irq);
-+ iic_ibmocp_adaps[instance]->iic_irq = 0;
-+ } else {
-+ DEB3(printk("iic_hw_resrc_init: Enabled interrupt\n"));
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+//
-+// Description: Release irq and memory
-+//
-+static void iic_ibmocp_release(void)
-+{
-+ int i;
-+
-+ for(i=0; i<IIC_NUMS; i++) {
-+ struct iic_ibm *priv_data = (struct iic_ibm *)iic_ibmocp_data[i]->data;
-+ if (priv_data->iic_irq > 0) {
-+ disable_irq(priv_data->iic_irq);
-+ free_irq(priv_data->iic_irq, 0);
-+ }
-+ kfree(iic_ibmocp_data[i]);
-+ kfree(iic_ibmocp_ops[i]);
-+ }
-+}
-+
-+
-+//
-+// Description: Called when the module is loaded. This function starts the
-+// cascade of calls up through the heirarchy of i2c modules (i.e. up to the
-+// algorithm layer and into to the core layer)
-+//
-+static int __init iic_ibmocp_init(void)
-+{
-+ int i;
-+
-+ printk(KERN_INFO "iic_ibmocp_init: IBM on-chip iic adapter module\n");
-+
-+ for(i=0; i<IIC_NUMS; i++) {
-+ iic_ibmocp_data[i] = kmalloc(sizeof(struct i2c_algo_iic_data),GFP_KERNEL);
-+ if(iic_ibmocp_data[i] == NULL) {
-+ return -ENOMEM;
-+ }
-+ memset(iic_ibmocp_data[i], 0, sizeof(struct i2c_algo_iic_data));
-+
-+ switch (i) {
-+ case 0:
-+ iic_ibmocp_adaps[i]->iic_irq = IIC_IRQ(0);
-+ break;
-+ case 1:
-+ iic_ibmocp_adaps[i]->iic_irq = IIC_IRQ(1);
-+ break;
-+ }
-+ iic_ibmocp_adaps[i]->iic_clock = IIC_CLOCK;
-+ iic_ibmocp_adaps[i]->iic_own = IIC_OWN;
-+ iic_ibmocp_adaps[i]->index = i;
-+
-+ DEB(printk("irq %x\n", iic_ibmocp_adaps[i]->iic_irq));
-+ DEB(printk("clock %x\n", iic_ibmocp_adaps[i]->iic_clock));
-+ DEB(printk("own %x\n", iic_ibmocp_adaps[i]->iic_own));
-+ DEB(printk("index %x\n", iic_ibmocp_adaps[i]->index));
-+
-+
-+ iic_ibmocp_data[i]->data = (struct iic_regs *)iic_ibmocp_adaps[i];
-+ iic_ibmocp_data[i]->setiic = iic_ibmocp_setbyte;
-+ iic_ibmocp_data[i]->getiic = iic_ibmocp_getbyte;
-+ iic_ibmocp_data[i]->getown = iic_ibmocp_getown;
-+ iic_ibmocp_data[i]->getclock = iic_ibmocp_getclock;
-+ iic_ibmocp_data[i]->waitforpin = iic_ibmocp_waitforpin;
-+ iic_ibmocp_data[i]->udelay = 80;
-+ iic_ibmocp_data[i]->mdelay = 80;
-+ iic_ibmocp_data[i]->timeout = HZ;
-+
-+ iic_ibmocp_ops[i] = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-+ if(iic_ibmocp_ops[i] == NULL) {
-+ return -ENOMEM;
-+ }
-+ memset(iic_ibmocp_ops[i], 0, sizeof(struct i2c_adapter));
-+ strcpy(iic_ibmocp_ops[i]->name, "IBM OCP IIC adapter");
-+ iic_ibmocp_ops[i]->owner = THIS_MODULE;
-+ iic_ibmocp_ops[i]->id = I2C_HW_OCP;
-+ iic_ibmocp_ops[i]->algo = NULL;
-+ iic_ibmocp_ops[i]->algo_data = iic_ibmocp_data[i];
-+
-+
-+ init_waitqueue_head(&(iic_wait[i]));
-+ if (iic_hw_resrc_init(i) == 0) {
-+ if (i2c_ocp_add_bus(iic_ibmocp_ops[i]) < 0)
-+ return -ENODEV;
-+ } else {
-+ return -ENODEV;
-+ }
-+ DEB(printk(KERN_INFO "iic_ibmocp_init: found device at %#x.\n\n", iic_ibmocp_adaps[i]->iic_base));
-+ }
-+ return 0;
-+}
-+
-+
-+static void __exit iic_ibmocp_exit(void)
-+{
-+ int i;
-+
-+ for(i=0; i<IIC_NUMS; i++) {
-+ i2c_ocp_del_bus(iic_ibmocp_ops[i]);
-+ }
-+ iic_ibmocp_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 PPC 405 IIC bus adapter");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(base, "i");
-+MODULE_PARM(irq, "i");
-+MODULE_PARM(clock, "i");
-+MODULE_PARM(own, "i");
-+MODULE_PARM(i2c_debug,"i");
-+
-+
-+module_init(iic_ibmocp_init);
-+module_exit(iic_ibmocp_exit);
---- linux-old/drivers/i2c/i2c-algo-8xx.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-algo-8xx.c Mon Dec 13 19:26:27 2004
-@@ -0,0 +1,616 @@
-+/*
-+ * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
-+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
-+ *
-+ 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.
-+ *
-+ * moved into proper i2c interface; separated out platform specific
-+ * parts into i2c-rpx.c
-+ * Brad Parker (brad@heeltoe.com)
-+ */
-+
-+// XXX todo
-+// timeout sleep?
-+
-+/* $Id: i2c-algo-8xx.c,v 1.14 2003/07/25 07:56:42 khali Exp $ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-8xx.h>
-+#include <asm/mpc8xx.h>
-+#include <asm/commproc.h>
-+
-+
-+#define CPM_MAX_READ 513
-+/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */
-+static wait_queue_head_t iic_wait;
-+static ushort r_tbase, r_rbase;
-+
-+int cpm_debug = 0;
-+
-+static void
-+cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
-+{
-+ volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;
-+ if (cpm_debug > 1)
-+ printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id);
-+#if 0
-+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs */
-+ /* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */
-+ /* Someone with a buggy CPU needs to confirm that */
-+ i2c->i2c_i2mod &= ~1;
-+#endif
-+ /* Clear interrupt.
-+ */
-+ i2c->i2c_i2cer = 0xff;
-+
-+ /* Get 'me going again.
-+ */
-+ wake_up_interruptible(&iic_wait);
-+}
-+
-+static void
-+cpm_iic_init(struct i2c_algo_8xx_data *cpm)
-+{
-+ volatile iic_t *iip = cpm->iip;
-+ volatile i2c8xx_t *i2c = cpm->i2c;
-+ unsigned char brg;
-+ bd_t *bd = (bd_t *)__res;
-+
-+ if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init()\n");
-+
-+ /* Initialize the parameter ram.
-+ * We need to make sure many things are initialized to zero,
-+ * especially in the case of a microcode patch.
-+ */
-+ iip->iic_rstate = 0;
-+ iip->iic_rdp = 0;
-+ iip->iic_rbptr = 0;
-+ iip->iic_rbc = 0;
-+ iip->iic_rxtmp = 0;
-+ iip->iic_tstate = 0;
-+ iip->iic_tdp = 0;
-+ iip->iic_tbptr = 0;
-+ iip->iic_tbc = 0;
-+ iip->iic_txtmp = 0;
-+
-+ /* Set up the IIC parameters in the parameter ram.
-+ */
-+ iip->iic_tbase = r_tbase = cpm->dp_addr;
-+ iip->iic_rbase = r_rbase = cpm->dp_addr + sizeof(cbd_t)*2;
-+
-+ iip->iic_tfcr = SMC_EB;
-+ iip->iic_rfcr = SMC_EB;
-+
-+ /* Set maximum receive size.
-+ */
-+ iip->iic_mrblr = CPM_MAX_READ;
-+
-+ /* Initialize Tx/Rx parameters.
-+ */
-+ if (cpm->reloc == 0) {
-+ volatile cpm8xx_t *cp = cpm->cp;
-+
-+ cp->cp_cpcr =
-+ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
-+ while (cp->cp_cpcr & CPM_CR_FLG);
-+ } else {
-+ iip->iic_rbptr = iip->iic_rbase;
-+ iip->iic_tbptr = iip->iic_tbase;
-+ iip->iic_rstate = 0;
-+ iip->iic_tstate = 0;
-+ }
-+
-+ /* Select an arbitrary address. Just make sure it is unique.
-+ */
-+ i2c->i2c_i2add = 0xfe;
-+
-+ /* Make clock run at 60 KHz.
-+ */
-+ brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
-+ i2c->i2c_i2brg = brg;
-+
-+ i2c->i2c_i2mod = 0x00;
-+ i2c->i2c_i2com = 0x01; /* Master mode */
-+
-+ /* Disable interrupts.
-+ */
-+ i2c->i2c_i2cmr = 0;
-+ i2c->i2c_i2cer = 0xff;
-+
-+ init_waitqueue_head(&iic_wait);
-+
-+ /* Install interrupt handler.
-+ */
-+ if (cpm_debug) {
-+ printk ("%s[%d] Install ISR for IRQ %d\n",
-+ __func__,__LINE__, CPMVEC_I2C);
-+ }
-+ (*cpm->setisr)(CPMVEC_I2C, cpm_iic_interrupt, (void *)i2c);
-+}
-+
-+
-+static int
-+cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm)
-+{
-+ volatile i2c8xx_t *i2c = cpm->i2c;
-+
-+ /* Shut down IIC.
-+ */
-+ i2c->i2c_i2mod &= ~1;
-+ i2c->i2c_i2cmr = 0;
-+ i2c->i2c_i2cer = 0xff;
-+
-+ return(0);
-+}
-+
-+static void
-+cpm_reset_iic_params(volatile iic_t *iip)
-+{
-+ iip->iic_tbase = r_tbase;
-+ iip->iic_rbase = r_rbase;
-+
-+ iip->iic_tfcr = SMC_EB;
-+ iip->iic_rfcr = SMC_EB;
-+
-+ iip->iic_mrblr = CPM_MAX_READ;
-+
-+ iip->iic_rstate = 0;
-+ iip->iic_rdp = 0;
-+ iip->iic_rbptr = iip->iic_rbase;
-+ iip->iic_rbc = 0;
-+ iip->iic_rxtmp = 0;
-+ iip->iic_tstate = 0;
-+ iip->iic_tdp = 0;
-+ iip->iic_tbptr = iip->iic_tbase;
-+ iip->iic_tbc = 0;
-+ iip->iic_txtmp = 0;
-+}
-+
-+#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
-+#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */
-+#define CPM_CR_CLOSE_RXBD ((ushort)0x0007)
-+
-+static void force_close(struct i2c_algo_8xx_data *cpm)
-+{
-+ volatile i2c8xx_t *i2c = cpm->i2c;
-+ if (cpm->reloc == 0) { /* micro code disabled */
-+ volatile cpm8xx_t *cp = cpm->cp;
-+
-+ if (cpm_debug) printk("force_close()\n");
-+ cp->cp_cpcr =
-+ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) |
-+ CPM_CR_FLG;
-+
-+ while (cp->cp_cpcr & CPM_CR_FLG);
-+ }
-+ i2c->i2c_i2cmr = 0x00; /* Disable all interrupts */
-+ i2c->i2c_i2cer = 0xff;
-+}
-+
-+
-+/* Read from IIC...
-+ * abyte = address byte, with r/w flag already set
-+ */
-+static int
-+cpm_iic_read(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf, int count)
-+{
-+ volatile iic_t *iip = cpm->iip;
-+ volatile i2c8xx_t *i2c = cpm->i2c;
-+ volatile cpm8xx_t *cp = cpm->cp;
-+ volatile cbd_t *tbdf, *rbdf;
-+ u_char *tb;
-+ unsigned long flags, tmo;
-+
-+ if (count >= CPM_MAX_READ)
-+ return -EINVAL;
-+
-+ /* check for and use a microcode relocation patch */
-+ if (cpm->reloc) {
-+ cpm_reset_iic_params(iip);
-+ }
-+
-+ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
-+ rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
-+
-+ /* To read, we need an empty buffer of the proper length.
-+ * All that is used is the first byte for address, the remainder
-+ * is just used for timing (and doesn't really have to exist).
-+ */
-+ tb = cpm->temp;
-+ tb = (u_char *)(((uint)tb + 15) & ~15);
-+ tb[0] = abyte; /* Device address byte w/rw flag */
-+
-+ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
-+
-+ if (cpm_debug) printk("cpm_iic_read(abyte=0x%x)\n", abyte);
-+
-+ tbdf->cbd_bufaddr = __pa(tb);
-+ tbdf->cbd_datlen = count + 1;
-+ tbdf->cbd_sc =
-+ BD_SC_READY | BD_SC_LAST |
-+ BD_SC_WRAP | BD_IIC_START;
-+
-+ iip->iic_mrblr = count +1; /* prevent excessive read, +1
-+ is needed otherwise will the
-+ RXB interrupt come too early */
-+
-+ /* flush will invalidate too. */
-+ flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count));
-+
-+ rbdf->cbd_datlen = 0;
-+ rbdf->cbd_bufaddr = __pa(buf);
-+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
-+ if(count > 16){
-+ /* Chip bug, set enable here */
-+ local_irq_save(flags);
-+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
-+ i2c->i2c_i2cer = 0xff;
-+ i2c->i2c_i2mod |= 1; /* Enable */
-+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
-+
-+ /* Wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+ local_irq_restore(flags);
-+ } else { /* busy wait for small transfers, its faster */
-+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
-+ i2c->i2c_i2cer = 0xff;
-+ i2c->i2c_i2mod |= 1; /* Enable */
-+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
-+ tmo = jiffies + 1*HZ;
-+ while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
-+ }
-+
-+ if (signal_pending(current) || !tmo){
-+ force_close(cpm);
-+ if(cpm_debug)
-+ printk("IIC read: timeout!\n");
-+ return -EIO;
-+ }
-+#ifdef I2C_CHIP_ERRATA
-+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
-+ Disabling I2C too early may cause too short stop condition */
-+ udelay(4);
-+ i2c->i2c_i2mod &= ~1;
-+#endif
-+ if (cpm_debug) {
-+ printk("tx sc %04x, rx sc %04x\n",
-+ tbdf->cbd_sc, rbdf->cbd_sc);
-+ }
-+
-+ if (tbdf->cbd_sc & BD_SC_READY) {
-+ printk("IIC read; complete but tbuf ready\n");
-+ force_close(cpm);
-+ printk("tx sc %04x, rx sc %04x\n",
-+ tbdf->cbd_sc, rbdf->cbd_sc);
-+ }
-+
-+ if (tbdf->cbd_sc & BD_SC_NAK) {
-+ if (cpm_debug)
-+ printk("IIC read; no ack\n");
-+ return -EREMOTEIO;
-+ }
-+
-+ if (rbdf->cbd_sc & BD_SC_EMPTY) {
-+ /* force_close(cpm); */
-+ if (cpm_debug){
-+ printk("IIC read; complete but rbuf empty\n");
-+ printk("tx sc %04x, rx sc %04x\n",
-+ tbdf->cbd_sc, rbdf->cbd_sc);
-+ }
-+ return -EREMOTEIO;
-+ }
-+
-+ if (rbdf->cbd_sc & BD_SC_OV) {
-+ if (cpm_debug)
-+ printk("IIC read; Overrun\n");
-+ return -EREMOTEIO;;
-+ }
-+
-+ if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen);
-+
-+ if (rbdf->cbd_datlen < count) {
-+ if (cpm_debug)
-+ printk("IIC read; short, wanted %d got %d\n",
-+ count, rbdf->cbd_datlen);
-+ return 0;
-+ }
-+
-+ return count;
-+}
-+
-+/* Write to IIC...
-+ * addr = address byte, with r/w flag already set
-+ */
-+static int
-+cpm_iic_write(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf,int count)
-+{
-+ volatile iic_t *iip = cpm->iip;
-+ volatile i2c8xx_t *i2c = cpm->i2c;
-+ volatile cpm8xx_t *cp = cpm->cp;
-+ volatile cbd_t *tbdf;
-+ u_char *tb;
-+ unsigned long flags, tmo;
-+
-+ /* check for and use a microcode relocation patch */
-+ if (cpm->reloc) {
-+ cpm_reset_iic_params(iip);
-+ }
-+ tb = cpm->temp;
-+ tb = (u_char *)(((uint)tb + 15) & ~15);
-+ *tb = abyte; /* Device address byte w/rw flag */
-+
-+ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
-+ flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count));
-+
-+ if (cpm_debug) printk("cpm_iic_write(abyte=0x%x)\n", abyte);
-+
-+ /* set up 2 descriptors */
-+ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
-+
-+ tbdf[0].cbd_bufaddr = __pa(tb);
-+ tbdf[0].cbd_datlen = 1;
-+ tbdf[0].cbd_sc = BD_SC_READY | BD_IIC_START;
-+
-+ tbdf[1].cbd_bufaddr = __pa(buf);
-+ tbdf[1].cbd_datlen = count;
-+ tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP;
-+
-+ if(count > 16){
-+ /* Chip bug, set enable here */
-+ local_irq_save(flags);
-+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
-+ i2c->i2c_i2cer = 0xff;
-+ i2c->i2c_i2mod |= 1; /* Enable */
-+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
-+
-+ /* Wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+ local_irq_restore(flags);
-+ } else { /* busy wait for small transfers, its faster */
-+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
-+ i2c->i2c_i2cer = 0xff;
-+ i2c->i2c_i2mod |= 1; /* Enable */
-+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
-+ tmo = jiffies + 1*HZ;
-+ while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
-+ }
-+
-+ if (signal_pending(current) || !tmo){
-+ force_close(cpm);
-+ if(cpm_debug && !tmo)
-+ printk("IIC write: timeout!\n");
-+ return -EIO;
-+ }
-+
-+#if I2C_CHIP_ERRATA
-+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
-+ Disabling I2C too early may cause too short stop condition */
-+ udelay(4);
-+ i2c->i2c_i2mod &= ~1;
-+#endif
-+ if (cpm_debug) {
-+ printk("tx0 sc %04x, tx1 sc %04x\n",
-+ tbdf[0].cbd_sc, tbdf[1].cbd_sc);
-+ }
-+
-+ if (tbdf->cbd_sc & BD_SC_NAK) {
-+ if (cpm_debug)
-+ printk("IIC write; no ack\n");
-+ return 0;
-+ }
-+
-+ if (tbdf->cbd_sc & BD_SC_READY) {
-+ if (cpm_debug)
-+ printk("IIC write; complete but tbuf ready\n");
-+ return 0;
-+ }
-+
-+ return count;
-+}
-+
-+/* See if an IIC address exists..
-+ * addr = 7 bit address, unshifted
-+ */
-+static int
-+cpm_iic_tryaddress(struct i2c_algo_8xx_data *cpm, int addr)
-+{
-+ volatile iic_t *iip = cpm->iip;
-+ volatile i2c8xx_t *i2c = cpm->i2c;
-+ volatile cpm8xx_t *cp = cpm->cp;
-+ volatile cbd_t *tbdf, *rbdf;
-+ u_char *tb;
-+ unsigned long flags, len, tmo;
-+
-+ if (cpm_debug > 1)
-+ printk("cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr);
-+
-+ /* check for and use a microcode relocation patch */
-+ if (cpm->reloc) {
-+ cpm_reset_iic_params(iip);
-+ }
-+
-+ if (cpm_debug && addr == 0) {
-+ printk("iip %p, dp_addr 0x%x\n", cpm->iip, cpm->dp_addr);
-+ printk("iic_tbase %d, r_tbase %d\n", iip->iic_tbase, r_tbase);
-+ }
-+
-+ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
-+ rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
-+
-+ tb = cpm->temp;
-+ tb = (u_char *)(((uint)tb + 15) & ~15);
-+
-+ /* do a simple read */
-+ tb[0] = (addr << 1) | 1; /* device address (+ read) */
-+ len = 2;
-+
-+ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+2));
-+
-+ tbdf->cbd_bufaddr = __pa(tb);
-+ tbdf->cbd_datlen = len;
-+ tbdf->cbd_sc =
-+ BD_SC_READY | BD_SC_LAST |
-+ BD_SC_WRAP | BD_IIC_START;
-+
-+ rbdf->cbd_datlen = 0;
-+ rbdf->cbd_bufaddr = __pa(tb+2);
-+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
-+
-+ local_irq_save(flags);
-+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
-+ i2c->i2c_i2cer = 0xff;
-+ i2c->i2c_i2mod |= 1; /* Enable */
-+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
-+
-+ if (cpm_debug > 1) printk("about to sleep\n");
-+
-+ /* wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+ local_irq_restore(flags);
-+
-+#ifdef I2C_CHIP_ERRATA
-+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
-+ Disabling I2C too early may cause too short stop condition */
-+ udelay(4);
-+ i2c->i2c_i2mod &= ~1;
-+#endif
-+
-+ if (signal_pending(current) || !tmo){
-+ force_close(cpm);
-+ if(cpm_debug && !tmo)
-+ printk("IIC tryaddress: timeout!\n");
-+ return -EIO;
-+ }
-+
-+ if (cpm_debug > 1) printk("back from sleep\n");
-+
-+ if (tbdf->cbd_sc & BD_SC_NAK) {
-+ if (cpm_debug > 1) printk("IIC try; no ack\n");
-+ return 0;
-+ }
-+
-+ if (tbdf->cbd_sc & BD_SC_READY) {
-+ printk("IIC try; complete but tbuf ready\n");
-+ }
-+
-+ return 1;
-+}
-+
-+static int cpm_xfer(struct i2c_adapter *adap,
-+ struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct i2c_algo_8xx_data *cpm = adap->algo_data;
-+ struct i2c_msg *pmsg;
-+ int i, ret;
-+ u_char addr;
-+
-+ for (i = 0; i < num; i++) {
-+ pmsg = &msgs[i];
-+
-+ if (cpm_debug)
-+ printk("i2c-algo-8xx.o: "
-+ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
-+ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
-+
-+ addr = pmsg->addr << 1;
-+ if (pmsg->flags & I2C_M_RD )
-+ addr |= 1;
-+ if (pmsg->flags & I2C_M_REV_DIR_ADDR )
-+ addr ^= 1;
-+
-+ if (!(pmsg->flags & I2C_M_NOSTART)) {
-+ }
-+ if (pmsg->flags & I2C_M_RD ) {
-+ /* read bytes into buffer*/
-+ ret = cpm_iic_read(cpm, addr, pmsg->buf, pmsg->len);
-+ if (cpm_debug)
-+ printk("i2c-algo-8xx.o: read %d bytes\n", ret);
-+ if (ret < pmsg->len ) {
-+ return (ret<0)? ret : -EREMOTEIO;
-+ }
-+ } else {
-+ /* write bytes from buffer */
-+ ret = cpm_iic_write(cpm, addr, pmsg->buf, pmsg->len);
-+ if (cpm_debug)
-+ printk("i2c-algo-8xx.o: wrote %d\n", ret);
-+ if (ret < pmsg->len ) {
-+ return (ret<0) ? ret : -EREMOTEIO;
-+ }
-+ }
-+ }
-+ return (num);
-+}
-+
-+static u32 cpm_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 cpm_algo = {
-+ .owner = THIS_MODULE,
-+ .name = "MPC8xx CPM algorithm",
-+ .id = I2C_ALGO_MPC8XX,
-+ .master_xfer = cpm_xfer,
-+ .functionality = cpm_func,
-+};
-+
-+/*
-+ * registering functions to load algorithms at runtime
-+ */
-+int i2c_8xx_add_bus(struct i2c_adapter *adap)
-+{
-+ int i;
-+ struct i2c_algo_8xx_data *cpm = adap->algo_data;
-+
-+ if (cpm_debug)
-+ printk("i2c-algo-8xx.o: hw routines for %s registered.\n",
-+ adap->name);
-+
-+ /* register new adapter to i2c module... */
-+
-+ adap->id |= cpm_algo.id;
-+ adap->algo = &cpm_algo;
-+
-+ i2c_add_adapter(adap);
-+ cpm_iic_init(cpm);
-+}
-+
-+
-+int i2c_8xx_del_bus(struct i2c_adapter *adap)
-+{
-+ struct i2c_algo_8xx_data *cpm = adap->algo_data;
-+
-+ cpm_iic_shutdown(cpm);
-+
-+ return i2c_del_adapter(adap);
-+}
-+
-+EXPORT_SYMBOL(i2c_8xx_add_bus);
-+EXPORT_SYMBOL(i2c_8xx_del_bus);
-+
-+MODULE_AUTHOR("Brad Parker <brad@heeltoe.com>");
-+MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm");
-+MODULE_LICENSE("GPL");
---- linux-old/include/linux/i2c-algo-8xx.h Thu Jan 1 00:00:00 1970
-+++ linux/include/linux/i2c-algo-8xx.h Mon Dec 13 19:26:27 2004
-@@ -0,0 +1,43 @@
-+/* ------------------------------------------------------------------------- */
-+/* i2c-algo-8xx.h i2c driver algorithms for MPX8XX CPM */
-+/*
-+ 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. */
-+/* ------------------------------------------------------------------------- */
-+
-+/* $Id: i2c-algo-8xx.h,v 1.7 2003/08/01 20:56:38 khali Exp $ */
-+
-+#ifndef _LINUX_I2C_ALGO_8XX_H
-+#define _LINUX_I2C_ALGO_8XX_H
-+
-+#include "asm/commproc.h"
-+
-+struct i2c_algo_8xx_data {
-+ uint dp_addr;
-+ int reloc;
-+ volatile i2c8xx_t *i2c;
-+ volatile iic_t *iip;
-+ volatile cpm8xx_t *cp;
-+
-+ int (*setisr) (int irq,
-+ void (*func)(void *, void *),
-+ void *data);
-+
-+ u_char temp[513];
-+};
-+
-+int i2c_8xx_add_bus(struct i2c_adapter *);
-+int i2c_8xx_del_bus(struct i2c_adapter *);
-+
-+#endif /* _LINUX_I2C_ALGO_8XX_H */
---- linux-old/drivers/i2c/i2c-algo-bit.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-algo-bit.c Mon Dec 13 19:26:27 2004
-@@ -18,24 +18,22 @@
- 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> */
-+/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
-+ <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */
-
--/* $Id: i2c-algo-bit.c,v 1.30 2001/07/29 02:44:25 mds Exp $ */
-+/* $Id: i2c-algo-bit.c,v 1.50 2003/12/22 20:03:39 khali Exp $ */
-
- #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-bit.h>
-
-+
- /* ----- global defines ----------------------------------------------- */
- #define DEB(x) if (i2c_debug>=1) x;
- #define DEB2(x) if (i2c_debug>=2) x;
-@@ -43,27 +41,13 @@
- #define DEBPROTO(x) if (i2c_debug>=9) { x; }
- /* debug the protocol by showing transferred bits */
-
--/* debugging - slow down transfer to have a look at the data .. */
--/* I use this with two leds&resistors, each one connected to sda,scl */
--/* respectively. This makes sure that the algorithm works. Some chips */
--/* might not like this, as they have an internal timeout of some mils */
--/*
--#define SLO_IO jif=jiffies;while(time_before_eq(jiffies, jif+i2c_table[minor].veryslow))\
-- if (need_resched) schedule();
--*/
--
-
- /* ----- global variables --------------------------------------------- */
-
--#ifdef SLO_IO
-- int jif;
--#endif
--
- /* module parameters:
- */
- static int i2c_debug;
- static int bit_test; /* see if the line-setting functions work */
--static int bit_scan; /* have a look at what's hanging 'round */
-
- /* --- setting states on the bus with the right timing: --------------- */
-
-@@ -88,9 +72,6 @@
- {
- setscl(adap,0);
- udelay(adap->udelay);
--#ifdef SLO_IO
-- SLO_IO
--#endif
- }
-
- /*
-@@ -99,33 +80,35 @@
- */
- static inline int sclhi(struct i2c_algo_bit_data *adap)
- {
-- int start=jiffies;
-+ int start;
-
- setscl(adap,1);
-
-- udelay(adap->udelay);
--
- /* Not all adapters have scl sense line... */
-- if (adap->getscl == NULL )
-+ if (adap->getscl == NULL ) {
-+ udelay(adap->udelay);
- return 0;
-+ }
-
-- while (! getscl(adap) ) {
-+ start=jiffies;
-+ while (! getscl(adap) ) {
- /* the hw knows how to read the clock line,
- * so we wait until it actually gets high.
- * This is safer as some chips may hold it low
- * while they are processing data internally.
- */
-- setscl(adap,1);
- if (time_after_eq(jiffies, start+adap->timeout)) {
- return -ETIMEDOUT;
- }
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if (current->need_resched)
- schedule();
-+#else
-+ cond_resched();
-+#endif
- }
- DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start));
--#ifdef SLO_IO
-- SLO_IO
--#endif
-+ udelay(adap->udelay);
- return 0;
- }
-
-@@ -144,7 +127,7 @@
- /* scl, sda may not be high */
- DEBPROTO(printk(" Sr "));
- setsda(adap,1);
-- setscl(adap,1);
-+ sclhi(adap);
- udelay(adap->udelay);
-
- sdalo(adap);
-@@ -178,7 +161,6 @@
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- /* assert: scl is low */
-- DEB2(printk(KERN_DEBUG " i2c_outb:%2.2X\n",c&0xff));
- for ( i=7 ; i>=0 ; i-- ) {
- sb = c & ( 1 << i );
- setsda(adap,sb);
-@@ -186,6 +168,7 @@
- DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
- if (sclhi(adap)<0) { /* timed out */
- sdahi(adap); /* we don't want to block the net */
-+ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i));
- return -ETIMEDOUT;
- };
- /* do arbitration here:
-@@ -196,11 +179,12 @@
- }
- sdahi(adap);
- if (sclhi(adap)<0){ /* timeout */
-+ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff));
- return -ETIMEDOUT;
- };
- /* read ack: SDA should be pulled down by slave */
- ack=getsda(adap); /* ack: sda is pulled low ->success. */
-- DEB2(printk(KERN_DEBUG " i2c_outb: getsda() = 0x%2.2x\n", ~ack ));
-+ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack));
-
- DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) );
- DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") );
-@@ -219,11 +203,10 @@
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- /* assert: scl is low */
-- DEB2(printk(KERN_DEBUG "i2c_inb.\n"));
--
- sdahi(adap);
- for (i=0;i<8;i++) {
- if (sclhi(adap)<0) { /* timeout */
-+ DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i));
- return -ETIMEDOUT;
- };
- indata *= 2;
-@@ -232,6 +215,8 @@
- scllo(adap);
- }
- /* assert: scl is low */
-+ DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff));
-+
- DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff));
- return (int) (indata & 0xff);
- }
-@@ -242,71 +227,75 @@
- */
- static int test_bus(struct i2c_algo_bit_data *adap, char* name) {
- int scl,sda;
-+
-+ if (adap->getscl==NULL)
-+ printk(KERN_INFO "i2c-algo-bit.o: Testing SDA only, "
-+ "SCL is not readable.\n");
-+
- sda=getsda(adap);
-- if (adap->getscl==NULL) {
-- printk("i2c-algo-bit.o: Warning: Adapter can't read from clock line - skipping test.\n");
-- return 0;
-- }
-- scl=getscl(adap);
-- printk("i2c-algo-bit.o: Adapter: %s scl: %d sda: %d -- testing...\n",
-- name,getscl(adap),getsda(adap));
-+ scl=(adap->getscl==NULL?1:getscl(adap));
-+ printk(KERN_DEBUG "i2c-algo-bit.o: (0) scl=%d, sda=%d\n",scl,sda);
- if (!scl || !sda ) {
-- printk("i2c-algo-bit.o: %s seems to be busy.\n",name);
-+ printk(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name);
- goto bailout;
- }
-+
- sdalo(adap);
-- printk("i2c-algo-bit.o:1 scl: %d sda: %d \n",getscl(adap),
-- getsda(adap));
-- if ( 0 != getsda(adap) ) {
-- printk("i2c-algo-bit.o: %s SDA stuck high!\n",name);
-- sdahi(adap);
-+ sda=getsda(adap);
-+ scl=(adap->getscl==NULL?1:getscl(adap));
-+ printk(KERN_DEBUG "i2c-algo-bit.o: (1) scl=%d, sda=%d\n",scl,sda);
-+ if ( 0 != sda ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck high!\n");
- goto bailout;
- }
-- if ( 0 == getscl(adap) ) {
-- printk("i2c-algo-bit.o: %s SCL unexpected low while pulling SDA low!\n",
-- name);
-+ if ( 0 == scl ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low "
-+ "while pulling SDA low!\n");
- goto bailout;
- }
-+
- sdahi(adap);
-- printk("i2c-algo-bit.o:2 scl: %d sda: %d \n",getscl(adap),
-- getsda(adap));
-- if ( 0 == getsda(adap) ) {
-- printk("i2c-algo-bit.o: %s SDA stuck low!\n",name);
-- sdahi(adap);
-+ sda=getsda(adap);
-+ scl=(adap->getscl==NULL?1:getscl(adap));
-+ printk(KERN_DEBUG "i2c-algo-bit.o: (2) scl=%d, sda=%d\n",scl,sda);
-+ if ( 0 == sda ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck low!\n");
- goto bailout;
- }
-- if ( 0 == getscl(adap) ) {
-- printk("i2c-algo-bit.o: %s SCL unexpected low while SDA high!\n",
-- name);
-- goto bailout;
-+ if ( 0 == scl ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low "
-+ "while pulling SDA high!\n");
-+ goto bailout;
- }
-+
- scllo(adap);
-- printk("i2c-algo-bit.o:3 scl: %d sda: %d \n",getscl(adap),
-- getsda(adap));
-- if ( 0 != getscl(adap) ) {
-- printk("i2c-algo-bit.o: %s SCL stuck high!\n",name);
-- sclhi(adap);
-+ sda=getsda(adap);
-+ scl=(adap->getscl==NULL?0:getscl(adap));
-+ printk(KERN_DEBUG "i2c-algo-bit.o: (3) scl=%d, sda=%d\n",scl,sda);
-+ if ( 0 != scl ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck high!\n");
- goto bailout;
- }
-- if ( 0 == getsda(adap) ) {
-- printk("i2c-algo-bit.o: %s SDA unexpected low while pulling SCL low!\n",
-- name);
-+ if ( 0 == sda ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low "
-+ "while pulling SCL low!\n");
- goto bailout;
- }
-+
- sclhi(adap);
-- printk("i2c-algo-bit.o:4 scl: %d sda: %d \n",getscl(adap),
-- getsda(adap));
-- if ( 0 == getscl(adap) ) {
-- printk("i2c-algo-bit.o: %s SCL stuck low!\n",name);
-- sclhi(adap);
-+ sda=getsda(adap);
-+ scl=(adap->getscl==NULL?1:getscl(adap));
-+ printk(KERN_DEBUG "i2c-algo-bit.o: (4) scl=%d, sda=%d\n",scl,sda);
-+ if ( 0 == scl ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck low!\n");
- goto bailout;
- }
-- if ( 0 == getsda(adap) ) {
-- printk("i2c-algo-bit.o: %s SDA unexpected low while SCL high!\n",
-- name);
-+ if ( 0 == sda ) {
-+ printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low "
-+ "while pulling SCL high!\n");
- goto bailout;
- }
-- printk("i2c-algo-bit.o: %s passed test.\n",name);
-+ printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name);
- return 0;
- bailout:
- sdahi(adap);
-@@ -340,16 +329,21 @@
- i2c_start(adap);
- udelay(adap->udelay);
- }
-- DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: needed %d retries for %d\n",
-- i,addr));
-+ DEB2(if (i)
-+ printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n",
-+ i+1, addr & 1 ? "read" : "write", addr>>1,
-+ ret==1 ? "success" : ret==0 ? "no ack" : "failed, timeout?" )
-+ );
- return ret;
- }
-
--static int sendbytes(struct i2c_adapter *i2c_adap,const char *buf, int count)
-+static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
- {
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- char c;
-- const char *temp = buf;
-+ const char *temp = msg->buf;
-+ int count = msg->len;
-+ unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
- int retval;
- int wrcount=0;
-
-@@ -358,7 +352,7 @@
- DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n",
- i2c_adap->name, c&0xff));
- retval = i2c_outb(i2c_adap,c);
-- if (retval>0) {
-+ if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */
- count--;
- temp++;
- wrcount++;
-@@ -377,12 +371,18 @@
- return wrcount;
- }
-
--static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count)
-+static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
- {
-- char *temp = buf;
- int inval;
- int rdcount=0; /* counts bytes read */
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-+ char *temp = msg->buf;
-+ int count = msg->len;
-+ int recv_len = 0;
-+
-+ /* Receive [Count] for I2C_SMBUS_BLOCK_DATA or I2C_SMBUS_BLOCK_PROC_CALL protocol */
-+ if (msg->flags & I2C_M_RECV_LEN)
-+ recv_len = 1;
-
- while (count > 0) {
- inval = i2c_inb(i2c_adap);
-@@ -395,6 +395,20 @@
- break;
- }
-
-+ if (recv_len) {
-+ recv_len = 0;
-+ /* [Count] should be between 1 and 31 (I2C_SMBUS_BLOCK_MAX - 1). */
-+ if (inval > 0 && inval < I2C_SMBUS_BLOCK_MAX) {
-+ count = inval + 1; /* plus one for [Count] itself */
-+ msg->len = count;
-+ if (msg->flags & I2C_M_RECV_PEC)
-+ count++; /* plus one for PEC */
-+ } else {
-+ printk(KERN_ERR "i2c-algo-bit.o: readbytes: bad block count (%d).\n", inval);
-+ break;
-+ }
-+ }
-+
- if ( count > 1 ) { /* send ack */
- sdalo(adap);
- DEBPROTO(printk(" Am "));
-@@ -419,31 +433,34 @@
- * try_address) and transmits the address in the necessary format to handle
- * reads, writes as well as 10bit-addresses.
- * returns:
-- * 0 everything went okay, the chip ack'ed
-+ * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
- * -x an error occurred (like: -EREMOTEIO if the device did not answer, or
- * -ETIMEDOUT, for example if the lines are stuck...)
- */
--static inline int bit_doAddress(struct i2c_adapter *i2c_adap,
-- struct i2c_msg *msg, int retries)
-+static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
- {
- unsigned short flags = msg->flags;
-+ unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- unsigned char addr;
-- int ret;
-+ int ret, retries;
-+
-+ retries = nak_ok ? 0 : i2c_adap->retries;
-+
- if ( (flags & I2C_M_TEN) ) {
- /* a ten bit address */
- addr = 0xf0 | (( msg->addr >> 7) & 0x03);
- DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
- /* try extended address code...*/
- ret = try_address(i2c_adap, addr, retries);
-- if (ret!=1) {
-+ if ((ret != 1) && !nak_ok) {
- printk(KERN_ERR "died at extended address code.\n");
- return -EREMOTEIO;
- }
- /* the remaining 8 bit address */
- ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
-- if (ret != 1) {
-+ if ((ret != 1) && !nak_ok) {
- /* the chip did not ack / xmission error occurred */
- printk(KERN_ERR "died at 2nd address code.\n");
- return -EREMOTEIO;
-@@ -453,7 +470,7 @@
- /* okay, now switch into reading mode */
- addr |= 0x01;
- ret = try_address(i2c_adap, addr, retries);
-- if (ret!=1) {
-+ if ((ret!=1) && !nak_ok) {
- printk(KERN_ERR "died at extended address code.\n");
- return -EREMOTEIO;
- }
-@@ -465,10 +482,10 @@
- if (flags & I2C_M_REV_DIR_ADDR )
- addr ^= 1;
- ret = try_address(i2c_adap, addr, retries);
-- if (ret!=1) {
-+ if ((ret!=1) && !nak_ok)
- return -EREMOTEIO;
-- }
- }
-+
- return 0;
- }
-
-@@ -479,16 +496,18 @@
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-
- int i,ret;
-+ unsigned short nak_ok;
-
- i2c_start(adap);
- for (i=0;i<num;i++) {
- pmsg = &msgs[i];
-+ nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
- if (!(pmsg->flags & I2C_M_NOSTART)) {
- if (i) {
- i2c_repstart(adap);
- }
-- ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries);
-- if (ret != 0) {
-+ ret = bit_doAddress(i2c_adap, pmsg);
-+ if ((ret != 0) && !nak_ok) {
- DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n",
- msgs[i].addr,i));
- return (ret<0) ? ret : -EREMOTEIO;
-@@ -496,14 +515,14 @@
- }
- if (pmsg->flags & I2C_M_RD ) {
- /* read bytes into buffer*/
-- ret = readbytes(i2c_adap,pmsg->buf,pmsg->len);
-+ ret = readbytes(i2c_adap, pmsg);
- DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret));
- if (ret < pmsg->len ) {
- return (ret<0)? ret : -EREMOTEIO;
- }
- } else {
- /* write bytes from buffer */
-- ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len);
-+ ret = sendbytes(i2c_adap, pmsg);
- DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret));
- if (ret < pmsg->len ) {
- return (ret<0) ? ret : -EREMOTEIO;
-@@ -514,30 +533,25 @@
- return num;
- }
-
--static int algo_control(struct i2c_adapter *adapter,
-- unsigned int cmd, unsigned long arg)
--{
-- return 0;
--}
--
--static u32 bit_func(struct i2c_adapter *adap)
-+static u32 bit_func(struct i2c_adapter *i2c_adap)
- {
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-- I2C_FUNC_PROTOCOL_MANGLING;
-+ I2C_FUNC_PROTOCOL_MANGLING |
-+ I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
-+ I2C_FUNC_SMBUS_READ_BLOCK_DATA |
-+ I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC |
-+ I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC;
- }
-
-
- /* -----exported algorithm data: ------------------------------------- */
-
- static struct i2c_algorithm i2c_bit_algo = {
-- "Bit-shift algorithm",
-- I2C_ALGO_BIT,
-- bit_xfer,
-- NULL,
-- NULL, /* slave_xmit */
-- NULL, /* slave_recv */
-- algo_control, /* ioctl */
-- bit_func, /* functionality */
-+ .owner = THIS_MODULE,
-+ .name = "Bit-shift algorithm",
-+ .id = I2C_ALGO_BIT,
-+ .master_xfer = bit_xfer,
-+ .functionality = bit_func,
- };
-
- /*
-@@ -545,7 +559,6 @@
- */
- int i2c_bit_add_bus(struct i2c_adapter *adap)
- {
-- int i;
- struct i2c_algo_bit_data *bit_adap = adap->algo_data;
-
- if (bit_test) {
-@@ -565,78 +578,26 @@
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
-
-- /* scan bus */
-- if (bit_scan) {
-- int ack;
-- printk(KERN_INFO " i2c-algo-bit.o: scanning bus %s.\n",
-- adap->name);
-- for (i = 0x00; i < 0xff; i+=2) {
-- i2c_start(bit_adap);
-- ack = i2c_outb(adap,i);
-- i2c_stop(bit_adap);
-- if (ack>0) {
-- printk("(%02x)",i>>1);
-- } else
-- printk(".");
-- }
-- printk("\n");
-- }
--
--#ifdef MODULE
-- MOD_INC_USE_COUNT;
--#endif
- i2c_add_adapter(adap);
--
- return 0;
- }
-
-
- int i2c_bit_del_bus(struct i2c_adapter *adap)
- {
-- int res;
--
-- if ((res = i2c_del_adapter(adap)) < 0)
-- return res;
--
-- DEB2(printk("i2c-algo-bit.o: adapter unregistered: %s\n",adap->name));
--
--#ifdef MODULE
-- MOD_DEC_USE_COUNT;
--#endif
-- return 0;
--}
--
--int __init i2c_algo_bit_init (void)
--{
-- printk(KERN_INFO "i2c-algo-bit.o: i2c bit algorithm module\n");
-- return 0;
-+ return i2c_del_adapter(adap);
- }
-
--
--
- EXPORT_SYMBOL(i2c_bit_add_bus);
- EXPORT_SYMBOL(i2c_bit_del_bus);
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
- MODULE_LICENSE("GPL");
-
- MODULE_PARM(bit_test, "i");
--MODULE_PARM(bit_scan, "i");
- MODULE_PARM(i2c_debug,"i");
-
- MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck");
--MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
- MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol");
--
--int init_module(void)
--{
-- return i2c_algo_bit_init();
--}
--
--void cleanup_module(void)
--{
--}
--#endif
---- linux-old/include/linux/i2c-algo-bit.h Sat Feb 5 06:47:38 2000
-+++ linux/include/linux/i2c-algo-bit.h Mon Dec 13 19:26:28 2004
-@@ -21,12 +21,10 @@
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
- Frodo Looijaard <frodol@dds.nl> */
-
--/* $Id: i2c-algo-bit.h,v 1.7 1999/12/21 23:45:58 frodo Exp $ */
-+/* $Id: i2c-algo-bit.h,v 1.11 2003/07/25 07:56:42 khali Exp $ */
-
--#ifndef I2C_ALGO_BIT_H
--#define I2C_ALGO_BIT_H 1
--
--#include <linux/i2c.h>
-+#ifndef _LINUX_I2C_ALGO_BIT_H
-+#define _LINUX_I2C_ALGO_BIT_H
-
- /* --- Defines for bit-adapters --------------------------------------- */
- /*
-@@ -42,9 +40,10 @@
- int (*getscl) (void *data);
-
- /* local settings */
-- int udelay;
-- int mdelay;
-- int timeout;
-+ int udelay; /* half-clock-cycle time in microsecs */
-+ /* i.e. clock is (500 / udelay) KHz */
-+ int mdelay; /* in millisecs, unused */
-+ int timeout; /* in jiffies */
- };
-
- #define I2C_BIT_ADAP_MAX 16
-@@ -52,4 +51,4 @@
- int i2c_bit_add_bus(struct i2c_adapter *);
- int i2c_bit_del_bus(struct i2c_adapter *);
-
--#endif /* I2C_ALGO_BIT_H */
-+#endif /* _LINUX_I2C_ALGO_BIT_H */
---- linux-old/drivers/i2c/i2c-algo-ibm_ocp.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-algo-ibm_ocp.c Mon Dec 13 19:26:29 2004
-@@ -0,0 +1,901 @@
-+/*
-+ -------------------------------------------------------------------------
-+ i2c-algo-ibm_ocp.c i2c driver algorithms for IBM PPC 405 adapters
-+ -------------------------------------------------------------------------
-+
-+ Ian DaSilva, MontaVista Software, Inc.
-+ idasilva@mvista.com or source@mvista.com
-+
-+ Copyright 2000 MontaVista Software Inc.
-+
-+ Changes made to support the IIC peripheral on the IBM PPC 405
-+
-+
-+ ---------------------------------------------------------------------------
-+ 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
-+
-+ 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>
-+
-+
-+ 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.
-+ ---------------------------------------------------------------------------
-+
-+ History: 01/20/12 - Armin
-+ akuster@mvista.com
-+ ported up to 2.4.16+
-+
-+ Version 02/03/25 - Armin
-+ converted to ocp format
-+ removed commented out or #if 0 code
-+ added Gérard Basler's fix to iic_combined_transaction() such that it
-+ returns the number of successfully completed transfers .
-+*/
-+
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-ibm_ocp.h>
-+#include <asm/ocp.h>
-+
-+
-+/* ----- global defines ----------------------------------------------- */
-+#define DEB(x) if (i2c_debug>=1) x
-+#define DEB2(x) if (i2c_debug>=2) x
-+#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-+#define DEBPROTO(x) if (i2c_debug>=9) x;
-+ /* debug the protocol by showing transferred bits */
-+#define DEF_TIMEOUT 5
-+
-+
-+/* ----- global variables --------------------------------------------- */
-+
-+
-+/* module parameters:
-+ */
-+static int i2c_debug=0;
-+
-+/* --- setting states on the bus with the right timing: --------------- */
-+
-+#define iic_outb(adap, reg, val) adap->setiic(adap->data, (int) &(reg), val)
-+#define iic_inb(adap, reg) adap->getiic(adap->data, (int) &(reg))
-+
-+#define IICO_I2C_SDAHIGH 0x0780
-+#define IICO_I2C_SDALOW 0x0781
-+#define IICO_I2C_SCLHIGH 0x0782
-+#define IICO_I2C_SCLLOW 0x0783
-+#define IICO_I2C_LINEREAD 0x0784
-+
-+#define IIC_SINGLE_XFER 0
-+#define IIC_COMBINED_XFER 1
-+
-+#define IIC_ERR_LOST_ARB -2
-+#define IIC_ERR_INCOMPLETE_XFR -3
-+#define IIC_ERR_NACK -1
-+
-+/* --- other auxiliary functions -------------------------------------- */
-+
-+
-+//
-+// Description: Puts this process to sleep for a period equal to timeout
-+//
-+static inline void iic_sleep(unsigned long timeout)
-+{
-+ schedule_timeout( timeout * HZ);
-+}
-+
-+
-+//
-+// Description: This performs the IBM PPC 405 IIC initialization sequence
-+// as described in the PPC405GP data book.
-+//
-+static int iic_init (struct i2c_algo_iic_data *adap)
-+{
-+ struct iic_regs *iic;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ unsigned short retval;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+ /* Clear master low master address */
-+ iic_outb(adap,iic->lmadr, 0);
-+
-+ /* Clear high master address */
-+ iic_outb(adap,iic->hmadr, 0);
-+
-+ /* Clear low slave address */
-+ iic_outb(adap,iic->lsadr, 0);
-+
-+ /* Clear high slave address */
-+ iic_outb(adap,iic->hsadr, 0);
-+
-+ /* Clear status */
-+ iic_outb(adap,iic->sts, 0x0a);
-+
-+ /* Clear extended status */
-+ iic_outb(adap,iic->extsts, 0x8f);
-+
-+ /* Set clock division */
-+ iic_outb(adap,iic->clkdiv, 0x04);
-+
-+ retval = iic_inb(adap, iic->clkdiv);
-+ DEB(printk("iic_init: CLKDIV register = %x\n", retval));
-+
-+ /* Enable interrupts on Requested Master Transfer Complete */
-+ iic_outb(adap,iic->intmsk, 0x01);
-+
-+ /* Clear transfer count */
-+ iic_outb(adap,iic->xfrcnt, 0x0);
-+
-+ /* Clear extended control and status */
-+ iic_outb(adap,iic->xtcntlss, 0xf0);
-+
-+ /* Set mode control (flush master data buf, enable hold SCL, exit */
-+ /* unknown state. */
-+ iic_outb(adap,iic->mdcntl, 0x47);
-+
-+ /* Clear control register */
-+ iic_outb(adap,iic->cntl, 0x0);
-+
-+ DEB2(printk(KERN_DEBUG "iic_init: Initialized IIC on PPC 405\n"));
-+ return 0;
-+}
-+
-+
-+//
-+// Description: 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, int *status)
-+{
-+
-+ int timeout = DEF_TIMEOUT;
-+ int retval;
-+ struct iic_regs *iic;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+
-+ *status = iic_inb(adap, iic->sts);
-+#ifndef STUB_I2C
-+
-+ while (timeout-- && (*status & 0x01)) {
-+ adap->waitforpin(adap->data);
-+ *status = iic_inb(adap, iic->sts);
-+ }
-+#endif
-+ if (timeout <= 0) {
-+ /* Issue stop signal on the bus, and force an interrupt */
-+ retval = iic_inb(adap, iic->cntl);
-+ iic_outb(adap, iic->cntl, retval | 0x80);
-+ /* Clear status register */
-+ iic_outb(adap, iic->sts, 0x0a);
-+ /* Exit unknown bus state */
-+ retval = iic_inb(adap, iic->mdcntl);
-+ iic_outb(adap, iic->mdcntl, (retval | 0x02));
-+
-+ // Check the status of the controller. Does it still see a
-+ // pending transfer, even though we've tried to stop any
-+ // ongoing transaction?
-+ retval = iic_inb(adap, iic->sts);
-+ retval = retval & 0x01;
-+ if(retval) {
-+ // The iic controller is hosed. It is not responding to any
-+ // of our commands. We have already tried to force it into
-+ // a known state, but it has not worked. Our only choice now
-+ // is a soft reset, which will clear all registers, and force
-+ // us to re-initialize the controller.
-+ /* Soft reset */
-+ iic_outb(adap, iic->xtcntlss, 0x01);
-+ udelay(500);
-+ iic_init(adap);
-+ /* Is the pending transfer bit in the sts reg finally cleared? */
-+ retval = iic_inb(adap, iic->sts);
-+ retval = retval & 0x01;
-+ if(retval) {
-+ printk(KERN_CRIT "The IIC Controller is hosed. A processor reset is required\n");
-+ }
-+ // For some reason, even though the interrupt bit in this
-+ // register was set during iic_init, it didn't take. We
-+ // need to set it again. Don't ask me why....this is just what
-+ // I saw when testing timeouts.
-+ iic_outb(adap, iic->intmsk, 0x01);
-+ }
-+ return(-1);
-+ }
-+ else
-+ return(0);
-+}
-+
-+
-+//------------------------------------
-+// Utility functions
-+//
-+
-+
-+//
-+// Description: Look at the status register to see if there was an error
-+// in the requested transaction. If there is, look at the extended status
-+// register and determine the exact cause.
-+//
-+int analyze_status(struct i2c_algo_iic_data *adap, int *error_code)
-+{
-+ int ret;
-+ struct iic_regs *iic;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+
-+ ret = iic_inb(adap, iic->sts);
-+ if(ret & 0x04) {
-+ // Error occurred
-+ ret = iic_inb(adap, iic->extsts);
-+ if(ret & 0x04) {
-+ // Lost arbitration
-+ *error_code = IIC_ERR_LOST_ARB;
-+ }
-+ if(ret & 0x02) {
-+ // Incomplete transfer
-+ *error_code = IIC_ERR_INCOMPLETE_XFR;
-+ }
-+ if(ret & 0x01) {
-+ // Master transfer aborted by a NACK during the transfer of the
-+ // address byte
-+ *error_code = IIC_ERR_NACK;
-+ }
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+
-+//
-+// Description: This function is called by the upper layers to do the
-+// grunt work for a master send transaction
-+//
-+static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-+ int count, int xfer_flag)
-+{
-+ struct iic_regs *iic;
-+ struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ int wrcount, status, timeout;
-+ int loops, remainder, i, j;
-+ int ret, error_code;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+
-+ if( count == 0 ) return 0;
-+ wrcount = 0;
-+ loops = count / 4;
-+ remainder = count % 4;
-+
-+ if((loops > 1) && (remainder == 0)) {
-+ for(i=0; i<(loops-1); i++) {
-+ //
-+ // Write four bytes to master data buffer
-+ //
-+ for(j=0; j<4; j++) {
-+ iic_outb(adap, iic->mdbuf,
-+ buf[wrcount++]);
-+ }
-+ //
-+ // Issue command to IICO device to begin transmission
-+ //
-+ iic_outb(adap, iic->cntl, 0x35);
-+ //
-+ // Wait for transmission to complete. When it does,
-+ //loop to the top of the for statement and write the
-+ // next four bytes.
-+ //
-+ timeout = wait_for_pin(adap, &status);
-+ if(timeout < 0) {
-+ //
-+ // Error handling
-+ //
-+ //printk(KERN_ERR "Error: write timeout\n");
-+ return wrcount;
-+ }
-+ ret = analyze_status(adap, &error_code);
-+ if(ret < 0) {
-+ if(error_code == IIC_ERR_INCOMPLETE_XFR) {
-+ // Return the number of bytes transferred
-+ ret = iic_inb(adap, iic->xfrcnt);
-+ ret = ret & 0x07;
-+ return (wrcount-4+ret);
-+ }
-+ else return error_code;
-+ }
-+ }
-+ }
-+ else if((loops >= 1) && (remainder > 0)){
-+ //printk(KERN_DEBUG "iic_sendbytes: (loops >= 1)\n");
-+ for(i=0; i<loops; i++) {
-+ //
-+ // Write four bytes to master data buffer
-+ //
-+ for(j=0; j<4; j++) {
-+ iic_outb(adap, iic->mdbuf,
-+ buf[wrcount++]);
-+ }
-+ //
-+ // Issue command to IICO device to begin transmission
-+ //
-+ iic_outb(adap, iic->cntl, 0x35);
-+ //
-+ // Wait for transmission to complete. When it does,
-+ //loop to the top of the for statement and write the
-+ // next four bytes.
-+ //
-+ timeout = wait_for_pin(adap, &status);
-+ if(timeout < 0) {
-+ //
-+ // Error handling
-+ //
-+ //printk(KERN_ERR "Error: write timeout\n");
-+ return wrcount;
-+ }
-+ ret = analyze_status(adap, &error_code);
-+ if(ret < 0) {
-+ if(error_code == IIC_ERR_INCOMPLETE_XFR) {
-+ // Return the number of bytes transferred
-+ ret = iic_inb(adap, iic->xfrcnt);
-+ ret = ret & 0x07;
-+ return (wrcount-4+ret);
-+ }
-+ else return error_code;
-+ }
-+ }
-+ }
-+
-+ //printk(KERN_DEBUG "iic_sendbytes: expedite write\n");
-+ if(remainder == 0) remainder = 4;
-+ // remainder = remainder - 1;
-+ //
-+ // Write the remaining bytes (less than or equal to 4)
-+ //
-+ for(i=0; i<remainder; i++) {
-+ iic_outb(adap, iic->mdbuf, buf[wrcount++]);
-+ //printk(KERN_DEBUG "iic_sendbytes: data transferred = %x, wrcount = %d\n", buf[wrcount-1], (wrcount-1));
-+ }
-+ //printk(KERN_DEBUG "iic_sendbytes: Issuing write\n");
-+
-+ if(xfer_flag == IIC_COMBINED_XFER) {
-+ iic_outb(adap, iic->cntl, (0x09 | ((remainder-1) << 4)));
-+ }
-+ else {
-+ iic_outb(adap, iic->cntl, (0x01 | ((remainder-1) << 4)));
-+ }
-+ DEB2(printk(KERN_DEBUG "iic_sendbytes: Waiting for interrupt\n"));
-+ timeout = wait_for_pin(adap, &status);
-+ if(timeout < 0) {
-+ //
-+ // Error handling
-+ //
-+ //printk(KERN_ERR "Error: write timeout\n");
-+ return wrcount;
-+ }
-+ ret = analyze_status(adap, &error_code);
-+ if(ret < 0) {
-+ if(error_code == IIC_ERR_INCOMPLETE_XFR) {
-+ // Return the number of bytes transferred
-+ ret = iic_inb(adap, iic->xfrcnt);
-+ ret = ret & 0x07;
-+ return (wrcount-4+ret);
-+ }
-+ else return error_code;
-+ }
-+ DEB2(printk(KERN_DEBUG "iic_sendbytes: Got interrupt\n"));
-+ return wrcount;
-+}
-+
-+
-+//
-+// Description: Called by the upper layers to do the grunt work for
-+// a master read transaction.
-+//
-+static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count, int xfer_type)
-+{
-+ struct iic_regs *iic;
-+ int rdcount=0, i, status, timeout;
-+ struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ int loops, remainder, j;
-+ int ret, error_code;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+ if(count == 0) return 0;
-+ loops = count / 4;
-+ remainder = count % 4;
-+
-+ //printk(KERN_DEBUG "iic_readbytes: loops = %d, remainder = %d\n", loops, remainder);
-+
-+ if((loops > 1) && (remainder == 0)) {
-+ //printk(KERN_DEBUG "iic_readbytes: (loops > 1) && (remainder == 0)\n");
-+ for(i=0; i<(loops-1); i++) {
-+ //
-+ // Issue command to begin master read (4 bytes maximum)
-+ //
-+ //printk(KERN_DEBUG "--->Issued read command\n");
-+ iic_outb(adap, iic->cntl, 0x37);
-+ //
-+ // Wait for transmission to complete. When it does,
-+ // loop to the top of the for statement and write the
-+ // next four bytes.
-+ //
-+ //printk(KERN_DEBUG "--->Waiting for interrupt\n");
-+ timeout = wait_for_pin(adap, &status);
-+ if(timeout < 0) {
-+ // Error Handler
-+ //printk(KERN_ERR "Error: read timed out\n");
-+ return rdcount;
-+ }
-+ //printk(KERN_DEBUG "--->Got interrupt\n");
-+
-+ ret = analyze_status(adap, &error_code);
-+ if(ret < 0) {
-+ if(error_code == IIC_ERR_INCOMPLETE_XFR)
-+ return rdcount;
-+ else
-+ return error_code;
-+ }
-+
-+ for(j=0; j<4; j++) {
-+ // Wait for data to shuffle to top of data buffer
-+ // This value needs to optimized.
-+ udelay(1);
-+ buf[rdcount] = iic_inb(adap, iic->mdbuf);
-+ rdcount++;
-+ //printk(KERN_DEBUG "--->Read one byte\n");
-+ }
-+ }
-+ }
-+
-+ else if((loops >= 1) && (remainder > 0)){
-+ //printk(KERN_DEBUG "iic_readbytes: (loops >=1) && (remainder > 0)\n");
-+ for(i=0; i<loops; i++) {
-+ //
-+ // Issue command to begin master read (4 bytes maximum)
-+ //
-+ //printk(KERN_DEBUG "--->Issued read command\n");
-+ iic_outb(adap, iic->cntl, 0x37);
-+ //
-+ // Wait for transmission to complete. When it does,
-+ // loop to the top of the for statement and write the
-+ // next four bytes.
-+ //
-+ //printk(KERN_DEBUG "--->Waiting for interrupt\n");
-+ timeout = wait_for_pin(adap, &status);
-+ if(timeout < 0) {
-+ // Error Handler
-+ //printk(KERN_ERR "Error: read timed out\n");
-+ return rdcount;
-+ }
-+ //printk(KERN_DEBUG "--->Got interrupt\n");
-+
-+ ret = analyze_status(adap, &error_code);
-+ if(ret < 0) {
-+ if(error_code == IIC_ERR_INCOMPLETE_XFR)
-+ return rdcount;
-+ else
-+ return error_code;
-+ }
-+
-+ for(j=0; j<4; j++) {
-+ // Wait for data to shuffle to top of data buffer
-+ // This value needs to optimized.
-+ udelay(1);
-+ buf[rdcount] = iic_inb(adap, iic->mdbuf);
-+ rdcount++;
-+ //printk(KERN_DEBUG "--->Read one byte\n");
-+ }
-+ }
-+ }
-+
-+ //printk(KERN_DEBUG "iic_readbytes: expedite read\n");
-+ if(remainder == 0) remainder = 4;
-+ DEB2(printk(KERN_DEBUG "iic_readbytes: writing %x to IICO_CNTL\n", (0x03 | ((remainder-1) << 4))));
-+
-+ if(xfer_type == IIC_COMBINED_XFER) {
-+ iic_outb(adap, iic->cntl, (0x0b | ((remainder-1) << 4)));
-+ }
-+ else {
-+ iic_outb(adap, iic->cntl, (0x03 | ((remainder-1) << 4)));
-+ }
-+ DEB2(printk(KERN_DEBUG "iic_readbytes: Wait for pin\n"));
-+ timeout = wait_for_pin(adap, &status);
-+ DEB2(printk(KERN_DEBUG "iic_readbytes: Got the interrupt\n"));
-+ if(timeout < 0) {
-+ // Error Handler
-+ //printk(KERN_ERR "Error: read timed out\n");
-+ return rdcount;
-+ }
-+
-+ ret = analyze_status(adap, &error_code);
-+ if(ret < 0) {
-+ if(error_code == IIC_ERR_INCOMPLETE_XFR)
-+ return rdcount;
-+ else
-+ return error_code;
-+ }
-+
-+ //printk(KERN_DEBUG "iic_readbyte: Begin reading data buffer\n");
-+ for(i=0; i<remainder; i++) {
-+ buf[rdcount] = iic_inb(adap, iic->mdbuf);
-+ // printk(KERN_DEBUG "iic_readbytes: Character read = %x\n", buf[rdcount]);
-+ rdcount++;
-+ }
-+
-+ return rdcount;
-+}
-+
-+
-+//
-+// Description: 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.
-+//
-+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(KERN_DEBUG "Beginning combined transaction\n"));
-+ for(i=0; i < num; i++) {
-+ pmsg = &msgs[i];
-+ if(pmsg->flags & I2C_M_RD) {
-+
-+ // Last read or write segment needs to be terminated with a stop
-+ if(i < num-1) {
-+ DEB2(printk(KERN_DEBUG "This one is a read\n"));
-+ }
-+ else {
-+ DEB2(printk(KERN_DEBUG "Doing the last read\n"));
-+ }
-+ ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER);
-+
-+ if (ret != pmsg->len) {
-+ DEB2(printk("i2c-algo-ppc405.o: fail: "
-+ "only read %d bytes.\n",ret));
-+ return i;
-+ }
-+ else {
-+ DEB2(printk("i2c-algo-ppc405.o: read %d bytes.\n",ret));
-+ }
-+ }
-+ else if(!(pmsg->flags & I2C_M_RD)) {
-+
-+ // Last read or write segment needs to be terminated with a stop
-+ if(i < num-1) {
-+ DEB2(printk(KERN_DEBUG "This one is a write\n"));
-+ }
-+ else {
-+ DEB2(printk(KERN_DEBUG "Doing the last write\n"));
-+ }
-+ ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER);
-+
-+ if (ret != pmsg->len) {
-+ DEB2(printk("i2c-algo-ppc405.o: fail: "
-+ "only wrote %d bytes.\n",ret));
-+ return i;
-+ }
-+ else {
-+ DEB2(printk("i2c-algo-ppc405.o: wrote %d bytes.\n",ret));
-+ }
-+ }
-+ }
-+
-+ return num;
-+}
-+
-+
-+//
-+// Description: 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)
-+{
-+ struct iic_regs *iic;
-+ unsigned short flags = msg->flags;
-+ unsigned char addr;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+//
-+// The following segment for 10 bit addresses needs to be ported
-+//
-+/* Ten bit addresses not supported right now
-+ if ( (flags & I2C_M_TEN) ) {
-+ // a ten bit address
-+ addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-+ DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
-+ // try extended address code...
-+ ret = try_address(adap, addr, retries);
-+ if (ret!=1) {
-+ printk(KERN_ERR "iic_doAddress: died at extended address code.\n");
-+ return -EREMOTEIO;
-+ }
-+ // the remaining 8 bit address
-+ iic_outb(adap,msg->addr & 0x7f);
-+ // Status check comes here
-+ if (ret != 1) {
-+ printk(KERN_ERR "iic_doAddress: died at 2nd address code.\n");
-+ return -EREMOTEIO;
-+ }
-+ if ( flags & I2C_M_RD ) {
-+ i2c_repstart(adap);
-+ // okay, now switch into reading mode
-+ addr |= 0x01;
-+ ret = try_address(adap, addr, retries);
-+ if (ret!=1) {
-+ printk(KERN_ERR "iic_doAddress: died at extended address code.\n");
-+ return -EREMOTEIO;
-+ }
-+ }
-+ } else ----------> // normal 7 bit address
-+
-+Ten bit addresses not supported yet */
-+
-+ addr = ( msg->addr << 1 );
-+ if (flags & I2C_M_RD )
-+ addr |= 1;
-+ if (flags & I2C_M_REV_DIR_ADDR )
-+ addr ^= 1;
-+ //
-+ // Write to the low slave address
-+ //
-+ iic_outb(adap, iic->lmadr, addr);
-+ //
-+ // Write zero to the high slave register since we are
-+ // only using 7 bit addresses
-+ //
-+ iic_outb(adap, iic->hmadr, 0);
-+
-+ 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.
-+//
-+static int iic_xfer(struct i2c_adapter *i2c_adap,
-+ struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct iic_regs *iic;
-+ struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ struct i2c_msg *pmsg;
-+ int i = 0;
-+ int ret;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+ pmsg = &msgs[i];
-+
-+ //
-+ // Clear status register
-+ //
-+ DEB2(printk(KERN_DEBUG "iic_xfer: iic_xfer: Clearing status register\n"));
-+ iic_outb(adap, iic->sts, 0x0a);
-+
-+ //
-+ // Wait for any pending transfers to complete
-+ //
-+ DEB2(printk(KERN_DEBUG "iic_xfer: Waiting for any pending transfers to complete\n"));
-+ while((ret = iic_inb(adap, iic->sts)) == 0x01) {
-+ ;
-+ }
-+
-+ //
-+ // Flush master data buf
-+ //
-+ DEB2(printk(KERN_DEBUG "iic_xfer: Clearing master data buffer\n"));
-+ ret = iic_inb(adap, iic->mdcntl);
-+ iic_outb(adap, iic->mdcntl, ret | 0x40);
-+
-+ //
-+ // Load slave address
-+ //
-+ DEB2(printk(KERN_DEBUG "iic_xfer: Loading slave address\n"));
-+ ret = iic_doAddress(adap, pmsg, i2c_adap->retries);
-+
-+ //
-+ // Check to see if the bus is busy
-+ //
-+ ret = iic_inb(adap, iic->extsts);
-+ // Mask off the irrelevent bits
-+ ret = ret & 0x70;
-+ // When the bus is free, the BCS bits in the EXTSTS register are 0b100
-+ if(ret != 0x40) return IIC_ERR_LOST_ARB;
-+
-+ //
-+ // Combined transaction (read and write)
-+ //
-+ if(num > 1) {
-+ DEB2(printk(KERN_DEBUG "iic_xfer: Call combined transaction\n"));
-+ ret = iic_combined_transaction(i2c_adap, msgs, num);
-+ }
-+ //
-+ // Read only
-+ //
-+ else if((num == 1) && (pmsg->flags & I2C_M_RD)) {
-+ //
-+ // Tell device to begin reading data from the master data
-+ //
-+ DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's read\n"));
-+ ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-+ }
-+ //
-+ // Write only
-+ //
-+ else if((num == 1 ) && (!(pmsg->flags & I2C_M_RD))) {
-+ //
-+ // Write data to master data buffers and tell our device
-+ // to begin transmitting
-+ //
-+ DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's write\n"));
-+ ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+//
-+// Description: 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 on the IBM PPC 405 IIC controller 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 iic_regs *iic;
-+ struct i2c_algo_iic_data *adap = adapter->algo_data;
-+ struct iic_ibm *adap_priv_data = adap->data;
-+ int ret=0;
-+ int lines;
-+ iic = (struct iic_regs *) adap_priv_data->iic_base;
-+
-+ lines = iic_inb(adap, iic->directcntl);
-+
-+ if (cmd == IICO_I2C_SDAHIGH) {
-+ lines = lines & 0x01;
-+ if( lines ) lines = 0x04;
-+ else lines = 0;
-+ iic_outb(adap, iic->directcntl,(0x08|lines));
-+ }
-+ else if (cmd == IICO_I2C_SDALOW) {
-+ lines = lines & 0x01;
-+ if( lines ) lines = 0x04;
-+ else lines = 0;
-+ iic_outb(adap, iic->directcntl,(0x00|lines));
-+ }
-+ else if (cmd == IICO_I2C_SCLHIGH) {
-+ lines = lines & 0x02;
-+ if( lines ) lines = 0x08;
-+ else lines = 0;
-+ iic_outb(adap, iic->directcntl,(0x04|lines));
-+ }
-+ else if (cmd == IICO_I2C_SCLLOW) {
-+ lines = lines & 0x02;
-+ if( lines ) lines = 0x08;
-+ else lines = 0;
-+ iic_outb(adap, iic->directcntl,(0x00|lines));
-+ }
-+ else if (cmd == IICO_I2C_LINEREAD) {
-+ ret = lines;
-+ }
-+ return ret;
-+}
-+
-+
-+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 = {
-+ .owner = THIS_MODULE,
-+ .name = "IBM on-chip IIC algorithm",
-+ .id = I2C_ALGO_OCP,
-+ .master_xfer = iic_xfer,
-+ .algo_control = algo_control,
-+ .functionality = iic_func,
-+};
-+
-+/*
-+ * registering functions to load algorithms at runtime
-+ */
-+
-+
-+//
-+// Description: Register bus structure
-+//
-+int i2c_ocp_add_bus(struct i2c_adapter *adap)
-+{
-+ struct i2c_algo_iic_data *iic_adap = adap->algo_data;
-+
-+ DEB2(printk(KERN_DEBUG "i2c-algo-iic.o: hw routines for %s registered.\n",
-+ adap->name));
-+
-+ /* register new adapter to i2c module... */
-+
-+ adap->id |= iic_algo.id;
-+ adap->algo = &iic_algo;
-+
-+ adap->timeout = 100; /* default values, should */
-+ adap->retries = 3; /* be replaced by defines */
-+
-+ iic_init(iic_adap);
-+ i2c_add_adapter(adap);
-+ return 0;
-+}
-+
-+
-+//
-+// Done
-+//
-+int i2c_ocp_del_bus(struct i2c_adapter *adap)
-+{
-+ return i2c_del_adapter(adap);
-+}
-+
-+
-+EXPORT_SYMBOL(i2c_ocp_add_bus);
-+EXPORT_SYMBOL(i2c_ocp_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("PPC 405 iic algorithm");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(i2c_debug,"i");
-+
-+MODULE_PARM_DESC(i2c_debug,
-+ "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
-+
---- linux-old/include/linux/i2c-algo-ibm_ocp.h Thu Jan 1 00:00:00 1970
-+++ linux/include/linux/i2c-algo-ibm_ocp.h Mon Dec 13 19:26:29 2004
-@@ -0,0 +1,52 @@
-+/* ------------------------------------------------------------------------- */
-+/* i2c-algo-ibm_ocp.h i2c driver algorithms for IBM PPC 405 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, August 2000
-+ Changes made to support the IIC peripheral on the IBM PPC 405 */
-+
-+#ifndef _LINUX_I2C_ALGO_IBM_OCP_H
-+#define _LINUX_I2C_ALGO_IBM_OCP_H
-+
-+struct i2c_algo_iic_data {
-+ struct iic_regs *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 *data);
-+
-+ /* local settings */
-+ int udelay;
-+ int mdelay;
-+ int timeout;
-+};
-+
-+
-+#define I2C_IIC_ADAP_MAX 16
-+
-+
-+int i2c_ocp_add_bus(struct i2c_adapter *);
-+int i2c_ocp_del_bus(struct i2c_adapter *);
-+
-+#endif /* _LINUX_I2C_ALGO_IBM_OCP_H */
---- linux-old/drivers/i2c/i2c-algo-pcf.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-algo-pcf.c Mon Dec 13 19:26:29 2004
-@@ -32,14 +32,11 @@
- #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-pcf.h>
--#include "i2c-pcf8584.h"
-+
-
- /* ----- global defines ----------------------------------------------- */
- #define DEB(x) if (i2c_debug>=1) x
-@@ -52,7 +49,6 @@
- /* module parameters:
- */
- static int i2c_debug=0;
--static int pcf_scan=0; /* have a look at what's hanging 'round */
-
- /* --- setting states on the bus with the right timing: --------------- */
-
-@@ -149,8 +145,7 @@
- set_pcf(adap, 1, I2C_PCF_PIN);
- /* check to see S1 now used as R/W ctrl -
- PCF8584 does that when ESO is zero */
-- /* PCF also resets PIN bit */
-- if ((temp = get_pcf(adap, 1)) != (0)) {
-+ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
- return -ENXIO; /* definetly not PCF8584 */
- }
-@@ -166,7 +161,7 @@
- /* S1=0xA0, next byte in S2 */
- set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
- /* check to see S2 now selected */
-- if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) {
-+ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
- DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
- return -ENXIO;
- }
-@@ -427,12 +422,6 @@
- return (i);
- }
-
--static int algo_control(struct i2c_adapter *adapter,
-- unsigned int cmd, unsigned long arg)
--{
-- return 0;
--}
--
- static u32 pcf_func(struct i2c_adapter *adap)
- {
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-@@ -442,14 +431,11 @@
- /* -----exported algorithm data: ------------------------------------- */
-
- static struct i2c_algorithm pcf_algo = {
-- "PCF8584 algorithm",
-- I2C_ALGO_PCF,
-- pcf_xfer,
-- NULL,
-- NULL, /* slave_xmit */
-- NULL, /* slave_recv */
-- algo_control, /* ioctl */
-- pcf_func, /* functionality */
-+ .owner = THIS_MODULE,
-+ .name = "PCF8584 algorithm",
-+ .id = I2C_ALGO_PCF,
-+ .master_xfer = pcf_xfer,
-+ .functionality = pcf_func,
- };
-
- /*
-@@ -457,7 +443,7 @@
- */
- int i2c_pcf_add_bus(struct i2c_adapter *adap)
- {
-- int i, status;
-+ int i;
- struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
-
- DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n",
-@@ -475,81 +461,23 @@
- return i;
- }
-
--#ifdef MODULE
-- MOD_INC_USE_COUNT;
--#endif
--
- i2c_add_adapter(adap);
--
-- /* scan bus */
-- if (pcf_scan) {
-- printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n",
-- adap->name);
-- for (i = 0x00; i < 0xff; i+=2) {
-- if (wait_for_bb(pcf_adap)) {
-- printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s - TIMEOUTed.\n",
-- adap->name);
-- break;
-- }
-- i2c_outb(pcf_adap, i);
-- i2c_start(pcf_adap);
-- if ((wait_for_pin(pcf_adap, &status) >= 0) &&
-- ((status & I2C_PCF_LRB) == 0)) {
-- printk("(%02x)",i>>1);
-- } else {
-- printk(".");
-- }
-- i2c_stop(pcf_adap);
-- udelay(pcf_adap->udelay);
-- }
-- printk("\n");
-- }
- return 0;
- }
-
-
- int i2c_pcf_del_bus(struct i2c_adapter *adap)
- {
-- int res;
-- if ((res = i2c_del_adapter(adap)) < 0)
-- return res;
-- DEB2(printk("i2c-algo-pcf.o: adapter unregistered: %s\n",adap->name));
--
--#ifdef MODULE
-- MOD_DEC_USE_COUNT;
--#endif
-- return 0;
--}
--
--int __init i2c_algo_pcf_init (void)
--{
-- printk("i2c-algo-pcf.o: i2c pcf8584 algorithm module\n");
-- return 0;
-+ return i2c_del_adapter(adap);
- }
-
--
- EXPORT_SYMBOL(i2c_pcf_add_bus);
- EXPORT_SYMBOL(i2c_pcf_del_bus);
-
--#ifdef MODULE
- MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
- MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
- MODULE_LICENSE("GPL");
-
--MODULE_PARM(pcf_scan, "i");
- MODULE_PARM(i2c_debug,"i");
--
--MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus");
- MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
--
--
--int init_module(void)
--{
-- return i2c_algo_pcf_init();
--}
--
--void cleanup_module(void)
--{
--}
--#endif
---- linux-old/include/linux/i2c-algo-pcf.h Thu Mar 23 02:26:01 2000
-+++ linux/include/linux/i2c-algo-pcf.h Mon Dec 13 19:26:30 2004
-@@ -22,13 +22,12 @@
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
- Frodo Looijaard <frodol@dds.nl> */
-
--/* $Id: i2c-algo-pcf.h,v 1.7 2000/02/27 23:02:45 frodo Exp $ */
-+/* $Id: i2c-algo-pcf.h,v 1.9 2003/07/25 07:56:42 khali Exp $ */
-
--#ifndef I2C_ALGO_PCF_H
--#define I2C_ALGO_PCF_H 1
-+#ifndef _LINUX_I2C_ALGO_PCF_H
-+#define _LINUX_I2C_ALGO_PCF_H
-
--/* --- Defines for pcf-adapters --------------------------------------- */
--#include <linux/i2c.h>
-+#include <linux/i2c-pcf8584.h>
-
- struct i2c_algo_pcf_data {
- void *data; /* private data for lolevel routines */
-@@ -49,4 +48,4 @@
- int i2c_pcf_add_bus(struct i2c_adapter *);
- int i2c_pcf_del_bus(struct i2c_adapter *);
-
--#endif /* I2C_ALGO_PCF_H */
-+#endif /* _LINUX_I2C_ALGO_PCF_H */
---- linux-old/drivers/i2c/i2c-core.c Wed Jul 7 00:38:02 2004
-+++ linux/drivers/i2c/i2c-core.c Mon Dec 13 19:26:31 2004
-@@ -18,56 +18,33 @@
- /* ------------------------------------------------------------------------- */
-
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
-- All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> */
-+ All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
-+ SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> */
-
--/* $Id: i2c-core.c,v 1.64 2001/08/13 01:35:56 mds Exp $ */
-+/* i2c-core.c,v 1.91.2.2 2003/01/21 10:00:19 kmalkki Exp */
-
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
- #include <linux/proc_fs.h>
--#include <linux/config.h>
--
--#include <linux/i2c.h>
--
--/* ----- compatibility stuff ----------------------------------------------- */
--
- #include <linux/init.h>
--
-+#include <linux/i2c.h>
- #include <asm/uaccess.h>
-
- /* ----- global defines ---------------------------------------------------- */
-
--/* exclusive access to the bus */
--#define I2C_LOCK(adap) down(&adap->lock)
--#define I2C_UNLOCK(adap) up(&adap->lock)
--
--#define ADAP_LOCK() down(&adap_lock)
--#define ADAP_UNLOCK() up(&adap_lock)
--
--#define DRV_LOCK() down(&driver_lock)
--#define DRV_UNLOCK() up(&driver_lock)
--
- #define DEB(x) if (i2c_debug>=1) x;
- #define DEB2(x) if (i2c_debug>=2) x;
-
- /* ----- global variables -------------------------------------------------- */
-
--/**** lock for writing to global variables: the adapter & driver list */
--struct semaphore adap_lock;
--struct semaphore driver_lock;
--
--/**** adapter list */
-+DECLARE_MUTEX(core_lists);
- static struct i2c_adapter *adapters[I2C_ADAP_MAX];
--static int adap_count;
--
--/**** drivers list */
- static struct i2c_driver *drivers[I2C_DRIVER_MAX];
--static int driver_count;
-
- /**** debug level */
--static int i2c_debug=1;
-+static int i2c_debug;
-
- /* ---------------------------------------------------
- * /proc entry declarations
-@@ -75,10 +52,6 @@
- */
-
- #ifdef CONFIG_PROC_FS
--
--static int i2cproc_init(void);
--static int i2cproc_cleanup(void);
--
- static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
- loff_t *ppos);
- static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
-@@ -87,15 +60,11 @@
- /* To implement the dynamic /proc/bus/i2c-? files, we need our own
- implementation of the read hook */
- static struct file_operations i2cproc_operations = {
-- read: i2cproc_bus_read,
-+ .read = i2cproc_bus_read,
- };
-
--static int i2cproc_initialized = 0;
--
--#else /* undef CONFIG_PROC_FS */
--
--#define i2cproc_init() 0
--#define i2cproc_cleanup() 0
-+static int i2cproc_register(struct i2c_adapter *adap, int bus);
-+static void i2cproc_remove(int bus);
-
- #endif /* CONFIG_PROC_FS */
-
-@@ -112,9 +81,9 @@
- */
- int i2c_add_adapter(struct i2c_adapter *adap)
- {
-- int i,j,res;
-+ int i,j,res = 0;
-
-- ADAP_LOCK();
-+ down(&core_lists);
- for (i = 0; i < I2C_ADAP_MAX; i++)
- if (NULL == adapters[i])
- break;
-@@ -125,68 +94,39 @@
- res = -ENOMEM;
- goto ERROR0;
- }
-+
-+#ifdef CONFIG_PROC_FS
-+ res = i2cproc_register(adap, i);
-+ if (res<0)
-+ goto ERROR0;
-+#endif /* def CONFIG_PROC_FS */
-
- adapters[i] = adap;
-- adap_count++;
-- ADAP_UNLOCK();
-
- /* init data types */
-- init_MUTEX(&adap->lock);
--
--#ifdef CONFIG_PROC_FS
--
-- if (i2cproc_initialized) {
-- char name[8];
-- struct proc_dir_entry *proc_entry;
--
-- sprintf(name,"i2c-%d", i);
--
-- proc_entry = create_proc_entry(name,0,proc_bus);
-- if (! proc_entry) {
-- printk("i2c-core.o: Could not create /proc/bus/%s\n",
-- name);
-- res = -ENOENT;
-- goto ERROR1;
-- }
--
-- proc_entry->proc_fops = &i2cproc_operations;
-- proc_entry->owner = THIS_MODULE;
-- adap->inode = proc_entry->low_ino;
-- }
--
--#endif /* def CONFIG_PROC_FS */
-+ init_MUTEX(&adap->bus);
-+ init_MUTEX(&adap->list);
-
- /* inform drivers of new adapters */
-- DRV_LOCK();
- for (j=0;j<I2C_DRIVER_MAX;j++)
- if (drivers[j]!=NULL &&
- (drivers[j]->flags&(I2C_DF_NOTIFY|I2C_DF_DUMMY)))
- /* We ignore the return code; if it fails, too bad */
- drivers[j]->attach_adapter(adap);
-- DRV_UNLOCK();
-
- DEB(printk(KERN_DEBUG "i2c-core.o: adapter %s registered as adapter %d.\n",
- adap->name,i));
--
-- return 0;
--
--
--ERROR1:
-- ADAP_LOCK();
-- adapters[i] = NULL;
-- adap_count--;
- ERROR0:
-- ADAP_UNLOCK();
-+ up(&core_lists);
- return res;
- }
-
-
- int i2c_del_adapter(struct i2c_adapter *adap)
- {
-- int i,j,res;
--
-- ADAP_LOCK();
-+ int i,j,res = 0;
-
-+ down(&core_lists);
- for (i = 0; i < I2C_ADAP_MAX; i++)
- if (adap == adapters[i])
- break;
-@@ -202,20 +142,17 @@
- * *detach* it! Of course, each dummy driver should know about
- * this or hell will break loose...
- */
-- DRV_LOCK();
- for (j = 0; j < I2C_DRIVER_MAX; j++)
- if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY))
- if ((res = drivers[j]->attach_adapter(adap))) {
- printk(KERN_WARNING "i2c-core.o: can't detach adapter %s "
- "while detaching driver %s: driver not "
- "detached!",adap->name,drivers[j]->name);
-- goto ERROR1;
-+ goto ERROR0;
- }
-- DRV_UNLOCK();
--
-
- /* detach any active clients. This must be done first, because
-- * it can fail; in which case we give upp. */
-+ * it can fail; in which case we give up. */
- for (j=0;j<I2C_CLIENT_MAX;j++) {
- struct i2c_client *client = adap->clients[j];
- if (client!=NULL)
-@@ -231,26 +168,15 @@
- goto ERROR0;
- }
- }
-+
- #ifdef CONFIG_PROC_FS
-- if (i2cproc_initialized) {
-- char name[8];
-- sprintf(name,"i2c-%d", i);
-- remove_proc_entry(name,proc_bus);
-- }
-+ i2cproc_remove(i);
- #endif /* def CONFIG_PROC_FS */
-
- adapters[i] = NULL;
-- adap_count--;
--
-- ADAP_UNLOCK();
- DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name));
-- return 0;
--
- ERROR0:
-- ADAP_UNLOCK();
-- return res;
--ERROR1:
-- DRV_UNLOCK();
-+ up(&core_lists);
- return res;
- }
-
-@@ -264,7 +190,8 @@
- int i2c_add_driver(struct i2c_driver *driver)
- {
- int i;
-- DRV_LOCK();
-+
-+ down(&core_lists);
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (NULL == drivers[i])
- break;
-@@ -273,19 +200,12 @@
- " i2c-core.o: register_driver(%s) "
- "- enlarge I2C_DRIVER_MAX.\n",
- driver->name);
-- DRV_UNLOCK();
-+ up(&core_lists);
- return -ENOMEM;
- }
--
- drivers[i] = driver;
-- driver_count++;
--
-- DRV_UNLOCK(); /* driver was successfully added */
--
- DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
-
-- ADAP_LOCK();
--
- /* now look for instances of driver on our adapters
- */
- if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
-@@ -294,15 +214,15 @@
- /* Ignore errors */
- driver->attach_adapter(adapters[i]);
- }
-- ADAP_UNLOCK();
-+ up(&core_lists);
- return 0;
- }
-
- int i2c_del_driver(struct i2c_driver *driver)
- {
-- int i,j,k,res;
-+ int i,j,k,res = 0;
-
-- DRV_LOCK();
-+ down(&core_lists);
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (driver == drivers[i])
- break;
-@@ -310,7 +230,7 @@
- printk(KERN_WARNING " i2c-core.o: unregister_driver: "
- "[%s] not found\n",
- driver->name);
-- DRV_UNLOCK();
-+ up(&core_lists);
- return -ENODEV;
- }
- /* Have a look at each adapter, if clients of this driver are still
-@@ -322,7 +242,6 @@
- * invalid operation might (will!) result, when using stale client
- * pointers.
- */
-- ADAP_LOCK(); /* should be moved inside the if statement... */
- for (k=0;k<I2C_ADAP_MAX;k++) {
- struct i2c_adapter *adap = adapters[k];
- if (adap == NULL) /* skip empty entries. */
-@@ -341,8 +260,7 @@
- "not be detached properly; driver "
- "not unloaded!",driver->name,
- adap->name);
-- ADAP_UNLOCK();
-- return res;
-+ goto ERROR0;
- }
- } else {
- for (j=0;j<I2C_CLIENT_MAX;j++) {
-@@ -359,37 +277,47 @@
- "unregistering driver "
- "`%s', the client at "
- "address %02x of "
-- "adapter `%s' could not"
-- "be detached; driver"
-+ "adapter `%s' could not "
-+ "be detached; driver "
- "not unloaded!",
- driver->name,
- client->addr,
- adap->name);
-- ADAP_UNLOCK();
-- return res;
-+ goto ERROR0;
- }
- }
- }
- }
- }
-- ADAP_UNLOCK();
- drivers[i] = NULL;
-- driver_count--;
-- DRV_UNLOCK();
--
- DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
-- return 0;
-+
-+ERROR0:
-+ up(&core_lists);
-+ return res;
- }
-
--int i2c_check_addr (struct i2c_adapter *adapter, int addr)
-+static int __i2c_check_addr (struct i2c_adapter *adapter, int addr)
- {
- int i;
- for (i = 0; i < I2C_CLIENT_MAX ; i++)
- if (adapter->clients[i] && (adapter->clients[i]->addr == addr))
- return -EBUSY;
-+
- return 0;
- }
-
-+int i2c_check_addr (struct i2c_adapter *adapter, int addr)
-+{
-+ int rval;
-+
-+ down(&adapter->list);
-+ rval = __i2c_check_addr(adapter, addr);
-+ up(&adapter->list);
-+
-+ return rval;
-+}
-+
- int i2c_attach_client(struct i2c_client *client)
- {
- struct i2c_adapter *adapter = client->adapter;
-@@ -398,6 +326,7 @@
- if (i2c_check_addr(client->adapter,client->addr))
- return -EBUSY;
-
-+ down(&adapter->list);
- for (i = 0; i < I2C_CLIENT_MAX; i++)
- if (NULL == adapter->clients[i])
- break;
-@@ -405,11 +334,11 @@
- printk(KERN_WARNING
- " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n",
- client->name);
-+ up(&adapter->list);
- return -ENOMEM;
- }
--
- adapter->clients[i] = client;
-- adapter->client_count++;
-+ up(&adapter->list);
-
- if (adapter->client_register)
- if (adapter->client_register(client))
-@@ -431,16 +360,6 @@
- struct i2c_adapter *adapter = client->adapter;
- int i,res;
-
-- for (i = 0; i < I2C_CLIENT_MAX; i++)
-- if (client == adapter->clients[i])
-- break;
-- if (I2C_CLIENT_MAX == i) {
-- printk(KERN_WARNING " i2c-core.o: unregister_client "
-- "[%s] not found\n",
-- client->name);
-- return -ENODEV;
-- }
--
- if( (client->flags & I2C_CLIENT_ALLOW_USE) &&
- (client->usage_count>0))
- return -EBUSY;
-@@ -452,33 +371,41 @@
- return res;
- }
-
-+ down(&adapter->list);
-+ for (i = 0; i < I2C_CLIENT_MAX; i++)
-+ if (client == adapter->clients[i])
-+ break;
-+ if (I2C_CLIENT_MAX == i) {
-+ printk(KERN_WARNING " i2c-core.o: unregister_client "
-+ "[%s] not found\n",
-+ client->name);
-+ up(&adapter->list);
-+ return -ENODEV;
-+ }
- adapter->clients[i] = NULL;
-- adapter->client_count--;
-+ up(&adapter->list);
-
- DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] unregistered.\n",client->name));
- return 0;
- }
-
--void i2c_inc_use_client(struct i2c_client *client)
-+static void i2c_inc_use_client(struct i2c_client *client)
- {
--
-- if (client->driver->inc_use != NULL)
-- client->driver->inc_use(client);
--
-- if (client->adapter->inc_use != NULL)
-- client->adapter->inc_use(client->adapter);
-+ if(client->driver->owner)
-+ __MOD_INC_USE_COUNT(client->driver->owner);
-+ if(client->adapter->owner)
-+ __MOD_INC_USE_COUNT(client->adapter->owner);
- }
-
--void i2c_dec_use_client(struct i2c_client *client)
-+static void i2c_dec_use_client(struct i2c_client *client)
- {
--
-- if (client->driver->dec_use != NULL)
-- client->driver->dec_use(client);
--
-- if (client->adapter->dec_use != NULL)
-- client->adapter->dec_use(client->adapter);
-+ if(client->driver->owner)
-+ __MOD_DEC_USE_COUNT(client->driver->owner);
-+ if(client->adapter->owner)
-+ __MOD_DEC_USE_COUNT(client->adapter->owner);
- }
-
-+#if 0 /* just forget about this for now --km */
- struct i2c_client *i2c_get_client(int driver_id, int adapter_id,
- struct i2c_client *prev)
- {
-@@ -545,18 +472,17 @@
-
- return 0;
- }
-+#endif
-
- int i2c_use_client(struct i2c_client *client)
- {
-- if(client->flags & I2C_CLIENT_ALLOW_USE) {
-- if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
-+ if (client->flags & I2C_CLIENT_ALLOW_USE) {
-+ if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
-+ client->usage_count++;
-+ else if (client->usage_count > 0)
-+ return -EBUSY;
-+ else
- client->usage_count++;
-- else {
-- if(client->usage_count > 0)
-- return -EBUSY;
-- else
-- client->usage_count++;
-- }
- }
-
- i2c_inc_use_client(client);
-@@ -589,12 +515,13 @@
- #ifdef CONFIG_PROC_FS
-
- /* This function generates the output for /proc/bus/i2c */
--int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
-+static int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
- void *private)
- {
- int i;
- int nr = 0;
- /* Note that it is safe to write a `little' beyond len. Yes, really. */
-+ down(&core_lists);
- for (i = 0; (i < I2C_ADAP_MAX) && (nr < len); i++)
- if (adapters[i]) {
- nr += sprintf(buf+nr, "i2c-%d\t", i);
-@@ -611,6 +538,7 @@
- adapters[i]->name,
- adapters[i]->algo->name);
- }
-+ up(&core_lists);
- return nr;
- }
-
-@@ -621,98 +549,125 @@
- struct inode * inode = file->f_dentry->d_inode;
- char *kbuf;
- struct i2c_client *client;
-+ struct i2c_adapter *adap;
- int i,j,k,order_nr,len=0;
- size_t len_total;
- int order[I2C_CLIENT_MAX];
-+#define OUTPUT_LENGTH_PER_LINE 70
-
-- if (count > 4000)
-- return -EINVAL;
- len_total = file->f_pos + count;
-- /* Too bad if this gets longer (unlikely) */
-- if (len_total > 4000)
-- len_total = 4000;
-- for (i = 0; i < I2C_ADAP_MAX; i++)
-- if (adapters[i]->inode == inode->i_ino) {
-- /* We need a bit of slack in the kernel buffer; this makes the
-- sprintf safe. */
-- if (! (kbuf = kmalloc(count + 80,GFP_KERNEL)))
-- return -ENOMEM;
-- /* Order will hold the indexes of the clients
-- sorted by address */
-- order_nr=0;
-- for (j = 0; j < I2C_CLIENT_MAX; j++) {
-- if ((client = adapters[i]->clients[j]) &&
-- (client->driver->id != I2C_DRIVERID_I2CDEV)) {
-- for(k = order_nr;
-- (k > 0) &&
-- adapters[i]->clients[order[k-1]]->
-- addr > client->addr;
-- k--)
-- order[k] = order[k-1];
-- order[k] = j;
-- order_nr++;
-- }
-- }
--
--
-- for (j = 0; (j < order_nr) && (len < len_total); j++) {
-- client = adapters[i]->clients[order[j]];
-- len += sprintf(kbuf+len,"%02x\t%-32s\t%-32s\n",
-- client->addr,
-- client->name,
-- client->driver->name);
-- }
-- len = len - file->f_pos;
-- if (len > count)
-- len = count;
-- if (len < 0)
-- len = 0;
-- if (copy_to_user (buf,kbuf+file->f_pos, len)) {
-- kfree(kbuf);
-- return -EFAULT;
-- }
-- file->f_pos += len;
-- kfree(kbuf);
-- return len;
-- }
-- return -ENOENT;
-+ if (len_total > (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE) )
-+ /* adjust to maximum file size */
-+ len_total = (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE);
-+
-+ down(&core_lists);
-+ /* adap = file->private_data; ?? --km */
-+ for (i = 0; i < I2C_ADAP_MAX; i++) {
-+ adap = adapters[i];
-+ if (adap && (adap->inode == inode->i_ino))
-+ break;
-+ }
-+ if ( I2C_ADAP_MAX == i ) {
-+ up(&core_lists);
-+ return -ENOENT;
-+ }
-+
-+ /* We need a bit of slack in the kernel buffer; this makes the
-+ sprintf safe. */
-+ if (! (kbuf = kmalloc(len_total +
-+ OUTPUT_LENGTH_PER_LINE,
-+ GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ /* Order will hold the indexes of the clients
-+ sorted by address */
-+ order_nr=0;
-+ down(&adap->list);
-+ for (j = 0; j < I2C_CLIENT_MAX; j++) {
-+ if ((client = adap->clients[j]) &&
-+ (client->driver->id != I2C_DRIVERID_I2CDEV)) {
-+ for(k = order_nr;
-+ (k > 0) &&
-+ adap->clients[order[k-1]]->
-+ addr > client->addr;
-+ k--)
-+ order[k] = order[k-1];
-+ order[k] = j;
-+ order_nr++;
-+ }
-+ }
-+
-+
-+ for (j = 0; (j < order_nr) && (len < len_total); j++) {
-+ client = adap->clients[order[j]];
-+ len += sprintf(kbuf+len,"%02x\t%-32s\t%-32s\n",
-+ client->addr,
-+ client->name,
-+ client->driver->name);
-+ }
-+ up(&adap->list);
-+ up(&core_lists);
-+
-+ len = len - file->f_pos;
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+ if (copy_to_user (buf,kbuf+file->f_pos, len)) {
-+ kfree(kbuf);
-+ return -EFAULT;
-+ }
-+ file->f_pos += len;
-+ kfree(kbuf);
-+ return len;
-+}
-+
-+static int i2cproc_register(struct i2c_adapter *adap, int bus)
-+{
-+ char name[8];
-+ struct proc_dir_entry *proc_entry;
-+
-+ sprintf(name,"i2c-%d", bus);
-+ proc_entry = create_proc_entry(name,0,proc_bus);
-+ if (! proc_entry) {
-+ printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/%s\n",
-+ name);
-+ return -ENOENT;
-+ }
-+
-+ proc_entry->proc_fops = &i2cproc_operations;
-+ proc_entry->owner = adap->owner;
-+ adap->inode = proc_entry->low_ino;
-+ return 0;
- }
-
--int i2cproc_init(void)
-+static void i2cproc_remove(int bus)
- {
-+ char name[8];
-+ sprintf(name,"i2c-%d", bus);
-+ remove_proc_entry(name, proc_bus);
-+}
-
-+static int __init i2cproc_init(void)
-+{
- struct proc_dir_entry *proc_bus_i2c;
-
-- i2cproc_initialized = 0;
--
-- if (! proc_bus) {
-- printk("i2c-core.o: /proc/bus/ does not exist");
-- i2cproc_cleanup();
-- return -ENOENT;
-- }
- proc_bus_i2c = create_proc_entry("i2c",0,proc_bus);
- if (!proc_bus_i2c) {
- printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c");
-- i2cproc_cleanup();
- return -ENOENT;
- }
-+
- proc_bus_i2c->read_proc = &read_bus_i2c;
- proc_bus_i2c->owner = THIS_MODULE;
-- i2cproc_initialized += 2;
- return 0;
- }
-
--int i2cproc_cleanup(void)
-+static void __exit i2cproc_cleanup(void)
- {
--
-- if (i2cproc_initialized >= 1) {
-- remove_proc_entry("i2c",proc_bus);
-- i2cproc_initialized -= 2;
-- }
-- return 0;
-+ remove_proc_entry("i2c",proc_bus);
- }
-
--
- #endif /* def CONFIG_PROC_FS */
-
- /* ----------------------------------------------------
-@@ -728,9 +683,9 @@
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_xfer: %s with %d msgs.\n",
- adap->name,num));
-
-- I2C_LOCK(adap);
-+ down(&adap->bus);
- ret = adap->algo->master_xfer(adap,msgs,num);
-- I2C_UNLOCK(adap);
-+ up(&adap->bus);
-
- return ret;
- } else {
-@@ -755,9 +710,9 @@
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_send: writing %d bytes on %s.\n",
- count,client->adapter->name));
-
-- I2C_LOCK(adap);
-+ down(&adap->bus);
- ret = adap->algo->master_xfer(adap,&msg,1);
-- I2C_UNLOCK(adap);
-+ up(&adap->bus);
-
- /* if everything went ok (i.e. 1 msg transmitted), return #bytes
- * transmitted, else error code.
-@@ -785,9 +740,9 @@
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: reading %d bytes on %s.\n",
- count,client->adapter->name));
-
-- I2C_LOCK(adap);
-+ down(&adap->bus);
- ret = adap->algo->master_xfer(adap,&msg,1);
-- I2C_UNLOCK(adap);
-+ up(&adap->bus);
-
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n",
- ret, count, client->addr));
-@@ -965,6 +920,123 @@
-
- /* The SMBus parts */
-
-+#define POLY (0x1070U << 3)
-+static u8
-+crc8(u16 data)
-+{
-+ int i;
-+
-+ for(i = 0; i < 8; i++) {
-+ if (data & 0x8000)
-+ data = data ^ POLY;
-+ data = data << 1;
-+ }
-+ return (u8)(data >> 8);
-+}
-+
-+/* CRC over count bytes in the first array plus the bytes in the rest
-+ array if it is non-null. rest[0] is the (length of rest) - 1
-+ and is included. */
-+u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest)
-+{
-+ int i;
-+
-+ for(i = 0; i < count; i++)
-+ crc = crc8((crc ^ first[i]) << 8);
-+ if(rest != NULL)
-+ for(i = 0; i <= rest[0]; i++)
-+ crc = crc8((crc ^ rest[i]) << 8);
-+ return crc;
-+}
-+
-+u8 i2c_smbus_pec(int count, u8 *first, u8 *rest)
-+{
-+ return i2c_smbus_partial_pec(0, count, first, rest);
-+}
-+
-+/* Returns new "size" (transaction type)
-+ Note that we convert byte to byte_data and byte_data to word_data
-+ rather than invent new xxx_PEC transactions. */
-+int i2c_smbus_add_pec(u16 addr, u8 command, int size,
-+ union i2c_smbus_data *data)
-+{
-+ u8 buf[3];
-+
-+ buf[0] = addr << 1;
-+ buf[1] = command;
-+ switch(size) {
-+ case I2C_SMBUS_BYTE:
-+ data->byte = i2c_smbus_pec(2, buf, NULL);
-+ size = I2C_SMBUS_BYTE_DATA;
-+ break;
-+ case I2C_SMBUS_BYTE_DATA:
-+ buf[2] = data->byte;
-+ data->word = buf[2] ||
-+ (i2c_smbus_pec(3, buf, NULL) << 8);
-+ size = I2C_SMBUS_WORD_DATA;
-+ break;
-+ case I2C_SMBUS_WORD_DATA:
-+ /* unsupported */
-+ break;
-+ case I2C_SMBUS_BLOCK_DATA:
-+ data->block[data->block[0] + 1] =
-+ i2c_smbus_pec(2, buf, data->block);
-+ size = I2C_SMBUS_BLOCK_DATA_PEC;
-+ break;
-+ }
-+ return size;
-+}
-+
-+int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial,
-+ union i2c_smbus_data *data)
-+{
-+ u8 buf[3], rpec, cpec;
-+
-+ buf[1] = command;
-+ switch(size) {
-+ case I2C_SMBUS_BYTE_DATA:
-+ buf[0] = (addr << 1) | 1;
-+ cpec = i2c_smbus_pec(2, buf, NULL);
-+ rpec = data->byte;
-+ break;
-+ case I2C_SMBUS_WORD_DATA:
-+ buf[0] = (addr << 1) | 1;
-+ buf[2] = data->word & 0xff;
-+ cpec = i2c_smbus_pec(3, buf, NULL);
-+ rpec = data->word >> 8;
-+ break;
-+ case I2C_SMBUS_WORD_DATA_PEC:
-+ /* unsupported */
-+ cpec = rpec = 0;
-+ break;
-+ case I2C_SMBUS_PROC_CALL_PEC:
-+ /* unsupported */
-+ cpec = rpec = 0;
-+ break;
-+ case I2C_SMBUS_BLOCK_DATA_PEC:
-+ buf[0] = (addr << 1);
-+ buf[2] = (addr << 1) | 1;
-+ cpec = i2c_smbus_pec(3, buf, data->block);
-+ rpec = data->block[data->block[0] + 1];
-+ break;
-+ case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
-+ buf[0] = (addr << 1) | 1;
-+ rpec = i2c_smbus_partial_pec(partial, 1,
-+ buf, data->block);
-+ cpec = data->block[data->block[0] + 1];
-+ break;
-+ default:
-+ cpec = rpec = 0;
-+ break;
-+ }
-+ if(rpec != cpec) {
-+ DEB(printk(KERN_DEBUG "i2c-core.o: Bad PEC 0x%02x vs. 0x%02x\n",
-+ rpec, cpec));
-+ return -1;
-+ }
-+ return 0;
-+}
-+
- extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value)
- {
- return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-@@ -983,8 +1055,9 @@
-
- extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value)
- {
-+ union i2c_smbus_data data; /* only for PEC */
- return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-- I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,NULL);
-+ I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data);
- }
-
- extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command)
-@@ -1072,6 +1145,43 @@
- I2C_SMBUS_BLOCK_DATA,&data);
- }
-
-+/* Returns the number of read bytes */
-+extern s32 i2c_smbus_block_process_call(struct i2c_client * client,
-+ u8 command, u8 length, u8 *values)
-+{
-+ union i2c_smbus_data data;
-+ int i;
-+ if (length > I2C_SMBUS_BLOCK_MAX - 1)
-+ return -1;
-+ data.block[0] = length;
-+ for (i = 1; i <= length; i++)
-+ data.block[i] = values[i-1];
-+ if(i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-+ I2C_SMBUS_WRITE, command,
-+ I2C_SMBUS_BLOCK_PROC_CALL, &data))
-+ return -1;
-+ for (i = 1; i <= data.block[0]; i++)
-+ values[i-1] = data.block[i];
-+ return data.block[0];
-+}
-+
-+/* Returns the number of read bytes */
-+extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-+ u8 command, u8 *values)
-+{
-+ union i2c_smbus_data data;
-+ int i;
-+ if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-+ I2C_SMBUS_READ,command,
-+ I2C_SMBUS_I2C_BLOCK_DATA,&data))
-+ return -1;
-+ else {
-+ for (i = 1; i <= data.block[0]; i++)
-+ values[i-1] = data.block[i];
-+ return data.block[0];
-+ }
-+}
-+
- extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
- u8 command, u8 length, u8 *values)
- {
-@@ -1098,13 +1208,13 @@
- need to use only one message; when reading, we need two. We initialize
- most things with sane defaults, to keep the code below somewhat
- simpler. */
-- unsigned char msgbuf0[34];
-- unsigned char msgbuf1[34];
-+ unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+2];
-+ 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 },
- { addr, flags | I2C_M_RD, 0, msgbuf1 }
- };
-- int i;
-+ int i, len;
-
- msgbuf0[0] = command;
- switch(size) {
-@@ -1140,16 +1250,30 @@
- break;
- case I2C_SMBUS_PROC_CALL:
- num = 2; /* Special case */
-+ read_write = I2C_SMBUS_READ;
- msg[0].len = 3;
- msg[1].len = 2;
- msgbuf0[1] = data->word & 0xff;
- msgbuf0[2] = (data->word >> 8) & 0xff;
- break;
- case I2C_SMBUS_BLOCK_DATA:
-+ case I2C_SMBUS_BLOCK_DATA_PEC:
- if (read_write == I2C_SMBUS_READ) {
-- printk(KERN_ERR "i2c-core.o: Block read not supported "
-- "under I2C emulation!\n");
-- return -1;
-+ /* I2C_FUNC_SMBUS_EMUL doesn't include I2C_FUNC_SMBUS_READ_BLOCK_DATA */
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
-+ printk(KERN_ERR "i2c-core.o: Block read not supported "
-+ "under I2C emulation!\n");
-+ return -1;
-+ }
-+ /* set send message */
-+ msg[0].len = 1;
-+ /* set recv message */
-+ msg[1].flags |= I2C_M_RECV_LEN;
-+ msg[1].len = I2C_SMBUS_BLOCK_MAX + 1;
-+ if (size == I2C_SMBUS_BLOCK_DATA_PEC) {
-+ msg[1].len++;
-+ msg[1].flags |= I2C_M_RECV_PEC;
-+ }
- } else {
- msg[0].len = data->block[0] + 2;
- if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
-@@ -1158,10 +1282,57 @@
- data->block[0]);
- return -1;
- }
-+ if(size == I2C_SMBUS_BLOCK_DATA_PEC)
-+ (msg[0].len)++;
- for (i = 1; i <= msg[0].len; i++)
- msgbuf0[i] = data->block[i-1];
- }
- break;
-+ case I2C_SMBUS_BLOCK_PROC_CALL:
-+ case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
-+ /* I2C_FUNC_SMBUS_EMUL doesn't include I2C_FUNC_SMBUS_BLOCK_PROC_CALL */
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_PROC_CALL)) {
-+ printk(KERN_ERR "i2c-core.o: adapter doesn't support block process call!\n");
-+ return -1;
-+ }
-+
-+ /* Another special case */
-+ num = 2;
-+ read_write = I2C_SMBUS_READ;
-+
-+ /* set send message */
-+ msg[0].len = data->block[0] + 2;
-+ if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
-+ printk(KERN_ERR "i2c-core.o: smbus_access called with "
-+ "invalid block write size (%d)\n", data->block[0]);
-+ return -1;
-+ }
-+ for (i = 1; i <= msg[0].len; i++)
-+ msgbuf0[i] = data->block[i-1];
-+
-+ /* set recv message */
-+ msg[1].flags |= I2C_M_RECV_LEN;
-+ msg[1].len = I2C_SMBUS_BLOCK_MAX + 1;
-+ if (size == I2C_SMBUS_BLOCK_PROC_CALL_PEC) {
-+ msg[1].len++;
-+ msg[1].flags |= I2C_M_RECV_PEC;
-+ }
-+ break;
-+ case I2C_SMBUS_I2C_BLOCK_DATA:
-+ if (read_write == I2C_SMBUS_READ) {
-+ msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX;
-+ } else {
-+ msg[0].len = data->block[0] + 1;
-+ if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) {
-+ printk("i2c-core.o: i2c_smbus_xfer_emulated called with "
-+ "invalid block write size (%d)\n",
-+ data->block[0]);
-+ return -1;
-+ }
-+ for (i = 1; i <= data->block[0]; i++)
-+ msgbuf0[i] = data->block[i];
-+ }
-+ break;
- default:
- printk(KERN_ERR "i2c-core.o: smbus_access called with invalid size (%d)\n",
- size);
-@@ -1183,25 +1354,72 @@
- case I2C_SMBUS_PROC_CALL:
- data->word = msgbuf1[0] | (msgbuf1[1] << 8);
- break;
-+ case I2C_SMBUS_I2C_BLOCK_DATA:
-+ /* fixed at 32 for now */
-+ data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX;
-+ for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++)
-+ data->block[i+1] = msgbuf1[i];
-+ break;
-+ case I2C_SMBUS_BLOCK_DATA:
-+ case I2C_SMBUS_BLOCK_PROC_CALL:
-+ case I2C_SMBUS_BLOCK_DATA_PEC:
-+ case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
-+ len = msgbuf1[0] + 1;
-+ if(size == I2C_SMBUS_BLOCK_DATA_PEC ||
-+ size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)
-+ len++;
-+ for (i = 0; i < len; i++)
-+ data->block[i] = msgbuf1[i];
-+ break;
- }
- return 0;
- }
-
-
--s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
-+s32 i2c_smbus_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
- char read_write, u8 command, int size,
- union i2c_smbus_data * data)
- {
- s32 res;
-- flags = flags & I2C_M_TEN;
-- if (adapter->algo->smbus_xfer) {
-- I2C_LOCK(adapter);
-- res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
-+ int swpec = 0;
-+ u8 partial = 0;
-+
-+ flags &= I2C_M_TEN | I2C_CLIENT_PEC;
-+ if((flags & I2C_CLIENT_PEC) &&
-+ !(i2c_check_functionality(adap, I2C_FUNC_SMBUS_HWPEC_CALC))) {
-+ swpec = 1;
-+ if(read_write == I2C_SMBUS_READ &&
-+ size == I2C_SMBUS_BLOCK_DATA)
-+ size = I2C_SMBUS_BLOCK_DATA_PEC;
-+ else if(size == I2C_SMBUS_PROC_CALL)
-+ size = I2C_SMBUS_PROC_CALL_PEC;
-+ else if(size == I2C_SMBUS_BLOCK_PROC_CALL) {
-+ i2c_smbus_add_pec(addr, command,
-+ I2C_SMBUS_BLOCK_DATA, data);
-+ partial = data->block[data->block[0] + 1];
-+ size = I2C_SMBUS_BLOCK_PROC_CALL_PEC;
-+ } else if(read_write == I2C_SMBUS_WRITE &&
-+ size != I2C_SMBUS_QUICK &&
-+ size != I2C_SMBUS_I2C_BLOCK_DATA)
-+ size = i2c_smbus_add_pec(addr, command, size, data);
-+ }
-+
-+ if (adap->algo->smbus_xfer) {
-+ down(&adap->bus);
-+ res = adap->algo->smbus_xfer(adap,addr,flags,read_write,
- command,size,data);
-- I2C_UNLOCK(adapter);
-+ up(&adap->bus);
- } else
-- res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
-+ res = i2c_smbus_xfer_emulated(adap,addr,flags,read_write,
- command,size,data);
-+
-+ if(res >= 0 && swpec &&
-+ size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA &&
-+ (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC ||
-+ size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) {
-+ if(i2c_smbus_check_pec(addr, command, size, partial, data))
-+ return -1;
-+ }
- return res;
- }
-
-@@ -1228,143 +1446,37 @@
- printk(KERN_INFO "i2c-core.o: i2c core module version %s (%s)\n", I2C_VERSION, I2C_DATE);
- memset(adapters,0,sizeof(adapters));
- memset(drivers,0,sizeof(drivers));
-- adap_count=0;
-- driver_count=0;
-
-- init_MUTEX(&adap_lock);
-- init_MUTEX(&driver_lock);
--
-- i2cproc_init();
--
-+#ifdef CONFIG_PROC_FS
-+ return i2cproc_init();
-+#else
- return 0;
--}
--
--#ifndef MODULE
--#ifdef CONFIG_I2C_CHARDEV
-- extern int i2c_dev_init(void);
--#endif
--#ifdef CONFIG_I2C_ALGOBIT
-- extern int i2c_algo_bit_init(void);
--#endif
--#ifdef CONFIG_I2C_PHILIPSPAR
-- extern int i2c_bitlp_init(void);
--#endif
--#ifdef CONFIG_I2C_ELV
-- extern int i2c_bitelv_init(void);
--#endif
--#ifdef CONFIG_I2C_VELLEMAN
-- extern int i2c_bitvelle_init(void);
--#endif
--#ifdef CONFIG_I2C_BITVIA
-- extern int i2c_bitvia_init(void);
--#endif
--
--#ifdef CONFIG_I2C_ALGOPCF
-- extern int i2c_algo_pcf_init(void);
--#endif
--#ifdef CONFIG_I2C_ELEKTOR
-- extern int i2c_pcfisa_init(void);
--#endif
--
--#ifdef CONFIG_I2C_ALGO8XX
-- extern int i2c_algo_8xx_init(void);
--#endif
--#ifdef CONFIG_I2C_RPXLITE
-- extern int i2c_rpx_init(void);
--#endif
--
--#ifdef CONFIG_I2C_ALGO_SIBYTE
-- extern int i2c_algo_sibyte_init(void);
-- extern int i2c_sibyte_init(void);
--#endif
--#ifdef CONFIG_I2C_MAX1617
-- extern int i2c_max1617_init(void);
--#endif
--#ifdef CONFIG_I2C_ALGO_AU1550
-- extern int i2c_pb1550_init(void);
- #endif
-+}
-
--#ifdef CONFIG_I2C_PROC
-- extern int sensors_init(void);
-+static void __exit i2c_exit(void)
-+{
-+#ifdef CONFIG_PROC_FS
-+ i2cproc_cleanup();
- #endif
-+}
-
--/* This is needed for automatic patch generation: sensors code starts here */
--/* This is needed for automatic patch generation: sensors code ends here */
--
-+/* leave this in for now simply to make patching easier so we don't have
-+ to remove the call in drivers/char/mem.c */
- int __init i2c_init_all(void)
- {
-- /* --------------------- global ----- */
-- i2c_init();
--
--#ifdef CONFIG_I2C_CHARDEV
-- i2c_dev_init();
--#endif
-- /* --------------------- bit -------- */
--#ifdef CONFIG_I2C_ALGOBIT
-- i2c_algo_bit_init();
--#endif
--#ifdef CONFIG_I2C_PHILIPSPAR
-- i2c_bitlp_init();
--#endif
--#ifdef CONFIG_I2C_ELV
-- i2c_bitelv_init();
--#endif
--#ifdef CONFIG_I2C_VELLEMAN
-- i2c_bitvelle_init();
--#endif
--
-- /* --------------------- pcf -------- */
--#ifdef CONFIG_I2C_ALGOPCF
-- i2c_algo_pcf_init();
--#endif
--#ifdef CONFIG_I2C_ELEKTOR
-- i2c_pcfisa_init();
--#endif
--
-- /* --------------------- 8xx -------- */
--#ifdef CONFIG_I2C_ALGO8XX
-- i2c_algo_8xx_init();
--#endif
--#ifdef CONFIG_I2C_RPXLITE
-- i2c_rpx_init();
--#endif
--
-- /* --------------------- SiByte -------- */
--#ifdef CONFIG_I2C_ALGO_SIBYTE
-- i2c_algo_sibyte_init();
-- i2c_sibyte_init();
--#endif
--#ifdef CONFIG_I2C_MAX1617
-- i2c_max1617_init();
--#endif
--
--#ifdef CONFIG_I2C_ALGO_AU1550
-- i2c_pb1550_init();
--#endif
--
-- /* -------------- proc interface ---- */
--#ifdef CONFIG_I2C_PROC
-- sensors_init();
--#endif
--/* This is needed for automatic patch generation: sensors code starts here */
--/* This is needed for automatic patch generation: sensors code ends here */
--
- return 0;
- }
-
--#endif
--
--
--
- EXPORT_SYMBOL(i2c_add_adapter);
- EXPORT_SYMBOL(i2c_del_adapter);
- EXPORT_SYMBOL(i2c_add_driver);
- EXPORT_SYMBOL(i2c_del_driver);
- EXPORT_SYMBOL(i2c_attach_client);
- EXPORT_SYMBOL(i2c_detach_client);
--EXPORT_SYMBOL(i2c_inc_use_client);
--EXPORT_SYMBOL(i2c_dec_use_client);
-+#if 0
- EXPORT_SYMBOL(i2c_get_client);
-+#endif
- EXPORT_SYMBOL(i2c_use_client);
- EXPORT_SYMBOL(i2c_release_client);
- EXPORT_SYMBOL(i2c_check_addr);
-@@ -1388,11 +1500,12 @@
- EXPORT_SYMBOL(i2c_smbus_process_call);
- EXPORT_SYMBOL(i2c_smbus_read_block_data);
- EXPORT_SYMBOL(i2c_smbus_write_block_data);
-+EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
-+EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
-
- EXPORT_SYMBOL(i2c_get_functionality);
- EXPORT_SYMBOL(i2c_check_functionality);
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus main module");
- MODULE_LICENSE("GPL");
-@@ -1400,13 +1513,5 @@
- MODULE_PARM(i2c_debug, "i");
- MODULE_PARM_DESC(i2c_debug,"debug level");
-
--int init_module(void)
--{
-- return i2c_init();
--}
--
--void cleanup_module(void)
--{
-- i2cproc_cleanup();
--}
--#endif
-+module_init(i2c_init);
-+module_exit(i2c_exit);
---- linux-old/drivers/i2c/i2c-dev.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-dev.c Mon Dec 13 19:26:32 2004
-@@ -28,9 +28,8 @@
- /* The devfs code is contributed by Philipp Matthias Hahn
- <pmhahn@titan.lahn.de> */
-
--/* $Id: i2c-dev.c,v 1.40 2001/08/25 01:28:01 mds Exp $ */
-+/* $Id: i2c-dev.c,v 1.57 2003/12/22 20:03:39 khali Exp $ */
-
--#include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/fs.h>
-@@ -39,21 +38,14 @@
- #ifdef CONFIG_DEVFS_FS
- #include <linux/devfs_fs_kernel.h>
- #endif
--
--
--/* If you want debugging uncomment: */
--/* #define DEBUG */
--
- #include <linux/init.h>
--#include <asm/uaccess.h>
--
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
-+#include <asm/uaccess.h>
-+
-+/* If you want debugging uncomment: */
-+/* #define DEBUG */
-
--#ifdef MODULE
--extern int init_module(void);
--extern int cleanup_module(void);
--#endif /* def MODULE */
-
- /* struct file_operations changed too often in the 2.1 series for nice code */
-
-@@ -73,22 +65,14 @@
- static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-
--#ifdef MODULE
--static
--#else
--extern
--#endif
-- int __init i2c_dev_init(void);
--static int i2cdev_cleanup(void);
--
- static struct file_operations i2cdev_fops = {
-- owner: THIS_MODULE,
-- llseek: no_llseek,
-- read: i2cdev_read,
-- write: i2cdev_write,
-- ioctl: i2cdev_ioctl,
-- open: i2cdev_open,
-- release: i2cdev_release,
-+ .owner = THIS_MODULE,
-+ .llseek = no_llseek,
-+ .read = i2cdev_read,
-+ .write = i2cdev_write,
-+ .ioctl = i2cdev_ioctl,
-+ .open = i2cdev_open,
-+ .release = i2cdev_release,
- };
-
- #define I2CDEV_ADAPS_MAX I2C_ADAP_MAX
-@@ -99,28 +83,22 @@
- #endif
-
- static struct i2c_driver i2cdev_driver = {
-- name: "i2c-dev dummy driver",
-- id: I2C_DRIVERID_I2CDEV,
-- flags: I2C_DF_DUMMY,
-- attach_adapter: i2cdev_attach_adapter,
-- detach_client: i2cdev_detach_client,
-- command: i2cdev_command,
--/* inc_use: NULL,
-- dec_use: NULL, */
-+ .owner = THIS_MODULE, /* not really used */
-+ .name = "i2c-dev dummy driver",
-+ .id = I2C_DRIVERID_I2CDEV,
-+ .flags = I2C_DF_DUMMY,
-+ .attach_adapter = i2cdev_attach_adapter,
-+ .detach_client = i2cdev_detach_client,
-+ .command = i2cdev_command,
- };
-
- static struct i2c_client i2cdev_client_template = {
-- name: "I2C /dev entry",
-- id: 1,
-- flags: 0,
-- addr: -1,
--/* adapter: NULL, */
-- driver: &i2cdev_driver,
--/* data: NULL */
-+ .name = "I2C /dev entry",
-+ .id = 1,
-+ .addr = -1,
-+ .driver = &i2cdev_driver,
- };
-
--static int i2cdev_initialized;
--
- static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
- loff_t *offset)
- {
-@@ -142,7 +120,7 @@
- return -ENOMEM;
-
- #ifdef DEBUG
-- printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev),
-+ printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",minor(inode->i_rdev),
- count);
- #endif
-
-@@ -177,7 +155,7 @@
- }
-
- #ifdef DEBUG
-- printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev),
-+ printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",minor(inode->i_rdev),
- count);
- #endif
- ret = i2c_master_send(client,tmp,count);
-@@ -199,7 +177,7 @@
-
- #ifdef DEBUG
- printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
-- MINOR(inode->i_rdev),cmd, arg);
-+ minor(inode->i_rdev),cmd, arg);
- #endif /* DEBUG */
-
- switch ( cmd ) {
-@@ -218,6 +196,12 @@
- else
- client->flags &= ~I2C_M_TEN;
- return 0;
-+ case I2C_PEC:
-+ if (arg)
-+ client->flags |= I2C_CLIENT_PEC;
-+ else
-+ client->flags &= ~I2C_CLIENT_PEC;
-+ return 0;
- case I2C_FUNCS:
- funcs = i2c_get_functionality(client->adapter);
- return (copy_to_user((unsigned long *)arg,&funcs,
-@@ -318,7 +302,8 @@
- (data_arg.size != I2C_SMBUS_WORD_DATA) &&
- (data_arg.size != I2C_SMBUS_PROC_CALL) &&
- (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
-- (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA)) {
-+ (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
-+ (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
- #ifdef DEBUG
- printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n",
- data_arg.size);
-@@ -361,10 +346,11 @@
- else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
- (data_arg.size == I2C_SMBUS_PROC_CALL))
- datasize = sizeof(data_arg.data->word);
-- else /* size == I2C_SMBUS_BLOCK_DATA */
-+ else /* size == smbus block, i2c block, or block proc. call */
- datasize = sizeof(data_arg.data->block);
-
- if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-+ (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
- (data_arg.read_write == I2C_SMBUS_WRITE)) {
- if (copy_from_user(&temp, data_arg.data, datasize))
- return -EFAULT;
-@@ -373,6 +359,7 @@
- data_arg.read_write,
- data_arg.command,data_arg.size,&temp);
- if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-+ (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
- (data_arg.read_write == I2C_SMBUS_READ))) {
- if (copy_to_user(data_arg.data, &temp, datasize))
- return -EFAULT;
-@@ -387,7 +374,7 @@
-
- int i2cdev_open (struct inode *inode, struct file *file)
- {
-- unsigned int minor = MINOR(inode->i_rdev);
-+ unsigned int minor = minor(inode->i_rdev);
- struct i2c_client *client;
-
- if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) {
-@@ -403,11 +390,13 @@
- if(! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
- return -ENOMEM;
- memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client));
-+
-+ /* registered with adapter, passed as client to user */
- client->adapter = i2cdev_adaps[minor];
- file->private_data = client;
-
-- if (i2cdev_adaps[minor]->inc_use)
-- i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]);
-+ if(client->adapter->owner)
-+ __MOD_INC_USE_COUNT(client->adapter->owner);
-
- #ifdef DEBUG
- printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor);
-@@ -417,16 +406,19 @@
-
- static int i2cdev_release (struct inode *inode, struct file *file)
- {
-- unsigned int minor = MINOR(inode->i_rdev);
-- kfree(file->private_data);
-- file->private_data=NULL;
-+ struct i2c_client *client;
-+#ifdef DEBUG
-+ unsigned int minor = minor(inode->i_rdev);
-+#endif
-+
-+ client = file->private_data;
-+ file->private_data = NULL;
-+ if(client->adapter->owner)
-+ __MOD_DEC_USE_COUNT(client->adapter->owner);
-+ kfree(client);
- #ifdef DEBUG
- printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor);
- #endif
-- lock_kernel();
-- if (i2cdev_adaps[minor]->dec_use)
-- i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]);
-- unlock_kernel();
- return 0;
- }
-
-@@ -451,7 +443,7 @@
- devfs_i2c[i] = devfs_register (devfs_handle, name,
- DEVFS_FL_DEFAULT, I2C_MAJOR, i,
- S_IFCHR | S_IRUSR | S_IWUSR,
-- &i2cdev_fops, NULL);
-+ &i2cdev_fops, adap);
- #endif
- printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i);
- } else {
-@@ -479,13 +471,12 @@
- return -1;
- }
-
--int __init i2c_dev_init(void)
-+static int __init i2c_dev_init(void)
- {
- int res;
-
- printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-- i2cdev_initialized = 0;
- #ifdef CONFIG_DEVFS_FS
- if (devfs_register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops)) {
- #else
-@@ -498,63 +489,31 @@
- #ifdef CONFIG_DEVFS_FS
- devfs_handle = devfs_mk_dir(NULL, "i2c", NULL);
- #endif
-- i2cdev_initialized ++;
--
- if ((res = i2c_add_driver(&i2cdev_driver))) {
- printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n");
-- i2cdev_cleanup();
-+#ifdef CONFIG_DEVFS_FS
-+ devfs_unregister(devfs_handle);
-+#endif
-+ unregister_chrdev(I2C_MAJOR,"i2c");
- return res;
- }
-- i2cdev_initialized ++;
- return 0;
- }
-
--int i2cdev_cleanup(void)
-+static void __exit i2c_dev_exit(void)
- {
-- int res;
--
-- if (i2cdev_initialized >= 2) {
-- if ((res = i2c_del_driver(&i2cdev_driver))) {
-- printk("i2c-dev.o: Driver deregistration failed, "
-- "module not removed.\n");
-- return res;
-- }
-- i2cdev_initialized --;
-- }
--
-- if (i2cdev_initialized >= 1) {
-+ i2c_del_driver(&i2cdev_driver);
- #ifdef CONFIG_DEVFS_FS
-- devfs_unregister(devfs_handle);
-- if ((res = devfs_unregister_chrdev(I2C_MAJOR, "i2c"))) {
--#else
-- if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
-+ devfs_unregister(devfs_handle);
- #endif
-- printk("i2c-dev.o: unable to release major %d for i2c bus\n",
-- I2C_MAJOR);
-- return res;
-- }
-- i2cdev_initialized --;
-- }
-- return 0;
-+ unregister_chrdev(I2C_MAJOR,"i2c");
- }
-
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
--
- MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C /dev entries driver");
- MODULE_LICENSE("GPL");
-
--int init_module(void)
--{
-- return i2c_dev_init();
--}
--
--int cleanup_module(void)
--{
-- return i2cdev_cleanup();
--}
--
--#endif /* def MODULE */
--
-+module_init(i2c_dev_init);
-+module_exit(i2c_dev_exit);
---- linux-old/include/linux/i2c-dev.h Sat Jul 5 03:23:47 2003
-+++ linux/include/linux/i2c-dev.h Mon Dec 13 19:26:32 2004
-@@ -19,14 +19,16 @@
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
--/* $Id: i2c-dev.h,v 1.9 2001/08/15 03:04:58 mds Exp $ */
--
--#ifndef I2C_DEV_H
--#define I2C_DEV_H
-+/* $Id: i2c-dev.h,v 1.14 2003/07/25 07:56:42 khali Exp $ */
-
-+#ifndef _LINUX_I2C_DEV_H
-+#define _LINUX_I2C_DEV_H
-
- #include <linux/types.h>
--#include <linux/i2c.h>
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+#define minor(d) MINOR(d)
-+#endif
-
- /* Some IOCTL commands are defined in <linux/i2c.h> */
- /* Note: 10-bit addresses are NOT supported! */
-@@ -45,137 +47,4 @@
- __u32 nmsgs; /* number of i2c_msgs */
- };
-
--#ifndef __KERNEL__
--
--#include <sys/ioctl.h>
--
--static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
-- int size, union i2c_smbus_data *data)
--{
-- struct i2c_smbus_ioctl_data args;
--
-- args.read_write = read_write;
-- args.command = command;
-- args.size = size;
-- args.data = data;
-- return ioctl(file,I2C_SMBUS,&args);
--}
--
--
--static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
--{
-- return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
--}
--
--static inline __s32 i2c_smbus_read_byte(int file)
--{
-- union i2c_smbus_data data;
-- if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
-- return -1;
-- else
-- return 0x0FF & data.byte;
--}
--
--static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
--{
-- return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
-- I2C_SMBUS_BYTE,NULL);
--}
--
--static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
--{
-- union i2c_smbus_data data;
-- if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
-- I2C_SMBUS_BYTE_DATA,&data))
-- return -1;
-- else
-- return 0x0FF & data.byte;
--}
--
--static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
-- __u8 value)
--{
-- union i2c_smbus_data data;
-- data.byte = value;
-- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
-- I2C_SMBUS_BYTE_DATA, &data);
--}
--
--static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
--{
-- union i2c_smbus_data data;
-- if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
-- I2C_SMBUS_WORD_DATA,&data))
-- return -1;
-- else
-- return 0x0FFFF & data.word;
--}
--
--static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
-- __u16 value)
--{
-- union i2c_smbus_data data;
-- data.word = value;
-- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
-- I2C_SMBUS_WORD_DATA, &data);
--}
--
--static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
--{
-- union i2c_smbus_data data;
-- data.word = value;
-- if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
-- I2C_SMBUS_PROC_CALL,&data))
-- return -1;
-- else
-- return 0x0FFFF & data.word;
--}
--
--
--/* Returns the number of read bytes */
--static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
-- __u8 *values)
--{
-- union i2c_smbus_data data;
-- int i;
-- if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
-- I2C_SMBUS_BLOCK_DATA,&data))
-- return -1;
-- else {
-- for (i = 1; i <= data.block[0]; i++)
-- values[i-1] = data.block[i];
-- return data.block[0];
-- }
--}
--
--static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
-- __u8 length, __u8 *values)
--{
-- union i2c_smbus_data data;
-- int i;
-- if (length > 32)
-- length = 32;
-- for (i = 1; i <= length; i++)
-- data.block[i] = values[i-1];
-- data.block[0] = length;
-- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
-- I2C_SMBUS_BLOCK_DATA, &data);
--}
--
--static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
-- __u8 length, __u8 *values)
--{
-- union i2c_smbus_data data;
-- int i;
-- if (length > 32)
-- length = 32;
-- for (i = 1; i <= length; i++)
-- data.block[i] = values[i-1];
-- data.block[0] = length;
-- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
-- I2C_SMBUS_I2C_BLOCK_DATA, &data);
--}
--
--#endif /* ndef __KERNEL__ */
--
--#endif
-+#endif /* _LINUX_I2C_DEV_H */
---- linux-old/drivers/i2c/i2c-elektor.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-elektor.c Mon Dec 13 19:26:33 2004
-@@ -31,23 +31,22 @@
- #include <linux/delay.h>
- #include <linux/slab.h>
- #include <linux/init.h>
-+#include <linux/interrupt.h>
- #include <linux/pci.h>
--#include <asm/irq.h>
--#include <asm/io.h>
--
-+#include <linux/wait.h>
- #include <linux/i2c.h>
- #include <linux/i2c-algo-pcf.h>
--#include <linux/i2c-elektor.h>
--#include "i2c-pcf8584.h"
-+#include <asm/io.h>
-+#include <asm/irq.h>
-
- #define DEFAULT_BASE 0x330
-
--static int base = 0;
--static int irq = 0;
-+static int base;
-+static int irq;
- static int clock = 0x1c;
- static int own = 0x55;
--static int mmapped = 0;
--static int i2c_debug = 0;
-+static int mmapped;
-+static int i2c_debug;
-
- /* vdovikin: removed static struct i2c_pcf_isa gpi; code -
- this module in real supports only one device, due to missing arguments
-@@ -56,6 +55,7 @@
-
- static wait_queue_head_t pcf_wait;
- static int pcf_pending;
-+static spinlock_t irq_driver_lock = SPIN_LOCK_UNLOCKED;
-
- /* ----- global defines ----------------------------------------------- */
- #define DEB(x) if (i2c_debug>=1) x
-@@ -63,13 +63,24 @@
- #define DEB3(x) if (i2c_debug>=3) x
- #define DEBE(x) x /* error messages */
-
-+
-+/* compatibility */
-+#ifndef isa_readb
-+#define isa_readb readb
-+#endif
-+
-+#ifndef isa_writeb
-+#define isa_writeb writeb
-+#endif
-+
- /* ----- local functions ---------------------------------------------- */
-
- static void pcf_isa_setbyte(void *data, int ctl, int val)
- {
- int address = ctl ? (base + 1) : base;
-
-- if (ctl && irq) {
-+ /* enable irq if any specified for serial operation */
-+ if (ctl && irq && (val & I2C_PCF_ESO)) {
- val |= I2C_PCF_ENI;
- }
-
-@@ -81,10 +92,10 @@
- break;
- case 2: /* double mapped I/O needed for UP2000 board,
- I don't know why this... */
-- writeb(val, address);
-+ isa_writeb(val, address);
- /* fall */
- case 1: /* memory mapped I/O */
-- writeb(val, address);
-+ isa_writeb(val, address);
- break;
- }
- }
-@@ -92,7 +103,7 @@
- static int pcf_isa_getbyte(void *data, int ctl)
- {
- int address = ctl ? (base + 1) : base;
-- int val = mmapped ? readb(address) : inb(address);
-+ int val = mmapped ? isa_readb(address) : inb(address);
-
- DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
-
-@@ -115,12 +126,12 @@
- int timeout = 2;
-
- if (irq > 0) {
-- cli();
-+ spin_lock_irq(&irq_driver_lock);
- if (pcf_pending == 0) {
- interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
- } else
- pcf_pending = 0;
-- sti();
-+ spin_unlock_irq(&irq_driver_lock);
- } else {
- udelay(100);
- }
-@@ -136,13 +147,11 @@
- static int pcf_isa_init(void)
- {
- if (!mmapped) {
-- if (check_region(base, 2) < 0 ) {
-+ if (!request_region(base, 2, "i2c (isa bus adapter)")) {
- printk(KERN_ERR
- "i2c-elektor.o: requested I/O region (0x%X:2) "
- "is in use.\n", base);
- return -ENODEV;
-- } else {
-- request_region(base, 2, "i2c (isa bus adapter)");
- }
- }
- if (irq > 0) {
-@@ -156,70 +165,29 @@
- }
-
-
--static void __exit pcf_isa_exit(void)
--{
-- if (irq > 0) {
-- disable_irq(irq);
-- free_irq(irq, 0);
-- }
-- if (!mmapped) {
-- release_region(base , 2);
-- }
--}
--
--
--static int pcf_isa_reg(struct i2c_client *client)
--{
-- return 0;
--}
--
--
--static int pcf_isa_unreg(struct i2c_client *client)
--{
-- return 0;
--}
--
--static void pcf_isa_inc_use(struct i2c_adapter *adap)
--{
--#ifdef MODULE
-- MOD_INC_USE_COUNT;
--#endif
--}
--
--static void pcf_isa_dec_use(struct i2c_adapter *adap)
--{
--#ifdef MODULE
-- MOD_DEC_USE_COUNT;
--#endif
--}
--
--
- /* ------------------------------------------------------------------------
- * 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_pcf_data pcf_isa_data = {
-- NULL,
-- pcf_isa_setbyte,
-- pcf_isa_getbyte,
-- pcf_isa_getown,
-- pcf_isa_getclock,
-- pcf_isa_waitforpin,
-- 10, 10, 100, /* waits, timeout */
-+ .setpcf = pcf_isa_setbyte,
-+ .getpcf = pcf_isa_getbyte,
-+ .getown = pcf_isa_getown,
-+ .getclock = pcf_isa_getclock,
-+ .waitforpin = pcf_isa_waitforpin,
-+ .udelay = 10,
-+ .mdelay = 10,
-+ .timeout = HZ,
- };
-
- static struct i2c_adapter pcf_isa_ops = {
-- "PCF8584 ISA adapter",
-- I2C_HW_P_ELEK,
-- NULL,
-- &pcf_isa_data,
-- pcf_isa_inc_use,
-- pcf_isa_dec_use,
-- pcf_isa_reg,
-- pcf_isa_unreg,
-+ .owner = THIS_MODULE,
-+ .name = "PCF8584 ISA adapter",
-+ .id = I2C_HW_P_ELEK,
-+ .algo_data = &pcf_isa_data,
- };
-
--int __init i2c_pcfisa_init(void)
-+static int __init i2c_pcfisa_init(void)
- {
- #ifdef __alpha__
- /* check to see we have memory mapped PCF8584 connected to the
-@@ -277,22 +245,41 @@
- }
-
- init_waitqueue_head(&pcf_wait);
-- if (pcf_isa_init() == 0) {
-- if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
-- return -ENODEV;
-- } else {
-+ if (pcf_isa_init())
- return -ENODEV;
-- }
-+ if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
-+ goto fail;
-
- printk(KERN_DEBUG "i2c-elektor.o: found device at %#x.\n", base);
-
- return 0;
-+
-+ fail:
-+ if (irq > 0) {
-+ disable_irq(irq);
-+ free_irq(irq, 0);
-+ }
-+
-+ if (!mmapped)
-+ release_region(base , 2);
-+ return -ENODEV;
- }
-
-+static void __exit i2c_pcfisa_exit(void)
-+{
-+ i2c_pcf_del_bus(&pcf_isa_ops);
-+
-+ if (irq > 0) {
-+ disable_irq(irq);
-+ free_irq(irq, 0);
-+ }
-+
-+ if (!mmapped)
-+ release_region(base , 2);
-+}
-
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
- MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
- MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
- MODULE_LICENSE("GPL");
-@@ -304,15 +291,5 @@
- MODULE_PARM(mmapped, "i");
- MODULE_PARM(i2c_debug, "i");
-
--int init_module(void)
--{
-- return i2c_pcfisa_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_pcf_del_bus(&pcf_isa_ops);
-- pcf_isa_exit();
--}
--
--#endif
-+module_init(i2c_pcfisa_init);
-+module_exit(i2c_pcfisa_exit);
---- linux-old/include/linux/i2c-elektor.h Tue Nov 6 00:55:29 2001
-+++ linux/include/linux/i2c-elektor.h Mon Dec 13 19:26:33 2004
-@@ -1,47 +0,0 @@
--/* ------------------------------------------------------------------------- */
--/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes */
--/* ------------------------------------------------------------------------- */
--/* 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> */
--
--/* $Id: i2c-elektor.h,v 1.5 2001/06/05 01:46:33 mds Exp $ */
--
--#ifndef I2C_PCF_ELEKTOR_H
--#define I2C_PCF_ELEKTOR_H 1
--
--/*
-- * This struct contains the hw-dependent functions of PCF8584 adapters to
-- * manipulate the registers, and to init any hw-specific features.
-- * vdovikin: removed: this module in real supports only one device,
-- * due to missing arguments in some functions, called from the algo-pcf module.
-- * Sometimes it's need to be rewriten -
-- * but for now just remove this for simpler reading */
--
--/*
--struct i2c_pcf_isa {
-- int pi_base;
-- int pi_irq;
-- int pi_clock;
-- int pi_own;
--};
--*/
--
--#endif /* PCF_ELEKTOR_H */
---- linux-old/drivers/i2c/i2c-elv.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-elv.c Mon Dec 13 19:26:33 2004
-@@ -21,21 +21,18 @@
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
- Frodo Looijaard <frodol@dds.nl> */
-
--/* $Id: i2c-elv.c,v 1.17 2001/07/29 02:44:25 mds Exp $ */
-+/* $Id: i2c-elv.c,v 1.29 2003/12/22 20:03:11 khali Exp $ */
-
- #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 <asm/io.h>
- #include <linux/errno.h>
- #include <linux/i2c.h>
- #include <linux/i2c-algo-bit.h>
-+#include <asm/io.h>
-
- #define DEFAULT_BASE 0x378
- static int base=0;
-@@ -89,58 +86,31 @@
-
- static int bit_elv_init(void)
- {
-- if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
-- return -ENODEV;
-- } else {
-- /* test for ELV adap. */
-- if (inb(base+1) & 0x80) { /* BUSY should be high */
-- DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
-- return -ENODEV;
-- } else {
-- outb(0x0c,base+2); /* SLCT auf low */
-- udelay(400);
-- if ( !(inb(base+1) && 0x10) ) {
-- outb(0x04,base+2);
-- DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
-- return -ENODEV;
-- }
-- }
-- request_region(base,(base == 0x3bc)? 3 : 8,
-- "i2c (ELV adapter)");
-- PortData = 0;
-- bit_elv_setsda((void*)base,1);
-- bit_elv_setscl((void*)base,1);
-+ if (!request_region(base, (base == 0x3bc) ? 3 : 8,
-+ "i2c (ELV adapter)"))
-+ return -ENODEV;
-+
-+ if (inb(base+1) & 0x80) { /* BUSY should be high */
-+ DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
-+ goto fail;
-+ }
-+
-+ outb(0x0c,base+2); /* SLCT auf low */
-+ udelay(400);
-+ if (!(inb(base+1) && 0x10)) {
-+ outb(0x04,base+2);
-+ DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
-+ goto fail;
- }
-- return 0;
--}
--
--static void __exit bit_elv_exit(void)
--{
-- release_region( base , (base == 0x3bc)? 3 : 8 );
--}
--
--static int bit_elv_reg(struct i2c_client *client)
--{
-- return 0;
--}
-
--static int bit_elv_unreg(struct i2c_client *client)
--{
-+ PortData = 0;
-+ bit_elv_setsda((void*)base,1);
-+ bit_elv_setscl((void*)base,1);
- return 0;
--}
-
--static void bit_elv_inc_use(struct i2c_adapter *adap)
--{
--#ifdef MODULE
-- MOD_INC_USE_COUNT;
--#endif
--}
--
--static void bit_elv_dec_use(struct i2c_adapter *adap)
--{
--#ifdef MODULE
-- MOD_DEC_USE_COUNT;
--#endif
-+fail:
-+ release_region(base , (base == 0x3bc) ? 3 : 8);
-+ return -ENODEV;
- }
-
- /* ------------------------------------------------------------------------
-@@ -148,26 +118,23 @@
- * This is only done when more than one hardware adapter is supported.
- */
- static struct i2c_algo_bit_data bit_elv_data = {
-- NULL,
-- bit_elv_setsda,
-- bit_elv_setscl,
-- bit_elv_getsda,
-- bit_elv_getscl,
-- 80, 80, 100, /* waits, timeout */
-+ .setsda = bit_elv_setsda,
-+ .setscl = bit_elv_setscl,
-+ .getsda = bit_elv_getsda,
-+ .getscl = bit_elv_getscl,
-+ .udelay = 80,
-+ .mdelay = 80,
-+ .timeout = HZ
- };
-
- static struct i2c_adapter bit_elv_ops = {
-- "ELV Parallel port adaptor",
-- I2C_HW_B_ELV,
-- NULL,
-- &bit_elv_data,
-- bit_elv_inc_use,
-- bit_elv_dec_use,
-- bit_elv_reg,
-- bit_elv_unreg,
-+ .owner = THIS_MODULE,
-+ .name = "ELV Parallel port adaptor",
-+ .id = I2C_HW_B_ELV,
-+ .algo_data = &bit_elv_data,
- };
-
--int __init i2c_bitelv_init(void)
-+static int __init i2c_bitelv_init(void)
- {
- printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
- if (base==0) {
-@@ -193,25 +160,19 @@
- return 0;
- }
-
-+static void __exit i2c_bitelv_exit(void)
-+{
-+ i2c_bit_del_bus(&bit_elv_ops);
-+ release_region(base, (base == 0x3bc) ? 3 : 8);
-+}
-
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
- MODULE_LICENSE("GPL");
-
- MODULE_PARM(base, "i");
-
--int init_module(void)
--{
-- return i2c_bitelv_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_bit_del_bus(&bit_elv_ops);
-- bit_elv_exit();
--}
--
--#endif
-+module_init(i2c_bitelv_init);
-+module_exit(i2c_bitelv_exit);
---- linux-old/drivers/i2c/i2c-frodo.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-frodo.c Mon Dec 13 19:26:33 2004
-@@ -0,0 +1,83 @@
-+
-+/*
-+ * linux/drivers/i2c/i2c-frodo.c
-+ *
-+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
-+ *
-+ * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110
-+ * Development board (Frodo).
-+ *
-+ * This source code 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/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+#include <asm/hardware.h>
-+
-+
-+static void frodo_setsda (void *data,int state)
-+{
-+ if (state)
-+ FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT;
-+ else
-+ FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT;
-+}
-+
-+static void frodo_setscl (void *data,int state)
-+{
-+ if (state)
-+ FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT;
-+ else
-+ FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT;
-+}
-+
-+static int frodo_getsda (void *data)
-+{
-+ return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0);
-+}
-+
-+static int frodo_getscl (void *data)
-+{
-+ return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0);
-+}
-+
-+static struct i2c_algo_bit_data bit_frodo_data = {
-+ .setsda = frodo_setsda,
-+ .setscl = frodo_setscl,
-+ .getsda = frodo_getsda,
-+ .getscl = frodo_getscl,
-+ .udelay = 80,
-+ .mdelay = 80,
-+ .timeout = HZ
-+};
-+
-+static struct i2c_adapter frodo_ops = {
-+ .owner = THIS_MODULE,
-+ .name = "Frodo adapter driver",
-+ .id = I2C_HW_B_FRODO,
-+ .algo_data = &bit_frodo_data,
-+};
-+
-+static int __init i2c_frodo_init (void)
-+{
-+ return i2c_bit_add_bus(&frodo_ops);
-+}
-+
-+static void __exit i2c_frodo_exit (void)
-+{
-+ i2c_bit_del_bus(&frodo_ops);
-+}
-+
-+MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
-+MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo");
-+MODULE_LICENSE ("GPL");
-+
-+module_init (i2c_frodo_init);
-+module_exit (i2c_frodo_exit);
-+
---- linux-old/include/linux/i2c-id.h Wed Jul 7 00:38:02 2004
-+++ linux/include/linux/i2c-id.h Mon Dec 13 19:26:33 2004
-@@ -20,10 +20,11 @@
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* ------------------------------------------------------------------------- */
-
--/* $Id: i2c-id.h,v 1.35 2001/08/12 17:22:20 mds Exp $ */
-+/* $Id: i2c-id.h,v 1.92 2004/07/27 18:15:06 mmh Exp $ */
-+
-+#ifndef LINUX_I2C_ID_H
-+#define LINUX_I2C_ID_H
-
--#ifndef I2C_ID_H
--#define I2C_ID_H
- /*
- * This file is part of the i2c-bus package and contains the identifier
- * values for drivers, adapters and other folk populating these serial
-@@ -90,10 +91,25 @@
- #define I2C_DRIVERID_DRP3510 43 /* ADR decoder (Astra Radio) */
- #define I2C_DRIVERID_SP5055 44 /* Satellite tuner */
- #define I2C_DRIVERID_STV0030 45 /* Multipurpose switch */
-+#define I2C_DRIVERID_SAA7108 46 /* video decoder, image scaler */
-+#define I2C_DRIVERID_DS1307 47 /* DS1307 real time clock */
- #define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */
--#define I2C_DRIVERID_MAX1617 56 /* temp sensor */
--#define I2C_DRIVERID_SAA7191 57 /* video decoder */
--#define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */
-+#define I2C_DRIVERID_ZR36067 49 /* Zoran 36067 video encoder */
-+#define I2C_DRIVERID_ZR36120 50 /* Zoran 36120 video encoder */
-+#define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */
-+#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_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_OVCAMCHIP 61 /* OmniVision CMOS image sens. */
-+#define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */
-+#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
-+
-
- #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
- #define I2C_DRIVERID_EXP1 0xF1
-@@ -102,6 +118,8 @@
-
- #define I2C_DRIVERID_I2CDEV 900
- #define I2C_DRIVERID_I2CPROC 901
-+#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
-+#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */
-
- /* IDs -- Use DRIVERIDs 1000-1999 for sensors.
- These were originally in sensors.h in the lm_sensors package */
-@@ -131,6 +149,28 @@
- #define I2C_DRIVERID_ADM1024 1025
- #define I2C_DRIVERID_IT87 1026
- #define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
-+#define I2C_DRIVERID_FSCPOS 1028
-+#define I2C_DRIVERID_FSCSCY 1029
-+#define I2C_DRIVERID_PCF8591 1030
-+#define I2C_DRIVERID_SMSC47M1 1031
-+#define I2C_DRIVERID_VT1211 1032
-+#define I2C_DRIVERID_LM92 1033
-+#define I2C_DRIVERID_VT8231 1034
-+#define I2C_DRIVERID_SMARTBATT 1035
-+#define I2C_DRIVERID_BMCSENSORS 1036
-+#define I2C_DRIVERID_FS451 1037
-+#define I2C_DRIVERID_W83627HF 1038
-+#define I2C_DRIVERID_LM85 1039
-+#define I2C_DRIVERID_LM83 1040
-+#define I2C_DRIVERID_SAA1064 1041
-+#define I2C_DRIVERID_LM90 1042
-+#define I2C_DRIVERID_ASB100 1043
-+#define I2C_DRIVERID_MAX6650 1044
-+#define I2C_DRIVERID_XEONTEMP 1045
-+#define I2C_DRIVERID_FSCHER 1046
-+#define I2C_DRIVERID_W83L785TS 1047
-+#define I2C_DRIVERID_ADM1026 1048
-+#define I2C_DRIVERID_LM93 1049
-
- /*
- * ---- Adapter types ----------------------------------------------------
-@@ -147,16 +187,21 @@
- #define I2C_ALGO_ISA 0x050000 /* lm_sensors ISA pseudo-adapter */
- #define I2C_ALGO_SAA7146 0x060000 /* SAA 7146 video decoder bus */
- #define I2C_ALGO_ACB 0x070000 /* ACCESS.bus algorithm */
--
-+#define I2C_ALGO_IIC 0x080000 /* ITE IIC bus */
-+#define I2C_ALGO_SAA7134 0x090000
-+#define I2C_ALGO_MPC824X 0x0a0000 /* Motorola 8240 / 8245 */
-+#define I2C_ALGO_IPMI 0x0b0000 /* IPMI dummy adapter */
-+#define I2C_ALGO_IPMB 0x0c0000 /* IPMB adapter */
-+#define I2C_ALGO_MPC107 0x0d0000
- #define I2C_ALGO_EC 0x100000 /* ACPI embedded controller */
-
- #define I2C_ALGO_MPC8XX 0x110000 /* MPC8xx PowerPC I2C algorithm */
--
--#define I2C_ALGO_SIBYTE 0x120000 /* Broadcom SiByte SOCs */
--
--#define I2C_ALGO_SGI 0x130000 /* SGI algorithm */
--
--#define I2C_ALGO_AU1550 0x140000 /* Alchemy Au1550 PSC */
-+#define I2C_ALGO_OCP 0x120000 /* IBM or otherwise On-chip I2C algorithm */
-+#define I2C_ALGO_BITHS 0x130000 /* enhanced bit style adapters */
-+#define I2C_ALGO_OCP_IOP3XX 0x140000 /* XSCALE IOP3XX On-chip I2C alg */
-+#define I2C_ALGO_SIBYTE 0x150000 /* Broadcom SiByte SOCs */
-+#define I2C_ALGO_SGI 0x160000 /* SGI algorithm */
-+#define I2C_ALGO_USB 0x170000 /* USB algorithm */
-
- #define I2C_ALGO_EXP 0x800000 /* experimental */
-
-@@ -184,21 +229,46 @@
- #define I2C_HW_B_I810 0x0a /* Intel I810 */
- #define I2C_HW_B_VOO 0x0b /* 3dfx Voodoo 3 / Banshee */
- #define I2C_HW_B_PPORT 0x0c /* Primitive parallel port adapter */
-+#define I2C_HW_B_SAVG 0x0d /* Savage 4 */
-+#define I2C_HW_B_SCX200 0x0e /* Nat'l Semi SCx200 I2C */
- #define I2C_HW_B_RIVA 0x10 /* Riva based graphics cards */
- #define I2C_HW_B_IOC 0x11 /* IOC bit-wiggling */
- #define I2C_HW_B_TSUNA 0x12 /* DEC Tsunami chipset */
-+#define I2C_HW_B_FRODO 0x13 /* 2d3D, Inc. SA-1110 Development Board */
-+#define I2C_HW_B_OMAHA 0x14 /* Omaha I2C interface (ARM) */
-+#define I2C_HW_B_GUIDE 0x15 /* Guide bit-basher */
-+#define I2C_HW_B_IXP2000 0x16 /* GPIO on IXP2000 systems */
-+#define I2C_HW_B_IXP425 0x17 /* GPIO on IXP425 systems */
-+#define I2C_HW_B_S3VIA 0x18 /* S3Via ProSavage adapter */
-+#define I2C_HW_B_ZR36067 0x19 /* Zoran-36057/36067 based boards */
-+#define I2C_HW_B_PCILYNX 0x1a /* TI PCILynx I2C adapter */
-
- /* --- PCF 8584 based algorithms */
- #define I2C_HW_P_LP 0x00 /* Parallel port interface */
- #define I2C_HW_P_ISA 0x01 /* generic ISA Bus inteface card */
- #define I2C_HW_P_ELEK 0x02 /* Elektor ISA Bus inteface card */
-
-+/* --- USB based adapters */
-+#define I2C_HW_USB_USBVISION 0x00
-+
- /* --- ACPI Embedded controller algorithms */
- #define I2C_HW_ACPI_EC 0x00
-
-+/* --- MPC824x PowerPC adapters */
-+#define I2C_HW_MPC824X 0x00 /* Motorola 8240 / 8245 */
-+
- /* --- MPC8xx PowerPC adapters */
- #define I2C_HW_MPC8XX_EPON 0x00 /* Eponymous MPC8xx I2C adapter */
-
-+/* --- ITE based algorithms */
-+#define I2C_HW_I_IIC 0x00 /* controller on the ITE */
-+
-+/* --- PowerPC on-chip adapters */
-+#define I2C_HW_OCP 0x00 /* IBM on-chip I2C adapter */
-+
-+/* --- XSCALE on-chip adapters */
-+#define I2C_HW_IOP321 0x00
-+
- /* --- Broadcom SiByte adapters */
- #define I2C_HW_SIBYTE 0x00
-
-@@ -206,9 +276,6 @@
- #define I2C_HW_SGI_VINO 0x00
- #define I2C_HW_SGI_MACE 0x01
-
--/* --- Au1550 PSC adapters */
--#define I2C_HW_AU1550_PSC 0x00
--
- /* --- SMBus only adapters */
- #define I2C_HW_SMBUS_PIIX4 0x00
- #define I2C_HW_SMBUS_ALI15X3 0x01
-@@ -218,9 +285,27 @@
- #define I2C_HW_SMBUS_AMD756 0x05
- #define I2C_HW_SMBUS_SIS5595 0x06
- #define I2C_HW_SMBUS_ALI1535 0x07
-+#define I2C_HW_SMBUS_SIS630 0x08
-+#define I2C_HW_SMBUS_SIS645 0x09
-+#define I2C_HW_SMBUS_AMD8111 0x0a
-+#define I2C_HW_SMBUS_SCX200 0x0b
-+#define I2C_HW_SMBUS_NFORCE2 0x0c
- #define I2C_HW_SMBUS_W9968CF 0x0d
-+#define I2C_HW_SMBUS_OV511 0x0e /* OV511(+) USB 1.1 webcam ICs */
-+#define I2C_HW_SMBUS_OV518 0x0f /* OV518(+) USB 1.1 webcam ICs */
-+#define I2C_HW_SMBUS_OV519 0x10 /* OV519 USB 1.1 webcam IC */
-+#define I2C_HW_SMBUS_OVFX2 0x11 /* Cypress/OmniVision FX2 webcam */
-
- /* --- ISA pseudo-adapter */
- #define I2C_HW_ISA 0x00
-
--#endif /* I2C_ID_H */
-+/* --- IPMI pseudo-adapter */
-+#define I2C_HW_IPMI 0x00
-+
-+/* --- IPMB adapter */
-+#define I2C_HW_IPMB 0x00
-+
-+/* --- MCP107 adapter */
-+#define I2C_HW_MPC107 0x00
-+
-+#endif /* LINUX_I2C_ID_H */
---- linux-old/drivers/i2c/i2c-pcf-epp.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-pcf-epp.c Mon Dec 13 19:26:34 2004
-@@ -0,0 +1,281 @@
-+/* ------------------------------------------------------------------------- */
-+/* i2c-pcf-epp.c i2c-hw access for PCF8584 style EPP parallel port adapters */
-+/* ------------------------------------------------------------------------- */
-+/* Copyright (C) 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 Ryosuke Tajima <rosk@jsk.t.u-tokyo.ac.jp> */
-+
-+#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/parport.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-pcf.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+
-+
-+struct i2c_pcf_epp {
-+ int pe_base;
-+ int pe_irq;
-+ int pe_clock;
-+ int pe_own;
-+} ;
-+
-+#define DEFAULT_BASE 0x378
-+#define DEFAULT_IRQ 7
-+#define DEFAULT_CLOCK 0x1c
-+#define DEFAULT_OWN 0x55
-+
-+static int base = 0;
-+static int irq = 0;
-+static int clock = 0;
-+static int own = 0;
-+static int i2c_debug=0;
-+static struct i2c_pcf_epp gpe;
-+static wait_queue_head_t pcf_wait;
-+static int pcf_pending;
-+static spinlock_t irq_driver_lock = SPIN_LOCK_UNLOCKED;
-+
-+/* ----- global defines ----------------------------------------------- */
-+#define DEB(x) if (i2c_debug>=1) x
-+#define DEB2(x) if (i2c_debug>=2) x
-+#define DEB3(x) if (i2c_debug>=3) x
-+#define DEBE(x) x /* error messages */
-+
-+/* --- Convenience defines for the EPP/SPP port: */
-+#define BASE ((struct i2c_pcf_epp *)(data))->pe_base
-+// #define DATA BASE /* SPP data port */
-+#define STAT (BASE+1) /* SPP status port */
-+#define CTRL (BASE+2) /* SPP control port */
-+#define EADD (BASE+3) /* EPP address port */
-+#define EDAT (BASE+4) /* EPP data port */
-+
-+/* ----- local functions ---------------------------------------------- */
-+
-+static void pcf_epp_setbyte(void *data, int ctl, int val)
-+{
-+ if (ctl) {
-+ if (gpe.pe_irq > 0) {
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write control 0x%x\n",
-+ val|I2C_PCF_ENI));
-+ // set A0 pin HIGH
-+ outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL);
-+ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: CTRL port = 0x%x\n", inb(CTRL)));
-+ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: STAT port = 0x%x\n", inb(STAT)));
-+
-+ // EPP write data cycle
-+ outb(val | I2C_PCF_ENI, EDAT);
-+ } else {
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write control 0x%x\n", val));
-+ // set A0 pin HIGH
-+ outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL);
-+ outb(val, CTRL);
-+ }
-+ } else {
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write data 0x%x\n", val));
-+ // set A0 pin LO
-+ outb(inb(CTRL) & ~PARPORT_CONTROL_INIT, CTRL);
-+ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: CTRL port = 0x%x\n", inb(CTRL)));
-+ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: STAT port = 0x%x\n", inb(STAT)));
-+ outb(val, EDAT);
-+ }
-+}
-+
-+static int pcf_epp_getbyte(void *data, int ctl)
-+{
-+ int val;
-+
-+ if (ctl) {
-+ // set A0 pin HIGH
-+ outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL);
-+ val = inb(EDAT);
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Read control 0x%x\n", val));
-+ } else {
-+ // set A0 pin LOW
-+ outb(inb(CTRL) & ~PARPORT_CONTROL_INIT, CTRL);
-+ val = inb(EDAT);
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Read data 0x%x\n", val));
-+ }
-+ return (val);
-+}
-+
-+static int pcf_epp_getown(void *data)
-+{
-+ return (gpe.pe_own);
-+}
-+
-+
-+static int pcf_epp_getclock(void *data)
-+{
-+ return (gpe.pe_clock);
-+}
-+
-+#if 0
-+static void pcf_epp_sleep(unsigned long timeout)
-+{
-+ schedule_timeout( timeout * HZ);
-+}
-+#endif
-+
-+static void pcf_epp_waitforpin(void) {
-+ int timeout = 10;
-+
-+ if (gpe.pe_irq > 0) {
-+ spin_lock_irq(&irq_driver_lock);
-+ if (pcf_pending == 0) {
-+ interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ);
-+ //udelay(100);
-+ } else {
-+ pcf_pending = 0;
-+ }
-+ spin_unlock_irq(&irq_driver_lock);
-+ } else {
-+ udelay(100);
-+ }
-+}
-+
-+static void pcf_epp_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
-+ pcf_pending = 1;
-+ wake_up_interruptible(&pcf_wait);
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: in interrupt handler.\n"));
-+}
-+
-+
-+static int pcf_epp_init(void *data)
-+{
-+ if (check_region(gpe.pe_base, 5) < 0 ) {
-+
-+ printk(KERN_WARNING "Could not request port region with base 0x%x\n", gpe.pe_base);
-+ return -ENODEV;
-+ } else {
-+ request_region(gpe.pe_base, 5, "i2c (EPP parallel port adapter)");
-+ }
-+
-+ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: init status port = 0x%x\n", inb(0x379)));
-+
-+ if (gpe.pe_irq > 0) {
-+ if (request_irq(gpe.pe_irq, pcf_epp_handler, 0, "PCF8584", 0) < 0) {
-+ printk(KERN_NOTICE "i2c-pcf-epp.o: Request irq%d failed\n", gpe.pe_irq);
-+ gpe.pe_irq = 0;
-+ } else
-+ disable_irq(gpe.pe_irq);
-+ enable_irq(gpe.pe_irq);
-+ }
-+ // EPP mode initialize
-+ // enable interrupt from nINTR pin
-+ outb(inb(CTRL)|0x14, CTRL);
-+ // clear ERROR bit of STAT
-+ outb(inb(STAT)|0x01, STAT);
-+ outb(inb(STAT)&~0x01,STAT);
-+
-+ return 0;
-+}
-+
-+/* ------------------------------------------------------------------------
-+ * 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_pcf_data pcf_epp_data = {
-+ .setpcf = pcf_epp_setbyte,
-+ .getpcf = pcf_epp_getbyte,
-+ .getown = pcf_epp_getown,
-+ .getclock = pcf_epp_getclock,
-+ .waitforpin = pcf_epp_waitforpin,
-+ .udelay = 80,
-+ .mdelay = 80,
-+ .timeout = HZ,
-+};
-+
-+static struct i2c_adapter pcf_epp_ops = {
-+ .owner = THIS_MODULE,
-+ .name = "PCF8584 EPP adapter",
-+ .id = I2C_HW_P_LP,
-+ .algo_data = &pcf_epp_data,
-+};
-+
-+static int __init i2c_pcfepp_init(void)
-+{
-+ struct i2c_pcf_epp *pepp = &gpe;
-+
-+ printk(KERN_DEBUG "i2c-pcf-epp.o: i2c pcf8584-epp adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-+ if (base == 0)
-+ pepp->pe_base = DEFAULT_BASE;
-+ else
-+ pepp->pe_base = base;
-+
-+ if (irq == 0)
-+ pepp->pe_irq = DEFAULT_IRQ;
-+ else if (irq<0) {
-+ // switch off irq
-+ pepp->pe_irq=0;
-+ } else {
-+ pepp->pe_irq = irq;
-+ }
-+ if (clock == 0)
-+ pepp->pe_clock = DEFAULT_CLOCK;
-+ else
-+ pepp->pe_clock = clock;
-+
-+ if (own == 0)
-+ pepp->pe_own = DEFAULT_OWN;
-+ else
-+ pepp->pe_own = own;
-+
-+ pcf_epp_data.data = (void *)pepp;
-+ init_waitqueue_head(&pcf_wait);
-+ if (pcf_epp_init(pepp) == 0) {
-+ int ret;
-+ if ( (ret = i2c_pcf_add_bus(&pcf_epp_ops)) < 0) {
-+ printk(KERN_WARNING "i2c_pcf_add_bus caused an error: %d\n",ret);
-+ release_region(pepp->pe_base , 5);
-+ return ret;
-+ }
-+ } else {
-+
-+ return -ENODEV;
-+ }
-+ printk(KERN_DEBUG "i2c-pcf-epp.o: found device at %#x.\n", pepp->pe_base);
-+ return 0;
-+}
-+
-+static void __exit pcf_epp_exit(void)
-+{
-+ i2c_pcf_del_bus(&pcf_epp_ops);
-+ if (gpe.pe_irq > 0) {
-+ disable_irq(gpe.pe_irq);
-+ free_irq(gpe.pe_irq, 0);
-+ }
-+ release_region(gpe.pe_base , 5);
-+}
-+
-+MODULE_AUTHOR("Hans Berglund <hb@spacetec.no> \n modified by Ryosuke Tajima <rosk@jsk.t.u-tokyo.ac.jp>");
-+MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 EPP parallel port adapter");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(base, "i");
-+MODULE_PARM(irq, "i");
-+MODULE_PARM(clock, "i");
-+MODULE_PARM(own, "i");
-+MODULE_PARM(i2c_debug, "i");
-+
-+module_init(i2c_pcfepp_init);
-+module_exit(pcf_epp_exit);
---- linux-old/include/linux/i2c-pcf8584.h Thu Jan 1 00:00:00 1970
-+++ linux/include/linux/i2c-pcf8584.h Mon Dec 13 19:26:34 2004
-@@ -0,0 +1,78 @@
-+/* -------------------------------------------------------------------- */
-+/* i2c-pcf8584.h: PCF 8584 global defines */
-+/* -------------------------------------------------------------------- */
-+/* Copyright (C) 1996 Simon G. Vogl
-+ 1999 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 Frodo Looijaard <frodol@dds.nl> */
-+
-+/* $Id: i2c-pcf8584.h,v 1.6 2003/07/25 07:56:42 khali Exp $ */
-+
-+#ifndef _LINUX_I2C_PCF8584_H
-+#define _LINUX_I2C_PCF8584_H
-+
-+/* ----- Control register bits ---------------------------------------- */
-+#define I2C_PCF_PIN 0x80
-+#define I2C_PCF_ESO 0x40
-+#define I2C_PCF_ES1 0x20
-+#define I2C_PCF_ES2 0x10
-+#define I2C_PCF_ENI 0x08
-+#define I2C_PCF_STA 0x04
-+#define I2C_PCF_STO 0x02
-+#define I2C_PCF_ACK 0x01
-+
-+#define I2C_PCF_START (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK)
-+#define I2C_PCF_STOP (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STO | I2C_PCF_ACK)
-+#define I2C_PCF_REPSTART ( I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK)
-+#define I2C_PCF_IDLE (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ACK)
-+
-+/* ----- Status register bits ----------------------------------------- */
-+/*#define I2C_PCF_PIN 0x80 as above*/
-+
-+#define I2C_PCF_INI 0x40 /* 1 if not initialized */
-+#define I2C_PCF_STS 0x20
-+#define I2C_PCF_BER 0x10
-+#define I2C_PCF_AD0 0x08
-+#define I2C_PCF_LRB 0x08
-+#define I2C_PCF_AAS 0x04
-+#define I2C_PCF_LAB 0x02
-+#define I2C_PCF_BB 0x01
-+
-+/* ----- Chip clock frequencies --------------------------------------- */
-+#define I2C_PCF_CLK3 0x00
-+#define I2C_PCF_CLK443 0x10
-+#define I2C_PCF_CLK6 0x14
-+#define I2C_PCF_CLK 0x18
-+#define I2C_PCF_CLK12 0x1c
-+
-+/* ----- transmission frequencies ------------------------------------- */
-+#define I2C_PCF_TRNS90 0x00 /* 90 kHz */
-+#define I2C_PCF_TRNS45 0x01 /* 45 kHz */
-+#define I2C_PCF_TRNS11 0x02 /* 11 kHz */
-+#define I2C_PCF_TRNS15 0x03 /* 1.5 kHz */
-+
-+
-+/* ----- Access to internal registers according to ES1,ES2 ------------ */
-+/* they are mapped to the data port ( a0 = 0 ) */
-+/* available when ESO == 0 : */
-+
-+#define I2C_PCF_OWNADR 0
-+#define I2C_PCF_INTREG I2C_PCF_ES2
-+#define I2C_PCF_CLKREG I2C_PCF_ES1
-+
-+#endif /* _LINUX_I2C_PCF8584_H */
---- linux-old/drivers/i2c/i2c-philips-par.c Fri Feb 20 01:22:16 2004
-+++ linux/drivers/i2c/i2c-philips-par.c Mon Dec 13 19:26:34 2004
-@@ -21,7 +21,7 @@
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
- Frodo Looijaard <frodol@dds.nl> */
-
--/* $Id: i2c-philips-par.c,v 1.18 2000/07/06 19:21:49 frodo Exp $ */
-+/* $Id: i2c-philips-par.c,v 1.33 2004/01/23 20:22:53 khali Exp $ */
-
- #include <linux/kernel.h>
- #include <linux/ioport.h>
-@@ -29,14 +29,10 @@
- #include <linux/init.h>
- #include <linux/stddef.h>
- #include <linux/parport.h>
--
-+#include <linux/slab.h>
- #include <linux/i2c.h>
- #include <linux/i2c-algo-bit.h>
-
--#ifndef __exit
--#define __exit __init
--#endif
--
- static int type;
-
- struct i2c_par
-@@ -130,59 +126,34 @@
- PARPORT_STATUS_BUSY) ? 0 : 1;
- }
-
--static int bit_lp_reg(struct i2c_client *client)
--{
-- return 0;
--}
--
--static int bit_lp_unreg(struct i2c_client *client)
--{
-- return 0;
--}
--
--static void bit_lp_inc_use(struct i2c_adapter *adap)
--{
-- MOD_INC_USE_COUNT;
--}
--
--static void bit_lp_dec_use(struct i2c_adapter *adap)
--{
-- MOD_DEC_USE_COUNT;
--}
--
- /* ------------------------------------------------------------------------
- * 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_bit_data bit_lp_data = {
-- NULL,
-- bit_lp_setsda,
-- bit_lp_setscl,
-- bit_lp_getsda,
-- bit_lp_getscl,
-- 80, 80, 100, /* waits, timeout */
-+ .setsda = bit_lp_setsda,
-+ .setscl = bit_lp_setscl,
-+ .getsda = bit_lp_getsda,
-+ .getscl = bit_lp_getscl,
-+ .udelay = 80,
-+ .mdelay = 80,
-+ .timeout = HZ
- };
-
- static struct i2c_algo_bit_data bit_lp_data2 = {
-- NULL,
-- bit_lp_setsda2,
-- bit_lp_setscl2,
-- bit_lp_getsda2,
-- NULL,
-- 80, 80, 100, /* waits, timeout */
-+ .setsda = bit_lp_setsda2,
-+ .setscl = bit_lp_setscl2,
-+ .getsda = bit_lp_getsda2,
-+ .udelay = 80,
-+ .mdelay = 80,
-+ .timeout = HZ
- };
-
- static struct i2c_adapter bit_lp_ops = {
-- "Philips Parallel port adapter",
-- I2C_HW_B_LP,
-- NULL,
-- NULL,
-- bit_lp_inc_use,
-- bit_lp_dec_use,
-- bit_lp_reg,
--
-- bit_lp_unreg,
-+ .owner = THIS_MODULE,
-+ .name = "Philips Parallel port adapter",
-+ .id = I2C_HW_B_LP,
- };
-
- static void i2c_parport_attach (struct parport *port)
-@@ -202,6 +173,7 @@
- NULL);
- if (!adapter->pdev) {
- printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
-+ kfree(adapter);
- return;
- }
-
-@@ -210,8 +182,12 @@
- adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data;
- adapter->bit_lp_data.data = port;
-
-+ if (parport_claim_or_block(adapter->pdev) < 0 ) {
-+ printk(KERN_ERR "i2c-philips-par: Could not claim parallel port.\n");
-+ kfree(adapter);
-+ return;
-+ }
- /* reset hardware to sane state */
-- parport_claim_or_block(adapter->pdev);
- adapter->bit_lp_data.setsda(port, 1);
- adapter->bit_lp_data.setscl(port, 1);
- parport_release(adapter->pdev);
-@@ -257,7 +233,7 @@
- NULL
- };
-
--int __init i2c_bitlp_init(void)
-+static int __init i2c_bitlp_init(void)
- {
- printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-@@ -266,7 +242,7 @@
- return 0;
- }
-
--void __exit i2c_bitlp_exit(void)
-+static void __exit i2c_bitlp_exit(void)
- {
- parport_unregister_driver(&i2c_driver);
- }
-@@ -279,14 +255,5 @@
-
- MODULE_PARM(type, "i");
-
--#ifdef MODULE
--int init_module(void)
--{
-- return i2c_bitlp_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_bitlp_exit();
--}
--#endif
-+module_init(i2c_bitlp_init);
-+module_exit(i2c_bitlp_exit);
---- linux-old/drivers/i2c/i2c-pport.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-pport.c Mon Dec 13 19:26:34 2004
-@@ -0,0 +1,169 @@
-+/* ------------------------------------------------------------------------- */
-+/* i2c-pport.c i2c-hw access for primitive i2c par. port adapter */
-+/* ------------------------------------------------------------------------- */
-+/* Copyright (C) 2001 Daniel Smolik
-+
-+ 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. */
-+/* ------------------------------------------------------------------------- */
-+
-+/*
-+ See doc/i2c-pport for instructions on wiring to the
-+ parallel port connector.
-+
-+ Cut & paste :-) based on Velleman K8000 driver by Simon G. Vogl
-+
-+ Note that SDA is hardware inverted.
-+*/
-+
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/ioport.h>
-+#include <linux/errno.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+#include <asm/io.h>
-+
-+
-+#define DEFAULT_BASE 0x378
-+static int base = DEFAULT_BASE;
-+static unsigned char PortData = 0;
-+
-+/* ----- global defines ----------------------------------------------- */
-+#define DEB(x) /* should be reasonable open, close &c. */
-+#define DEB2(x) /* low level debugging - very slow */
-+#define DEBE(x) x /* error messages */
-+#define DEBINIT(x) x /* detection status messages */
-+
-+/* --- Convenience defines for the parallel port: */
-+#define BASE (unsigned int)(data)
-+#define DATA BASE /* Centronics data port */
-+#define STAT (BASE+1) /* Centronics status port */
-+#define CTRL (BASE+2) /* Centronics control port */
-+
-+/* we will use SDA - Auto Linefeed(14) POUT (ctrl bit 1) */
-+/* we will use SCL - Initialize printer(16) BUSY (ctrl bit 2) */
-+
-+#define SET_SCL | 0x04
-+#define CLR_SCL & 0xFB
-+
-+#define SET_SDA & 0xFD
-+#define CLR_SDA | 0x02
-+
-+
-+/* ----- local functions ---------------------------------------------- */
-+
-+
-+static void bit_pport_setscl(void *data, int state)
-+{
-+ if (state) {
-+ PortData = PortData SET_SCL;
-+ } else {
-+ PortData = PortData CLR_SCL;
-+ }
-+ outb(PortData, CTRL);
-+}
-+
-+static void bit_pport_setsda(void *data, int state)
-+{
-+ if (state) {
-+ PortData = PortData SET_SDA;
-+ } else {
-+ PortData = PortData CLR_SDA;
-+ }
-+ outb(PortData, CTRL);
-+}
-+
-+static int bit_pport_getscl(void *data)
-+{
-+ return ( 4 == ( (inb_p(CTRL)) & 0x04 ) );
-+}
-+
-+static int bit_pport_getsda(void *data)
-+{
-+ return ( 0 == ( (inb_p(CTRL)) & 0x02 ) );
-+}
-+
-+static int bit_pport_init(void)
-+{
-+ if (!request_region((base+2),1, "i2c (PPORT adapter)")) {
-+ return -ENODEV;
-+ }
-+
-+ PortData = inb(base+2);
-+ bit_pport_setsda((void*)base, 1);
-+ bit_pport_setscl((void*)base, 1);
-+
-+ return 0;
-+}
-+
-+
-+/* ------------------------------------------------------------------------
-+ * 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_bit_data bit_pport_data = {
-+ .setsda = bit_pport_setsda,
-+ .setscl = bit_pport_setscl,
-+ .getsda = bit_pport_getsda,
-+ .getscl = bit_pport_getscl,
-+ .udelay = 40,
-+ .mdelay = 80,
-+ .timeout = HZ
-+};
-+
-+static struct i2c_adapter bit_pport_ops = {
-+ .owner = THIS_MODULE,
-+ .name = "Primitive Parallel port adaptor",
-+ .id = I2C_HW_B_PPORT,
-+ .algo_data = &bit_pport_data,
-+};
-+
-+static int __init i2c_bitpport_init(void)
-+{
-+ printk("i2c-pport.o: i2c Primitive parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-+
-+ bit_pport_data.data = (void*)base;
-+ if (bit_pport_init() < 0)
-+ return -ENODEV;
-+
-+ if (i2c_bit_add_bus(&bit_pport_ops) < 0) {
-+ release_region(base+2, 1);
-+ return -ENODEV;
-+ }
-+
-+ printk("i2c-pport.o: found device at %#x.\n",base);
-+ return 0;
-+}
-+
-+static void __exit i2c_bitpport_exit(void)
-+{
-+ i2c_bit_del_bus(&bit_pport_ops);
-+ release_region((base+2),1);
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("Daniel Smolik <marvin@sitour.cz>");
-+MODULE_DESCRIPTION("I2C-Bus adapter routines for Primitive parallel port adapter");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(base, "i");
-+
-+module_init(i2c_bitpport_init);
-+module_exit(i2c_bitpport_exit);
---- linux-old/drivers/i2c/i2c-proc.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-proc.c Mon Dec 13 19:26:35 2004
-@@ -23,29 +23,26 @@
- This driver puts entries in /proc/sys/dev/sensors for each I2C device
- */
-
-+#include <linux/config.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/ctype.h>
- #include <linux/sysctl.h>
- #include <linux/proc_fs.h>
-+#include <linux/init.h>
- #include <linux/ioport.h>
--#include <asm/uaccess.h>
--
- #include <linux/i2c.h>
- #include <linux/i2c-proc.h>
-+#include <asm/uaccess.h>
-
--#include <linux/init.h>
--
--#ifndef THIS_MODULE
--#define THIS_MODULE NULL
-+#ifndef CONFIG_SYSCTL
-+#error Your kernel lacks sysctl support (CONFIG_SYSCTL)!
- #endif
-
--static int i2c_create_name(char **name, const char *prefix,
-- struct i2c_adapter *adapter, int addr);
- static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
- long *results, int magnitude);
--static int i2c_write_reals(int nrels, void *buffer, int *bufsize,
-+static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
- long *results, int magnitude);
- static int i2c_proc_chips(ctl_table * ctl, int write,
- struct file *filp, void *buffer,
-@@ -55,22 +52,10 @@
- void *newval, size_t newlen,
- void **context);
-
--int __init sensors_init(void);
--
- #define SENSORS_ENTRY_MAX 20
- static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
-
- static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX];
--static unsigned short i2c_inodes[SENSORS_ENTRY_MAX];
--
--static ctl_table sysctl_table[] = {
-- {CTL_DEV, "dev", NULL, 0, 0555},
-- {0},
-- {DEV_SENSORS, "sensors", NULL, 0, 0555},
-- {0},
-- {0, NULL, NULL, 0, 0555},
-- {0}
--};
-
- static ctl_table i2c_proc_dev_sensors[] = {
- {SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips,
-@@ -91,31 +76,45 @@
-
-
- static struct ctl_table_header *i2c_proc_header;
--static int i2c_initialized;
-
- /* This returns a nice name for a new directory; for example lm78-isa-0310
- (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
- a LM75 chip on the third i2c bus at address 0x4e).
- name is allocated first. */
--int i2c_create_name(char **name, const char *prefix,
-- struct i2c_adapter *adapter, int addr)
-+static char *generate_name(struct i2c_client *client, const char *prefix)
- {
-- char name_buffer[50];
-- int id;
-- if (i2c_is_isa_adapter(adapter))
-+ struct i2c_adapter *adapter = client->adapter;
-+ int addr = client->addr;
-+ char name_buffer[50], *name;
-+
-+ if (i2c_is_isa_adapter(adapter)) {
- sprintf(name_buffer, "%s-isa-%04x", prefix, addr);
-- else {
-- if ((id = i2c_adapter_id(adapter)) < 0)
-- return -ENOENT;
-+ } else if (adapter->algo->smbus_xfer || adapter->algo->master_xfer) {
-+ int id = i2c_adapter_id(adapter);
-+ if (id < 0)
-+ return ERR_PTR(-ENOENT);
- sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
-+ } else { /* dummy adapter, generate prefix */
-+ int end, i;
-+
-+ sprintf(name_buffer, "%s-", prefix);
-+ end = strlen(name_buffer);
-+
-+ for (i = 0; i < 32; i++) {
-+ if (adapter->algo->name[i] == ' ')
-+ break;
-+ name_buffer[end++] = tolower(adapter->algo->name[i]);
-+ }
-+
-+ name_buffer[end] = 0;
-+ sprintf(name_buffer + end, "-%04x", addr);
- }
-- *name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
-- if (!*name) {
-- printk (KERN_WARNING "i2c_create_name: not enough memory\n");
-- return -ENOMEM;
-- }
-- strcpy(*name, name_buffer);
-- return 0;
-+
-+ name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
-+ if (!name)
-+ return ERR_PTR(-ENOMEM);
-+ strcpy(name, name_buffer);
-+ return name;
- }
-
- /* This rather complex function must be called when you want to add an entry
-@@ -124,139 +123,91 @@
- ctl_template should be a template of the newly created directory. It is
- copied in memory. The extra2 field of each file is set to point to client.
- If any driver wants subdirectories within the newly created directory,
-- this function must be updated!
-- controlling_mod is the controlling module. It should usually be
-- THIS_MODULE when calling. Note that this symbol is not defined in
-- kernels before 2.3.13; define it to NULL in that case. We will not use it
-- for anything older than 2.3.27 anyway. */
-+ this function must be updated! */
- int i2c_register_entry(struct i2c_client *client, const char *prefix,
-- ctl_table * ctl_template,
-- struct module *controlling_mod)
-+ struct ctl_table *ctl_template)
- {
-- int i, res, len, id;
-- ctl_table *new_table;
-- char *name;
-- struct ctl_table_header *new_header;
--
-- if ((res = i2c_create_name(&name, prefix, client->adapter,
-- client->addr))) return res;
-+ struct { struct ctl_table root[2], dev[2], sensors[2]; } *tbl;
-+ struct ctl_table_header *hdr;
-+ struct ctl_table *tmp, *leaf;
-+ const char *name;
-+ int id, len = 0;
-
-- for (id = 0; id < SENSORS_ENTRY_MAX; id++)
-- if (!i2c_entries[id]) {
-- break;
-- }
-- if (id == SENSORS_ENTRY_MAX) {
-- kfree(name);
-- return -ENOMEM;
-- }
-- id += 256;
-+ name = generate_name(client, prefix);
-+ if (IS_ERR(name))
-+ return PTR_ERR(name);
-
-- len = 0;
-- while (ctl_template[len].procname)
-- len++;
-- len += 7;
-- if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
-- kfree(name);
-- return -ENOMEM;
-- }
--
-- memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table));
-- new_table[0].child = &new_table[2];
-- new_table[2].child = &new_table[4];
-- new_table[4].child = &new_table[6];
-- new_table[4].procname = name;
-- new_table[4].ctl_name = id;
-- memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table));
-- for (i = 6; i < len; i++)
-- new_table[i].extra2 = client;
--
-- if (!(new_header = register_sysctl_table(new_table, 0))) {
-- kfree(new_table);
-- kfree(name);
-- return -ENOMEM;
-+ for (id = 0; id < SENSORS_ENTRY_MAX; id++) {
-+ if (!i2c_entries[id])
-+ goto free_slot;
- }
-
-- i2c_entries[id - 256] = new_header;
-+ goto out_free_name;
-
-- i2c_clients[id - 256] = client;
--#ifdef DEBUG
-- if (!new_header || !new_header->ctl_table ||
-- !new_header->ctl_table->child ||
-- !new_header->ctl_table->child->child ||
-- !new_header->ctl_table->child->child->de) {
-- printk
-- ("i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n");
-- return id;
-- }
--#endif /* DEBUG */
-- i2c_inodes[id - 256] =
-- new_header->ctl_table->child->child->de->low_ino;
-- new_header->ctl_table->child->child->de->owner = controlling_mod;
--
-- return id;
-+ free_slot:
-+ while (ctl_template[len].ctl_name)
-+ len++;
-+ tbl = kmalloc(sizeof(*tbl) + sizeof(ctl_table) * (len + 1),
-+ GFP_KERNEL);
-+ if (!tbl)
-+ goto out_free_name;
-+ memset(tbl, 0, sizeof(*tbl));
-+
-+ /* The client sysctls */
-+ leaf = (struct ctl_table *) (tbl + 1);
-+ memcpy(leaf, ctl_template, sizeof(ctl_table) * (len+1));
-+ for (tmp = leaf; tmp->ctl_name; tmp++)
-+ tmp->extra2 = client;
-+
-+ tbl->sensors->ctl_name = id+256;
-+ tbl->sensors->procname = name;
-+ tbl->sensors->mode = 0555;
-+ tbl->sensors->child = leaf;
-+
-+ tbl->dev->ctl_name = DEV_SENSORS;
-+ tbl->dev->procname = "sensors";
-+ tbl->dev->mode = 0555;
-+ tbl->dev->child = tbl->sensors;
-+
-+ tbl->root->ctl_name = CTL_DEV;
-+ tbl->root->procname = "dev";
-+ tbl->root->mode = 0555;
-+ tbl->root->child = tbl->dev;
-+
-+ hdr = register_sysctl_table(tbl->root, 0);
-+ if (!hdr)
-+ goto out_free_tbl;
-+
-+ i2c_entries[id] = hdr;
-+ i2c_clients[id] = client;
-+
-+ return (id + 256); /* XXX(hch) why?? */
-+
-+ out_free_tbl:
-+ kfree(tbl);
-+ out_free_name:
-+ kfree(name);
-+ return -ENOMEM;
- }
-
- void i2c_deregister_entry(int id)
- {
-- ctl_table *table;
-- char *temp;
- id -= 256;
-- if (i2c_entries[id]) {
-- table = i2c_entries[id]->ctl_table;
-- unregister_sysctl_table(i2c_entries[id]);
-- /* 2-step kfree needed to keep gcc happy about const points */
-- (const char *) temp = table[4].procname;
-- kfree(temp);
-- kfree(table);
-- i2c_entries[id] = NULL;
-- i2c_clients[id] = NULL;
-- }
--}
-
--/* Monitor access for /proc/sys/dev/sensors; make unloading i2c-proc.o
-- impossible if some process still uses it or some file in it */
--void i2c_fill_inode(struct inode *inode, int fill)
--{
-- if (fill)
-- MOD_INC_USE_COUNT;
-- else
-- MOD_DEC_USE_COUNT;
--}
--
--/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading
-- the corresponding module impossible if some process still uses it or
-- some file in it */
--void i2c_dir_fill_inode(struct inode *inode, int fill)
--{
-- int i;
-- struct i2c_client *client;
-+ if (i2c_entries[id]) {
-+ struct ctl_table_header *hdr = i2c_entries[id];
-+ struct ctl_table *tbl = hdr->ctl_table;
-
--#ifdef DEBUG
-- if (!inode) {
-- printk("i2c-proc.o: Warning: inode NULL in fill_inode()\n");
-- return;
-+ unregister_sysctl_table(hdr);
-+ kfree(tbl->child->child->procname);
-+ kfree(tbl); /* actually the whole anonymous struct */
- }
--#endif /* def DEBUG */
-
-- for (i = 0; i < SENSORS_ENTRY_MAX; i++)
-- if (i2c_clients[i]
-- && (i2c_inodes[i] == inode->i_ino)) break;
--#ifdef DEBUG
-- if (i == SENSORS_ENTRY_MAX) {
-- printk
-- ("i2c-proc.o: Warning: inode (%ld) not found in fill_inode()\n",
-- inode->i_ino);
-- return;
-- }
--#endif /* def DEBUG */
-- client = i2c_clients[i];
-- if (fill)
-- client->driver->inc_use(client);
-- else
-- client->driver->dec_use(client);
-+ i2c_entries[id] = NULL;
-+ i2c_clients[id] = NULL;
- }
-
--int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
-+static int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
- void *buffer, size_t * lenp)
- {
- char BUF[SENSORS_PREFIX_MAX + 30];
-@@ -294,7 +245,7 @@
- return 0;
- }
-
--int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
-+static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
- void *oldval, size_t * oldlenp, void *newval,
- size_t newlen, void **context)
- {
-@@ -456,7 +407,7 @@
- WARNING! This is tricky code. I have tested it, but there may still be
- hidden bugs in it, even leading to crashes and things!
- */
--int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
-+static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
- long *results, int magnitude)
- {
- int maxels, min, mag;
-@@ -557,7 +508,7 @@
- return 0;
- }
-
--int i2c_write_reals(int nrels, void *buffer, int *bufsize,
-+static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
- long *results, int magnitude)
- {
- #define BUFLEN 20
-@@ -646,6 +597,7 @@
- I2C_FUNC_SMBUS_QUICK)) return -1;
-
- for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
-+ /* XXX: WTF is going on here??? */
- if ((is_isa && check_region(addr, 1)) ||
- (!is_isa && i2c_check_addr(adapter, addr)))
- continue;
-@@ -846,46 +798,33 @@
- return 0;
- }
-
--int __init sensors_init(void)
-+static int __init i2c_proc_init(void)
- {
- printk(KERN_INFO "i2c-proc.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
-- i2c_initialized = 0;
- if (!
- (i2c_proc_header =
-- register_sysctl_table(i2c_proc, 0))) return -ENOMEM;
-+ register_sysctl_table(i2c_proc, 0))) {
-+ printk(KERN_ERR "i2c-proc.o: error: sysctl interface not supported by kernel!\n");
-+ return -EPERM;
-+ }
- i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE;
-- i2c_initialized++;
- return 0;
- }
-
-+static void __exit i2c_proc_exit(void)
-+{
-+ unregister_sysctl_table(i2c_proc_header);
-+}
-+
-+EXPORT_SYMBOL(i2c_register_entry);
- EXPORT_SYMBOL(i2c_deregister_entry);
--EXPORT_SYMBOL(i2c_detect);
- EXPORT_SYMBOL(i2c_proc_real);
--EXPORT_SYMBOL(i2c_register_entry);
- EXPORT_SYMBOL(i2c_sysctl_real);
--
--#ifdef MODULE
-+EXPORT_SYMBOL(i2c_detect);
-
- MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
- MODULE_DESCRIPTION("i2c-proc driver");
- MODULE_LICENSE("GPL");
-
--int i2c_cleanup(void)
--{
-- if (i2c_initialized >= 1) {
-- unregister_sysctl_table(i2c_proc_header);
-- i2c_initialized--;
-- }
-- return 0;
--}
--
--int init_module(void)
--{
-- return sensors_init();
--}
--
--int cleanup_module(void)
--{
-- return i2c_cleanup();
--}
--#endif /* MODULE */
-+module_init(i2c_proc_init);
-+module_exit(i2c_proc_exit);
---- linux-old/include/linux/i2c-proc.h Tue Nov 6 00:55:29 2001
-+++ linux/include/linux/i2c-proc.h Mon Dec 13 19:26:36 2004
-@@ -1,6 +1,7 @@
- /*
-- sensors.h - Part of lm_sensors, Linux kernel modules for hardware
-- monitoring
-+ i2c-proc.h - Part of the i2c package
-+ was originally sensors.h - Part of lm_sensors, Linux kernel modules
-+ for hardware monitoring
- Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
-
- This program is free software; you can redistribute it and/or modify
-@@ -18,14 +19,9 @@
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
--#ifndef SENSORS_SENSORS_H
--#define SENSORS_SENSORS_H
-+#ifndef _LINUX_I2C_PROC_H
-+#define _LINUX_I2C_PROC_H
-
--#ifdef __KERNEL__
--
--/* Next two must be included before sysctl.h can be included, in 2.0 kernels */
--#include <linux/types.h>
--#include <linux/fs.h>
- #include <linux/sysctl.h>
-
- /* The type of callback functions used in sensors_{proc,sysctl}_real */
-@@ -73,8 +69,7 @@
- these functions must be updated! */
- extern int i2c_register_entry(struct i2c_client *client,
- const char *prefix,
-- ctl_table * ctl_template,
-- struct module *controlling_mod);
-+ ctl_table * ctl_template);
-
- extern void i2c_deregister_entry(int id);
-
-@@ -347,6 +342,31 @@
- {NULL}}; \
- SENSORS_INSMOD
-
-+#define SENSORS_INSMOD_8(chip1,chip2,chip3,chip4,chip5,chip6,chip7,chip8) \
-+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8 }; \
-+ SENSORS_MODULE_PARM(force, \
-+ "List of adapter,address pairs to boldly assume " \
-+ "to be present"); \
-+ SENSORS_MODULE_PARM_FORCE(chip1); \
-+ SENSORS_MODULE_PARM_FORCE(chip2); \
-+ SENSORS_MODULE_PARM_FORCE(chip3); \
-+ SENSORS_MODULE_PARM_FORCE(chip4); \
-+ SENSORS_MODULE_PARM_FORCE(chip5); \
-+ SENSORS_MODULE_PARM_FORCE(chip6); \
-+ SENSORS_MODULE_PARM_FORCE(chip7); \
-+ SENSORS_MODULE_PARM_FORCE(chip8); \
-+ static struct i2c_force_data forces[] = {{force,any_chip}, \
-+ {force_ ## chip1,chip1}, \
-+ {force_ ## chip2,chip2}, \
-+ {force_ ## chip3,chip3}, \
-+ {force_ ## chip4,chip4}, \
-+ {force_ ## chip5,chip5}, \
-+ {force_ ## chip6,chip6}, \
-+ {force_ ## chip7,chip7}, \
-+ {force_ ## chip8,chip8}, \
-+ {NULL}}; \
-+ SENSORS_INSMOD
-+
- typedef int i2c_found_addr_proc(struct i2c_adapter *adapter,
- int addr, unsigned short flags,
- int kind);
-@@ -362,7 +382,7 @@
-
- /* This macro is used to scale user-input to sensible values in almost all
- chip drivers. */
--extern inline int SENSORS_LIMIT(long value, long low, long high)
-+static inline int SENSORS_LIMIT(long value, long low, long high)
- {
- if (value < low)
- return low;
-@@ -372,8 +392,6 @@
- return value;
- }
-
--#endif /* def __KERNEL__ */
--
-
- /* The maximum length of the prefix */
- #define SENSORS_PREFIX_MAX 20
-@@ -392,5 +410,5 @@
- char name[SENSORS_PREFIX_MAX + 13];
- };
-
--#endif /* def SENSORS_SENSORS_H */
-+#endif /* def _LINUX_I2C_PROC_H */
-
---- linux-old/drivers/i2c/i2c-rpx.c Thu Jan 1 00:00:00 1970
-+++ linux/drivers/i2c/i2c-rpx.c Mon Dec 13 19:26:36 2004
-@@ -0,0 +1,101 @@
-+/*
-+ * Embedded Planet RPX Lite MPC8xx CPM I2C interface.
-+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
-+ *
-+ * moved into proper i2c interface;
-+ * Brad Parker (brad@heeltoe.com)
-+ *
-+ * RPX lite specific parts of the i2c interface
-+ * Update: There actually isn't anything RPXLite-specific about this module.
-+ * This should work for most any 8xx board. The console messages have been
-+ * changed to eliminate RPXLite references.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/stddef.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-8xx.h>
-+#include <asm/mpc8xx.h>
-+#include <asm/commproc.h>
-+
-+
-+static void
-+rpx_iic_init(struct i2c_algo_8xx_data *data)
-+{
-+ volatile cpm8xx_t *cp;
-+ volatile immap_t *immap;
-+
-+ cp = cpmp; /* Get pointer to Communication Processor */
-+ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
-+
-+ data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
-+
-+ /* Check for and use a microcode relocation patch.
-+ */
-+ if ((data->reloc = data->iip->iic_rpbase))
-+ data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase];
-+
-+ data->i2c = (i2c8xx_t *)&(immap->im_i2c);
-+ data->cp = cp;
-+
-+ /* Initialize Port B IIC pins.
-+ */
-+ cp->cp_pbpar |= 0x00000030;
-+ cp->cp_pbdir |= 0x00000030;
-+ cp->cp_pbodr |= 0x00000030;
-+
-+ /* Allocate space for two transmit and two receive buffer
-+ * descriptors in the DP ram.
-+ */
-+ data->dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 4);
-+
-+ /* ptr to i2c area */
-+ data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
-+}
-+
-+static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data)
-+{
-+ /* install interrupt handler */
-+ cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data);
-+
-+ return 0;
-+}
-+
-+static struct i2c_algo_8xx_data rpx_data = {
-+ .setisr = rpx_install_isr
-+};
-+
-+static struct i2c_adapter rpx_ops = {
-+ .owner = THIS_MODULE,
-+ .name = "m8xx",
-+ .id = I2C_HW_MPC8XX_EPON,
-+ .algo_data = &rpx_data,
-+};
-+
-+static int __init i2c_rpx_init(void)
-+{
-+ printk("i2c-rpx.o: i2c MPC8xx module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-+
-+ /* reset hardware to sane state */
-+ rpx_iic_init(&rpx_data);
-+
-+ if (i2c_8xx_add_bus(&rpx_ops) < 0) {
-+ printk("i2c-rpx: Unable to register with I2C\n");
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit i2c_rpx_exit(void)
-+{
-+ i2c_8xx_del_bus(&rpx_ops);
-+}
-+
-+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
-+MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
-+
-+module_init(i2c_rpx_init);
-+module_exit(i2c_rpx_exit);
---- linux-old/drivers/i2c/i2c-velleman.c Tue Jan 20 15:10:31 2004
-+++ linux/drivers/i2c/i2c-velleman.c Mon Dec 13 19:26:36 2004
-@@ -18,18 +18,18 @@
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* ------------------------------------------------------------------------- */
-
--/* $Id: i2c-velleman.c,v 1.19 2000/01/24 02:06:33 mds Exp $ */
-+/* $Id: i2c-velleman.c,v 1.33 2003/12/24 17:49:44 khali Exp $ */
-
- #include <linux/kernel.h>
- #include <linux/ioport.h>
- #include <linux/module.h>
- #include <linux/init.h>
--#include <linux/string.h> /* for 2.0 kernels to get NULL */
--#include <asm/errno.h> /* for 2.0 kernels to get ENODEV */
--#include <asm/io.h>
--
-+#include <linux/errno.h>
-+#include <linux/delay.h>
- #include <linux/i2c.h>
- #include <linux/i2c-algo-bit.h>
-+#include <asm/io.h>
-+#include <asm/param.h> /* for HZ */
-
- /* ----- global defines ----------------------------------------------- */
- #define DEB(x) /* should be reasonable open, close &c. */
-@@ -90,75 +90,38 @@
-
- static int bit_velle_init(void)
- {
-- if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
-- DEBE(printk("i2c-velleman.o: Port %#x already in use.\n",
-- base));
-+ if (!request_region(base, (base == 0x3bc) ? 3 : 8,
-+ "i2c (Vellemann adapter)"))
- return -ENODEV;
-- } else {
-- request_region(base, (base == 0x3bc)? 3 : 8,
-- "i2c (Vellemann adapter)");
-- bit_velle_setsda((void*)base,1);
-- bit_velle_setscl((void*)base,1);
-- }
-- return 0;
--}
-
--static void __exit bit_velle_exit(void)
--{
-- release_region( base , (base == 0x3bc)? 3 : 8 );
--}
--
--
--static int bit_velle_reg(struct i2c_client *client)
--{
-- return 0;
--}
--
--static int bit_velle_unreg(struct i2c_client *client)
--{
-+ bit_velle_setsda((void*)base,1);
-+ bit_velle_setscl((void*)base,1);
- return 0;
- }
-
--static void bit_velle_inc_use(struct i2c_adapter *adap)
--{
--#ifdef MODULE
-- MOD_INC_USE_COUNT;
--#endif
--}
--
--static void bit_velle_dec_use(struct i2c_adapter *adap)
--{
--#ifdef MODULE
-- MOD_DEC_USE_COUNT;
--#endif
--}
--
- /* ------------------------------------------------------------------------
- * 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_bit_data bit_velle_data = {
-- NULL,
-- bit_velle_setsda,
-- bit_velle_setscl,
-- bit_velle_getsda,
-- bit_velle_getscl,
-- 10, 10, 100, /* waits, timeout */
-+ .setsda = bit_velle_setsda,
-+ .setscl = bit_velle_setscl,
-+ .getsda = bit_velle_getsda,
-+ .getscl = bit_velle_getscl,
-+ .udelay = 10,
-+ .mdelay = 10,
-+ .timeout = HZ
- };
-
- static struct i2c_adapter bit_velle_ops = {
-- "Velleman K8000",
-- I2C_HW_B_VELLE,
-- NULL,
-- &bit_velle_data,
-- bit_velle_inc_use,
-- bit_velle_dec_use,
-- bit_velle_reg,
-- bit_velle_unreg,
-+ .owner = THIS_MODULE,
-+ .name = "Velleman K8000",
-+ .id = I2C_HW_B_VELLE,
-+ .algo_data = &bit_velle_data,
- };
-
--int __init i2c_bitvelle_init(void)
-+static int __init i2c_bitvelle_init(void)
- {
- printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
- if (base==0) {
-@@ -184,24 +147,19 @@
- return 0;
- }
-
-+static void __exit i2c_bitvelle_exit(void)
-+{
-+ i2c_bit_del_bus(&bit_velle_ops);
-+ release_region(base, (base == 0x3bc) ? 3 : 8);
-+}
-+
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
- MODULE_LICENSE("GPL");
-
- MODULE_PARM(base, "i");
-
--int init_module(void)
--{
-- return i2c_bitvelle_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_bit_del_bus(&bit_velle_ops);
-- bit_velle_exit();
--}
--
--#endif
-+module_init(i2c_bitvelle_init);
-+module_exit(i2c_bitvelle_exit);
---- linux-old/include/linux/i2c.h Tue Jan 20 15:10:34 2004
-+++ linux/include/linux/i2c.h Mon Dec 13 19:26:37 2004
-@@ -23,36 +23,33 @@
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
- Frodo Looijaard <frodol@dds.nl> */
-
--/* $Id: i2c.h,v 1.46 2001/08/31 00:04:07 phil Exp $ */
-+/* $Id: i2c.h,v 1.80 2004/10/07 23:47:17 phil Exp $ */
-
--#ifndef I2C_H
--#define I2C_H
-+#ifndef _LINUX_I2C_H
-+#define _LINUX_I2C_H
-
--#define I2C_DATE "20010830"
--#define I2C_VERSION "2.6.1"
-+#define I2C_DATE "20041007"
-+#define I2C_VERSION "2.8.8"
-
--#include <linux/i2c-id.h> /* id values of adapters et. al. */
-+#include <linux/module.h>
- #include <linux/types.h>
--
--
--struct i2c_msg;
--
--
--#ifdef __KERNEL__
--
--/* --- Includes and compatibility declarations ------------------------ */
--
-+#include <linux/errno.h>
-+#include <linux/sched.h>
- #include <asm/semaphore.h>
--#include <linux/config.h>
-+#include <linux/i2c-id.h>
-+
-+#include <linux/version.h>
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
-+#define MODULE_LICENSE(x)
-+#endif
-
- /* --- General options ------------------------------------------------ */
-
--#define I2C_ALGO_MAX 4 /* control memory consumption */
--#define I2C_ADAP_MAX 16
-+#define I2C_ADAP_MAX 16 /* control memory consumption */
- #define I2C_DRIVER_MAX 16
- #define I2C_CLIENT_MAX 32
--#define I2C_DUMMY_MAX 4
-
-+struct i2c_msg;
- struct i2c_algorithm;
- struct i2c_adapter;
- struct i2c_client;
-@@ -60,7 +57,6 @@
- struct i2c_client_address_data;
- 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
-@@ -113,6 +109,8 @@
- extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
- u8 command, u8 length,
- u8 *values);
-+extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-+ u8 command, u8 *values);
- extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
- u8 command, u8 length,
- u8 *values);
-@@ -125,6 +123,7 @@
- */
-
- struct i2c_driver {
-+ struct module *owner;
- char name[32];
- int id;
- unsigned int flags; /* div., see below */
-@@ -148,18 +147,6 @@
- * with the device.
- */
- int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
--
-- /* These two are mainly used for bookkeeping & dynamic unloading of
-- * kernel modules. inc_use tells the driver that a client is being
-- * used by another module & that it should increase its ref. counter.
-- * dec_use is the inverse operation.
-- * NB: Make sure you have no circular dependencies, or else you get a
-- * deadlock when trying to unload the modules.
-- * You should use the i2c_{inc,dec}_use_client functions instead of
-- * calling this function directly.
-- */
-- void (*inc_use)(struct i2c_client *client);
-- void (*dec_use)(struct i2c_client *client);
- };
-
- /*
-@@ -192,6 +179,7 @@
- * to name two of the most common.
- */
- struct i2c_algorithm {
-+ struct module *owner; /* future use --km */
- char name[32]; /* textual description */
- unsigned int id;
-
-@@ -221,16 +209,13 @@
- * with the access algorithms necessary to access it.
- */
- struct i2c_adapter {
-+ struct module *owner;
- char name[32]; /* some useful name to identify the adapter */
- unsigned int id;/* == is algo->id | hwdep.struct->id, */
- /* for registered values see below */
- struct i2c_algorithm *algo;/* the algorithm to access the bus */
- void *algo_data;
-
-- /* --- These may be NULL, but should increase the module use count */
-- void (*inc_use)(struct i2c_adapter *);
-- void (*dec_use)(struct i2c_adapter *);
--
- /* --- administration stuff. */
- int (*client_register)(struct i2c_client *);
- int (*client_unregister)(struct i2c_client *);
-@@ -241,11 +226,11 @@
- /* and can be set via the i2c_ioctl call */
-
- /* data fields that are valid for all devices */
-- struct semaphore lock;
-+ struct semaphore bus;
-+ struct semaphore list;
- unsigned int flags;/* flags specifying div. data */
-
- struct i2c_client *clients[I2C_CLIENT_MAX];
-- int client_count;
-
- int timeout;
- int retries;
-@@ -264,6 +249,9 @@
- #define I2C_CLIENT_ALLOW_USE 0x01 /* Client allows access */
- #define I2C_CLIENT_ALLOW_MULTIPLE_USE 0x02 /* Allow multiple access-locks */
- /* on an i2c_client */
-+#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
-+#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
-+ /* Must equal I2C_M_TEN below */
-
- /* i2c_client_address_data is the struct for holding default client
- * addresses for a driver and for the parameters supplied on the
-@@ -302,12 +290,6 @@
- extern int i2c_attach_client(struct i2c_client *);
- extern int i2c_detach_client(struct i2c_client *);
-
--/* Only call these if you grab a resource that makes unloading the
-- client and the adapter it is on completely impossible. Like when a
-- /proc directory is entered. */
--extern void i2c_inc_use_client(struct i2c_client *);
--extern void i2c_dec_use_client(struct i2c_client *);
--
- /* New function: This is to get an i2c_client-struct for controlling the
- client either by using i2c_control-function or having the
- client-module export functions that can be used with the i2c_client
-@@ -341,6 +323,15 @@
- struct i2c_client_address_data *address_data,
- i2c_client_found_addr_proc *found_proc);
-
-+static inline int i2c_client_command(struct i2c_client *client,
-+ unsigned int cmd, void *arg)
-+{
-+ if (client->driver && client->driver->command)
-+ return client->driver->command(client, cmd, arg);
-+ else
-+ return -EINVAL;
-+}
-+
- /* An ioctl like call to set div. parameters of the adapter.
- */
- extern int i2c_control(struct i2c_client *,unsigned int, unsigned long);
-@@ -358,8 +349,6 @@
- /* Return 1 if adapter supports everything we need, 0 if not. */
- extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func);
-
--#endif /* __KERNEL__ */
--
- /*
- * I2C Message - used for pure i2c transaction, also from /dev interface
- */
-@@ -370,15 +359,28 @@
- #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
-+#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
-+#define I2C_M_RECV_PEC 0x0200 /* receive one more than the returned
-+ length byte for the PEC */
- __u16 len; /* msg length */
- __u8 *buf; /* pointer to msg data */
-+ int err;
-+ short done;
- };
-
- /* To determine what functionality is present */
-
- #define I2C_FUNC_I2C 0x00000001
- #define I2C_FUNC_10BIT_ADDR 0x00000002
--#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART} */
-+#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_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */
-+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */
-+#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */
-+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* 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
-@@ -389,8 +391,12 @@
- #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 /* New I2C-like block */
--#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* transfer */
-+#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 */
-+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
-+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */
-+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
-
- #define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \
- I2C_FUNC_SMBUS_WRITE_BYTE
-@@ -402,13 +408,28 @@
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
- #define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
-+#define I2C_FUNC_SMBUS_I2C_BLOCK_2 I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \
-+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2
-+#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \
-+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC
-+#define I2C_FUNC_SMBUS_WORD_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \
-+ I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC
-+
-+#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA
-+#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA
-+#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA
-+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA
-+#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA
-+#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA
-
- #define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \
- I2C_FUNC_SMBUS_BYTE | \
- I2C_FUNC_SMBUS_BYTE_DATA | \
- I2C_FUNC_SMBUS_WORD_DATA | \
- I2C_FUNC_SMBUS_PROC_CALL | \
-- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
-+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
-+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \
-+ I2C_FUNC_SMBUS_I2C_BLOCK
-
- /*
- * Data for SMBus Messages
-@@ -418,8 +439,9 @@
- union i2c_smbus_data {
- __u8 byte;
- __u16 word;
-- __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
-+ __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */
- /* one more for read length in block process call */
-+ /* and one more for PEC */
- };
-
- /* smbus_access read or write markers */
-@@ -435,6 +457,11 @@
- #define I2C_SMBUS_PROC_CALL 4
- #define I2C_SMBUS_BLOCK_DATA 5
- #define I2C_SMBUS_I2C_BLOCK_DATA 6
-+#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
-+#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */
-+#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */
-+#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */
-+#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */
-
-
- /* ----- commands for the ioctl like i2c_command call:
-@@ -460,6 +487,7 @@
-
- #define I2C_FUNCS 0x0705 /* Get the adapter functionality */
- #define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
-+#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */
- #if 0
- #define I2C_ACK_TEST 0x0710 /* See if a slave is at a specific address */
- #endif
-@@ -475,16 +503,6 @@
-
- #define I2C_MAJOR 89 /* Device major number */
-
--#ifdef __KERNEL__
--
--# ifndef NULL
--# define NULL ( (void *) 0 )
--# endif
--
--# ifndef ENODEV
--# include <asm/errno.h>
--# endif
--
- /* These defines are used for probing i2c client addresses */
- /* Default fill of many variables */
- #define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-@@ -546,5 +564,11 @@
- #define i2c_is_isa_adapter(adapptr) \
- ((adapptr)->algo->id == I2C_ALGO_ISA)
-
--#endif /* def __KERNEL__ */
--#endif /* I2C_H */
-+/* Tiny delay function used by the i2c bus drivers */
-+static inline void i2c_delay(signed long timeout)
-+{
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(timeout);
-+}
-+
-+#endif /* _LINUX_I2C_H */