Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 5 May 2007 00:46:27 +0000 (17:46 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 5 May 2007 00:46:27 +0000 (17:46 -0700)
* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: (44 commits)
  i2c-s3c2410: Fix bug in releasing driver
  i2c-s3c2410: Fix I2C SDA to SCL setup time
  i2c: New i2c-tiny-usb bus driver
  i2c: Documentation update
  i2c: SPIN_LOCK_UNLOCKED cleanup
  i2c: Obsolete i2c-ixp2000, i2c-ixp4xx and scx200_i2c
  i2c: New Simtec I2C bus driver
  i2c: Bitbanging I2C bus driver using the GPIO API
  Use menuconfig objects - I2C
  i2c: Restore i2c_smbus_read_block_data
  i2c-pxa: Clean transaction stop
  i2c-algo-bit: Improve debugging
  i2c-algo-bit: Implement a 50/50 SCL duty cycle
  i2c-omap: Switch to static adapter numbering
  i2c: Blackfin Two Wire Interface driver
  i2c-algo-sgi: Comment and whitespace cleanups
  i2c: Make i2c_del_driver a void function
  i2c: Move i2c-isa-only exported symbol declarations
  i2c: Document i2c_new_device()
  i2c: Add i2c_new_probed_device()
  ...

Fixed trivial conflict in Documentation/feature-removal-schedule.txt manually.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
61 files changed:
Documentation/feature-removal-schedule.txt
Documentation/i2c/busses/i2c-nforce2
Documentation/i2c/porting-clients
Documentation/i2c/summary
Documentation/i2c/writing-clients
MAINTAINERS
arch/powerpc/platforms/powermac/cpufreq_32.c
drivers/Makefile
drivers/i2c/Kconfig
drivers/i2c/Makefile
drivers/i2c/algos/Kconfig
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-sgi.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-bfin-twi.c [new file with mode: 0644]
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-gpio.c [new file with mode: 0644]
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-isa.c
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-ixp4xx.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-simtec.c [new file with mode: 0644]
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-tiny-usb.c [new file with mode: 0644]
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/chips/Kconfig
drivers/i2c/i2c-boardinfo.c [new file with mode: 0644]
drivers/i2c/i2c-core.c
drivers/i2c/i2c-core.h [new file with mode: 0644]
drivers/macintosh/therm_windtunnel.c
drivers/media/dvb/b2c2/flexcop-i2c.c
drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
drivers/media/dvb/frontends/dibx000_common.c
drivers/media/video/cx2341x.c
drivers/media/video/ovcamchip/ovcamchip_priv.h
drivers/media/video/usbvision/usbvision-cards.c
drivers/video/intelfb/intelfb_i2c.c
drivers/video/matrox/i2c-matroxfb.c
include/linux/i2c-algo-bit.h
include/linux/i2c-gpio.h [new file with mode: 0644]
include/linux/i2c-id.h
include/linux/i2c.h
include/linux/pci_ids.h
include/media/ovcamchip.h
include/media/tuner.h
sound/oss/dmasound/tas_ioctl.h

index 1a9e600a73a8fb1839eb956cc039e8b324eb7a7b..7d252dbe7d172398517d7e8b469fe73497f7566d 100644 (file)
@@ -190,18 +190,10 @@ Who:      Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
 
-What:  i2c_adapter.dev
-       i2c_adapter.list
+What:  i2c_adapter.list
 When:  July 2007
-Why:   Superfluous, given i2c_adapter.class_dev:
-         * The "dev" was a stand-in for the physical device node that legacy
-           drivers would not have; but now it's almost always present.  Any
-           remaining legacy drivers must upgrade (they now trigger warnings).
-         * The "list" duplicates class device children.
-       The delay in removing this is so upgraded lm_sensors and libsensors
-       can get deployed.  (Removal causes minor changes in the sysfs layout,
-       notably the location of the adapter type name and parenting the i2c
-       client hardware directly from their controller.)
+Why:   Superfluous, this list duplicates the one maintained by the driver
+       core.
 Who:   Jean Delvare <khali@linux-fr.org>,
        David Brownell <dbrownell@users.sourceforge.net>
 
@@ -331,3 +323,10 @@ Who:       Cornelia Huck <cornelia.huck@de.ibm.com>
 
 ---------------------------
 
+What:  i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
+When:  September 2007
+Why:   Obsolete. The new i2c-gpio driver replaces all hardware-specific
+       I2C-over-GPIO drivers.
+Who:   Jean Delvare <khali@linux-fr.org>
+
+---------------------------
index 7f61fbc03f7f51e294054fbff4037dec5995e9fa..fae3495bcbaf39c94efc4b4273367d10d21f16b6 100644 (file)
@@ -9,6 +9,8 @@ Supported adapters:
   * nForce4 MCP-04             10de:0034
   * nForce4 MCP51              10de:0264
   * nForce4 MCP55              10de:0368
+  * nForce4 MCP61              10de:03EB
+  * nForce4 MCP65              10de:0446
 
 Datasheet: not publicly available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
index ca272b263a92e5f2aefaf0158c30145ba7119a9f..7bf82c08f6ca71a7376fb3a104c3d327f9c59659 100644 (file)
@@ -1,4 +1,4 @@
-Revision 6, 2005-11-20
+Revision 7, 2007-04-19
 Jean Delvare <khali@linux-fr.org>
 Greg KH <greg@kroah.com>
 
@@ -20,6 +20,10 @@ yours for best results.
 
 Technical changes:
 
+* [Driver type] Any driver that was relying on i2c-isa has to be
+  converted to a proper isa, platform or pci driver. This is not
+  covered by this guide.
+
 * [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
   Includes typically look like that:
   #include <linux/module.h>
@@ -27,12 +31,10 @@ Technical changes:
   #include <linux/slab.h>
   #include <linux/jiffies.h>
   #include <linux/i2c.h>
-  #include <linux/i2c-isa.h>   /* for ISA drivers */
   #include <linux/hwmon.h>     /* for hardware monitoring drivers */
   #include <linux/hwmon-sysfs.h>
   #include <linux/hwmon-vid.h> /* if you need VRM support */
   #include <linux/err.h>       /* for class registration */
-  #include <asm/io.h>          /* if you have I/O operations */
   Please respect this inclusion order. Some extra headers may be
   required for a given driver (e.g. "lm75.h").
 
@@ -69,20 +71,16 @@ Technical changes:
   sensors mailing list <lm-sensors@lm-sensors.org> by providing a
   patch to the Documentation/hwmon/sysfs-interface file.
 
-* [Attach] For I2C drivers, the attach function should make sure
-  that the adapter's class has I2C_CLASS_HWMON (or whatever class is
-  suitable for your driver), using the following construct:
+* [Attach] The attach function should make sure that the adapter's
+  class has I2C_CLASS_HWMON (or whatever class is suitable for your
+  driver), using the following construct:
   if (!(adapter->class & I2C_CLASS_HWMON))
           return 0;
-  ISA-only drivers of course don't need this.
   Call i2c_probe() instead of i2c_detect().
 
 * [Detect] As mentioned earlier, the flags parameter is gone.
   The type_name and client_name strings are replaced by a single
   name string, which will be filled with a lowercase, short string.
-  In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
-  useless. Same for isa-only drivers, as the test would always be
-  true. Only hybrid drivers (which are quite rare) still need it.
   The labels used for error paths are reduced to the number needed.
   It is advised that the labels are given descriptive names such as
   exit and exit_free. Don't forget to properly set err before
index 41dde877679135ed161cd72a9a87f1673e5a43cd..aea60bf7e8f0847370e17beec79880307754a5d5 100644 (file)
@@ -4,17 +4,23 @@ I2C and SMBus
 =============
 
 I2C (pronounce: I squared C) is a protocol developed by Philips. It is a 
-slow two-wire protocol (10-400 kHz), but it suffices for many types of 
-devices.
+slow two-wire protocol (variable speed, up to 400 kHz), with a high speed
+extension (3.4 MHz).  It provides an inexpensive bus for connecting many
+types of devices with infrequent or low bandwidth communications needs.
+I2C is widely used with embedded systems.  Some systems use variants that
+don't meet branding requirements, and so are not advertised as being I2C.
 
-SMBus (System Management Bus) is a subset of the I2C protocol. Many
-modern mainboards have a System Management Bus. There are a lot of 
-devices which can be connected to a SMBus; the most notable are modern 
-memory chips with EEPROM memories and chips for hardware monitoring.
+SMBus (System Management Bus) is based on the I2C protocol, and is mostly
+a subset of I2C protocols and signaling.  Many I2C devices will work on an
+SMBus, but some SMBus protocols add semantics beyond what is required to
+achieve I2C branding.  Modern PC mainboards rely on SMBus.  The most common
+devices connected through SMBus are RAM modules configured using I2C EEPROMs,
+and hardware monitoring chips.
 
-Because the SMBus is just a special case of the generalized I2C bus, we
-can simulate the SMBus protocol on plain I2C busses. The reverse is
-regretfully impossible.
+Because the SMBus is mostly a subset of the generalized I2C bus, we can
+use its protocols on many I2C systems.  However, there are systems that don't
+meet both SMBus and I2C electrical constraints; and others which can't
+implement all the common SMBus protocol semantics or messages.
 
 
 Terminology
@@ -29,6 +35,7 @@ When we talk about I2C, we use the following terms:
 An Algorithm driver contains general code that can be used for a whole class
 of I2C adapters. Each specific adapter driver depends on one algorithm
 driver.
+
 A Driver driver (yes, this sounds ridiculous, sorry) contains the general
 code to access some type of device. Each detected device gets its own
 data in the Client structure. Usually, Driver and Client are more closely
@@ -40,6 +47,10 @@ a separate Adapter and Algorithm driver), and drivers for your I2C devices
 in this package. See the lm_sensors project http://www.lm-sensors.nu
 for device drivers.
 
+At this time, Linux only operates I2C (or SMBus) in master mode; you can't
+use these APIs to make a Linux system behave as a slave/device, either to
+speak a custom protocol or to emulate some other device.
+
 
 Included Bus Drivers
 ====================
index fbcff96f4ca1f8881d8459ff94c74ac1e38e6417..3d8d36b0ad1262f0a8b4c0fc2fbce21faf07d318 100644 (file)
@@ -1,5 +1,5 @@
 This is a small guide for those who want to write kernel drivers for I2C
-or SMBus devices.
+or SMBus devices, using Linux as the protocol host/master (not slave).
 
 To set up a driver, you need to do several things. Some are optional, and
 some things can be done slightly or completely different. Use this as a
@@ -29,8 +29,16 @@ static struct i2c_driver foo_driver = {
        .driver = {
                .name   = "foo",
        },
+
+       /* iff driver uses driver model ("new style") binding model: */
+       .probe          = foo_probe,
+       .remove         = foo_remove,
+
+       /* else, driver uses "legacy" binding model: */
        .attach_adapter = foo_attach_adapter,
        .detach_client  = foo_detach_client,
+
+       /* these may be used regardless of the driver binding model */
        .shutdown       = foo_shutdown, /* optional */
        .suspend        = foo_suspend,  /* optional */
        .resume         = foo_resume,   /* optional */
@@ -40,7 +48,8 @@ static struct i2c_driver foo_driver = {
 The name field is the driver name, and must not contain spaces.  It
 should match the module name (if the driver can be compiled as a module),
 although you can use MODULE_ALIAS (passing "foo" in this example) to add
-another name for the module.
+another name for the module.  If the driver name doesn't match the module
+name, the module won't be automatically loaded (hotplug/coldplug).
 
 All other fields are for call-back functions which will be explained 
 below.
@@ -65,16 +74,13 @@ An example structure is below.
 
   struct foo_data {
     struct i2c_client client;
-    struct semaphore lock; /* For ISA access in `sensors' drivers. */
-    int sysctl_id;         /* To keep the /proc directory entry for 
-                              `sensors' drivers. */
     enum chips type;       /* To keep the chips type for `sensors' drivers. */
    
     /* Because the i2c bus is slow, it is often useful to cache the read
        information of a chip for some time (for example, 1 or 2 seconds).
        It depends of course on the device whether this is really worthwhile
        or even sensible. */
-    struct semaphore update_lock; /* When we are reading lots of information,
+    struct mutex update_lock;     /* When we are reading lots of information,
                                      another process should not update the
                                      below information */
     char valid;                   /* != 0 if the following fields are valid. */
@@ -95,8 +101,7 @@ some obscure clients). But we need generic reading and writing routines.
 I have found it useful to define foo_read and foo_write function for this.
 For some cases, it will be easier to call the i2c functions directly,
 but many chips have some kind of register-value idea that can easily
-be encapsulated. Also, some chips have both ISA and I2C interfaces, and
-it useful to abstract from this (only for `sensors' drivers).
+be encapsulated.
 
 The below functions are simple examples, and should not be copied
 literally.
@@ -119,28 +124,101 @@ literally.
       return i2c_smbus_write_word_data(client,reg,value);
   }
 
-For sensors code, you may have to cope with ISA registers too. Something
-like the below often works. Note the locking! 
-
-  int foo_read_value(struct i2c_client *client, u8 reg)
-  {
-    int res;
-    if (i2c_is_isa_client(client)) {
-      down(&(((struct foo_data *) (client->data)) -> lock));
-      outb_p(reg,client->addr + FOO_ADDR_REG_OFFSET);
-      res = inb_p(client->addr + FOO_DATA_REG_OFFSET);
-      up(&(((struct foo_data *) (client->data)) -> lock));
-      return res;
-    } else
-      return i2c_smbus_read_byte_data(client,reg);
-  }
-
-Writing is done the same way.
-
 
 Probing and attaching
 =====================
 
+The Linux I2C stack was originally written to support access to hardware
+monitoring chips on PC motherboards, and thus it embeds some assumptions
+that are more appropriate to SMBus (and PCs) than to I2C.  One of these
+assumptions is that most adapters and devices drivers support the SMBUS_QUICK
+protocol to probe device presence.  Another is that devices and their drivers
+can be sufficiently configured using only such probe primitives.
+
+As Linux and its I2C stack became more widely used in embedded systems
+and complex components such as DVB adapters, those assumptions became more
+problematic.  Drivers for I2C devices that issue interrupts need more (and
+different) configuration information, as do drivers handling chip variants
+that can't be distinguished by protocol probing, or which need some board
+specific information to operate correctly.
+
+Accordingly, the I2C stack now has two models for associating I2C devices
+with their drivers:  the original "legacy" model, and a newer one that's
+fully compatible with the Linux 2.6 driver model.  These models do not mix,
+since the "legacy" model requires drivers to create "i2c_client" device
+objects after SMBus style probing, while the Linux driver model expects
+drivers to be given such device objects in their probe() routines.
+
+
+Standard Driver Model Binding ("New Style")
+-------------------------------------------
+
+System infrastructure, typically board-specific initialization code or
+boot firmware, reports what I2C devices exist.  For example, there may be
+a table, in the kernel or from the boot loader, identifying I2C devices
+and linking them to board-specific configuration information about IRQs
+and other wiring artifacts, chip type, and so on.  That could be used to
+create i2c_client objects for each I2C device.
+
+I2C device drivers using this binding model work just like any other
+kind of driver in Linux:  they provide a probe() method to bind to
+those devices, and a remove() method to unbind.
+
+       static int foo_probe(struct i2c_client *client);
+       static int foo_remove(struct i2c_client *client);
+
+Remember that the i2c_driver does not create those client handles.  The
+handle may be used during foo_probe().  If foo_probe() reports success
+(zero not a negative status code) it may save the handle and use it until
+foo_remove() returns.  That binding model is used by most Linux drivers.
+
+Drivers match devices when i2c_client.driver_name and the driver name are
+the same; this approach is used in several other busses that don't have
+device typing support in the hardware.  The driver and module name should
+match, so hotplug/coldplug mechanisms will modprobe the driver.
+
+
+Device Creation (Standard driver model)
+---------------------------------------
+
+If you know for a fact that an I2C device is connected to a given I2C bus,
+you can instantiate that device by simply filling an i2c_board_info
+structure with the device address and driver name, and calling
+i2c_new_device().  This will create the device, then the driver core will
+take care of finding the right driver and will call its probe() method.
+If a driver supports different device types, you can specify the type you
+want using the type field.  You can also specify an IRQ and platform data
+if needed.
+
+Sometimes you know that a device is connected to a given I2C bus, but you
+don't know the exact address it uses.  This happens on TV adapters for
+example, where the same driver supports dozens of slightly different
+models, and I2C device addresses change from one model to the next.  In
+that case, you can use the i2c_new_probed_device() variant, which is
+similar to i2c_new_device(), except that it takes an additional list of
+possible I2C addresses to probe.  A device is created for the first
+responsive address in the list.  If you expect more than one device to be
+present in the address range, simply call i2c_new_probed_device() that
+many times.
+
+The call to i2c_new_device() or i2c_new_probed_device() typically happens
+in the I2C bus driver. You may want to save the returned i2c_client
+reference for later use.
+
+
+Device Deletion (Standard driver model)
+---------------------------------------
+
+Each I2C device which has been created using i2c_new_device() or
+i2c_new_probed_device() can be unregistered by calling
+i2c_unregister_device().  If you don't call it explicitly, it will be
+called automatically before the underlying I2C bus itself is removed, as a
+device can't survive its parent in the device driver model.
+
+
+Legacy Driver Binding Model
+---------------------------
+
 Most i2c devices can be present on several i2c addresses; for some this
 is determined in hardware (by soldering some chip pins to Vcc or Ground),
 for others this can be changed in software (by writing to specific client
@@ -157,13 +235,9 @@ detection algorithm.
 You do not have to use this parameter interface; but don't try to use
 function i2c_probe() if you don't.
 
-NOTE: If you want to write a `sensors' driver, the interface is slightly
-      different! See below.
-
 
-
-Probing classes
----------------
+Probing classes (Legacy model)
+------------------------------
 
 All parameters are given as lists of unsigned 16-bit integers. Lists are
 terminated by I2C_CLIENT_END.
@@ -210,8 +284,8 @@ Note that you *have* to call the defined variable `normal_i2c',
 without any prefix!
 
 
-Attaching to an adapter
------------------------
+Attaching to an adapter (Legacy model)
+--------------------------------------
 
 Whenever a new adapter is inserted, or for all adapters if the driver is
 being registered, the callback attach_adapter() is called. Now is the
@@ -237,17 +311,13 @@ them (unless a `force' parameter was used). In addition, addresses that
 are already in use (by some other registered client) are skipped.
 
 
-The detect client function
---------------------------
+The detect client function (Legacy model)
+-----------------------------------------
 
 The detect client function is called by i2c_probe. The `kind' parameter
 contains -1 for a probed detection, 0 for a forced detection, or a positive
 number for a forced detection with a chip type forced.
 
-Below, some things are only needed if this is a `sensors' driver. Those
-parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */
-markers. 
-
 Returning an error different from -ENODEV in a detect function will cause
 the detection to stop: other addresses and adapters won't be scanned.
 This should only be done on fatal or internal errors, such as a memory
@@ -256,64 +326,20 @@ shortage or i2c_attach_client failing.
 For now, you can ignore the `flags' parameter. It is there for future use.
 
   int foo_detect_client(struct i2c_adapter *adapter, int address, 
-                        unsigned short flags, int kind)
+                        int kind)
   {
     int err = 0;
     int i;
-    struct i2c_client *new_client;
+    struct i2c_client *client;
     struct foo_data *data;
-    const char *client_name = ""; /* For non-`sensors' drivers, put the real
-                                     name here! */
+    const char *name = "";
    
     /* Let's see whether this adapter can support what we need.
-       Please substitute the things you need here! 
-       For `sensors' drivers, add `! is_isa &&' to the if statement */
+       Please substitute the things you need here! */
     if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
                                         I2C_FUNC_SMBUS_WRITE_BYTE))
        goto ERROR0;
 
-    /* SENSORS ONLY START */
-    const char *type_name = "";
-    int is_isa = i2c_is_isa_adapter(adapter);
-
-    /* Do this only if the chip can additionally be found on the ISA bus
-       (hybrid chip). */
-
-    if (is_isa) {
-
-      /* Discard immediately if this ISA range is already used */
-      /* FIXME: never use check_region(), only request_region() */
-      if (check_region(address,FOO_EXTENT))
-        goto ERROR0;
-
-      /* Probe whether there is anything on this address.
-         Some example code is below, but you will have to adapt this
-         for your own driver */
-
-      if (kind < 0) /* Only if no force parameter was used */ {
-        /* We may need long timeouts at least for some chips. */
-        #define REALLY_SLOW_IO
-        i = inb_p(address + 1);
-        if (inb_p(address + 2) != i)
-          goto ERROR0;
-        if (inb_p(address + 3) != i)
-          goto ERROR0;
-        if (inb_p(address + 7) != i)
-          goto ERROR0;
-        #undef REALLY_SLOW_IO
-
-        /* Let's just hope nothing breaks here */
-        i = inb_p(address + 5) & 0x7f;
-        outb_p(~i & 0x7f,address+5);
-        if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
-          outb_p(i,address+5);
-          return 0;
-        }
-      }
-    }
-
-    /* SENSORS ONLY END */
-
     /* OK. For now, we presume we have a valid client. We now create the
        client structure, even though we cannot fill it completely yet.
        But it allows us to access several i2c functions safely */
@@ -323,13 +349,12 @@ For now, you can ignore the `flags' parameter. It is there for future use.
       goto ERROR0;
     }
 
-    new_client = &data->client;
-    i2c_set_clientdata(new_client, data);
+    client = &data->client;
+    i2c_set_clientdata(client, data);
 
-    new_client->addr = address;
-    new_client->adapter = adapter;
-    new_client->driver = &foo_driver;
-    new_client->flags = 0;
+    client->addr = address;
+    client->adapter = adapter;
+    client->driver = &foo_driver;
 
     /* Now, we do the remaining detection. If no `force' parameter is used. */
 
@@ -337,19 +362,17 @@ For now, you can ignore the `flags' parameter. It is there for future use.
        parameter was used. */
     if (kind < 0) {
       /* The below is of course bogus */
-      if (foo_read(new_client,FOO_REG_GENERIC) != FOO_GENERIC_VALUE)
+      if (foo_read(client, FOO_REG_GENERIC) != FOO_GENERIC_VALUE)
          goto ERROR1;
     }
 
-    /* SENSORS ONLY START */
-
     /* Next, specific detection. This is especially important for `sensors'
        devices. */
 
     /* Determine the chip type. Not needed if a `force_CHIPTYPE' parameter
        was used. */
     if (kind <= 0) {
-      i = foo_read(new_client,FOO_REG_CHIPTYPE);
+      i = foo_read(client, FOO_REG_CHIPTYPE);
       if (i == FOO_TYPE_1) 
         kind = chip1; /* As defined in the enum */
       else if (i == FOO_TYPE_2)
@@ -363,63 +386,31 @@ For now, you can ignore the `flags' parameter. It is there for future use.
 
     /* Now set the type and chip names */
     if (kind == chip1) {
-      type_name = "chip1"; /* For /proc entry */
-      client_name = "CHIP 1";
+      name = "chip1";
     } else if (kind == chip2) {
-      type_name = "chip2"; /* For /proc entry */
-      client_name = "CHIP 2";
+      name = "chip2";
     }
    
-    /* Reserve the ISA region */
-    if (is_isa)
-      request_region(address,FOO_EXTENT,type_name);
-
-    /* SENSORS ONLY END */
-
     /* Fill in the remaining client fields. */
-    strcpy(new_client->name,client_name);
-
-    /* SENSORS ONLY BEGIN */
+    strlcpy(client->name, name, I2C_NAME_SIZE);
     data->type = kind;
-    /* SENSORS ONLY END */
-
-    data->valid = 0; /* Only if you use this field */
-    init_MUTEX(&data->update_lock); /* Only if you use this field */
+    mutex_init(&data->update_lock); /* Only if you use this field */
 
     /* Any other initializations in data must be done here too. */
 
-    /* Tell the i2c layer a new client has arrived */
-    if ((err = i2c_attach_client(new_client)))
-      goto ERROR3;
-
-    /* SENSORS ONLY BEGIN */
-    /* Register a new directory entry with module sensors. See below for
-       the `template' structure. */
-    if ((i = i2c_register_entry(new_client, type_name,
-                                    foo_dir_table_template,THIS_MODULE)) < 0) {
-      err = i;
-      goto ERROR4;
-    }
-    data->sysctl_id = i;
-
-    /* SENSORS ONLY END */
-
     /* This function can write default values to the client registers, if
        needed. */
-    foo_init_client(new_client);
+    foo_init_client(client);
+
+    /* Tell the i2c layer a new client has arrived */
+    if ((err = i2c_attach_client(client)))
+      goto ERROR1;
+
     return 0;
 
     /* OK, this is not exactly good programming practice, usually. But it is
        very code-efficient in this case. */
 
-    ERROR4:
-      i2c_detach_client(new_client);
-    ERROR3:
-    ERROR2:
-    /* SENSORS ONLY START */
-      if (is_isa)
-        release_region(address,FOO_EXTENT);
-    /* SENSORS ONLY END */
     ERROR1:
       kfree(data);
     ERROR0:
@@ -427,8 +418,8 @@ For now, you can ignore the `flags' parameter. It is there for future use.
   }
 
 
-Removing the client
-===================
+Removing the client (Legacy model)
+==================================
 
 The detach_client call back function is called when a client should be
 removed. It may actually fail, but only when panicking. This code is
@@ -436,22 +427,12 @@ much simpler than the attachment code, fortunately!
 
   int foo_detach_client(struct i2c_client *client)
   {
-    int err,i;
-
-    /* SENSORS ONLY START */
-    /* Deregister with the `i2c-proc' module. */
-    i2c_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
-    /* SENSORS ONLY END */
+    int err;
 
     /* Try to detach the client from i2c space */
     if ((err = i2c_detach_client(client)))
       return err;
 
-    /* HYBRID SENSORS CHIP ONLY START */
-    if i2c_is_isa_client(client)
-      release_region(client->addr,LM78_EXTENT);
-    /* HYBRID SENSORS CHIP ONLY END */
-
     kfree(i2c_get_clientdata(client));
     return 0;
   }
@@ -464,45 +445,34 @@ When the kernel is booted, or when your foo driver module is inserted,
 you have to do some initializing. Fortunately, just attaching (registering)
 the driver module is usually enough.
 
-  /* Keep track of how far we got in the initialization process. If several
-     things have to initialized, and we fail halfway, only those things
-     have to be cleaned up! */
-  static int __initdata foo_initialized = 0;
-
   static int __init foo_init(void)
   {
     int res;
-    printk("foo version %s (%s)\n",FOO_VERSION,FOO_DATE);
     
     if ((res = i2c_add_driver(&foo_driver))) {
       printk("foo: Driver registration failed, module not inserted.\n");
-      foo_cleanup();
       return res;
     }
-    foo_initialized ++;
     return 0;
   }
 
-  void foo_cleanup(void)
+  static void __exit foo_cleanup(void)
   {
-    if (foo_initialized == 1) {
-      if ((res = i2c_del_driver(&foo_driver))) {
-        printk("foo: Driver registration failed, module not removed.\n");
-        return;
-      }
-      foo_initialized --;
-    }
+    i2c_del_driver(&foo_driver);
   }
 
   /* Substitute your own name and email address */
   MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
   MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
 
+  /* a few non-GPL license types are also allowed */
+  MODULE_LICENSE("GPL");
+
   module_init(foo_init);
   module_exit(foo_cleanup);
 
 Note that some functions are marked by `__init', and some data structures
-by `__init_data'.  Hose functions and structures can be removed after
+by `__initdata'.  These functions and structures can be removed after
 kernel booting (or module loading) is completed.
 
 
@@ -632,110 +602,7 @@ General purpose routines
 Below all general purpose routines are listed, that were not mentioned
 before.
 
-  /* This call returns a unique low identifier for each registered adapter,
-   * or -1 if the adapter was not registered.
+  /* This call returns a unique low identifier for each registered adapter.
    */
   extern int i2c_adapter_id(struct i2c_adapter *adap);
 
-
-The sensors sysctl/proc interface
-=================================
-
-This section only applies if you write `sensors' drivers.
-
-Each sensors driver creates a directory in /proc/sys/dev/sensors for each
-registered client. The directory is called something like foo-i2c-4-65.
-The sensors module helps you to do this as easily as possible.
-
-The template
-------------
-
-You will need to define a ctl_table template. This template will automatically
-be copied to a newly allocated structure and filled in where necessary when
-you call sensors_register_entry.
-
-First, I will give an example definition.
-  static ctl_table foo_dir_table_template[] = {
-    { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real,
-      &i2c_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &i2c_proc_real,
-      &i2c_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &i2c_proc_real,
-      &i2c_sysctl_real,NULL,&foo_data },
-    { 0 }
-  };
-
-In the above example, three entries are defined. They can either be
-accessed through the /proc interface, in the /proc/sys/dev/sensors/*
-directories, as files named func1, func2 and data, or alternatively 
-through the sysctl interface, in the appropriate table, with identifiers
-FOO_SYSCTL_FUNC1, FOO_SYSCTL_FUNC2 and FOO_SYSCTL_DATA.
-
-The third, sixth and ninth parameters should always be NULL, and the
-fourth should always be 0. The fifth is the mode of the /proc file;
-0644 is safe, as the file will be owned by root:root. 
-
-The seventh and eighth parameters should be &i2c_proc_real and
-&i2c_sysctl_real if you want to export lists of reals (scaled
-integers). You can also use your own function for them, as usual.
-Finally, the last parameter is the call-back to gather the data
-(see below) if you use the *_proc_real functions. 
-
-
-Gathering the data
-------------------
-
-The call back functions (foo_func and foo_data in the above example)
-can be called in several ways; the operation parameter determines
-what should be done:
-
-  * If operation == SENSORS_PROC_REAL_INFO, you must return the
-    magnitude (scaling) in nrels_mag;
-  * If operation == SENSORS_PROC_REAL_READ, you must read information
-    from the chip and return it in results. The number of integers
-    to display should be put in nrels_mag;
-  * If operation == SENSORS_PROC_REAL_WRITE, you must write the
-    supplied information to the chip. nrels_mag will contain the number
-    of integers, results the integers themselves.
-
-The *_proc_real functions will display the elements as reals for the
-/proc interface. If you set the magnitude to 2, and supply 345 for
-SENSORS_PROC_REAL_READ, it would display 3.45; and if the user would
-write 45.6 to the /proc file, it would be returned as 4560 for
-SENSORS_PROC_REAL_WRITE. A magnitude may even be negative!
-
-An example function:
-
-  /* FOO_FROM_REG and FOO_TO_REG translate between scaled values and
-     register values. Note the use of the read cache. */
-  void foo_in(struct i2c_client *client, int operation, int ctl_name, 
-              int *nrels_mag, long *results)
-  {
-    struct foo_data *data = client->data;
-    int nr = ctl_name - FOO_SYSCTL_FUNC1; /* reduce to 0 upwards */
-    
-    if (operation == SENSORS_PROC_REAL_INFO)
-      *nrels_mag = 2;
-    else if (operation == SENSORS_PROC_REAL_READ) {
-      /* Update the readings cache (if necessary) */
-      foo_update_client(client);
-      /* Get the readings from the cache */
-      results[0] = FOO_FROM_REG(data->foo_func_base[nr]);
-      results[1] = FOO_FROM_REG(data->foo_func_more[nr]);
-      results[2] = FOO_FROM_REG(data->foo_func_readonly[nr]);
-      *nrels_mag = 2;
-    } else if (operation == SENSORS_PROC_REAL_WRITE) {
-      if (*nrels_mag >= 1) {
-        /* Update the cache */
-        data->foo_base[nr] = FOO_TO_REG(results[0]);
-        /* Update the chip */
-        foo_write_value(client,FOO_REG_FUNC_BASE(nr),data->foo_base[nr]);
-      }
-      if (*nrels_mag >= 2) {
-        /* Update the cache */
-        data->foo_more[nr] = FOO_TO_REG(results[1]);
-        /* Update the chip */
-        foo_write_value(client,FOO_REG_FUNC_MORE(nr),data->foo_more[nr]);
-      }
-    }
-  }
index 17c5e30f20f332baceab6af90d2ccb02c28d689c..1e8c37054ea291db9311b56b7cc2253c46649b8e 100644 (file)
@@ -733,6 +733,13 @@ M: tigran@aivazian.fsnet.co.uk
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+BLACKFIN I2C TWI DRIVER
+P:     Sonic Zhang
+M:     sonic.zhang@analog.com
+L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+W:     http://blackfin.uclinux.org/
+S:     Supported
+
 BLOCK LAYER
 P:     Jens Axboe
 M:     axboe@kernel.dk
@@ -1459,6 +1466,11 @@ L:       linux-scsi@vger.kernel.org
 W:     http://www.icp-vortex.com/
 S:     Supported
 
+GENERIC GPIO I2C DRIVER
+P:     Haavard Skinnemoen
+M:     hskinnemoen@atmel.com
+S:     Supported
+
 GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS
 P:     Krzysztof Halasa
 M:     khc@pm.waw.pl
@@ -1631,6 +1643,13 @@ L:       i2c@lm-sensors.org
 T:     quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
 S:     Maintained
 
+I2C-TINY-USB DRIVER
+P:     Till Harbaum
+M:     till@harbaum.org
+L:     i2c@lm-sensors.org
+T:     http://www.harbaum.org/till/i2c_tiny_usb
+S:     Maintained
+
 i386 BOOT CODE
 P:     Riley H. Williams
 M:     Riley@Williams.Name
index 8943a9456bb7088b64a94c07ce0f8519b85233a8..1fe35dab0e9eb7d519569ef37265956d0b85613d 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
-#include <linux/i2c.h>
 #include <linux/hardirq.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
index 920c975bb6d469f0390b4af3d79e9bd59861030c..26ca9031ea496320106d62772dba56e178eae7c7 100644 (file)
@@ -58,7 +58,7 @@ obj-$(CONFIG_GAMEPORT)                += input/gameport/
 obj-$(CONFIG_INPUT)            += input/
 obj-$(CONFIG_I2O)              += message/
 obj-$(CONFIG_RTC_LIB)          += rtc/
-obj-$(CONFIG_I2C)              += i2c/
+obj-y                          += i2c/
 obj-$(CONFIG_W1)               += w1/
 obj-$(CONFIG_HWMON)            += hwmon/
 obj-$(CONFIG_PHONE)            += telephony/
index 11935f66fcd8fcf839bafc73c74fbb1eb1a9f009..434a61b415a347ba529241ac439bbe3e36d69bbe 100644 (file)
@@ -2,9 +2,7 @@
 # I2C subsystem configuration
 #
 
-menu "I2C support"
-
-config I2C
+menuconfig I2C
        tristate "I2C support"
        ---help---
          I2C (pronounce: I-square-C) is a slow serial bus protocol used in
@@ -22,9 +20,14 @@ config I2C
          This I2C support can also be built as a module.  If so, the module
          will be called i2c-core.
 
+if I2C
+
+config I2C_BOARDINFO
+       boolean
+       default y
+
 config I2C_CHARDEV
        tristate "I2C device interface"
-       depends on I2C
        help
          Say Y here to use i2c-* device files, usually found in the /dev
          directory on your system.  They make it possible to have user-space
@@ -40,7 +43,6 @@ source drivers/i2c/chips/Kconfig
 
 config I2C_DEBUG_CORE
        bool "I2C Core debugging messages"
-       depends on I2C
        help
          Say Y here if you want the I2C core to produce a bunch of debug
          messages to the system log.  Select this if you are having a
@@ -48,7 +50,6 @@ config I2C_DEBUG_CORE
 
 config I2C_DEBUG_ALGO
        bool "I2C Algorithm debugging messages"
-       depends on I2C
        help
          Say Y here if you want the I2C algorithm drivers to produce a bunch
          of debug messages to the system log.  Select this if you are having
@@ -57,7 +58,6 @@ config I2C_DEBUG_ALGO
 
 config I2C_DEBUG_BUS
        bool "I2C Bus debugging messages"
-       depends on I2C
        help
          Say Y here if you want the I2C bus drivers to produce a bunch of
          debug messages to the system log.  Select this if you are having
@@ -66,12 +66,10 @@ config I2C_DEBUG_BUS
 
 config I2C_DEBUG_CHIP
        bool "I2C Chip debugging messages"
-       depends on I2C
        help
          Say Y here if you want the I2C chip drivers to produce a bunch of
          debug messages to the system log.  Select this if you are having
          a problem with I2C support and want to see more of what is going
          on.
 
-endmenu
-
+endif # I2C
index 71c5a854ac5d646d31e03ad511ea5ceb00ef8af8..ba26e6cbe74e7eb21a9a3231d84f593aed9342cd 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for the i2c core.
 #
 
+obj-$(CONFIG_I2C_BOARDINFO)    += i2c-boardinfo.o
 obj-$(CONFIG_I2C)              += i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)      += i2c-dev.o
 obj-y                          += busses/ chips/ algos/
index af0203409dd113a8f7bbb6478ec6fbb179af5b81..58899078810b787b03dfda4ff894ef43ab2d6709 100644 (file)
@@ -3,11 +3,9 @@
 #
 
 menu "I2C Algorithms"
-       depends on I2C
 
 config I2C_ALGOBIT
        tristate "I2C bit-banging interfaces"
-       depends on I2C
        help
          This allows you to use a range of I2C adapters called bit-banging
          adapters.  Say Y if you own an I2C adapter belonging to this class
@@ -18,7 +16,6 @@ config I2C_ALGOBIT
 
 config I2C_ALGOPCF
        tristate "I2C PCF 8584 interfaces"
-       depends on I2C
        help
          This allows you to use a range of I2C adapters called PCF adapters.
          Say Y if you own an I2C adapter belonging to this class and then say
@@ -29,7 +26,6 @@ config I2C_ALGOPCF
 
 config I2C_ALGOPCA
        tristate "I2C PCA 9564 interfaces"
-       depends on I2C
        help
          This allows you to use a range of I2C adapters called PCA adapters.
          Say Y if you own an I2C adapter belonging to this class and then say
@@ -40,11 +36,11 @@ config I2C_ALGOPCA
 
 config I2C_ALGO8XX
        tristate "MPC8xx CPM I2C interface"
-       depends on 8xx && I2C
+       depends on 8xx
 
 config I2C_ALGO_SGI
        tristate "I2C SGI interfaces"
-       depends on I2C && (SGI_IP22 || SGI_IP32 || X86_VISWS)
+       depends on SGI_IP22 || SGI_IP32 || X86_VISWS
        help
          Supports the SGI interfaces like the ones found on SGI Indy VINO
          or SGI O2 MACE.
index 95aa5395a5bedb02fcf99b5eaa45fd03c929a9e0..8a5f5825bb7294ea3056695748bd824df089d4f2 100644 (file)
 
 
 /* ----- global defines ----------------------------------------------- */
-#define DEB(x) if (i2c_debug>=1) x;
-#define DEB2(x) if (i2c_debug>=2) x;
-#define DEBSTAT(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 */
 
+#ifdef DEBUG
+#define bit_dbg(level, dev, format, args...) \
+       do { \
+               if (i2c_debug >= level) \
+                       dev_dbg(dev, format, ##args); \
+       } while (0)
+#else
+#define bit_dbg(level, dev, format, args...) \
+       do {} while (0)
+#endif /* DEBUG */
 
 /* ----- global variables ---------------------------------------------        */
 
-/* module parameters:
- */
-static int i2c_debug;
 static int bit_test;   /* see if the line-setting functions work       */
+module_param(bit_test, bool, 0);
+MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck");
+
+#ifdef DEBUG
+static int i2c_debug = 1;
+module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(i2c_debug,
+                "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose");
+#endif
 
 /* --- setting states on the bus with the right timing: ---------------        */
 
@@ -57,19 +68,19 @@ static int bit_test;        /* see if the line-setting functions work       */
 static inline void sdalo(struct i2c_algo_bit_data *adap)
 {
        setsda(adap,0);
-       udelay(adap->udelay);
+       udelay((adap->udelay + 1) / 2);
 }
 
 static inline void sdahi(struct i2c_algo_bit_data *adap)
 {
        setsda(adap,1);
-       udelay(adap->udelay);
+       udelay((adap->udelay + 1) / 2);
 }
 
 static inline void scllo(struct i2c_algo_bit_data *adap)
 {
        setscl(adap,0);
-       udelay(adap->udelay);
+       udelay(adap->udelay / 2);
 }
 
 /*
@@ -98,7 +109,11 @@ static int sclhi(struct i2c_algo_bit_data *adap)
                }
                cond_resched();
        }
-       DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start));
+#ifdef DEBUG
+       if (jiffies != start && i2c_debug >= 3)
+               pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
+                        "high\n", jiffies - start);
+#endif
 
 done:
        udelay(adap->udelay);
@@ -110,30 +125,29 @@ done:
 static void i2c_start(struct i2c_algo_bit_data *adap) 
 {
        /* assert: scl, sda are high */
-       DEBPROTO(printk("S "));
-       sdalo(adap);
+       setsda(adap, 0);
+       udelay(adap->udelay);
        scllo(adap);
 }
 
 static void i2c_repstart(struct i2c_algo_bit_data *adap) 
 {
-       /* scl, sda may not be high */
-       DEBPROTO(printk(" Sr "));
-       setsda(adap,1);
+       /* assert: scl is low */
+       sdahi(adap);
        sclhi(adap);
-       
-       sdalo(adap);
+       setsda(adap, 0);
+       udelay(adap->udelay);
        scllo(adap);
 }
 
 
 static void i2c_stop(struct i2c_algo_bit_data *adap) 
 {
-       DEBPROTO(printk("P\n"));
        /* assert: scl is low */
        sdalo(adap);
        sclhi(adap); 
-       sdahi(adap);
+       setsda(adap, 1);
+       udelay(adap->udelay);
 }
 
 
@@ -145,7 +159,7 @@ static void i2c_stop(struct i2c_algo_bit_data *adap)
  * 0 if the device did not ack
  * -ETIMEDOUT if an error occurred (while raising the scl line)
  */
-static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
+static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
 {
        int i;
        int sb;
@@ -154,34 +168,32 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
 
        /* assert: scl is low */
        for ( i=7 ; i>=0 ; i-- ) {
-               sb = c & ( 1 << i );
+               sb = (c >> i) & 1;
                setsda(adap,sb);
-               udelay(adap->udelay);
-               DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
+               udelay((adap->udelay + 1) / 2);
                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));
+                       bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
+                               "timeout at bit #%d\n", (int)c, i);
                        return -ETIMEDOUT;
                };
                /* do arbitration here: 
                 * if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
                 */
-               setscl(adap, 0 );
-               udelay(adap->udelay);
+               scllo(adap);
        }
        sdahi(adap);
        if (sclhi(adap)<0){ /* timeout */
-           DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff));
-           return -ETIMEDOUT;
+               bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
+                       "timeout at ack\n", (int)c);
+               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: 0x%02x , getsda() = %d\n", c & 0xff, ack));
+       ack = !getsda(adap);    /* ack: sda is pulled low -> success */
+       bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
+               ack ? "A" : "NA");
 
-       DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) );
-       DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") );
        scllo(adap);
-       return 0==ack;          /* return 1 if device acked      */
+       return ack;
        /* assert: scl is low (sda undef) */
 }
 
@@ -198,19 +210,18 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
        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));
+                       bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
+                               "#%d\n", 7 - i);
                        return -ETIMEDOUT;
                };
                indata *= 2;
                if ( getsda(adap) ) 
                        indata |= 0x01;
-               scllo(adap);
+               setscl(adap, 0);
+               udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
        }
        /* 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);
+       return indata;
 }
 
 /*
@@ -221,73 +232,67 @@ 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");
+               pr_info("%s: Testing SDA only, SCL is not readable\n", name);
 
        sda=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(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name);
+               printk(KERN_WARNING "%s: bus seems to be busy\n", name);
                goto bailout;
        }
 
        sdalo(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");
+               printk(KERN_WARNING "%s: SDA stuck high!\n", name);
                goto bailout;
        }
        if ( 0 == scl ) {
-               printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low "
-                       "while pulling SDA low!\n");
+               printk(KERN_WARNING "%s: SCL unexpected low "
+                      "while pulling SDA low!\n", name);
                goto bailout;
        }               
 
        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");
+               printk(KERN_WARNING "%s: SDA stuck low!\n", name);
                goto bailout;
        }
        if ( 0 == scl ) {
-               printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low "
-                       "while pulling SDA high!\n");
+               printk(KERN_WARNING "%s: SCL unexpected low "
+                      "while pulling SDA high!\n", name);
                goto bailout;
        }
 
        scllo(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");
+               printk(KERN_WARNING "%s: SCL stuck high!\n", name);
                goto bailout;
        }
        if ( 0 == sda ) {
-               printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low "
-                       "while pulling SCL low!\n");
+               printk(KERN_WARNING "%s: SDA unexpected low "
+                      "while pulling SCL low!\n", name);
                goto bailout;
        }
        
        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");
+               printk(KERN_WARNING "%s: SCL stuck low!\n", name);
                goto bailout;
        }
        if ( 0 == sda ) {
-               printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low "
-                       "while pulling SCL high!\n");
+               printk(KERN_WARNING "%s: SDA unexpected low "
+                      "while pulling SCL high!\n", name);
                goto bailout;
        }
-       printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name);
+       pr_info("%s: Test OK\n", name);
        return 0;
 bailout:
        sdahi(adap);
@@ -312,44 +317,39 @@ static int try_address(struct i2c_adapter *i2c_adap,
        int i,ret = -1;
        for (i=0;i<=retries;i++) {
                ret = i2c_outb(i2c_adap,addr);
-               if (ret==1)
-                       break;  /* success! */
-               i2c_stop(adap);
-               udelay(5/*adap->udelay*/);
-               if (i==retries)  /* no success */
+               if (ret == 1 || i == retries)
                        break;
-               i2c_start(adap);
+               bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
+               i2c_stop(adap);
                udelay(adap->udelay);
+               yield();
+               bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
+               i2c_start(adap);
        }
-       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?" )
-           );
+       if (i && ret)
+               bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
+                       "0x%02x: %s\n", i + 1,
+                       addr & 1 ? "read from" : "write to", addr >> 1,
+                       ret == 1 ? "success" : "failed, timeout?");
        return ret;
 }
 
 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 = msg->buf;
+       const unsigned char *temp = msg->buf;
        int count = msg->len;
        unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; 
        int retval;
        int wrcount=0;
 
        while (count > 0) {
-               c = *temp;
-               DEB2(dev_dbg(&i2c_adap->dev, "sendbytes: writing %2.2X\n", c&0xff));
-               retval = i2c_outb(i2c_adap,c);
+               retval = i2c_outb(i2c_adap, *temp);
                if ((retval>0) || (nak_ok && (retval==0)))  { /* ok or ignored NAK */
                        count--; 
                        temp++;
                        wrcount++;
                } else { /* arbitration or no acknowledge */
                        dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n");
-                       i2c_stop(adap);
                        return (retval<0)? retval : -EFAULT;
                                /* got a better one ?? */
                }
@@ -362,7 +362,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
        int inval;
        int rdcount=0;          /* counts bytes read */
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-       char *temp = msg->buf;
+       unsigned char *temp = msg->buf;
        int count = msg->len;
 
        while (count > 0) {
@@ -371,30 +371,44 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        *temp = inval;
                        rdcount++;
                } else {   /* read timed out */
-                       printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n");
                        break;
                }
 
                temp++;
                count--;
 
-               if (msg->flags & I2C_M_NO_RD_ACK)
+               if (msg->flags & I2C_M_NO_RD_ACK) {
+                       bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n",
+                               inval);
                        continue;
-
-               if ( count > 0 ) {              /* send ack */
-                       sdalo(adap);
-                       DEBPROTO(printk(" Am "));
-               } else {
-                       sdahi(adap);    /* neg. ack on last byte */
-                       DEBPROTO(printk(" NAm "));
                }
+
+               /* assert: sda is high */
+               if (count)              /* send ack */
+                       setsda(adap, 0);
+               udelay((adap->udelay + 1) / 2);
+               bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval,
+                       count ? "A" : "NA");
                if (sclhi(adap)<0) {    /* timeout */
-                       sdahi(adap);
-                       printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
+                       dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n");
                        return -ETIMEDOUT;
                };
                scllo(adap);
-               sdahi(adap);
+
+               /* Some SMBus transactions require that we receive the
+                  transaction length as the first read byte. */
+               if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) {
+                       if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
+                               dev_err(&i2c_adap->dev, "readbytes: invalid "
+                                       "block length (%d)\n", inval);
+                               return -EREMOTEIO;
+                       }
+                       /* The original count value accounts for the extra
+                          bytes, that is, either 1 for a regular transaction,
+                          or 2 for a PEC transaction. */
+                       count += inval;
+                       msg->len += inval;
+               }
        }
        return rdcount;
 }
@@ -421,27 +435,31 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
        if ( (flags & I2C_M_TEN)  ) { 
                /* a ten bit address */
                addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-               DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
+               bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
                /* try extended address code...*/
                ret = try_address(i2c_adap, addr, retries);
                if ((ret != 1) && !nak_ok)  {
-                       printk(KERN_ERR "died at extended address code.\n");
+                       dev_err(&i2c_adap->dev,
+                               "died at extended address code\n");
                        return -EREMOTEIO;
                }
                /* the remaining 8 bit address */
                ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
                if ((ret != 1) && !nak_ok) {
                        /* the chip did not ack / xmission error occurred */
-                       printk(KERN_ERR "died at 2nd address code.\n");
+                       dev_err(&i2c_adap->dev, "died at 2nd address code\n");
                        return -EREMOTEIO;
                }
                if ( flags & I2C_M_RD ) {
+                       bit_dbg(3, &i2c_adap->dev, "emitting repeated "
+                               "start condition\n");
                        i2c_repstart(adap);
                        /* okay, now switch into reading mode */
                        addr |= 0x01;
                        ret = try_address(i2c_adap, addr, retries);
                        if ((ret!=1) && !nak_ok) {
-                               printk(KERN_ERR "died at extended address code.\n");
+                               dev_err(&i2c_adap->dev,
+                                       "died at repeated address code\n");
                                return -EREMOTEIO;
                        }
                }
@@ -468,44 +486,62 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
        int i,ret;
        unsigned short nak_ok;
 
+       bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
        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) {
+                               bit_dbg(3, &i2c_adap->dev, "emitting "
+                                       "repeated start condition\n");
                                i2c_repstart(adap);
                        }
                        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;
+                               bit_dbg(1, &i2c_adap->dev, "NAK from "
+                                       "device addr 0x%02x msg #%d\n",
+                                       msgs[i].addr, i);
+                               goto bailout;
                        }
                }
                if (pmsg->flags & I2C_M_RD ) {
                        /* read bytes into buffer*/
                        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;
+                       if (ret >= 1)
+                               bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n",
+                                       ret, ret == 1 ? "" : "s");
+                       if (ret < pmsg->len) {
+                               if (ret >= 0)
+                                       ret = -EREMOTEIO;
+                               goto bailout;
                        }
                } else {
                        /* write bytes from buffer */
                        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;
+                       if (ret >= 1)
+                               bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n",
+                                       ret, ret == 1 ? "" : "s");
+                       if (ret < pmsg->len) {
+                               if (ret >= 0)
+                                       ret = -EREMOTEIO;
+                               goto bailout;
                        }
                }
        }
+       ret = i;
+
+bailout:
+       bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
        i2c_stop(adap);
-       return num;
+       return ret;
 }
 
 static u32 bit_func(struct i2c_adapter *adap)
 {
        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 
+              I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+              I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
               I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
 }
 
@@ -520,7 +556,7 @@ static const struct i2c_algorithm i2c_bit_algo = {
 /* 
  * registering functions to load algorithms at runtime 
  */
-int i2c_bit_add_bus(struct i2c_adapter *adap)
+static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
 {
        struct i2c_algo_bit_data *bit_adap = adap->algo_data;
 
@@ -530,25 +566,39 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
                        return -ENODEV;
        }
 
-       DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));
-
        /* register new adapter to i2c module... */
        adap->algo = &i2c_bit_algo;
 
        adap->timeout = 100;    /* default values, should       */
        adap->retries = 3;      /* be replaced by defines       */
 
+       return 0;
+}
+
+int i2c_bit_add_bus(struct i2c_adapter *adap)
+{
+       int err;
+
+       err = i2c_bit_prepare_bus(adap);
+       if (err)
+               return err;
+
        return i2c_add_adapter(adap);
 }
 EXPORT_SYMBOL(i2c_bit_add_bus);
 
+int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
+{
+       int err;
+
+       err = i2c_bit_prepare_bus(adap);
+       if (err)
+               return err;
+
+       return i2c_add_numbered_adapter(adap);
+}
+EXPORT_SYMBOL(i2c_bit_add_numbered_bus);
+
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
 MODULE_LICENSE("GPL");
-
-module_param(bit_test, bool, 0);
-module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
-
-MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck");
-MODULE_PARM_DESC(i2c_debug,
-                "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol");
index ac2d5053078a51043170c9aff0fbc260b033494f..6eaf145e1adae6f8c244f392d77dbba53c5a176c 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * i2c-algo-sgi.c: i2c driver algorithms for SGI adapters.
- * 
+ * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
+ * MACE (SGI O2) chips.
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License version 2 as published by the Free Software Foundation.
  *
@@ -162,8 +163,8 @@ static const struct i2c_algorithm sgi_algo = {
        .functionality  = sgi_func,
 };
 
-/* 
- * registering functions to load algorithms at runtime 
+/*
+ * registering functions to load algorithms at runtime
  */
 int i2c_sgi_add_bus(struct i2c_adapter *adap)
 {
index ece31d2c6c64fde3a50b48c0db7bf6c13af18af7..838dc1c19d61b4ba0fe7908a9ac851d1c5189a59 100644 (file)
@@ -3,11 +3,10 @@
 #
 
 menu "I2C Hardware Bus support"
-       depends on I2C
 
 config I2C_ALI1535
        tristate "ALI 1535"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the SMB
          Host controller on Acer Labs Inc. (ALI) M1535 South Bridges.  The SMB
@@ -19,7 +18,7 @@ config I2C_ALI1535
 
 config I2C_ALI1563
        tristate "ALI 1563"
-       depends on I2C && PCI && EXPERIMENTAL
+       depends on PCI && EXPERIMENTAL
        help
          If you say yes to this option, support will be included for the SMB
          Host controller on Acer Labs Inc. (ALI) M1563 South Bridges.  The SMB
@@ -31,7 +30,7 @@ config I2C_ALI1563
 
 config I2C_ALI15X3
        tristate "ALI 15x3"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the
          Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
@@ -41,7 +40,7 @@ config I2C_ALI15X3
 
 config I2C_AMD756
        tristate "AMD 756/766/768/8111 and nVidia nForce"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the AMD
          756/766/768 mainboard I2C interfaces.  The driver also includes
@@ -66,7 +65,7 @@ config I2C_AMD756_S4882
 
 config I2C_AMD8111
        tristate "AMD 8111"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the
          second (SMBus 2.0) AMD 8111 mainboard I2C interface.
@@ -76,14 +75,14 @@ config I2C_AMD8111
 
 config I2C_AT91
        tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
-       depends on I2C && ARCH_AT91 && EXPERIMENTAL
+       depends on ARCH_AT91 && EXPERIMENTAL
        help
          This supports the use of the I2C interface on Atmel AT91
          processors.
 
 config I2C_AU1550
        tristate "Au1550/Au1200 SMBus interface"
-       depends on I2C && (SOC_AU1550 || SOC_AU1200)
+       depends on SOC_AU1550 || SOC_AU1200
        help
          If you say yes to this option, support will be included for the
          Au1550 and Au1200 SMBus interface.
@@ -91,9 +90,25 @@ config I2C_AU1550
          This driver can also be built as a module.  If so, the module
          will be called i2c-au1550.
 
+config I2C_BLACKFIN_TWI
+       tristate "Blackfin TWI I2C support"
+       depends on BF534 || BF536 || BF537
+       help
+         This is the TWI I2C device driver for Blackfin 534/536/537.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-bfin-twi.
+
+config I2C_BLACKFIN_TWI_CLK_KHZ
+       int "Blackfin TWI I2C clock (kHz)"
+       depends on I2C_BLACKFIN_TWI
+       range 10 400
+       default 50
+       help
+         The unit of the TWI clock is kHz.
+
 config I2C_ELEKTOR
        tristate "Elektor ISA card"
-       depends on I2C && ISA && BROKEN_ON_SMP
+       depends on ISA && BROKEN_ON_SMP
        select I2C_ALGOPCF
        help
          This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
@@ -102,9 +117,17 @@ config I2C_ELEKTOR
          This support is also available as a module.  If so, the module 
          will be called i2c-elektor.
 
+config I2C_GPIO
+       tristate "GPIO-based bitbanging I2C"
+       depends on GENERIC_GPIO
+       select I2C_ALGOBIT
+       help
+         This is a very simple bitbanging I2C driver utilizing the
+         arch-neutral GPIO API to control the SCL and SDA lines.
+
 config I2C_HYDRA
        tristate "CHRP Apple Hydra Mac I/O I2C interface"
-       depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL
+       depends on PCI && PPC_CHRP && EXPERIMENTAL
        select I2C_ALGOBIT
        help
          This supports the use of the I2C interface in the Apple Hydra Mac
@@ -116,7 +139,7 @@ config I2C_HYDRA
 
 config I2C_I801
        tristate "Intel 82801 (ICH)"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the Intel
          801 family of mainboard I2C interfaces.  Specifically, the following
@@ -139,7 +162,7 @@ config I2C_I801
 
 config I2C_I810
        tristate "Intel 810/815"
-       depends on I2C && PCI
+       depends on PCI
        select I2C_ALGOBIT
        help
          If you say yes to this option, support will be included for the Intel
@@ -156,7 +179,7 @@ config I2C_I810
 
 config I2C_PXA
        tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
-       depends on I2C && EXPERIMENTAL && ARCH_PXA
+       depends on EXPERIMENTAL && ARCH_PXA
        help
          If you have devices in the PXA I2C bus, say yes to this option.
          This driver can also be built as a module.  If so, the module
@@ -172,7 +195,7 @@ config I2C_PXA_SLAVE
 
 config I2C_PIIX4
        tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the Intel
          PIIX4 family of mainboard I2C interfaces.  Specifically, the following
@@ -195,7 +218,7 @@ config I2C_PIIX4
 
 config I2C_IBM_IIC
        tristate "IBM PPC 4xx on-chip I2C interface"
-       depends on IBM_OCP && I2C
+       depends on IBM_OCP
        help
          Say Y here if you want to use IIC peripheral found on 
          embedded IBM PPC 4xx based systems. 
@@ -205,7 +228,7 @@ config I2C_IBM_IIC
 
 config I2C_IOP3XX
        tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
-       depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX) && I2C
+       depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
        help
          Say Y here if you want to use the IIC bus controller on
          the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
@@ -215,11 +238,10 @@ config I2C_IOP3XX
 
 config I2C_ISA
        tristate
-       depends on I2C
 
 config I2C_IXP4XX
-       tristate "IXP4xx GPIO-Based I2C Interface"
-       depends on I2C && ARCH_IXP4XX
+       tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)"
+       depends on ARCH_IXP4XX
        select I2C_ALGOBIT
        help
          Say Y here if you have an Intel IXP4xx(420,421,422,425) based 
@@ -228,9 +250,12 @@ config I2C_IXP4XX
          This support is also available as a module. If so, the module
          will be called i2c-ixp4xx.
 
+         This driver is deprecated and will be dropped soon. Use i2c-gpio
+         instead.
+
 config I2C_IXP2000
-       tristate "IXP2000 GPIO-Based I2C Interface"
-       depends on I2C && ARCH_IXP2000
+       tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)"
+       depends on ARCH_IXP2000
        select I2C_ALGOBIT
        help
          Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based 
@@ -239,9 +264,12 @@ config I2C_IXP2000
          This support is also available as a module. If so, the module
          will be called i2c-ixp2000.
 
+         This driver is deprecated and will be dropped soon. Use i2c-gpio
+         instead.
+
 config I2C_POWERMAC
        tristate "Powermac I2C interface"
-       depends on I2C && PPC_PMAC
+       depends on PPC_PMAC
        default y
        help
          This exposes the various PowerMac i2c interfaces to the linux i2c
@@ -253,7 +281,7 @@ config I2C_POWERMAC
 
 config I2C_MPC
        tristate "MPC107/824x/85xx/52xx/86xx"
-       depends on I2C && PPC32
+       depends on PPC32
        help
          If you say yes to this option, support will be included for the
          built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
@@ -265,7 +293,7 @@ config I2C_MPC
 
 config I2C_NFORCE2
        tristate "Nvidia nForce2, nForce3 and nForce4"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the Nvidia
          nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
@@ -275,7 +303,7 @@ config I2C_NFORCE2
 
 config I2C_OCORES
        tristate "OpenCores I2C Controller"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          If you say yes to this option, support will be included for the
          OpenCores I2C controller. For details see
@@ -286,7 +314,7 @@ config I2C_OCORES
 
 config I2C_OMAP
        tristate "OMAP I2C adapter"
-       depends on I2C && ARCH_OMAP
+       depends on ARCH_OMAP
        default y if MACH_OMAP_H3 || MACH_OMAP_OSK
        help
          If you say yes to this option, support will be included for the
@@ -296,7 +324,7 @@ config I2C_OMAP
 
 config I2C_PARPORT
        tristate "Parallel port adapter"
-       depends on I2C && PARPORT
+       depends on PARPORT
        select I2C_ALGOBIT
        help
          This supports parallel port I2C adapters such as the ones made by
@@ -320,7 +348,6 @@ config I2C_PARPORT
 
 config I2C_PARPORT_LIGHT
        tristate "Parallel port adapter (light)"
-       depends on I2C
        select I2C_ALGOBIT
        help
          This supports parallel port I2C adapters such as the ones made by
@@ -344,13 +371,13 @@ config I2C_PARPORT_LIGHT
 
 config I2C_PASEMI
        tristate "PA Semi SMBus interface"
-       depends on PPC_PASEMI && I2C && PCI
+       depends on PPC_PASEMI && PCI
        help
          Supports the PA Semi PWRficient on-chip SMBus interfaces.
 
 config I2C_PROSAVAGE
        tristate "S3/VIA (Pro)Savage"
-       depends on I2C && PCI
+       depends on PCI
        select I2C_ALGOBIT
        help
          If you say yes to this option, support will be included for the
@@ -365,19 +392,19 @@ config I2C_PROSAVAGE
 
 config I2C_RPXLITE
        tristate "Embedded Planet RPX Lite/Classic support"
-       depends on (RPXLITE || RPXCLASSIC) && I2C
+       depends on RPXLITE || RPXCLASSIC
        select I2C_ALGO8XX
 
 config I2C_S3C2410
        tristate "S3C2410 I2C Driver"
-       depends on I2C && ARCH_S3C2410
+       depends on ARCH_S3C2410
        help
          Say Y here to include support for I2C controller in the
          Samsung S3C2410 based System-on-Chip devices.
 
 config I2C_SAVAGE4
        tristate "S3 Savage 4"
-       depends on I2C && PCI && EXPERIMENTAL
+       depends on PCI && EXPERIMENTAL
        select I2C_ALGOBIT
        help
          If you say yes to this option, support will be included for the 
@@ -388,13 +415,25 @@ config I2C_SAVAGE4
 
 config I2C_SIBYTE
        tristate "SiByte SMBus interface"
-       depends on SIBYTE_SB1xxx_SOC && I2C
+       depends on SIBYTE_SB1xxx_SOC
        help
          Supports the SiByte SOC on-chip I2C interfaces (2 channels).
 
+config I2C_SIMTEC
+       tristate "Simtec Generic I2C interface"
+       select I2C_ALGOBIT
+       help
+         If you say yes to this option, support will be inclyded for
+         the Simtec Generic I2C interface. This driver is for the
+         simple I2C bus used on newer Simtec products for general
+         I2C, such as DDC on the Simtec BBD2016A.
+
+         This driver can also be build as a module. If so, the module
+         will be called i2c-simtec.
+
 config SCx200_I2C
-       tristate "NatSemi SCx200 I2C using GPIO pins"
-       depends on SCx200_GPIO && I2C
+       tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
+       depends on SCx200_GPIO
        select I2C_ALGOBIT
        help
          Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
@@ -404,6 +443,9 @@ config SCx200_I2C
          This support is also available as a module.  If so, the module 
          will be called scx200_i2c.
 
+         This driver is deprecated and will be dropped soon. Use i2c-gpio
+         (or scx200_acb) instead.
+
 config SCx200_I2C_SCL
        int "GPIO pin used for SCL"
        depends on SCx200_I2C
@@ -422,7 +464,7 @@ config SCx200_I2C_SDA
 
 config SCx200_ACB
        tristate "Geode ACCESS.bus support"
-       depends on X86_32 && I2C && PCI
+       depends on X86_32 && PCI
        help
          Enable the use of the ACCESS.bus controllers on the Geode SCx200 and
          SC1100 processors and the CS5535 and CS5536 Geode companion devices.
@@ -434,7 +476,7 @@ config SCx200_ACB
 
 config I2C_SIS5595
        tristate "SiS 5595"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the 
          SiS5595 SMBus (a subset of I2C) interface.
@@ -444,7 +486,7 @@ config I2C_SIS5595
 
 config I2C_SIS630
        tristate "SiS 630/730"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the 
          SiS630 and SiS730 SMBus (a subset of I2C) interface.
@@ -454,7 +496,7 @@ config I2C_SIS630
 
 config I2C_SIS96X
        tristate "SiS 96x"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the SiS
          96x SMBus (a subset of I2C) interfaces.  Specifically, the following
@@ -472,7 +514,7 @@ config I2C_SIS96X
 
 config I2C_STUB
        tristate "I2C/SMBus Test Stub"
-       depends on I2C && EXPERIMENTAL && 'm'
+       depends on EXPERIMENTAL && m
        default 'n'
        help
          This module may be useful to developers of SMBus client drivers,
@@ -483,9 +525,20 @@ config I2C_STUB
 
          If you don't know what to do here, definitely say N.
 
+config I2C_TINY_USB
+       tristate "I2C-Tiny-USB"
+       depends on USB
+       help
+         If you say yes to this option, support will be included for the
+         i2c-tiny-usb, a simple do-it-yourself USB to I2C interface. See
+         http://www.harbaum.org/till/i2c_tiny_usb for hardware details.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-tiny-usb.
+
 config I2C_VERSATILE
        tristate "ARM Versatile/Realview I2C bus support"
-       depends on I2C && (ARCH_VERSATILE || ARCH_REALVIEW)
+       depends on ARCH_VERSATILE || ARCH_REALVIEW
        select I2C_ALGOBIT
        help
          Say yes if you want to support the I2C serial bus on ARMs Versatile
@@ -496,7 +549,7 @@ config I2C_VERSATILE
 
 config I2C_ACORN
        bool "Acorn IOC/IOMD I2C bus support"
-       depends on I2C && ARCH_ACORN
+       depends on ARCH_ACORN
        default y
        select I2C_ALGOBIT
        help
@@ -506,7 +559,7 @@ config I2C_ACORN
 
 config I2C_VIA
        tristate "VIA 82C586B"
-       depends on I2C && PCI && EXPERIMENTAL
+       depends on PCI && EXPERIMENTAL
        select I2C_ALGOBIT
        help
          If you say yes to this option, support will be included for the VIA
@@ -517,7 +570,7 @@ config I2C_VIA
 
 config I2C_VIAPRO
        tristate "VIA VT82C596/82C686/82xx and CX700"
-       depends on I2C && PCI
+       depends on PCI
        help
          If you say yes to this option, support will be included for the VIA
          VT82C596 and later SMBus interface.  Specifically, the following
@@ -536,7 +589,7 @@ config I2C_VIAPRO
 
 config I2C_VOODOO3
        tristate "Voodoo 3"
-       depends on I2C && PCI
+       depends on PCI
        select I2C_ALGOBIT
        help
          If you say yes to this option, support will be included for the
@@ -547,7 +600,7 @@ config I2C_VOODOO3
 
 config I2C_PCA_ISA
        tristate "PCA9564 on an ISA bus"
-       depends on I2C
+       depends on ISA
        select I2C_ALGOPCA
        default n
        help
@@ -564,7 +617,7 @@ config I2C_PCA_ISA
 
 config I2C_MV64XXX
        tristate "Marvell mv64xxx I2C Controller"
-       depends on I2C && MV64X60 && EXPERIMENTAL
+       depends on MV64X60 && EXPERIMENTAL
        help
          If you say yes to this option, support will be included for the
          built-in I2C interface on the Marvell 64xxx line of host bridges.
@@ -574,7 +627,7 @@ config I2C_MV64XXX
 
 config I2C_PNX
        tristate "I2C bus support for Philips PNX targets"
-       depends on ARCH_PNX4008 && I2C
+       depends on ARCH_PNX4008
        help
          This driver supports the Philips IP3204 I2C IP block master and/or
          slave controller
index 290b54018354088165b64d49f946e405509351b9..14d1432f698bf9b24ffd6b70917361dd93403238 100644 (file)
@@ -10,7 +10,9 @@ obj-$(CONFIG_I2C_AMD756_S4882)        += i2c-amd756-s4882.o
 obj-$(CONFIG_I2C_AMD8111)      += i2c-amd8111.o
 obj-$(CONFIG_I2C_AT91)         += i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)       += i2c-au1550.o
+obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
 obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
+obj-$(CONFIG_I2C_GPIO)         += i2c-gpio.o
 obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
 obj-$(CONFIG_I2C_I801)         += i2c-i801.o
 obj-$(CONFIG_I2C_I810)         += i2c-i810.o
@@ -37,10 +39,12 @@ obj-$(CONFIG_I2C_RPXLITE)   += i2c-rpx.o
 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o
 obj-$(CONFIG_I2C_SAVAGE4)      += i2c-savage4.o
 obj-$(CONFIG_I2C_SIBYTE)       += i2c-sibyte.o
+obj-$(CONFIG_I2C_SIMTEC)       += i2c-simtec.o
 obj-$(CONFIG_I2C_SIS5595)      += i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
 obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
+obj-$(CONFIG_I2C_TINY_USB)     += i2c-tiny-usb.o
 obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
 obj-$(CONFIG_I2C_ACORN)                += i2c-acorn.o
 obj-$(CONFIG_I2C_VIA)          += i2c-via.o
index 1e277ba5a9f34aaa3f2f6beee5704c447d79edd0..f14372ac2fc5d08ef0b8ced5b994d86af7a5dee5 100644 (file)
@@ -497,7 +497,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_
        /* set up the sysfs linkage to our parent device */
        ali1535_adapter.dev.parent = &dev->dev;
 
-       snprintf(ali1535_adapter.name, I2C_NAME_SIZE, 
+       snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
                "SMBus ALI1535 adapter at %04x", ali1535_smba);
        return i2c_add_adapter(&ali1535_adapter);
 }
index e47fe01bf42ae5c0bd73fcf215e8a1c01d361e66..93bf87d709618fff0ba489aa17028b2d84a39f23 100644 (file)
@@ -492,7 +492,7 @@ static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_
        /* set up the sysfs linkage to our parent device */
        ali15x3_adapter.dev.parent = &dev->dev;
 
-       snprintf(ali15x3_adapter.name, I2C_NAME_SIZE,
+       snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name),
                "SMBus ALI15X3 adapter at %04x", ali15x3_smba);
        return i2c_add_adapter(&ali15x3_adapter);
 }
index 0c70f8293341c9aee6f7cc5e6206b57c51ef8742..c9fca7b492675a7c765635761602562eca7b024a 100644 (file)
@@ -365,7 +365,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
        }
 
        smbus->adapter.owner = THIS_MODULE;
-       snprintf(smbus->adapter.name, I2C_NAME_SIZE,
+       snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
                "SMBus2 AMD8111 adapter at %04x", smbus->base);
        smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
        smbus->adapter.class = I2C_CLASS_HWMON;
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
new file mode 100644 (file)
index 0000000..6311039
--- /dev/null
@@ -0,0 +1,644 @@
+/*
+ * drivers/i2c/busses/i2c-bfin-twi.c
+ *
+ * Description: Driver for Blackfin Two Wire Interface
+ *
+ * Author:      sonicz  <sonic.zhang@analog.com>
+ *
+ * Copyright (c) 2005-2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/mm.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+#define POLL_TIMEOUT       (2 * HZ)
+
+/* SMBus mode*/
+#define TWI_I2C_MODE_STANDARD          0x01
+#define TWI_I2C_MODE_STANDARDSUB       0x02
+#define TWI_I2C_MODE_COMBINED          0x04
+
+struct bfin_twi_iface {
+       struct mutex            twi_lock;
+       int                     irq;
+       spinlock_t              lock;
+       char                    read_write;
+       u8                      command;
+       u8                      *transPtr;
+       int                     readNum;
+       int                     writeNum;
+       int                     cur_mode;
+       int                     manual_stop;
+       int                     result;
+       int                     timeout_count;
+       struct timer_list       timeout_timer;
+       struct i2c_adapter      adap;
+       struct completion       complete;
+};
+
+static struct bfin_twi_iface twi_iface;
+
+static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
+{
+       unsigned short twi_int_status = bfin_read_TWI_INT_STAT();
+       unsigned short mast_stat = bfin_read_TWI_MASTER_STAT();
+
+       if (twi_int_status & XMTSERV) {
+               /* Transmit next data */
+               if (iface->writeNum > 0) {
+                       bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+                       iface->writeNum--;
+               }
+               /* start receive immediately after complete sending in
+                * combine mode.
+                */
+               else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+                       bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
+                               | MDIR | RSTART);
+               } else if (iface->manual_stop)
+                       bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
+                               | STOP);
+               SSYNC();
+               /* Clear status */
+               bfin_write_TWI_INT_STAT(XMTSERV);
+               SSYNC();
+       }
+       if (twi_int_status & RCVSERV) {
+               if (iface->readNum > 0) {
+                       /* Receive next data */
+                       *(iface->transPtr) = bfin_read_TWI_RCV_DATA8();
+                       if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+                               /* Change combine mode into sub mode after
+                                * read first data.
+                                */
+                               iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+                               /* Get read number from first byte in block
+                                * combine mode.
+                                */
+                               if (iface->readNum == 1 && iface->manual_stop)
+                                       iface->readNum = *iface->transPtr + 1;
+                       }
+                       iface->transPtr++;
+                       iface->readNum--;
+               } else if (iface->manual_stop) {
+                       bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
+                               | STOP);
+                       SSYNC();
+               }
+               /* Clear interrupt source */
+               bfin_write_TWI_INT_STAT(RCVSERV);
+               SSYNC();
+       }
+       if (twi_int_status & MERR) {
+               bfin_write_TWI_INT_STAT(MERR);
+               bfin_write_TWI_INT_MASK(0);
+               bfin_write_TWI_MASTER_STAT(0x3e);
+               bfin_write_TWI_MASTER_CTL(0);
+               SSYNC();
+               iface->result = -1;
+               /* if both err and complete int stats are set, return proper
+                * results.
+                */
+               if (twi_int_status & MCOMP) {
+                       bfin_write_TWI_INT_STAT(MCOMP);
+                       bfin_write_TWI_INT_MASK(0);
+                       bfin_write_TWI_MASTER_CTL(0);
+                       SSYNC();
+                       /* If it is a quick transfer, only address bug no data,
+                        * not an err, return 1.
+                        */
+                       if (iface->writeNum == 0 && (mast_stat & BUFRDERR))
+                               iface->result = 1;
+                       /* If address not acknowledged return -1,
+                        * else return 0.
+                        */
+                       else if (!(mast_stat & ANAK))
+                               iface->result = 0;
+               }
+               complete(&iface->complete);
+               return;
+       }
+       if (twi_int_status & MCOMP) {
+               bfin_write_TWI_INT_STAT(MCOMP);
+               SSYNC();
+               if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+                       if (iface->readNum == 0) {
+                               /* set the read number to 1 and ask for manual
+                                * stop in block combine mode
+                                */
+                               iface->readNum = 1;
+                               iface->manual_stop = 1;
+                               bfin_write_TWI_MASTER_CTL(
+                                       bfin_read_TWI_MASTER_CTL()
+                                       | (0xff << 6));
+                       } else {
+                               /* set the readd number in other
+                                * combine mode.
+                                */
+                               bfin_write_TWI_MASTER_CTL(
+                                       (bfin_read_TWI_MASTER_CTL() &
+                                       (~(0xff << 6))) |
+                                       ( iface->readNum << 6));
+                       }
+                       /* remove restart bit and enable master receive */
+                       bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() &
+                               ~RSTART);
+                       bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() |
+                               MEN | MDIR);
+                       SSYNC();
+               } else {
+                       iface->result = 1;
+                       bfin_write_TWI_INT_MASK(0);
+                       bfin_write_TWI_MASTER_CTL(0);
+                       SSYNC();
+                       complete(&iface->complete);
+               }
+       }
+}
+
+/* Interrupt handler */
+static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)
+{
+       struct bfin_twi_iface *iface = dev_id;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iface->lock, flags);
+       del_timer(&iface->timeout_timer);
+       bfin_twi_handle_interrupt(iface);
+       spin_unlock_irqrestore(&iface->lock, flags);
+       return IRQ_HANDLED;
+}
+
+static void bfin_twi_timeout(unsigned long data)
+{
+       struct bfin_twi_iface *iface = (struct bfin_twi_iface *)data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iface->lock, flags);
+       bfin_twi_handle_interrupt(iface);
+       if (iface->result == 0) {
+               iface->timeout_count--;
+               if (iface->timeout_count > 0) {
+                       iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+                       add_timer(&iface->timeout_timer);
+               } else {
+                       iface->result = -1;
+                       complete(&iface->complete);
+               }
+       }
+       spin_unlock_irqrestore(&iface->lock, flags);
+}
+
+/*
+ * Generic i2c master transfer entrypoint
+ */
+static int bfin_twi_master_xfer(struct i2c_adapter *adap,
+                               struct i2c_msg *msgs, int num)
+{
+       struct bfin_twi_iface *iface = adap->algo_data;
+       struct i2c_msg *pmsg;
+       int i, ret;
+       int rc = 0;
+
+       if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
+               return -ENXIO;
+
+       mutex_lock(&iface->twi_lock);
+
+       while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
+               mutex_unlock(&iface->twi_lock);
+               yield();
+               mutex_lock(&iface->twi_lock);
+       }
+
+       ret = 0;
+       for (i = 0; rc >= 0 && i < num; i++) {
+               pmsg = &msgs[i];
+               if (pmsg->flags & I2C_M_TEN) {
+                       dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr "
+                               "not supported !\n");
+                       rc = -EINVAL;
+                       break;
+               }
+
+               iface->cur_mode = TWI_I2C_MODE_STANDARD;
+               iface->manual_stop = 0;
+               iface->transPtr = pmsg->buf;
+               iface->writeNum = iface->readNum = pmsg->len;
+               iface->result = 0;
+               iface->timeout_count = 10;
+               /* Set Transmit device address */
+               bfin_write_TWI_MASTER_ADDR(pmsg->addr);
+
+               /* FIFO Initiation. Data in FIFO should be
+                *  discarded before start a new operation.
+                */
+               bfin_write_TWI_FIFO_CTL(0x3);
+               SSYNC();
+               bfin_write_TWI_FIFO_CTL(0);
+               SSYNC();
+
+               if (pmsg->flags & I2C_M_RD)
+                       iface->read_write = I2C_SMBUS_READ;
+               else {
+                       iface->read_write = I2C_SMBUS_WRITE;
+                       /* Transmit first data */
+                       if (iface->writeNum > 0) {
+                               bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+                               iface->writeNum--;
+                               SSYNC();
+                       }
+               }
+
+               /* clear int stat */
+               bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
+
+               /* Interrupt mask . Enable XMT, RCV interrupt */
+               bfin_write_TWI_INT_MASK(MCOMP | MERR |
+                       ((iface->read_write == I2C_SMBUS_READ)?
+                       RCVSERV : XMTSERV));
+               SSYNC();
+
+               if (pmsg->len > 0 && pmsg->len <= 255)
+                       bfin_write_TWI_MASTER_CTL(pmsg->len << 6);
+               else if (pmsg->len > 255) {
+                       bfin_write_TWI_MASTER_CTL(0xff << 6);
+                       iface->manual_stop = 1;
+               } else
+                       break;
+
+               iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+               add_timer(&iface->timeout_timer);
+
+               /* Master enable */
+               bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+                       ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
+                       ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
+               SSYNC();
+
+               wait_for_completion(&iface->complete);
+
+               rc = iface->result;
+               if (rc == 1)
+                       ret++;
+               else if (rc == -1)
+                       break;
+       }
+
+       /* Release mutex */
+       mutex_unlock(&iface->twi_lock);
+
+       return ret;
+}
+
+/*
+ * SMBus type transfer entrypoint
+ */
+
+int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+                       unsigned short flags, char read_write,
+                       u8 command, int size, union i2c_smbus_data *data)
+{
+       struct bfin_twi_iface *iface = adap->algo_data;
+       int rc = 0;
+
+       if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
+               return -ENXIO;
+
+       mutex_lock(&iface->twi_lock);
+
+       while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
+               mutex_unlock(&iface->twi_lock);
+               yield();
+               mutex_lock(&iface->twi_lock);
+       }
+
+       iface->writeNum = 0;
+       iface->readNum = 0;
+
+       /* Prepare datas & select mode */
+       switch (size) {
+       case I2C_SMBUS_QUICK:
+               iface->transPtr = NULL;
+               iface->cur_mode = TWI_I2C_MODE_STANDARD;
+               break;
+       case I2C_SMBUS_BYTE:
+               if (data == NULL)
+                       iface->transPtr = NULL;
+               else {
+                       if (read_write == I2C_SMBUS_READ)
+                               iface->readNum = 1;
+                       else
+                               iface->writeNum = 1;
+                       iface->transPtr = &data->byte;
+               }
+               iface->cur_mode = TWI_I2C_MODE_STANDARD;
+               break;
+       case I2C_SMBUS_BYTE_DATA:
+               if (read_write == I2C_SMBUS_READ) {
+                       iface->readNum = 1;
+                       iface->cur_mode = TWI_I2C_MODE_COMBINED;
+               } else {
+                       iface->writeNum = 1;
+                       iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+               }
+               iface->transPtr = &data->byte;
+               break;
+       case I2C_SMBUS_WORD_DATA:
+               if (read_write == I2C_SMBUS_READ) {
+                       iface->readNum = 2;
+                       iface->cur_mode = TWI_I2C_MODE_COMBINED;
+               } else {
+                       iface->writeNum = 2;
+                       iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+               }
+               iface->transPtr = (u8 *)&data->word;
+               break;
+       case I2C_SMBUS_PROC_CALL:
+               iface->writeNum = 2;
+               iface->readNum = 2;
+               iface->cur_mode = TWI_I2C_MODE_COMBINED;
+               iface->transPtr = (u8 *)&data->word;
+               break;
+       case I2C_SMBUS_BLOCK_DATA:
+               if (read_write == I2C_SMBUS_READ) {
+                       iface->readNum = 0;
+                       iface->cur_mode = TWI_I2C_MODE_COMBINED;
+               } else {
+                       iface->writeNum = data->block[0] + 1;
+                       iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+               }
+               iface->transPtr = data->block;
+               break;
+       default:
+               return -1;
+       }
+
+       iface->result = 0;
+       iface->manual_stop = 0;
+       iface->read_write = read_write;
+       iface->command = command;
+       iface->timeout_count = 10;
+
+       /* FIFO Initiation. Data in FIFO should be discarded before
+        * start a new operation.
+        */
+       bfin_write_TWI_FIFO_CTL(0x3);
+       SSYNC();
+       bfin_write_TWI_FIFO_CTL(0);
+
+       /* clear int stat */
+       bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
+
+       /* Set Transmit device address */
+       bfin_write_TWI_MASTER_ADDR(addr);
+       SSYNC();
+
+       iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+       add_timer(&iface->timeout_timer);
+
+       switch (iface->cur_mode) {
+       case TWI_I2C_MODE_STANDARDSUB:
+               bfin_write_TWI_XMT_DATA8(iface->command);
+               bfin_write_TWI_INT_MASK(MCOMP | MERR |
+                       ((iface->read_write == I2C_SMBUS_READ) ?
+                       RCVSERV : XMTSERV));
+               SSYNC();
+
+               if (iface->writeNum + 1 <= 255)
+                       bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
+               else {
+                       bfin_write_TWI_MASTER_CTL(0xff << 6);
+                       iface->manual_stop = 1;
+               }
+               /* Master enable */
+               bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+                       ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
+               break;
+       case TWI_I2C_MODE_COMBINED:
+               bfin_write_TWI_XMT_DATA8(iface->command);
+               bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV);
+               SSYNC();
+
+               if (iface->writeNum > 0)
+                       bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
+               else
+                       bfin_write_TWI_MASTER_CTL(0x1 << 6);
+               /* Master enable */
+               bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+                       ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
+               break;
+       default:
+               bfin_write_TWI_MASTER_CTL(0);
+               if (size != I2C_SMBUS_QUICK) {
+                       /* Don't access xmit data register when this is a
+                        * read operation.
+                        */
+                       if (iface->read_write != I2C_SMBUS_READ) {
+                               if (iface->writeNum > 0) {
+                                       bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+                                       if (iface->writeNum <= 255)
+                                               bfin_write_TWI_MASTER_CTL(iface->writeNum << 6);
+                                       else {
+                                               bfin_write_TWI_MASTER_CTL(0xff << 6);
+                                               iface->manual_stop = 1;
+                                       }
+                                       iface->writeNum--;
+                               } else {
+                                       bfin_write_TWI_XMT_DATA8(iface->command);
+                                       bfin_write_TWI_MASTER_CTL(1 << 6);
+                               }
+                       } else {
+                               if (iface->readNum > 0 && iface->readNum <= 255)
+                                       bfin_write_TWI_MASTER_CTL(iface->readNum << 6);
+                               else if (iface->readNum > 255) {
+                                       bfin_write_TWI_MASTER_CTL(0xff << 6);
+                                       iface->manual_stop = 1;
+                               } else {
+                                       del_timer(&iface->timeout_timer);
+                                       break;
+                               }
+                       }
+               }
+               bfin_write_TWI_INT_MASK(MCOMP | MERR |
+                       ((iface->read_write == I2C_SMBUS_READ) ?
+                       RCVSERV : XMTSERV));
+               SSYNC();
+
+               /* Master enable */
+               bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+                       ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
+                       ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
+               break;
+       }
+       SSYNC();
+
+       wait_for_completion(&iface->complete);
+
+       rc = (iface->result >= 0) ? 0 : -1;
+
+       /* Release mutex */
+       mutex_unlock(&iface->twi_lock);
+
+       return rc;
+}
+
+/*
+ * Return what the adapter supports
+ */
+static u32 bfin_twi_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+              I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+              I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
+              I2C_FUNC_I2C;
+}
+
+
+static struct i2c_algorithm bfin_twi_algorithm = {
+       .master_xfer   = bfin_twi_master_xfer,
+       .smbus_xfer    = bfin_twi_smbus_xfer,
+       .functionality = bfin_twi_functionality,
+};
+
+
+static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
+{
+/*     struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
+
+       /* Disable TWI */
+       bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA);
+       SSYNC();
+
+       return 0;
+}
+
+static int i2c_bfin_twi_resume(struct platform_device *dev)
+{
+/*     struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
+
+       /* Enable TWI */
+       bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+       SSYNC();
+
+       return 0;
+}
+
+static int i2c_bfin_twi_probe(struct platform_device *dev)
+{
+       struct bfin_twi_iface *iface = &twi_iface;
+       struct i2c_adapter *p_adap;
+       int rc;
+
+       mutex_init(&(iface->twi_lock));
+       spin_lock_init(&(iface->lock));
+       init_completion(&(iface->complete));
+       iface->irq = IRQ_TWI;
+
+       init_timer(&(iface->timeout_timer));
+       iface->timeout_timer.function = bfin_twi_timeout;
+       iface->timeout_timer.data = (unsigned long)iface;
+
+       p_adap = &iface->adap;
+       p_adap->id = I2C_HW_BLACKFIN;
+       strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
+       p_adap->algo = &bfin_twi_algorithm;
+       p_adap->algo_data = iface;
+       p_adap->class = I2C_CLASS_ALL;
+       p_adap->dev.parent = &dev->dev;
+
+       rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
+               IRQF_DISABLED, dev->name, iface);
+       if (rc) {
+               dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n",
+                       iface->irq);
+               return -ENODEV;
+       }
+
+       /* Set TWI internal clock as 10MHz */
+       bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
+
+       /* Set Twi interface clock as specified */
+       bfin_write_TWI_CLKDIV((( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ )
+                       << 8) | (( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ )
+                       & 0xFF));
+
+       /* Enable TWI */
+       bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+       SSYNC();
+
+       rc = i2c_add_adapter(p_adap);
+       if (rc < 0)
+               free_irq(iface->irq, iface);
+       else
+               platform_set_drvdata(dev, iface);
+
+       return rc;
+}
+
+static int i2c_bfin_twi_remove(struct platform_device *pdev)
+{
+       struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+
+       i2c_del_adapter(&(iface->adap));
+       free_irq(iface->irq, iface);
+
+       return 0;
+}
+
+static struct platform_driver i2c_bfin_twi_driver = {
+       .probe          = i2c_bfin_twi_probe,
+       .remove         = i2c_bfin_twi_remove,
+       .suspend        = i2c_bfin_twi_suspend,
+       .resume         = i2c_bfin_twi_resume,
+       .driver         = {
+               .name   = "i2c-bfin-twi",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init i2c_bfin_twi_init(void)
+{
+       pr_info("I2C: Blackfin I2C TWI driver\n");
+
+       return platform_driver_register(&i2c_bfin_twi_driver);
+}
+
+static void __exit i2c_bfin_twi_exit(void)
+{
+       platform_driver_unregister(&i2c_bfin_twi_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Blackfin TWI");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_bfin_twi_init);
+module_exit(i2c_bfin_twi_exit);
index 834967464814e08f8fafeb65b6d6e91d39c3d9b9..804f0a551c055fd9447f6b75d6b364d19a89567e 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/pci.h>
 #include <linux/wait.h>
 
+#include <linux/isa.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-pcf.h>
 
@@ -207,7 +208,7 @@ static struct i2c_adapter pcf_isa_ops = {
        .name           = "i2c-elektor",
 };
 
-static int __init i2c_pcfisa_init(void)
+static int __devinit elektor_match(struct device *dev, unsigned int id)
 {
 #ifdef __alpha__
        /* check to see we have memory mapped PCF8584 connected to the
@@ -222,9 +223,8 @@ static int __init i2c_pcfisa_init(void)
                        /* yeap, we've found cypress, let's check config */
                        if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
 
-                               pr_debug("%s: found cy82c693, config "
-                                        "register 0x47 = 0x%02x\n",
-                                        pcf_isa_ops.name, config);
+                               dev_dbg(dev, "found cy82c693, config "
+                                       "register 0x47 = 0x%02x\n", config);
 
                                /* UP2000 board has this register set to 0xe1,
                                   but the most significant bit as seems can be
@@ -244,9 +244,9 @@ static int __init i2c_pcfisa_init(void)
                                           8.25 MHz (PCI/4) clock
                                           (this can be read from cypress) */
                                        clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
-                                       pr_info("%s: found API UP2000 like "
-                                               "board, will probe PCF8584 "
-                                               "later\n", pcf_isa_ops.name);
+                                       dev_info(dev, "found API UP2000 like "
+                                                "board, will probe PCF8584 "
+                                                "later\n");
                                }
                        }
                        pci_dev_put(cy693_dev);
@@ -256,22 +256,27 @@ static int __init i2c_pcfisa_init(void)
 
        /* sanity checks for mmapped I/O */
        if (mmapped && base < 0xc8000) {
-               printk(KERN_ERR "%s: incorrect base address (%#x) specified "
-                      "for mmapped I/O\n", pcf_isa_ops.name, base);
-               return -ENODEV;
+               dev_err(dev, "incorrect base address (%#x) specified "
+                      "for mmapped I/O\n", base);
+               return 0;
        }
 
        if (base == 0) {
                base = DEFAULT_BASE;
        }
+       return 1;
+}
 
+static int __devinit elektor_probe(struct device *dev, unsigned int id)
+{
        init_waitqueue_head(&pcf_wait);
        if (pcf_isa_init())
                return -ENODEV;
+       pcf_isa_ops.dev.parent = dev;
        if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
                goto fail;
 
-       dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base);
+       dev_info(dev, "found device at %#x\n", base);
 
        return 0;
 
@@ -291,7 +296,7 @@ static int __init i2c_pcfisa_init(void)
        return -ENODEV;
 }
 
-static void i2c_pcfisa_exit(void)
+static int __devexit elektor_remove(struct device *dev, unsigned int id)
 {
        i2c_del_adapter(&pcf_isa_ops);
 
@@ -307,6 +312,28 @@ static void i2c_pcfisa_exit(void)
                iounmap(base_iomem);
                release_mem_region(base, 2);
        }
+
+       return 0;
+}
+
+static struct isa_driver i2c_elektor_driver = {
+       .match          = elektor_match,
+       .probe          = elektor_probe,
+       .remove         = __devexit_p(elektor_remove),
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "i2c-elektor",
+       },
+};
+
+static int __init i2c_pcfisa_init(void)
+{
+       return isa_register_driver(&i2c_elektor_driver, 1);
+}
+
+static void __exit i2c_pcfisa_exit(void)
+{
+       isa_unregister_driver(&i2c_elektor_driver);
 }
 
 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
new file mode 100644 (file)
index 0000000..a7dd546
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Bitbanging I2C bus driver using the GPIO API
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-gpio.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/gpio.h>
+
+/* Toggle SDA by changing the direction of the pin */
+static void i2c_gpio_setsda_dir(void *data, int state)
+{
+       struct i2c_gpio_platform_data *pdata = data;
+
+       if (state)
+               gpio_direction_input(pdata->sda_pin);
+       else
+               gpio_direction_output(pdata->sda_pin, 0);
+}
+
+/*
+ * Toggle SDA by changing the output value of the pin. This is only
+ * valid for pins configured as open drain (i.e. setting the value
+ * high effectively turns off the output driver.)
+ */
+static void i2c_gpio_setsda_val(void *data, int state)
+{
+       struct i2c_gpio_platform_data *pdata = data;
+
+       gpio_set_value(pdata->sda_pin, state);
+}
+
+/* Toggle SCL by changing the direction of the pin. */
+static void i2c_gpio_setscl_dir(void *data, int state)
+{
+       struct i2c_gpio_platform_data *pdata = data;
+
+       if (state)
+               gpio_direction_input(pdata->scl_pin);
+       else
+               gpio_direction_output(pdata->scl_pin, 0);
+}
+
+/*
+ * Toggle SCL by changing the output value of the pin. This is used
+ * for pins that are configured as open drain and for output-only
+ * pins. The latter case will break the i2c protocol, but it will
+ * often work in practice.
+ */
+static void i2c_gpio_setscl_val(void *data, int state)
+{
+       struct i2c_gpio_platform_data *pdata = data;
+
+       gpio_set_value(pdata->scl_pin, state);
+}
+
+int i2c_gpio_getsda(void *data)
+{
+       struct i2c_gpio_platform_data *pdata = data;
+
+       return gpio_get_value(pdata->sda_pin);
+}
+
+int i2c_gpio_getscl(void *data)
+{
+       struct i2c_gpio_platform_data *pdata = data;
+
+       return gpio_get_value(pdata->scl_pin);
+}
+
+static int __init i2c_gpio_probe(struct platform_device *pdev)
+{
+       struct i2c_gpio_platform_data *pdata;
+       struct i2c_algo_bit_data *bit_data;
+       struct i2c_adapter *adap;
+       int ret;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata)
+               return -ENXIO;
+
+       ret = -ENOMEM;
+       adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+       if (!adap)
+               goto err_alloc_adap;
+       bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
+       if (!bit_data)
+               goto err_alloc_bit_data;
+
+       ret = gpio_request(pdata->sda_pin, "sda");
+       if (ret)
+               goto err_request_sda;
+       ret = gpio_request(pdata->scl_pin, "scl");
+       if (ret)
+               goto err_request_scl;
+
+       if (pdata->sda_is_open_drain) {
+               gpio_direction_output(pdata->sda_pin, 1);
+               bit_data->setsda = i2c_gpio_setsda_val;
+       } else {
+               gpio_direction_input(pdata->sda_pin);
+               bit_data->setsda = i2c_gpio_setsda_dir;
+       }
+
+       if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
+               gpio_direction_output(pdata->scl_pin, 1);
+               bit_data->setscl = i2c_gpio_setscl_val;
+       } else {
+               gpio_direction_input(pdata->scl_pin);
+               bit_data->setscl = i2c_gpio_setscl_dir;
+       }
+
+       if (!pdata->scl_is_output_only)
+               bit_data->getscl = i2c_gpio_getscl;
+       bit_data->getsda = i2c_gpio_getsda;
+
+       if (pdata->udelay)
+               bit_data->udelay = pdata->udelay;
+       else if (pdata->scl_is_output_only)
+               bit_data->udelay = 50;                  /* 10 kHz */
+       else
+               bit_data->udelay = 5;                   /* 100 kHz */
+
+       if (pdata->timeout)
+               bit_data->timeout = pdata->timeout;
+       else
+               bit_data->timeout = HZ / 10;            /* 100 ms */
+
+       bit_data->data = pdata;
+
+       adap->owner = THIS_MODULE;
+       snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
+       adap->algo_data = bit_data;
+       adap->dev.parent = &pdev->dev;
+
+       ret = i2c_bit_add_bus(adap);
+       if (ret)
+               goto err_add_bus;
+
+       platform_set_drvdata(pdev, adap);
+
+       dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
+                pdata->sda_pin, pdata->scl_pin,
+                pdata->scl_is_output_only
+                ? ", no clock stretching" : "");
+
+       return 0;
+
+err_add_bus:
+       gpio_free(pdata->scl_pin);
+err_request_scl:
+       gpio_free(pdata->sda_pin);
+err_request_sda:
+       kfree(bit_data);
+err_alloc_bit_data:
+       kfree(adap);
+err_alloc_adap:
+       return ret;
+}
+
+static int __exit i2c_gpio_remove(struct platform_device *pdev)
+{
+       struct i2c_gpio_platform_data *pdata;
+       struct i2c_adapter *adap;
+
+       adap = platform_get_drvdata(pdev);
+       pdata = pdev->dev.platform_data;
+
+       i2c_del_adapter(adap);
+       gpio_free(pdata->scl_pin);
+       gpio_free(pdata->sda_pin);
+       kfree(adap->algo_data);
+       kfree(adap);
+
+       return 0;
+}
+
+static struct platform_driver i2c_gpio_driver = {
+       .driver         = {
+               .name   = "i2c-gpio",
+               .owner  = THIS_MODULE,
+       },
+       .remove         = __exit_p(i2c_gpio_remove),
+};
+
+static int __init i2c_gpio_init(void)
+{
+       int ret;
+
+       ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe);
+       if (ret)
+               printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
+
+       return ret;
+}
+module_init(i2c_gpio_init);
+
+static void __exit i2c_gpio_exit(void)
+{
+       platform_driver_unregister(&i2c_gpio_driver);
+}
+module_exit(i2c_gpio_exit);
+
+MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
+MODULE_LICENSE("GPL");
index a320e7d82c1fe1a5044eb60aab53a48872ce8386..611b57192c9618ac6159267b4371f89835efd75c 100644 (file)
@@ -527,7 +527,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        /* set up the sysfs linkage to our parent device */
        i801_adapter.dev.parent = &dev->dev;
 
-       snprintf(i801_adapter.name, I2C_NAME_SIZE,
+       snprintf(i801_adapter.name, sizeof(i801_adapter.name),
                "SMBus I801 adapter at %04lx", i801_smba);
        err = i2c_add_adapter(&i801_adapter);
        if (err) {
index 5f33bc9c1e02ba7c134121c5beb8880c51f79eb3..b0e1370075deed8e8c6ba04e245c8cd2d3085c40 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/completion.h>
 
+/* Exported by i2c-core for i2c-isa only */
+extern void i2c_adapter_dev_release(struct device *dev);
+extern struct class i2c_adapter_class;
+
 static u32 isa_func(struct i2c_adapter *adapter);
 
 /* This is the actual algorithm we define */
@@ -64,16 +68,6 @@ static u32 isa_func(struct i2c_adapter *adapter)
 }
 
 
-/* Copied from i2c-core */
-static ssize_t show_adapter_name(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
-       return sprintf(buf, "%s\n", adap->name);
-}
-static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
-
-
 /* We implement an interface which resembles i2c_{add,del}_driver,
    but for i2c-isa drivers. We don't have to remember and handle lists
    of drivers and adapters so this is much more simple, of course. */
@@ -139,41 +133,18 @@ static int __init i2c_isa_init(void)
        isa_adapter.nr = ANY_I2C_ISA_BUS;
        isa_adapter.dev.parent = &platform_bus;
        sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
-       isa_adapter.dev.driver = &i2c_adapter_driver;
        isa_adapter.dev.release = &i2c_adapter_dev_release;
+       isa_adapter.dev.class = &i2c_adapter_class;
        err = device_register(&isa_adapter.dev);
        if (err) {
                printk(KERN_ERR "i2c-isa: Failed to register device\n");
                goto exit;
        }
-       err = device_create_file(&isa_adapter.dev, &dev_attr_name);
-       if (err) {
-               printk(KERN_ERR "i2c-isa: Failed to create name file\n");
-               goto exit_unregister;
-       }
-
-       /* Add this adapter to the i2c_adapter class */
-       memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device));
-       isa_adapter.class_dev.dev = &isa_adapter.dev;
-       isa_adapter.class_dev.class = &i2c_adapter_class;
-       strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id,
-               BUS_ID_SIZE);
-       err = class_device_register(&isa_adapter.class_dev);
-       if (err) {
-               printk(KERN_ERR "i2c-isa: Failed to register class device\n");
-               goto exit_remove_name;
-       }
 
        dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
 
        return 0;
 
-exit_remove_name:
-       device_remove_file(&isa_adapter.dev, &dev_attr_name);
-exit_unregister:
-       init_completion(&isa_adapter.dev_released); /* Needed? */
-       device_unregister(&isa_adapter.dev);
-       wait_for_completion(&isa_adapter.dev_released);
 exit:
        return err;
 }
@@ -201,15 +172,11 @@ static void __exit i2c_isa_exit(void)
        /* Clean up the sysfs representation */
        dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n");
        init_completion(&isa_adapter.dev_released);
-       init_completion(&isa_adapter.class_dev_released);
-       class_device_unregister(&isa_adapter.class_dev);
-       device_remove_file(&isa_adapter.dev, &dev_attr_name);
        device_unregister(&isa_adapter.dev);
 
        /* Wait for sysfs to drop all references */
        dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n");
        wait_for_completion(&isa_adapter.dev_released);
-       wait_for_completion(&isa_adapter.class_dev_released);
 
        dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name);
 }
index efa3ecc5522ac32b33dbae416d2ad3ae84ff8045..6352121a28275552bd1a360288485afdd5e4ca52 100644 (file)
@@ -118,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
 
        drv_data->adapter.id = I2C_HW_B_IXP2000,
        strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
-               I2C_NAME_SIZE);
+               sizeof(drv_data->adapter.name));
        drv_data->adapter.algo_data = &drv_data->algo_data,
 
        drv_data->adapter.dev.parent = &plat_dev->dev;
index 08e89b83984a6a31944583bb3b3f5bc5f8034257..069ed7f3b39553a9de2a3c51b4b0209fd11fc909 100644 (file)
@@ -127,7 +127,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
        drv_data->adapter.id = I2C_HW_B_IXP4XX;
        drv_data->adapter.class = I2C_CLASS_HWMON;
        strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
-               I2C_NAME_SIZE);
+               sizeof(drv_data->adapter.name));
        drv_data->adapter.algo_data = &drv_data->algo_data;
 
        drv_data->adapter.dev.parent = &plat_dev->dev;
index a3283b907eb87a947fe30979e27867c34811cfaf..a55b3335d1becd05d5ebbcafb8d4477b50f9d099 100644 (file)
@@ -508,7 +508,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
        }
 
        strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
-               I2C_NAME_SIZE);
+               sizeof(drv_data->adapter.name));
 
        init_waitqueue_head(&drv_data->waitq);
        spin_lock_init(&drv_data->lock);
index 1514ec5b77f8e82f72a66ffc27ff8dc3f8414f7b..3cd0d63e7b501c047e04e52945211e988409b0a1 100644 (file)
@@ -33,6 +33,8 @@
     nForce4 MCP-04             0034
     nForce4 MCP51              0264
     nForce4 MCP55              0368
+    nForce MCP61               03EB
+    nForce MCP65               0446
 
     This driver supports the 2 SMBuses that are included in the MCP of the
     nForce2/3/4/5xx chipsets.
@@ -200,6 +202,8 @@ static struct pci_device_id nforce2_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
        { 0 }
 };
 
@@ -240,7 +244,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
        smbus->adapter.dev.parent = &dev->dev;
-       snprintf(smbus->adapter.name, I2C_NAME_SIZE,
+       snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
                "SMBus nForce2 adapter at %04x", smbus->base);
 
        error = i2c_add_adapter(&smbus->adapter);
index bcd8367cede1aa0dc13b221d14266166c1e9e346..e471e3bfdc1e08872dcc9d4dd23e1e81a5d422cd 100644 (file)
@@ -605,7 +605,8 @@ omap_i2c_probe(struct platform_device *pdev)
        adap->dev.parent = &pdev->dev;
 
        /* i2c device drivers may be active on return from add_adapter() */
-       r = i2c_add_adapter(adap);
+       adap->nr = pdev->id;
+       r = i2c_add_numbered_adapter(adap);
        if (r) {
                dev_err(dev->dev, "failure adding adapter\n");
                goto err_free_irq;
index 4bc42810b9aadb7fddfe703e5bf5d3ac17e34a47..49a95e2887bc39221d63dd9c1511d54004cb3af2 100644 (file)
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------ *
- * i2c-parport.c I2C bus over parallel port                                 *
+ * i2c-parport-light.c I2C bus over parallel port                           *
  * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
+   Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
    
    Based on older i2c-velleman.c driver
    Copyright (C) 1995-2000 Simon G. Vogl
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -34,6 +35,9 @@
 #include "i2c-parport.h"
 
 #define DEFAULT_BASE 0x378
+#define DRVNAME "i2c-parport-light"
+
+static struct platform_device *pdev;
 
 static u16 base;
 module_param(base, ushort, 0);
@@ -106,7 +110,7 @@ static struct i2c_algo_bit_data parport_algo_data = {
        .timeout        = HZ,
 }; 
 
-/* ----- I2c structure ---------------------------------------------------- */
+/* ----- Driver registration ---------------------------------------------- */
 
 static struct i2c_adapter parport_adapter = {
        .owner          = THIS_MODULE,
@@ -116,55 +120,141 @@ static struct i2c_adapter parport_adapter = {
        .name           = "Parallel port adapter (light)",
 };
 
-/* ----- Module loading, unloading and information ------------------------ */
+static int __devinit i2c_parport_probe(struct platform_device *pdev)
+{
+       int err;
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (!request_region(res->start, res->end - res->start + 1, DRVNAME))
+               return -EBUSY;
+
+       /* Reset hardware to a sane state (SCL and SDA high) */
+       parport_setsda(NULL, 1);
+       parport_setscl(NULL, 1);
+       /* Other init if needed (power on...) */
+       if (adapter_parm[type].init.val)
+               line_set(1, &adapter_parm[type].init);
+
+       parport_adapter.dev.parent = &pdev->dev;
+       err = i2c_bit_add_bus(&parport_adapter);
+       if (err) {
+               dev_err(&pdev->dev, "Unable to register with I2C\n");
+               goto exit_region;
+       }
+       return 0;
+
+exit_region:
+       release_region(res->start, res->end - res->start + 1);
+       return err;
+}
+
+static int __devexit i2c_parport_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+
+       i2c_del_adapter(&parport_adapter);
+
+       /* Un-init if needed (power off...) */
+       if (adapter_parm[type].init.val)
+               line_set(0, &adapter_parm[type].init);
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       release_region(res->start, res->end - res->start + 1);
+       return 0;
+}
+
+static struct platform_driver i2c_parport_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = DRVNAME,
+       },
+       .probe          = i2c_parport_probe,
+       .remove         = __devexit_p(i2c_parport_remove),
+};
+
+static int __init i2c_parport_device_add(u16 address)
+{
+       struct resource res = {
+               .start  = address,
+               .end    = address + 2,
+               .name   = DRVNAME,
+               .flags  = IORESOURCE_IO,
+       };
+       int err;
+
+       pdev = platform_device_alloc(DRVNAME, -1);
+       if (!pdev) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+               goto exit;
+       }
+
+       err = platform_device_add_resources(pdev, &res, 1);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device resource addition failed "
+                      "(%d)\n", err);
+               goto exit_device_put;
+       }
+
+       err = platform_device_add(pdev);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+                      err);
+               goto exit_device_put;
+       }
+
+       return 0;
+
+exit_device_put:
+       platform_device_put(pdev);
+exit:
+       return err;
+}
 
 static int __init i2c_parport_init(void)
 {
+       int err;
+
        if (type < 0) {
-               printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
+               printk(KERN_ERR DRVNAME ": adapter type unspecified\n");
                return -ENODEV;
        }
 
        if (type >= ARRAY_SIZE(adapter_parm)) {
-               printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
+               printk(KERN_ERR DRVNAME ": invalid type (%d)\n", type);
                return -ENODEV;
        }
 
        if (base == 0) {
-               printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE);
+               pr_info(DRVNAME ": using default base 0x%x\n", DEFAULT_BASE);
                base = DEFAULT_BASE;
        }
 
-       if (!request_region(base, 3, "i2c-parport"))
-               return -ENODEV;
-
         if (!adapter_parm[type].getscl.val)
                parport_algo_data.getscl = NULL;
 
-       /* Reset hardware to a sane state (SCL and SDA high) */
-       parport_setsda(NULL, 1);
-       parport_setscl(NULL, 1);
-       /* Other init if needed (power on...) */
-       if (adapter_parm[type].init.val)
-               line_set(1, &adapter_parm[type].init);
+       /* Sets global pdev as a side effect */
+       err = i2c_parport_device_add(base);
+       if (err)
+               goto exit;
 
-       if (i2c_bit_add_bus(&parport_adapter) < 0) {
-               printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
-               release_region(base, 3);
-               return -ENODEV;
-       }
+       err = platform_driver_register(&i2c_parport_driver);
+       if (err)
+               goto exit_device;
 
        return 0;
+
+exit_device:
+       platform_device_unregister(pdev);
+exit:
+       return err;
 }
 
 static void __exit i2c_parport_exit(void)
 {
-       /* Un-init if needed (power off...) */
-       if (adapter_parm[type].init.val)
-               line_set(0, &adapter_parm[type].init);
-
-       i2c_del_adapter(&parport_adapter);
-       release_region(base, 3);
+       platform_driver_unregister(&i2c_parport_driver);
+       platform_device_unregister(pdev);
 }
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
index 66696a40c7b5a877c738edae5e848fcdaf521460..8c953707253fad6abec1c9b9cb7020c4d9f82f61 100644 (file)
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------ *
  * i2c-parport.c I2C bus over parallel port                                 *
  * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
+   Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
    
    Based on older i2c-philips-par.c driver
    Copyright (C) 1995-2000 Simon G. Vogl
@@ -137,19 +137,12 @@ static struct i2c_algo_bit_data parport_algo_data = {
        .setscl         = parport_setscl,
        .getsda         = parport_getsda,
        .getscl         = parport_getscl,
-       .udelay         = 60,
+       .udelay         = 10, /* ~50 kbps */
        .timeout        = HZ,
 }; 
 
 /* ----- I2c and parallel port call-back functions and structures --------- */
 
-static struct i2c_adapter parport_adapter = {
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
-       .id             = I2C_HW_B_LP,
-       .name           = "Parallel port adapter",
-};
-
 static void i2c_parport_attach (struct parport *port)
 {
        struct i2c_par *adapter;
@@ -169,10 +162,17 @@ static void i2c_parport_attach (struct parport *port)
        }
 
        /* Fill the rest of the structure */
-       adapter->adapter = parport_adapter;
+       adapter->adapter.owner = THIS_MODULE;
+       adapter->adapter.class = I2C_CLASS_HWMON;
+       adapter->adapter.id = I2C_HW_B_LP;
+       strlcpy(adapter->adapter.name, "Parallel port adapter",
+               sizeof(adapter->adapter.name));
        adapter->algo_data = parport_algo_data;
-       if (!adapter_parm[type].getscl.val)
+       /* Slow down if we can't sense SCL */
+       if (!adapter_parm[type].getscl.val) {
                adapter->algo_data.getscl = NULL;
+               adapter->algo_data.udelay = 50; /* ~10 kbps */
+       }
        adapter->algo_data.data = port;
        adapter->adapter.algo_data = &adapter->algo_data;
 
@@ -214,11 +214,12 @@ static void i2c_parport_detach (struct parport *port)
        for (prev = NULL, adapter = adapter_list; adapter;
             prev = adapter, adapter = adapter->next) {
                if (adapter->pdev->port == port) {
+                       i2c_del_adapter(&adapter->adapter);
+
                        /* Un-init if needed (power off...) */
                        if (adapter_parm[type].init.val)
                                line_set(port, 0, &adapter_parm[type].init);
                                
-                       i2c_del_adapter(&adapter->adapter);
                        parport_unregister_device(adapter->pdev);
                        if (prev)
                                prev->next = adapter->next;
index bf89eeef74e9f83c7fcd5d687304050c0492d68b..58e32714afb5b881068c9ca096d8ec271a448cd7 100644 (file)
@@ -358,7 +358,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
        }
 
        smbus->adapter.owner = THIS_MODULE;
-       snprintf(smbus->adapter.name, I2C_NAME_SIZE,
+       snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
                 "PA Semi SMBus adapter at 0x%lx", smbus->base);
        smbus->adapter.class = I2C_CLASS_HWMON;
        smbus->adapter.algo = &smbus_algorithm;
index cc6536a19ecaa46be9b297a0ba7a1ac7386eb481..5f94e617fe0c83772c0840647b81210ab04f2092 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/wait.h>
 
+#include <linux/isa.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-pca.h>
 
@@ -119,27 +120,26 @@ static struct i2c_adapter pca_isa_ops = {
        .name           = "PCA9564 ISA Adapter",
 };
 
-static int __init pca_isa_init(void)
+static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
 {
-
        init_waitqueue_head(&pca_wait);
 
-       printk(KERN_INFO "i2c-pca-isa: i/o base %#08lx. irq %d\n", base, irq);
+       dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
 
        if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
-               printk(KERN_ERR "i2c-pca-isa: I/O address %#08lx is in use.\n", base);
+               dev_err(dev, "I/O address %#08lx is in use\n", base);
                goto out;
        }
 
        if (irq > -1) {
                if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) {
-                       printk(KERN_ERR "i2c-pca-isa: Request irq%d failed\n", irq);
+                       dev_err(dev, "Request irq%d failed\n", irq);
                        goto out_region;
                }
        }
 
        if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
-               printk(KERN_ERR "i2c-pca-isa: Failed to add i2c bus\n");
+               dev_err(dev, "Failed to add i2c bus\n");
                goto out_irq;
        }
 
@@ -154,7 +154,7 @@ static int __init pca_isa_init(void)
        return -ENODEV;
 }
 
-static void pca_isa_exit(void)
+static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
 {
        i2c_del_adapter(&pca_isa_ops);
 
@@ -163,6 +163,27 @@ static void pca_isa_exit(void)
                free_irq(irq, &pca_isa_ops);
        }
        release_region(base, IO_SIZE);
+
+       return 0;
+}
+
+static struct isa_driver pca_isa_driver = {
+       .probe          = pca_isa_probe,
+       .remove         = __devexit_p(pca_isa_remove),
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "i2c-pca-isa",
+       }
+};
+
+static int __init pca_isa_init(void)
+{
+       return isa_register_driver(&pca_isa_driver, 1);
+}
+
+static void __exit pca_isa_exit(void)
+{
+       isa_unregister_driver(&pca_isa_driver);
 }
 
 MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
index 21b180904085e433cd69923d49dc304b5c19497c..5a52bf5e3fb0a8c2f93263fa4e95e85e1b50763f 100644 (file)
@@ -428,7 +428,7 @@ static int __devinit piix4_probe(struct pci_dev *dev,
        /* set up the sysfs linkage to our parent device */
        piix4_adapter.dev.parent = &dev->dev;
 
-       snprintf(piix4_adapter.name, I2C_NAME_SIZE,
+       snprintf(piix4_adapter.name, sizeof(piix4_adapter.name),
                "SMBus PIIX4 adapter at %04x", piix4_smba);
 
        if ((retval = i2c_add_adapter(&piix4_adapter))) {
index 14e83d0aac8c8fcc94372710f53067bd5a4ddad9..c059b27fa88194901d2381e2de738b2e4642d150 100644 (file)
@@ -539,6 +539,18 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
        writel(icr | ICR_START | ICR_TB, _ICR(i2c));
 }
 
+static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
+{
+       u32 icr;
+
+       /*
+        * Clear the STOP and ACK flags
+        */
+       icr = readl(_ICR(i2c));
+       icr &= ~(ICR_STOP | ICR_ACKNAK);
+       writel(icr, _IRC(i2c));
+}
+
 /*
  * We are protected by the adapter bus mutex.
  */
@@ -581,6 +593,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
         * The rest of the processing occurs in the interrupt handler.
         */
        timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+       i2c_pxa_stop_message(i2c);
 
        /*
         * We place the return code in i2c->msg_idx.
@@ -825,7 +838,7 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
 };
 
 static struct pxa_i2c i2c_pxa = {
-       .lock   = SPIN_LOCK_UNLOCKED,
+       .lock   = __SPIN_LOCK_UNLOCKED(i2c_pxa.lock),
        .adap   = {
                .owner          = THIS_MODULE,
                .algo           = &i2c_pxa_algorithm,
index 556f244aae769e3b156a39900077dd5af279aa37..e68a96f589fd39f830135457b44b94c0ffcf5eb3 100644 (file)
@@ -61,6 +61,8 @@ struct s3c24xx_i2c {
        unsigned int            msg_idx;
        unsigned int            msg_ptr;
 
+       unsigned int            tx_setup;
+
        enum s3c24xx_i2c_state  state;
 
        void __iomem            *regs;
@@ -199,8 +201,11 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
        dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
        writeb(addr, i2c->regs + S3C2410_IICDS);
        
-       // delay a bit and reset iiccon before setting start (per samsung)
-       udelay(1);
+       /* delay here to ensure the data byte has gotten onto the bus
+        * before the transaction is started */
+
+       ndelay(i2c->tx_setup);
+
        dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
        writel(iiccon, i2c->regs + S3C2410_IICCON);
        
@@ -322,7 +327,15 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
                if (!is_msgend(i2c)) {
                        byte = i2c->msg->buf[i2c->msg_ptr++];
                        writeb(byte, i2c->regs + S3C2410_IICDS);
-                       
+
+                       /* delay after writing the byte to allow the
+                        * data setup time on the bus, as writing the
+                        * data to the register causes the first bit
+                        * to appear on SDA, and SCL will change as
+                        * soon as the interrupt is acknowledged */
+
+                       ndelay(i2c->tx_setup);
+
                } else if (!is_lastmsg(i2c)) {
                        /* we need to go to the next i2c message */
 
@@ -570,9 +583,10 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
 };
 
 static struct s3c24xx_i2c s3c24xx_i2c = {
-       .lock   = SPIN_LOCK_UNLOCKED,
-       .wait   = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
-       .adap   = {
+       .lock           = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock),
+       .wait           = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
+       .tx_setup       = 50,
+       .adap           = {
                .name                   = "s3c2410-i2c",
                .owner                  = THIS_MODULE,
                .algo                   = &s3c24xx_i2c_algorithm,
@@ -731,26 +745,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
        return 0;
 }
 
-static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c)
-{
-       if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {
-               clk_disable(i2c->clk);
-               clk_put(i2c->clk);
-               i2c->clk = NULL;
-       }
-
-       if (i2c->regs != NULL) {
-               iounmap(i2c->regs);
-               i2c->regs = NULL;
-       }
-
-       if (i2c->ioarea != NULL) {
-               release_resource(i2c->ioarea);
-               kfree(i2c->ioarea);
-               i2c->ioarea = NULL;
-       }
-}
-
 /* s3c24xx_i2c_probe
  *
  * called by the bus driver when a suitable device is found
@@ -769,7 +763,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        if (IS_ERR(i2c->clk)) {
                dev_err(&pdev->dev, "cannot get clock\n");
                ret = -ENOENT;
-               goto out;
+               goto err_noclk;
        }
 
        dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
@@ -782,7 +776,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        if (res == NULL) {
                dev_err(&pdev->dev, "cannot find IO resource\n");
                ret = -ENOENT;
-               goto out;
+               goto err_clk;
        }
 
        i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1,
@@ -791,7 +785,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        if (i2c->ioarea == NULL) {
                dev_err(&pdev->dev, "cannot request IO\n");
                ret = -ENXIO;
-               goto out;
+               goto err_clk;
        }
 
        i2c->regs = ioremap(res->start, (res->end-res->start)+1);
@@ -799,7 +793,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        if (i2c->regs == NULL) {
                dev_err(&pdev->dev, "cannot map IO\n");
                ret = -ENXIO;
-               goto out;
+               goto err_ioarea;
        }
 
        dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
@@ -813,7 +807,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 
        ret = s3c24xx_i2c_init(i2c);
        if (ret != 0)
-               goto out;
+               goto err_iomap;
 
        /* find the IRQ for this unit (note, this relies on the init call to
         * ensure no current IRQs pending 
@@ -823,7 +817,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        if (res == NULL) {
                dev_err(&pdev->dev, "cannot find IRQ\n");
                ret = -ENOENT;
-               goto out;
+               goto err_iomap;
        }
 
        ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED,
@@ -831,7 +825,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 
        if (ret != 0) {
                dev_err(&pdev->dev, "cannot claim IRQ\n");
-               goto out;
+               goto err_iomap;
        }
 
        i2c->irq = res;
@@ -841,17 +835,29 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        ret = i2c_add_adapter(&i2c->adap);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to add bus to i2c core\n");
-               goto out;
+               goto err_irq;
        }
 
        platform_set_drvdata(pdev, i2c);
 
        dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
+       return 0;
 
- out:
-       if (ret < 0)
-               s3c24xx_i2c_free(i2c);
+ err_irq:
+       free_irq(i2c->irq->start, i2c);
+
+ err_iomap:
+       iounmap(i2c->regs);
 
+ err_ioarea:
+       release_resource(i2c->ioarea);
+       kfree(i2c->ioarea);
+
+ err_clk:
+       clk_disable(i2c->clk);
+       clk_put(i2c->clk);
+
+ err_noclk:
        return ret;
 }
 
@@ -863,11 +869,17 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 static int s3c24xx_i2c_remove(struct platform_device *pdev)
 {
        struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
-       
-       if (i2c != NULL) {
-               s3c24xx_i2c_free(i2c);
-               platform_set_drvdata(pdev, NULL);
-       }
+
+       i2c_del_adapter(&i2c->adap);
+       free_irq(i2c->irq->start, i2c);
+
+       clk_disable(i2c->clk);
+       clk_put(i2c->clk);
+
+       iounmap(i2c->regs);
+
+       release_resource(i2c->ioarea);
+       kfree(i2c->ioarea);
 
        return 0;
 }
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c
new file mode 100644 (file)
index 0000000..10af8d3
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec Generic I2C Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/io.h>
+
+struct simtec_i2c_data {
+       struct resource         *ioarea;
+       void __iomem            *reg;
+       struct i2c_adapter       adap;
+       struct i2c_algo_bit_data bit;
+};
+
+#define CMD_SET_SDA    (1<<2)
+#define CMD_SET_SCL    (1<<3)
+
+#define STATE_SDA      (1<<0)
+#define STATE_SCL      (1<<1)
+
+/* i2c bit-bus functions */
+
+static void simtec_i2c_setsda(void *pw, int state)
+{
+       struct simtec_i2c_data *pd = pw;
+       writeb(CMD_SET_SDA | (state ? STATE_SDA : 0), pd->reg);
+}
+
+static void simtec_i2c_setscl(void *pw, int state)
+{
+       struct simtec_i2c_data *pd = pw;
+       writeb(CMD_SET_SCL | (state ? STATE_SCL : 0), pd->reg);
+}
+
+static int simtec_i2c_getsda(void *pw)
+{
+       struct simtec_i2c_data *pd = pw;
+       return readb(pd->reg) & STATE_SDA ? 1 : 0;
+}
+
+static int simtec_i2c_getscl(void *pw)
+{
+       struct simtec_i2c_data *pd = pw;
+       return readb(pd->reg) & STATE_SCL ? 1 : 0;
+}
+
+/* device registration */
+
+static int simtec_i2c_probe(struct platform_device *dev)
+{
+       struct simtec_i2c_data *pd;
+       struct resource *res;
+       int size;
+       int ret;
+
+       pd = kzalloc(sizeof(struct simtec_i2c_data), GFP_KERNEL);
+       if (pd == NULL) {
+               dev_err(&dev->dev, "cannot allocate private data\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(dev, pd);
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&dev->dev, "cannot find IO resource\n");
+               ret = -ENOENT;
+               goto err;
+       }
+
+       size = (res->end-res->start)+1;
+
+       pd->ioarea = request_mem_region(res->start, size, dev->name);
+       if (pd->ioarea == NULL) {
+               dev_err(&dev->dev, "cannot request IO\n");
+               ret = -ENXIO;
+               goto err;
+       }
+
+       pd->reg = ioremap(res->start, size);
+       if (pd->reg == NULL) {
+               dev_err(&dev->dev, "cannot map IO\n");
+               ret = -ENXIO;
+               goto err_res;
+       }
+
+       /* setup the private data */
+
+       pd->adap.owner = THIS_MODULE;
+       pd->adap.algo_data = &pd->bit;
+       pd->adap.dev.parent = &dev->dev;
+
+       strlcpy(pd->adap.name, "Simtec I2C", sizeof(pd->adap.name));
+
+       pd->bit.data = pd;
+       pd->bit.setsda = simtec_i2c_setsda;
+       pd->bit.setscl = simtec_i2c_setscl;
+       pd->bit.getsda = simtec_i2c_getsda;
+       pd->bit.getscl = simtec_i2c_getscl;
+       pd->bit.timeout = HZ;
+       pd->bit.udelay = 20;
+
+       ret = i2c_bit_add_bus(&pd->adap);
+       if (ret)
+               goto err_all;
+
+       return 0;
+
+ err_all:
+       iounmap(pd->reg);
+
+ err_res:
+       release_resource(pd->ioarea);
+       kfree(pd->ioarea);
+
+ err:
+       kfree(pd);
+       return ret;
+}
+
+static int simtec_i2c_remove(struct platform_device *dev)
+{
+       struct simtec_i2c_data *pd = platform_get_drvdata(dev);
+
+       i2c_del_adapter(&pd->adap);
+
+       iounmap(pd->reg);
+       release_resource(pd->ioarea);
+       kfree(pd->ioarea);
+       kfree(pd);
+
+       return 0;
+}
+
+
+/* device driver */
+
+static struct platform_driver simtec_i2c_driver = {
+       .driver         = {
+               .name           = "simtec-i2c",
+               .owner          = THIS_MODULE,
+       },
+       .probe          = simtec_i2c_probe,
+       .remove         = simtec_i2c_remove,
+};
+
+static int __init i2c_adap_simtec_init(void)
+{
+       return platform_driver_register(&simtec_i2c_driver);
+}
+
+static void __exit i2c_adap_simtec_exit(void)
+{
+       platform_driver_unregister(&simtec_i2c_driver);
+}
+
+module_init(i2c_adap_simtec_init);
+module_exit(i2c_adap_simtec_exit);
+
+MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
index 4157b0cd604c5415c727f5c49113f68151b798db..dc235bb8e24d448ae5f815ff45314bdea789d740 100644 (file)
@@ -300,7 +300,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
        /* set up the sysfs linkage to our parent device */
        sis96x_adapter.dev.parent = &dev->dev;
 
-       snprintf(sis96x_adapter.name, I2C_NAME_SIZE,
+       snprintf(sis96x_adapter.name, sizeof(sis96x_adapter.name),
                "SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
 
        if ((retval = i2c_add_adapter(&sis96x_adapter))) {
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
new file mode 100644 (file)
index 0000000..9079990
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * driver for the i2c-tiny-usb adapter - 1.0
+ * http://www.harbaum.org/till/i2c_tiny_usb
+ *
+ * Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+/* include interfaces to usb layer */
+#include <linux/usb.h>
+
+/* include interface to i2c layer */
+#include <linux/i2c.h>
+
+/* commands via USB, must match command ids in the firmware */
+#define CMD_ECHO               0
+#define CMD_GET_FUNC           1
+#define CMD_SET_DELAY          2
+#define CMD_GET_STATUS         3
+
+#define CMD_I2C_IO             4
+#define CMD_I2C_IO_BEGIN       (1<<0)
+#define CMD_I2C_IO_END         (1<<1)
+
+/* i2c bit delay, default is 10us -> 100kHz */
+static int delay = 10;
+module_param(delay, int, 0);
+MODULE_PARM_DESC(delay, "bit delay in microseconds, "
+                "e.g. 10 for 100kHz (default is 100kHz)");
+
+static int usb_read(struct i2c_adapter *adapter, int cmd,
+                   int value, int index, void *data, int len);
+
+static int usb_write(struct i2c_adapter *adapter, int cmd,
+                    int value, int index, void *data, int len);
+
+/* ----- begin of i2c layer ---------------------------------------------- */
+
+#define STATUS_IDLE            0
+#define STATUS_ADDRESS_ACK     1
+#define STATUS_ADDRESS_NAK     2
+
+static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+       unsigned char status;
+       struct i2c_msg *pmsg;
+       int i;
+
+       dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
+
+       for (i = 0 ; i < num ; i++) {
+               int cmd = CMD_I2C_IO;
+
+               if (i == 0)
+                       cmd |= CMD_I2C_IO_BEGIN;
+
+               if (i == num-1)
+                       cmd |= CMD_I2C_IO_END;
+
+               pmsg = &msgs[i];
+
+               dev_dbg(&adapter->dev,
+                       "  %d: %s (flags %d) %d bytes to 0x%02x\n",
+                       i, pmsg->flags & I2C_M_RD ? "read" : "write",
+                       pmsg->flags, pmsg->len, pmsg->addr);
+
+               /* and directly send the message */
+               if (pmsg->flags & I2C_M_RD) {
+                       /* read data */
+                       if (usb_read(adapter, cmd,
+                                    pmsg->flags, pmsg->addr,
+                                    pmsg->buf, pmsg->len) != pmsg->len) {
+                               dev_err(&adapter->dev,
+                                       "failure reading data\n");
+                               return -EREMOTEIO;
+                       }
+               } else {
+                       /* write data */
+                       if (usb_write(adapter, cmd,
+                                     pmsg->flags, pmsg->addr,
+                                     pmsg->buf, pmsg->len) != pmsg->len) {
+                               dev_err(&adapter->dev,
+                                       "failure writing data\n");
+                               return -EREMOTEIO;
+                       }
+               }
+
+               /* read status */
+               if (usb_read(adapter, CMD_GET_STATUS, 0, 0, &status, 1) != 1) {
+                       dev_err(&adapter->dev, "failure reading status\n");
+                       return -EREMOTEIO;
+               }
+
+               dev_dbg(&adapter->dev, "  status = %d\n", status);
+               if (status == STATUS_ADDRESS_NAK)
+                       return -EREMOTEIO;
+       }
+
+       return i;
+}
+
+static u32 usb_func(struct i2c_adapter *adapter)
+{
+       u32 func;
+
+       /* get functionality from adapter */
+       if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
+           sizeof(func)) {
+               dev_err(&adapter->dev, "failure reading functionality\n");
+               return 0;
+       }
+
+       return func;
+}
+
+/* This is the actual algorithm we define */
+static const struct i2c_algorithm usb_algorithm = {
+       .master_xfer    = usb_xfer,
+       .functionality  = usb_func,
+};
+
+/* ----- end of i2c layer ------------------------------------------------ */
+
+/* ----- begin of usb layer ---------------------------------------------- */
+
+/* The usb i2c interface uses a vid/pid pair donated by */
+/* Future Technology Devices International Ltd. */
+static struct usb_device_id i2c_tiny_usb_table [] = {
+       { USB_DEVICE(0x0403, 0xc631) },
+       { }                     /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table);
+
+/* Structure to hold all of our device specific stuff */
+struct i2c_tiny_usb {
+       struct usb_device *usb_dev; /* the usb device for this device */
+       struct usb_interface *interface; /* the interface for this device */
+       struct i2c_adapter adapter; /* i2c related things */
+};
+
+static int usb_read(struct i2c_adapter *adapter, int cmd,
+                   int value, int index, void *data, int len)
+{
+       struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
+
+       /* do control transfer */
+       return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
+                              cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
+                              USB_DIR_IN, value, index, data, len, 2000);
+}
+
+static int usb_write(struct i2c_adapter *adapter, int cmd,
+                    int value, int index, void *data, int len)
+{
+       struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
+
+       /* do control transfer */
+       return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
+                              cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+                              value, index, data, len, 2000);
+}
+
+static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev)
+{
+       usb_put_dev(dev->usb_dev);
+       kfree(dev);
+}
+
+static int i2c_tiny_usb_probe(struct usb_interface *interface,
+                             const struct usb_device_id *id)
+{
+       struct i2c_tiny_usb *dev;
+       int retval = -ENOMEM;
+       u16 version;
+
+       dev_dbg(&interface->dev, "probing usb device\n");
+
+       /* allocate memory for our device state and initialize it */
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (dev == NULL) {
+               dev_err(&interface->dev, "Out of memory\n");
+               goto error;
+       }
+
+       dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
+       dev->interface = interface;
+
+       /* save our data pointer in this interface device */
+       usb_set_intfdata(interface, dev);
+
+       version = le16_to_cpu(dev->usb_dev->descriptor.bcdDevice);
+       dev_info(&interface->dev,
+                "version %x.%02x found at bus %03d address %03d\n",
+                version >> 8, version & 0xff,
+                dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
+
+       /* setup i2c adapter description */
+       dev->adapter.owner = THIS_MODULE;
+       dev->adapter.class = I2C_CLASS_HWMON;
+       dev->adapter.algo = &usb_algorithm;
+       dev->adapter.algo_data = dev;
+       snprintf(dev->adapter.name, I2C_NAME_SIZE,
+                "i2c-tiny-usb at bus %03d device %03d",
+                dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
+
+       if (usb_write(&dev->adapter, CMD_SET_DELAY,
+                     cpu_to_le16(delay), 0, NULL, 0) != 0) {
+               dev_err(&dev->adapter.dev,
+                       "failure setting delay to %dus\n", delay);
+               retval = -EIO;
+               goto error;
+       }
+
+       dev->adapter.dev.parent = &dev->interface->dev;
+
+       /* and finally attach to i2c layer */
+       i2c_add_adapter(&dev->adapter);
+
+       /* inform user about successful attachment to i2c layer */
+       dev_info(&dev->adapter.dev, "connected i2c-tiny-usb device\n");
+
+       return 0;
+
+ error:
+       if (dev)
+               i2c_tiny_usb_free(dev);
+
+       return retval;
+}
+
+static void i2c_tiny_usb_disconnect(struct usb_interface *interface)
+{
+       struct i2c_tiny_usb *dev = usb_get_intfdata(interface);
+
+       i2c_del_adapter(&dev->adapter);
+       usb_set_intfdata(interface, NULL);
+       i2c_tiny_usb_free(dev);
+
+       dev_dbg(&interface->dev, "disconnected\n");
+}
+
+static struct usb_driver i2c_tiny_usb_driver = {
+       .name           = "i2c-tiny-usb",
+       .probe          = i2c_tiny_usb_probe,
+       .disconnect     = i2c_tiny_usb_disconnect,
+       .id_table       = i2c_tiny_usb_table,
+};
+
+static int __init usb_i2c_tiny_usb_init(void)
+{
+       /* register this driver with the USB subsystem */
+       return usb_register(&i2c_tiny_usb_driver);
+}
+
+static void __exit usb_i2c_tiny_usb_exit(void)
+{
+       /* deregister this driver with the USB subsystem */
+       usb_deregister(&i2c_tiny_usb_driver);
+}
+
+module_init(usb_i2c_tiny_usb_init);
+module_exit(usb_i2c_tiny_usb_exit);
+
+/* ----- end of usb layer ------------------------------------------------ */
+
+MODULE_AUTHOR("Till Harbaum <Till@Harbaum.org>");
+MODULE_DESCRIPTION("i2c-tiny-usb driver v1.0");
+MODULE_LICENSE("GPL");
index 03c5fc868548d3d121aca6d879b06e13031594c2..7a2bc06304fca779a3a5c2194d6d9d92e34a199c 100644 (file)
@@ -404,7 +404,7 @@ found:
        }
 
        vt596_adapter.dev.parent = &pdev->dev;
-       snprintf(vt596_adapter.name, I2C_NAME_SIZE,
+       snprintf(vt596_adapter.name, sizeof(vt596_adapter.name),
                 "SMBus Via Pro adapter at %04x", vt596_smba);
 
        vt596_pdev = pci_dev_get(pdev);
index 0b082c5a01956d7e98b52329ad920b69693793e3..0db56e7bc34e95369f18edd027e34ed487d0579e 100644 (file)
@@ -441,7 +441,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
 
        adapter = &iface->adapter;
        i2c_set_adapdata(adapter, iface);
-       snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index);
+       snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
        adapter->owner = THIS_MODULE;
        adapter->id = I2C_HW_SMBUS_SCX200;
        adapter->algo = &scx200_acb_algorithm;
@@ -599,6 +599,7 @@ static __init int scx200_scan_pci(void)
                else {
                        int i;
 
+                       pci_dev_put(pdev);
                        for (i = 0; i < MAX_DEVICES; ++i) {
                                if (base[i] == 0)
                                        continue;
index 87ee3ce58618b7c3ed7a519859b042023be325fb..ea085a006eadd163318a9e68e79d9a8c8cc31627 100644 (file)
@@ -3,11 +3,10 @@
 #
 
 menu "Miscellaneous I2C Chip support"
-       depends on I2C
 
 config SENSORS_DS1337
        tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          If you say yes here you get support for Dallas Semiconductor
          DS1337 and DS1339 real-time clock chips.
@@ -17,7 +16,7 @@ config SENSORS_DS1337
 
 config SENSORS_DS1374
        tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          If you say yes here you get support for Dallas Semiconductor
          DS1374 real-time clock chips.
@@ -27,7 +26,7 @@ config SENSORS_DS1374
 
 config SENSORS_EEPROM
        tristate "EEPROM reader"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          If you say yes here you get read-only access to the EEPROM data
          available on modern memory DIMMs and Sony Vaio laptops.  Such
@@ -38,7 +37,7 @@ config SENSORS_EEPROM
 
 config SENSORS_PCF8574
        tristate "Philips PCF8574 and PCF8574A"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        default n
        help
          If you say yes here you get support for Philips PCF8574 and 
@@ -52,7 +51,7 @@ config SENSORS_PCF8574
 
 config SENSORS_PCA9539
        tristate "Philips PCA9539 16-bit I/O port"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          If you say yes here you get support for the Philips PCA9539
          16-bit I/O port.
@@ -62,7 +61,7 @@ config SENSORS_PCA9539
 
 config SENSORS_PCF8591
        tristate "Philips PCF8591"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        default n
        help
          If you say yes here you get support for Philips PCF8591 chips.
@@ -75,7 +74,7 @@ config SENSORS_PCF8591
 
 config ISP1301_OMAP
        tristate "Philips ISP1301 with OMAP OTG"
-       depends on I2C && ARCH_OMAP_OTG
+       depends on ARCH_OMAP_OTG
        help
          If you say yes here you get support for the Philips ISP1301
          USB-On-The-Go transceiver working with the OMAP OTG controller.
@@ -90,7 +89,7 @@ config ISP1301_OMAP
 # and having mostly OMAP-specific board support
 config TPS65010
        tristate "TPS6501x Power Management chips"
-       depends on I2C && ARCH_OMAP
+       depends on ARCH_OMAP
        default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
        help
          If you say yes here you get support for the TPS6501x series of
@@ -103,7 +102,7 @@ config TPS65010
 
 config SENSORS_M41T00
        tristate "ST M41T00 RTC chip"
-       depends on I2C && PPC32
+       depends on PPC32
        help
          If you say yes here you get support for the ST M41T00 RTC chip.
 
@@ -112,7 +111,7 @@ config SENSORS_M41T00
 
 config SENSORS_MAX6875
        tristate "Maxim MAX6875 Power supply supervisor"
-       depends on I2C && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          If you say yes here you get support for the Maxim MAX6875
          EEPROM-programmable, quad power-supply sequencer/supervisor.
diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c
new file mode 100644 (file)
index 0000000..ffb35f0
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * i2c-boardinfo.h - collect pre-declarations of I2C devices
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+
+#include "i2c-core.h"
+
+
+/* These symbols are exported ONLY FOR the i2c core.
+ * No other users will be supported.
+ */
+DEFINE_MUTEX(__i2c_board_lock);
+EXPORT_SYMBOL_GPL(__i2c_board_lock);
+
+LIST_HEAD(__i2c_board_list);
+EXPORT_SYMBOL_GPL(__i2c_board_list);
+
+int __i2c_first_dynamic_bus_num;
+EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
+
+
+/**
+ * i2c_register_board_info - statically declare I2C devices
+ * @busnum: identifies the bus to which these devices belong
+ * @info: vector of i2c device descriptors
+ * @len: how many descriptors in the vector; may be zero to reserve
+ *     the specified bus number.
+ *
+ * Systems using the Linux I2C driver stack can declare tables of board info
+ * while they initialize.  This should be done in board-specific init code
+ * near arch_initcall() time, or equivalent, before any I2C adapter driver is
+ * registered.  For example, mainboard init code could define several devices,
+ * as could the init code for each daughtercard in a board stack.
+ *
+ * The I2C devices will be created later, after the adapter for the relevant
+ * bus has been registered.  After that moment, standard driver model tools
+ * are used to bind "new style" I2C drivers to the devices.  The bus number
+ * for any device declared using this routine is not available for dynamic
+ * allocation.
+ *
+ * The board info passed can safely be __initdata, but be careful of embedded
+ * pointers (for platform_data, functions, etc) since that won't be copied.
+ */
+int __init
+i2c_register_board_info(int busnum,
+       struct i2c_board_info const *info, unsigned len)
+{
+       int status;
+
+       mutex_lock(&__i2c_board_lock);
+
+       /* dynamic bus numbers will be assigned after the last static one */
+       if (busnum >= __i2c_first_dynamic_bus_num)
+               __i2c_first_dynamic_bus_num = busnum + 1;
+
+       for (status = 0; len; len--, info++) {
+               struct i2c_devinfo      *devinfo;
+
+               devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
+               if (!devinfo) {
+                       pr_debug("i2c-core: can't register boardinfo!\n");
+                       status = -ENOMEM;
+                       break;
+               }
+
+               devinfo->busnum = busnum;
+               devinfo->board_info = *info;
+               list_add_tail(&devinfo->list, &__i2c_board_list);
+       }
+
+       mutex_unlock(&__i2c_board_lock);
+
+       return status;
+}
index 21fe1406c8b4276b6c0faca6c0ba00826464664c..64f8e56d300ec7046ab3389ff4c53198d775b12e 100644 (file)
 #include <linux/completion.h>
 #include <asm/uaccess.h>
 
+#include "i2c-core.h"
+
 
 static LIST_HEAD(adapters);
 static LIST_HEAD(drivers);
 static DEFINE_MUTEX(core_lists);
 static DEFINE_IDR(i2c_adapter_idr);
 
+#define is_newstyle_driver(d) ((d)->probe || (d)->remove)
 
 /* ------------------------------------------------------------------------- */
 
-/* match always succeeds, as we want the probe() to tell if we really accept this match */
 static int i2c_device_match(struct device *dev, struct device_driver *drv)
 {
-       return 1;
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_driver       *driver = to_i2c_driver(drv);
+
+       /* make legacy i2c drivers bypass driver model probing entirely;
+        * such drivers scan each i2c adapter/bus themselves.
+        */
+       if (!is_newstyle_driver(driver))
+               return 0;
+
+       /* new style drivers use the same kind of driver matching policy
+        * as platform devices or SPI:  compare device and driver IDs.
+        */
+       return strcmp(client->driver_name, drv->name) == 0;
+}
+
+#ifdef CONFIG_HOTPLUG
+
+/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
+static int i2c_device_uevent(struct device *dev, char **envp, int num_envp,
+                     char *buffer, int buffer_size)
+{
+       struct i2c_client       *client = to_i2c_client(dev);
+       int                     i = 0, length = 0;
+
+       /* by definition, legacy drivers can't hotplug */
+       if (dev->driver || !client->driver_name)
+               return 0;
+
+       if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                       "MODALIAS=%s", client->driver_name))
+               return -ENOMEM;
+       envp[i] = NULL;
+       dev_dbg(dev, "uevent\n");
+       return 0;
 }
 
+#else
+#define i2c_device_uevent      NULL
+#endif /* CONFIG_HOTPLUG */
+
 static int i2c_device_probe(struct device *dev)
 {
-       return -ENODEV;
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_driver       *driver = to_i2c_driver(dev->driver);
+
+       if (!driver->probe)
+               return -ENODEV;
+       client->driver = driver;
+       dev_dbg(dev, "probe\n");
+       return driver->probe(client);
 }
 
 static int i2c_device_remove(struct device *dev)
 {
-       return 0;
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_driver       *driver;
+       int                     status;
+
+       if (!dev->driver)
+               return 0;
+
+       driver = to_i2c_driver(dev->driver);
+       if (driver->remove) {
+               dev_dbg(dev, "remove\n");
+               status = driver->remove(client);
+       } else {
+               dev->driver = NULL;
+               status = 0;
+       }
+       if (status == 0)
+               client->driver = NULL;
+       return status;
 }
 
 static void i2c_device_shutdown(struct device *dev)
@@ -95,122 +158,184 @@ static int i2c_device_resume(struct device * dev)
        return driver->resume(to_i2c_client(dev));
 }
 
+static void i2c_client_release(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       complete(&client->released);
+}
+
+static void i2c_client_dev_release(struct device *dev)
+{
+       kfree(to_i2c_client(dev));
+}
+
+static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       return sprintf(buf, "%s\n", client->name);
+}
+
+static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       return client->driver_name
+               ? sprintf(buf, "%s\n", client->driver_name)
+               : 0;
+}
+
+static struct device_attribute i2c_dev_attrs[] = {
+       __ATTR(name, S_IRUGO, show_client_name, NULL),
+       /* modalias helps coldplug:  modprobe $(cat .../modalias) */
+       __ATTR(modalias, S_IRUGO, show_modalias, NULL),
+       { },
+};
+
 struct bus_type i2c_bus_type = {
        .name           = "i2c",
+       .dev_attrs      = i2c_dev_attrs,
        .match          = i2c_device_match,
+       .uevent         = i2c_device_uevent,
        .probe          = i2c_device_probe,
        .remove         = i2c_device_remove,
        .shutdown       = i2c_device_shutdown,
        .suspend        = i2c_device_suspend,
        .resume         = i2c_device_resume,
 };
+EXPORT_SYMBOL_GPL(i2c_bus_type);
 
-/* ------------------------------------------------------------------------- */
+/**
+ * i2c_new_device - instantiate an i2c device for use with a new style driver
+ * @adap: the adapter managing the device
+ * @info: describes one I2C device; bus_num is ignored
+ *
+ * Create a device to work with a new style i2c driver, where binding is
+ * handled through driver model probe()/remove() methods.  This call is not
+ * appropriate for use by mainboad initialization logic, which usually runs
+ * during an arch_initcall() long before any i2c_adapter could exist.
+ *
+ * This returns the new i2c client, which may be saved for later use with
+ * i2c_unregister_device(); or NULL to indicate an error.
+ */
+struct i2c_client *
+i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
+{
+       struct i2c_client       *client;
+       int                     status;
 
-void i2c_adapter_dev_release(struct device *dev)
+       client = kzalloc(sizeof *client, GFP_KERNEL);
+       if (!client)
+               return NULL;
+
+       client->adapter = adap;
+
+       client->dev.platform_data = info->platform_data;
+       client->flags = info->flags;
+       client->addr = info->addr;
+       client->irq = info->irq;
+
+       strlcpy(client->driver_name, info->driver_name,
+               sizeof(client->driver_name));
+       strlcpy(client->name, info->type, sizeof(client->name));
+
+       /* a new style driver may be bound to this device when we
+        * return from this function, or any later moment (e.g. maybe
+        * hotplugging will load the driver module).  and the device
+        * refcount model is the standard driver model one.
+        */
+       status = i2c_attach_client(client);
+       if (status < 0) {
+               kfree(client);
+               client = NULL;
+       }
+       return client;
+}
+EXPORT_SYMBOL_GPL(i2c_new_device);
+
+
+/**
+ * i2c_unregister_device - reverse effect of i2c_new_device()
+ * @client: value returned from i2c_new_device()
+ */
+void i2c_unregister_device(struct i2c_client *client)
 {
-       struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
-       complete(&adap->dev_released);
+       struct i2c_adapter      *adapter = client->adapter;
+       struct i2c_driver       *driver = client->driver;
+
+       if (driver && !is_newstyle_driver(driver)) {
+               dev_err(&client->dev, "can't unregister devices "
+                       "with legacy drivers\n");
+               WARN_ON(1);
+               return;
+       }
+
+       mutex_lock(&adapter->clist_lock);
+       list_del(&client->list);
+       mutex_unlock(&adapter->clist_lock);
+
+       device_unregister(&client->dev);
 }
+EXPORT_SYMBOL_GPL(i2c_unregister_device);
 
-struct device_driver i2c_adapter_driver = {
-       .owner = THIS_MODULE,
-       .name = "i2c_adapter",
-       .bus = &i2c_bus_type,
-};
 
 /* ------------------------------------------------------------------------- */
 
 /* I2C bus adapters -- one roots each I2C or SMBUS segment */
 
-static void i2c_adapter_class_dev_release(struct class_device *dev)
+void i2c_adapter_dev_release(struct device *dev)
 {
-       struct i2c_adapter *adap = class_dev_to_i2c_adapter(dev);
-       complete(&adap->class_dev_released);
+       struct i2c_adapter *adap = to_i2c_adapter(dev);
+       complete(&adap->dev_released);
 }
+EXPORT_SYMBOL_GPL(i2c_adapter_dev_release);    /* exported to i2c-isa */
 
-static ssize_t i2c_adapter_show_name(struct class_device *cdev, char *buf)
+static ssize_t
+show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct i2c_adapter *adap = class_dev_to_i2c_adapter(cdev);
+       struct i2c_adapter *adap = to_i2c_adapter(dev);
        return sprintf(buf, "%s\n", adap->name);
 }
 
-static struct class_device_attribute i2c_adapter_attrs[] = {
-       __ATTR(name, S_IRUGO, i2c_adapter_show_name, NULL),
+static struct device_attribute i2c_adapter_attrs[] = {
+       __ATTR(name, S_IRUGO, show_adapter_name, NULL),
        { },
 };
 
 struct class i2c_adapter_class = {
        .owner                  = THIS_MODULE,
        .name                   = "i2c-adapter",
-       .class_dev_attrs        = i2c_adapter_attrs,
-       .release                = &i2c_adapter_class_dev_release,
+       .dev_attrs              = i2c_adapter_attrs,
 };
+EXPORT_SYMBOL_GPL(i2c_adapter_class);          /* exported to i2c-isa */
 
-static ssize_t show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
-       return sprintf(buf, "%s\n", adap->name);
-}
-static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
-
-
-static void i2c_client_release(struct device *dev)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-       complete(&client->released);
-}
-
-static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
+static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       return sprintf(buf, "%s\n", client->name);
+       struct i2c_devinfo      *devinfo;
+
+       mutex_lock(&__i2c_board_lock);
+       list_for_each_entry(devinfo, &__i2c_board_list, list) {
+               if (devinfo->busnum == adapter->nr
+                               && !i2c_new_device(adapter,
+                                               &devinfo->board_info))
+                       printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",
+                               i2c_adapter_id(adapter),
+                               devinfo->board_info.addr);
+       }
+       mutex_unlock(&__i2c_board_lock);
 }
 
-/*
- * We can't use the DEVICE_ATTR() macro here, as we used the same name for
- * an i2c adapter attribute (above).
- */
-static struct device_attribute dev_attr_client_name =
-       __ATTR(name, S_IRUGO, &show_client_name, NULL);
-
-
-/* ---------------------------------------------------
- * registering functions
- * ---------------------------------------------------
- */
-
-/* -----
- * i2c_add_adapter is called from within the algorithm layer,
- * when a new hw adapter registers. A new device is register to be
- * available for clients.
- */
-int i2c_add_adapter(struct i2c_adapter *adap)
+static int i2c_register_adapter(struct i2c_adapter *adap)
 {
-       int id, res = 0;
+       int res = 0;
        struct list_head   *item;
        struct i2c_driver  *driver;
 
-       mutex_lock(&core_lists);
-
-       if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) {
-               res = -ENOMEM;
-               goto out_unlock;
-       }
-
-       res = idr_get_new(&i2c_adapter_idr, adap, &id);
-       if (res < 0) {
-               if (res == -EAGAIN)
-                       res = -ENOMEM;
-               goto out_unlock;
-       }
-
-       adap->nr =  id & MAX_ID_MASK;
        mutex_init(&adap->bus_lock);
        mutex_init(&adap->clist_lock);
-       list_add_tail(&adap->list,&adapters);
        INIT_LIST_HEAD(&adap->clients);
 
+       mutex_lock(&core_lists);
+       list_add_tail(&adap->list, &adapters);
+
        /* Add the adapter to the driver core.
         * If the parent pointer is not set up,
         * we add this adapter to the host bus.
@@ -221,27 +346,19 @@ int i2c_add_adapter(struct i2c_adapter *adap)
                         "physical device\n", adap->name);
        }
        sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
-       adap->dev.driver = &i2c_adapter_driver;
        adap->dev.release = &i2c_adapter_dev_release;
+       adap->dev.class = &i2c_adapter_class;
        res = device_register(&adap->dev);
        if (res)
                goto out_list;
-       res = device_create_file(&adap->dev, &dev_attr_name);
-       if (res)
-               goto out_unregister;
-
-       /* Add this adapter to the i2c_adapter class */
-       memset(&adap->class_dev, 0x00, sizeof(struct class_device));
-       adap->class_dev.dev = &adap->dev;
-       adap->class_dev.class = &i2c_adapter_class;
-       strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE);
-       res = class_device_register(&adap->class_dev);
-       if (res)
-               goto out_remove_name;
 
        dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
 
-       /* inform drivers of new adapters */
+       /* create pre-declared device nodes for new-style drivers */
+       if (adap->nr < __i2c_first_dynamic_bus_num)
+               i2c_scan_static_board_info(adap);
+
+       /* let legacy drivers scan this bus for matching devices */
        list_for_each(item,&drivers) {
                driver = list_entry(item, struct i2c_driver, list);
                if (driver->attach_adapter)
@@ -253,18 +370,98 @@ out_unlock:
        mutex_unlock(&core_lists);
        return res;
 
-out_remove_name:
-       device_remove_file(&adap->dev, &dev_attr_name);
-out_unregister:
-       init_completion(&adap->dev_released); /* Needed? */
-       device_unregister(&adap->dev);
-       wait_for_completion(&adap->dev_released);
 out_list:
        list_del(&adap->list);
        idr_remove(&i2c_adapter_idr, adap->nr);
        goto out_unlock;
 }
 
+/**
+ * i2c_add_adapter - declare i2c adapter, use dynamic bus number
+ * @adapter: the adapter to add
+ *
+ * This routine is used to declare an I2C adapter when its bus number
+ * doesn't matter.  Examples: for I2C adapters dynamically added by
+ * USB links or PCI plugin cards.
+ *
+ * When this returns zero, a new bus number was allocated and stored
+ * in adap->nr, and the specified adapter became available for clients.
+ * Otherwise, a negative errno value is returned.
+ */
+int i2c_add_adapter(struct i2c_adapter *adapter)
+{
+       int     id, res = 0;
+
+retry:
+       if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
+               return -ENOMEM;
+
+       mutex_lock(&core_lists);
+       /* "above" here means "above or equal to", sigh */
+       res = idr_get_new_above(&i2c_adapter_idr, adapter,
+                               __i2c_first_dynamic_bus_num, &id);
+       mutex_unlock(&core_lists);
+
+       if (res < 0) {
+               if (res == -EAGAIN)
+                       goto retry;
+               return res;
+       }
+
+       adapter->nr = id;
+       return i2c_register_adapter(adapter);
+}
+EXPORT_SYMBOL(i2c_add_adapter);
+
+/**
+ * i2c_add_numbered_adapter - declare i2c adapter, use static bus number
+ * @adap: the adapter to register (with adap->nr initialized)
+ *
+ * This routine is used to declare an I2C adapter when its bus number
+ * matters.  Example: for I2C adapters from system-on-chip CPUs, or
+ * otherwise built in to the system's mainboard, and where i2c_board_info
+ * is used to properly configure I2C devices.
+ *
+ * If no devices have pre-been declared for this bus, then be sure to
+ * register the adapter before any dynamically allocated ones.  Otherwise
+ * the required bus ID may not be available.
+ *
+ * When this returns zero, the specified adapter became available for
+ * clients using the bus number provided in adap->nr.  Also, the table
+ * of I2C devices pre-declared using i2c_register_board_info() is scanned,
+ * and the appropriate driver model device nodes are created.  Otherwise, a
+ * negative errno value is returned.
+ */
+int i2c_add_numbered_adapter(struct i2c_adapter *adap)
+{
+       int     id;
+       int     status;
+
+       if (adap->nr & ~MAX_ID_MASK)
+               return -EINVAL;
+
+retry:
+       if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
+               return -ENOMEM;
+
+       mutex_lock(&core_lists);
+       /* "above" here means "above or equal to", sigh;
+        * we need the "equal to" result to force the result
+        */
+       status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);
+       if (status == 0 && id != adap->nr) {
+               status = -EBUSY;
+               idr_remove(&i2c_adapter_idr, id);
+       }
+       mutex_unlock(&core_lists);
+       if (status == -EAGAIN)
+               goto retry;
+
+       if (status == 0)
+               status = i2c_register_adapter(adap);
+       return status;
+}
+EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
 int i2c_del_adapter(struct i2c_adapter *adap)
 {
@@ -302,9 +499,19 @@ int i2c_del_adapter(struct i2c_adapter *adap)
        /* detach any active clients. This must be done first, because
         * it can fail; in which case we give up. */
        list_for_each_safe(item, _n, &adap->clients) {
+               struct i2c_driver       *driver;
+
                client = list_entry(item, struct i2c_client, list);
+               driver = client->driver;
+
+               /* new style, follow standard driver model */
+               if (!driver || is_newstyle_driver(driver)) {
+                       i2c_unregister_device(client);
+                       continue;
+               }
 
-               if ((res=client->driver->detach_client(client))) {
+               /* legacy drivers create and remove clients themselves */
+               if ((res = driver->detach_client(client))) {
                        dev_err(&adap->dev, "detach_client failed for client "
                                "[%s] at address 0x%02x\n", client->name,
                                client->addr);
@@ -314,17 +521,13 @@ int i2c_del_adapter(struct i2c_adapter *adap)
 
        /* clean up the sysfs representation */
        init_completion(&adap->dev_released);
-       init_completion(&adap->class_dev_released);
-       class_device_unregister(&adap->class_dev);
-       device_remove_file(&adap->dev, &dev_attr_name);
        device_unregister(&adap->dev);
        list_del(&adap->list);
 
        /* wait for sysfs to drop all references */
        wait_for_completion(&adap->dev_released);
-       wait_for_completion(&adap->class_dev_released);
 
-       /* free dynamically allocated bus id */
+       /* free bus id */
        idr_remove(&i2c_adapter_idr, adap->nr);
 
        dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
@@ -333,24 +536,42 @@ int i2c_del_adapter(struct i2c_adapter *adap)
        mutex_unlock(&core_lists);
        return res;
 }
+EXPORT_SYMBOL(i2c_del_adapter);
+
 
+/* ------------------------------------------------------------------------- */
 
-/* -----
- * What follows is the "upwards" interface: commands for talking to clients,
- * which implement the functions to access the physical information of the
- * chips.
+/*
+ * An i2c_driver is used with one or more i2c_client (device) nodes to access
+ * i2c slave chips, on a bus instance associated with some i2c_adapter.  There
+ * are two models for binding the driver to its device:  "new style" drivers
+ * follow the standard Linux driver model and just respond to probe() calls
+ * issued if the driver core sees they match(); "legacy" drivers create device
+ * nodes themselves.
  */
 
 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 {
-       struct list_head   *item;
-       struct i2c_adapter *adapter;
        int res;
 
+       /* new style driver methods can't mix with legacy ones */
+       if (is_newstyle_driver(driver)) {
+               if (driver->attach_adapter || driver->detach_adapter
+                               || driver->detach_client) {
+                       printk(KERN_WARNING
+                                       "i2c-core: driver [%s] is confused\n",
+                                       driver->driver.name);
+                       return -EINVAL;
+               }
+       }
+
        /* add the driver to the list of i2c drivers in the driver core */
        driver->driver.owner = owner;
        driver->driver.bus = &i2c_bus_type;
 
+       /* for new style drivers, when registration returns the driver core
+        * will have called probe() for all matching-but-unbound devices.
+        */
        res = driver_register(&driver->driver);
        if (res)
                return res;
@@ -360,10 +581,11 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
        list_add_tail(&driver->list,&drivers);
        pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
 
-       /* now look for instances of driver on our adapters */
+       /* legacy drivers scan i2c busses directly */
        if (driver->attach_adapter) {
-               list_for_each(item,&adapters) {
-                       adapter = list_entry(item, struct i2c_adapter, list);
+               struct i2c_adapter *adapter;
+
+               list_for_each_entry(adapter, &adapters, list) {
                        driver->attach_adapter(adapter);
                }
        }
@@ -373,16 +595,22 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 }
 EXPORT_SYMBOL(i2c_register_driver);
 
-int i2c_del_driver(struct i2c_driver *driver)
+/**
+ * i2c_del_driver - unregister I2C driver
+ * @driver: the driver being unregistered
+ */
+void i2c_del_driver(struct i2c_driver *driver)
 {
        struct list_head   *item1, *item2, *_n;
        struct i2c_client  *client;
        struct i2c_adapter *adap;
 
-       int res = 0;
-
        mutex_lock(&core_lists);
 
+       /* new-style driver? */
+       if (is_newstyle_driver(driver))
+               goto unregister;
+
        /* Have a look at each adapter, if clients of this driver are still
         * attached. If so, detach them to be able to kill the driver
         * afterwards.
@@ -390,11 +618,10 @@ int i2c_del_driver(struct i2c_driver *driver)
        list_for_each(item1,&adapters) {
                adap = list_entry(item1, struct i2c_adapter, list);
                if (driver->detach_adapter) {
-                       if ((res = driver->detach_adapter(adap))) {
+                       if (driver->detach_adapter(adap)) {
                                dev_err(&adap->dev, "detach_adapter failed "
                                        "for driver [%s]\n",
                                        driver->driver.name);
-                               goto out_unlock;
                        }
                } else {
                        list_for_each_safe(item2, _n, &adap->clients) {
@@ -404,25 +631,26 @@ int i2c_del_driver(struct i2c_driver *driver)
                                dev_dbg(&adap->dev, "detaching client [%s] "
                                        "at 0x%02x\n", client->name,
                                        client->addr);
-                               if ((res = driver->detach_client(client))) {
+                               if (driver->detach_client(client)) {
                                        dev_err(&adap->dev, "detach_client "
                                                "failed for client [%s] at "
                                                "0x%02x\n", client->name,
                                                client->addr);
-                                       goto out_unlock;
                                }
                        }
                }
        }
 
+ unregister:
        driver_unregister(&driver->driver);
        list_del(&driver->list);
        pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
 
- out_unlock:
        mutex_unlock(&core_lists);
-       return 0;
 }
+EXPORT_SYMBOL(i2c_del_driver);
+
+/* ------------------------------------------------------------------------- */
 
 static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)
 {
@@ -447,6 +675,7 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
 
        return rval;
 }
+EXPORT_SYMBOL(i2c_check_addr);
 
 int i2c_attach_client(struct i2c_client *client)
 {
@@ -463,9 +692,15 @@ int i2c_attach_client(struct i2c_client *client)
        client->usage_count = 0;
 
        client->dev.parent = &client->adapter->dev;
-       client->dev.driver = &client->driver->driver;
        client->dev.bus = &i2c_bus_type;
-       client->dev.release = &i2c_client_release;
+
+       if (client->driver)
+               client->dev.driver = &client->driver->driver;
+
+       if (client->driver && !is_newstyle_driver(client->driver))
+               client->dev.release = i2c_client_release;
+       else
+               client->dev.release = i2c_client_dev_release;
 
        snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
                "%d-%04x", i2c_adapter_id(adapter), client->addr);
@@ -474,9 +709,6 @@ int i2c_attach_client(struct i2c_client *client)
        res = device_register(&client->dev);
        if (res)
                goto out_list;
-       res = device_create_file(&client->dev, &dev_attr_client_name);
-       if (res)
-               goto out_unregister;
        mutex_unlock(&adapter->clist_lock);
 
        if (adapter->client_register)  {
@@ -489,10 +721,6 @@ int i2c_attach_client(struct i2c_client *client)
 
        return 0;
 
-out_unregister:
-       init_completion(&client->released); /* Needed? */
-       device_unregister(&client->dev);
-       wait_for_completion(&client->released);
 out_list:
        list_del(&client->list);
        dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
@@ -501,7 +729,7 @@ out_unlock:
        mutex_unlock(&adapter->clist_lock);
        return res;
 }
-
+EXPORT_SYMBOL(i2c_attach_client);
 
 int i2c_detach_client(struct i2c_client *client)
 {
@@ -527,7 +755,6 @@ int i2c_detach_client(struct i2c_client *client)
        mutex_lock(&adapter->clist_lock);
        list_del(&client->list);
        init_completion(&client->released);
-       device_remove_file(&client->dev, &dev_attr_client_name);
        device_unregister(&client->dev);
        mutex_unlock(&adapter->clist_lock);
        wait_for_completion(&client->released);
@@ -535,6 +762,7 @@ int i2c_detach_client(struct i2c_client *client)
  out:
        return res;
 }
+EXPORT_SYMBOL(i2c_detach_client);
 
 static int i2c_inc_use_client(struct i2c_client *client)
 {
@@ -567,6 +795,7 @@ int i2c_use_client(struct i2c_client *client)
 
        return 0;
 }
+EXPORT_SYMBOL(i2c_use_client);
 
 int i2c_release_client(struct i2c_client *client)
 {
@@ -581,6 +810,7 @@ int i2c_release_client(struct i2c_client *client)
 
        return 0;
 }
+EXPORT_SYMBOL(i2c_release_client);
 
 void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
 {
@@ -601,15 +831,13 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
        }
        mutex_unlock(&adap->clist_lock);
 }
+EXPORT_SYMBOL(i2c_clients_command);
 
 static int __init i2c_init(void)
 {
        int retval;
 
        retval = bus_register(&i2c_bus_type);
-       if (retval)
-               return retval;
-       retval = driver_register(&i2c_adapter_driver);
        if (retval)
                return retval;
        return class_register(&i2c_adapter_class);
@@ -618,7 +846,6 @@ static int __init i2c_init(void)
 static void __exit i2c_exit(void)
 {
        class_unregister(&i2c_adapter_class);
-       driver_unregister(&i2c_adapter_driver);
        bus_unregister(&i2c_bus_type);
 }
 
@@ -638,8 +865,9 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
 #ifdef DEBUG
                for (ret = 0; ret < num; ret++) {
                        dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
-                               "len=%d\n", ret, msgs[ret].flags & I2C_M_RD ?
-                               'R' : 'W', msgs[ret].addr, msgs[ret].len);
+                               "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
+                               ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
+                               (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
                }
 #endif
 
@@ -653,6 +881,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
                return -ENOSYS;
        }
 }
+EXPORT_SYMBOL(i2c_transfer);
 
 int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
 {
@@ -671,6 +900,7 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
           transmitted, else error code. */
        return (ret == 1) ? count : ret;
 }
+EXPORT_SYMBOL(i2c_master_send);
 
 int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
 {
@@ -690,7 +920,7 @@ int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
           transmitted, else error code. */
        return (ret == 1) ? count : ret;
 }
-
+EXPORT_SYMBOL(i2c_master_recv);
 
 int i2c_control(struct i2c_client *client,
        unsigned int cmd, unsigned long arg)
@@ -712,6 +942,7 @@ int i2c_control(struct i2c_client *client,
        }
        return ret;
 }
+EXPORT_SYMBOL(i2c_control);
 
 /* ----------------------------------------------------
  * the i2c address scanning function
@@ -853,6 +1084,70 @@ int i2c_probe(struct i2c_adapter *adapter,
 
        return 0;
 }
+EXPORT_SYMBOL(i2c_probe);
+
+struct i2c_client *
+i2c_new_probed_device(struct i2c_adapter *adap,
+                     struct i2c_board_info *info,
+                     unsigned short const *addr_list)
+{
+       int i;
+
+       /* Stop here if the bus doesn't support probing */
+       if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
+               dev_err(&adap->dev, "Probing not supported\n");
+               return NULL;
+       }
+
+       mutex_lock(&adap->clist_lock);
+       for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
+               /* Check address validity */
+               if (addr_list[i] < 0x03 || addr_list[i] > 0x77) {
+                       dev_warn(&adap->dev, "Invalid 7-bit address "
+                                "0x%02x\n", addr_list[i]);
+                       continue;
+               }
+
+               /* Check address availability */
+               if (__i2c_check_addr(adap, addr_list[i])) {
+                       dev_dbg(&adap->dev, "Address 0x%02x already in "
+                               "use, not probing\n", addr_list[i]);
+                       continue;
+               }
+
+               /* Test address responsiveness
+                  The default probe method is a quick write, but it is known
+                  to corrupt the 24RF08 EEPROMs due to a state machine bug,
+                  and could also irreversibly write-protect some EEPROMs, so
+                  for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte
+                  read instead. Also, some bus drivers don't implement
+                  quick write, so we fallback to a byte read it that case
+                  too. */
+               if ((addr_list[i] & ~0x07) == 0x30
+                || (addr_list[i] & ~0x0f) == 0x50
+                || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
+                       if (i2c_smbus_xfer(adap, addr_list[i], 0,
+                                          I2C_SMBUS_READ, 0,
+                                          I2C_SMBUS_BYTE, NULL) >= 0)
+                               break;
+               } else {
+                       if (i2c_smbus_xfer(adap, addr_list[i], 0,
+                                          I2C_SMBUS_WRITE, 0,
+                                          I2C_SMBUS_QUICK, NULL) >= 0)
+                               break;
+               }
+       }
+       mutex_unlock(&adap->clist_lock);
+
+       if (addr_list[i] == I2C_CLIENT_END) {
+               dev_dbg(&adap->dev, "Probing failed, no device found\n");
+               return NULL;
+       }
+
+       info->addr = addr_list[i];
+       return i2c_new_device(adap, info);
+}
+EXPORT_SYMBOL_GPL(i2c_new_probed_device);
 
 struct i2c_adapter* i2c_get_adapter(int id)
 {
@@ -866,11 +1161,13 @@ struct i2c_adapter* i2c_get_adapter(int id)
        mutex_unlock(&core_lists);
        return adapter;
 }
+EXPORT_SYMBOL(i2c_get_adapter);
 
 void i2c_put_adapter(struct i2c_adapter *adap)
 {
        module_put(adap->owner);
 }
+EXPORT_SYMBOL(i2c_put_adapter);
 
 /* The SMBus parts */
 
@@ -939,6 +1236,7 @@ s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value)
        return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
                              value,0,I2C_SMBUS_QUICK,NULL);
 }
+EXPORT_SYMBOL(i2c_smbus_write_quick);
 
 s32 i2c_smbus_read_byte(struct i2c_client *client)
 {
@@ -949,12 +1247,14 @@ s32 i2c_smbus_read_byte(struct i2c_client *client)
        else
                return data.byte;
 }
+EXPORT_SYMBOL(i2c_smbus_read_byte);
 
 s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
 {
        return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
                              I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
 }
+EXPORT_SYMBOL(i2c_smbus_write_byte);
 
 s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
 {
@@ -965,6 +1265,7 @@ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
        else
                return data.byte;
 }
+EXPORT_SYMBOL(i2c_smbus_read_byte_data);
 
 s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value)
 {
@@ -974,6 +1275,7 @@ s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value)
                              I2C_SMBUS_WRITE,command,
                              I2C_SMBUS_BYTE_DATA,&data);
 }
+EXPORT_SYMBOL(i2c_smbus_write_byte_data);
 
 s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command)
 {
@@ -984,6 +1286,7 @@ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command)
        else
                return data.word;
 }
+EXPORT_SYMBOL(i2c_smbus_read_word_data);
 
 s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
 {
@@ -993,6 +1296,23 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
                              I2C_SMBUS_WRITE,command,
                              I2C_SMBUS_WORD_DATA,&data);
 }
+EXPORT_SYMBOL(i2c_smbus_write_word_data);
+
+/* Returns the number of read bytes */
+s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command,
+                             u8 *values)
+{
+       union i2c_smbus_data data;
+
+       if (i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                          I2C_SMBUS_READ, command,
+                          I2C_SMBUS_BLOCK_DATA, &data))
+               return -1;
+
+       memcpy(values, &data.block[1], data.block[0]);
+       return data.block[0];
+}
+EXPORT_SYMBOL(i2c_smbus_read_block_data);
 
 s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
                               u8 length, const u8 *values)
@@ -1007,6 +1327,7 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
                              I2C_SMBUS_WRITE,command,
                              I2C_SMBUS_BLOCK_DATA,&data);
 }
+EXPORT_SYMBOL(i2c_smbus_write_block_data);
 
 /* Returns the number of read bytes */
 s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values)
@@ -1021,6 +1342,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val
        memcpy(values, &data.block[1], data.block[0]);
        return data.block[0];
 }
+EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
 
 s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
                                   u8 length, const u8 *values)
@@ -1035,6 +1357,7 @@ s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
                              I2C_SMBUS_WRITE, command,
                              I2C_SMBUS_I2C_BLOCK_DATA, &data);
 }
+EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
 
 /* Simulate a SMBus command using the i2c protocol
    No checking of parameters is done!  */
@@ -1098,9 +1421,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                break;
        case I2C_SMBUS_BLOCK_DATA:
                if (read_write == I2C_SMBUS_READ) {
-                       dev_err(&adapter->dev, "Block read not supported "
-                              "under I2C emulation!\n");
-                       return -1;
+                       msg[1].flags |= I2C_M_RECV_LEN;
+                       msg[1].len = 1; /* block length will be added by
+                                          the underlying bus driver */
                } else {
                        msg[0].len = data->block[0] + 2;
                        if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
@@ -1114,9 +1437,21 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                }
                break;
        case I2C_SMBUS_BLOCK_PROC_CALL:
-               dev_dbg(&adapter->dev, "Block process call not supported "
-                      "under I2C emulation!\n");
-               return -1;
+               num = 2; /* Another special case */
+               read_write = I2C_SMBUS_READ;
+               if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
+                       dev_err(&adapter->dev, "%s called with invalid "
+                               "block proc call size (%d)\n", __FUNCTION__,
+                               data->block[0]);
+                       return -1;
+               }
+               msg[0].len = data->block[0] + 2;
+               for (i = 1; i < msg[0].len; i++)
+                       msgbuf0[i] = data->block[i-1];
+               msg[1].flags |= I2C_M_RECV_LEN;
+               msg[1].len = 1; /* block length will be added by
+                                  the underlying bus driver */
+               break;
        case I2C_SMBUS_I2C_BLOCK_DATA:
                if (read_write == I2C_SMBUS_READ) {
                        msg[1].len = I2C_SMBUS_BLOCK_MAX;
@@ -1180,6 +1515,11 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                                for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
                                        data->block[i+1] = msgbuf1[i];
                                break;
+                       case I2C_SMBUS_BLOCK_DATA:
+                       case I2C_SMBUS_BLOCK_PROC_CALL:
+                               for (i = 0; i < msgbuf1[0] + 1; i++)
+                                       data->block[i] = msgbuf1[i];
+                               break;
                }
        return 0;
 }
@@ -1204,43 +1544,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
 
        return res;
 }
-
-
-/* Next four are needed by i2c-isa */
-EXPORT_SYMBOL_GPL(i2c_adapter_dev_release);
-EXPORT_SYMBOL_GPL(i2c_adapter_driver);
-EXPORT_SYMBOL_GPL(i2c_adapter_class);
-EXPORT_SYMBOL_GPL(i2c_bus_type);
-
-EXPORT_SYMBOL(i2c_add_adapter);
-EXPORT_SYMBOL(i2c_del_adapter);
-EXPORT_SYMBOL(i2c_del_driver);
-EXPORT_SYMBOL(i2c_attach_client);
-EXPORT_SYMBOL(i2c_detach_client);
-EXPORT_SYMBOL(i2c_use_client);
-EXPORT_SYMBOL(i2c_release_client);
-EXPORT_SYMBOL(i2c_clients_command);
-EXPORT_SYMBOL(i2c_check_addr);
-
-EXPORT_SYMBOL(i2c_master_send);
-EXPORT_SYMBOL(i2c_master_recv);
-EXPORT_SYMBOL(i2c_control);
-EXPORT_SYMBOL(i2c_transfer);
-EXPORT_SYMBOL(i2c_get_adapter);
-EXPORT_SYMBOL(i2c_put_adapter);
-EXPORT_SYMBOL(i2c_probe);
-
 EXPORT_SYMBOL(i2c_smbus_xfer);
-EXPORT_SYMBOL(i2c_smbus_write_quick);
-EXPORT_SYMBOL(i2c_smbus_read_byte);
-EXPORT_SYMBOL(i2c_smbus_write_byte);
-EXPORT_SYMBOL(i2c_smbus_read_byte_data);
-EXPORT_SYMBOL(i2c_smbus_write_byte_data);
-EXPORT_SYMBOL(i2c_smbus_read_word_data);
-EXPORT_SYMBOL(i2c_smbus_write_word_data);
-EXPORT_SYMBOL(i2c_smbus_write_block_data);
-EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
-EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
new file mode 100644 (file)
index 0000000..cd5bff8
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * i2c-core.h - interfaces internal to the I2C framework
+ *
+ * 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.
+ */
+
+struct i2c_devinfo {
+       struct list_head        list;
+       int                     busnum;
+       struct i2c_board_info   board_info;
+};
+
+/* board_lock protects board_list and first_dynamic_bus_num.
+ * only i2c core components are allowed to use these symbols.
+ */
+extern struct mutex    __i2c_board_lock;
+extern struct list_head        __i2c_board_list;
+extern int             __i2c_first_dynamic_bus_num;
+
index 35233de460ad7f6e574b552c710ea10b0867abae..3d0354e96a9775242ae1c81cf0800bb77130db54 100644 (file)
@@ -459,7 +459,8 @@ therm_of_probe( struct of_device *dev, const struct of_device_id *match )
 static int
 therm_of_remove( struct of_device *dev )
 {
-       return i2c_del_driver( &g4fan_driver );
+       i2c_del_driver( &g4fan_driver );
+       return 0;
 }
 
 static struct of_device_id therm_of_match[] = {{
index 5347a406fff7e0e73abe885eff3562ca747a10a6..02a0ea6e1c17e030e7391ec09ec396a24d70eb96 100644 (file)
@@ -183,7 +183,8 @@ int flexcop_i2c_init(struct flexcop_device *fc)
        mutex_init(&fc->i2c_mutex);
 
        memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
-       strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE);
+       strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",
+               sizeof(fc->i2c_adap.name));
 
        i2c_set_adapdata(&fc->i2c_adap,fc);
 
index 70df31b0a8a9cdecfae95d3f4dea2efc07ad0b5f..088b6dee3a7fbfa289e3ff9c11b77b34405fb478 100644 (file)
@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
                return -EINVAL;
        }
 
-       strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE);
+       strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
 #ifdef I2C_ADAP_CLASS_TV_DIGITAL
        d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
 #else
index a18c8f45a2eeecded00ff1ecb2760d56141e71bf..315e09e95b0c47723463c2b3b68f9d7df6f2e496 100644 (file)
@@ -105,9 +105,9 @@ struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enu
 }
 EXPORT_SYMBOL(dibx000_get_i2c_adapter);
 
-static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst)
+static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst)
 {
-       strncpy(i2c_adap->name, name, I2C_NAME_SIZE);
+       strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
        i2c_adap->class     = I2C_CLASS_TV_DIGITAL,
        i2c_adap->algo      = algo;
        i2c_adap->algo_data = NULL;
index 88dbdddeec42afaa34c9fded534cd5f9cbd0ab10..d73c86aeeaacb9a13e5f190492cb8ad31f419882 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/videodev2.h>
-#include <linux/i2c.h>
 
 #include <media/tuner.h>
 #include <media/cx2341x.h>
index 1231335a9f4ac345a0d312bc7da0787daec73d0c..50c7763d44b3cad08799299a9f46c2f3839be43c 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef __LINUX_OVCAMCHIP_PRIV_H
 #define __LINUX_OVCAMCHIP_PRIV_H
 
+#include <linux/i2c.h>
 #include <media/ovcamchip.h>
 
 #ifdef DEBUG
index 13f69fe6360da8e774998b49a87213b872a0d672..51ab265d566ac29154c9234d3c7d60167a7fa482 100644 (file)
@@ -24,7 +24,6 @@
 
 
 #include <linux/list.h>
-#include <linux/i2c.h>
 #include <media/v4l2-dev.h>
 #include <media/tuner.h>
 #include "usbvision.h"
index f4ede5f6b588da583e43545566737fc736545104..61e4c8759b231da79de6c45e6708041d5ee53292 100644 (file)
@@ -104,7 +104,8 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
 
        chan->dinfo                                     = dinfo;
        chan->reg                                       = reg;
-       snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name);
+       snprintf(chan->adapter.name, sizeof(chan->adapter.name),
+                "intelfb %s", name);
        chan->adapter.owner                     = THIS_MODULE;
        chan->adapter.id                        = I2C_HW_B_INTELFB;
        chan->adapter.algo_data         = &chan->algo;
index 5ec718a5fe2257c093ccaf74f550ba9100bf4c27..4baab7be58de4f075de0f197ac5b019da3d35eb4 100644 (file)
@@ -111,7 +111,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
        b->mask.data = data;
        b->mask.clock = clock;
        b->adapter = matrox_i2c_adapter_template;
-       snprintf(b->adapter.name, I2C_NAME_SIZE, name,
+       snprintf(b->adapter.name, sizeof(b->adapter.name), name,
                minfo->fbcon.node);
        i2c_set_adapdata(&b->adapter, b);
        b->adapter.algo_data = &b->bac;
index 937da70cb4c415b962e9de76f2940a4806cae112..9ee0f800592f030bd56592ec2de113e5c8deb214 100644 (file)
@@ -38,11 +38,14 @@ struct i2c_algo_bit_data {
        int  (*getscl) (void *data);
 
        /* local settings */
-       int udelay;             /* half-clock-cycle time in microsecs */
-                               /* i.e. clock is (500 / udelay) KHz */
+       int udelay;             /* half clock cycle time in us,
+                                  minimum 2 us for fast-mode I2C,
+                                  minimum 5 us for standard-mode I2C and SMBus,
+                                  maximum 50 us for SMBus */
        int timeout;            /* in jiffies */
 };
 
 int i2c_bit_add_bus(struct i2c_adapter *);
+int i2c_bit_add_numbered_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_BIT_H */
diff --git a/include/linux/i2c-gpio.h b/include/linux/i2c-gpio.h
new file mode 100644 (file)
index 0000000..c1bcb1f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * i2c-gpio interface to platform code
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _LINUX_I2C_GPIO_H
+#define _LINUX_I2C_GPIO_H
+
+/**
+ * struct i2c_gpio_platform_data - Platform-dependent data for i2c-gpio
+ * @sda_pin: GPIO pin ID to use for SDA
+ * @scl_pin: GPIO pin ID to use for SCL
+ * @udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz
+ * @timeout: clock stretching timeout in jiffies. If the slave keeps
+ *     SCL low for longer than this, the transfer will time out.
+ * @sda_is_open_drain: SDA is configured as open drain, i.e. the pin
+ *     isn't actively driven high when setting the output value high.
+ *     gpio_get_value() must return the actual pin state even if the
+ *     pin is configured as an output.
+ * @scl_is_open_drain: SCL is set up as open drain. Same requirements
+ *     as for sda_is_open_drain apply.
+ * @scl_is_output_only: SCL output drivers cannot be turned off.
+ */
+struct i2c_gpio_platform_data {
+       unsigned int    sda_pin;
+       unsigned int    scl_pin;
+       int             udelay;
+       int             timeout;
+       unsigned int    sda_is_open_drain:1;
+       unsigned int    scl_is_open_drain:1;
+       unsigned int    scl_is_output_only:1;
+};
+
+#endif /* _LINUX_I2C_GPIO_H */
index 9c21dc793d7b160d525a78841ecdc98f6cf89dca..0e8da684ce6851d94c88ad492ace3669eaf3c480 100644 (file)
 /* --- MCP107 adapter */
 #define I2C_HW_MPC107          0x0d0000
 
-/* --- Marvell mv64xxx i2c adapter */
+/* --- Embedded adapters */
 #define I2C_HW_MV64XXX         0x190000
+#define I2C_HW_BLACKFIN                0x190001 /* ADI Blackfin I2C TWI driver */
 
 /* --- Miscellaneous adapters */
 #define I2C_HW_SAA7146         0x060000 /* SAA7146 video decoder bus */
index 9428092017e346dea02ca6442da258859ff39342..cae7d618030cbc0e0580a8cb5b9663dd29d2c793 100644 (file)
 #include <linux/sched.h>       /* for completion */
 #include <linux/mutex.h>
 
-/* --- For i2c-isa ---------------------------------------------------- */
-
-extern void i2c_adapter_dev_release(struct device *dev);
-extern struct device_driver i2c_adapter_driver;
-extern struct class i2c_adapter_class;
 extern struct bus_type i2c_bus_type;
 
 /* --- General options ------------------------------------------------        */
@@ -87,6 +82,9 @@ extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
 extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
 extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
                                      u8 command, u16 value);
+/* Returns the number of read bytes */
+extern s32 i2c_smbus_read_block_data(struct i2c_client *client,
+                                    u8 command, u8 *values);
 extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
                                      u8 command, u8 length,
                                      const u8 *values);
@@ -114,7 +112,7 @@ struct i2c_driver {
         * can be used by the driver to test if the bus meets its conditions
         * & seek for the presence of the chip(s) it supports. If found, it
         * registers the client(s) that are on the bus to the i2c admin. via
-        * i2c_attach_client.
+        * i2c_attach_client.  (LEGACY I2C DRIVERS ONLY)
         */
        int (*attach_adapter)(struct i2c_adapter *);
        int (*detach_adapter)(struct i2c_adapter *);
@@ -122,10 +120,17 @@ struct i2c_driver {
        /* tells the driver that a client is about to be deleted & gives it
         * the chance to remove its private data. Also, if the client struct
         * has been dynamically allocated by the driver in the function above,
-        * it must be freed here.
+        * it must be freed here.  (LEGACY I2C DRIVERS ONLY)
         */
        int (*detach_client)(struct i2c_client *);
 
+       /* Standard driver model interfaces, for "new style" i2c drivers.
+        * With the driver model, device enumeration is NEVER done by drivers;
+        * it's done by infrastructure.  (NEW STYLE DRIVERS ONLY)
+        */
+       int (*probe)(struct i2c_client *);
+       int (*remove)(struct i2c_client *);
+
        /* driver model interfaces that don't relate to enumeration  */
        void (*shutdown)(struct i2c_client *);
        int (*suspend)(struct i2c_client *, pm_message_t mesg);
@@ -141,25 +146,34 @@ struct i2c_driver {
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
-#define I2C_NAME_SIZE  50
+#define I2C_NAME_SIZE  20
 
-/*
- * i2c_client identifies a single device (i.e. chip) that is connected to an
- * i2c bus. The behaviour is defined by the routines of the driver. This
- * function is mainly used for lookup & other admin. functions.
+/**
+ * struct i2c_client - represent an I2C slave device
+ * @addr: Address used on the I2C bus connected to the parent adapter.
+ * @name: Indicates the type of the device, usually a chip name that's
+ *     generic enough to hide second-sourcing and compatible revisions.
+ * @dev: Driver model device node for the slave.
+ * @driver_name: Identifies new-style driver used with this device; also
+ *     used as the module name for hotplug/coldplug modprobe support.
+ *
+ * An i2c_client identifies a single device (i.e. chip) connected to an
+ * i2c bus. The behaviour is defined by the routines of the driver.
  */
 struct i2c_client {
-       unsigned int flags;             /* div., see below              */
+       unsigned short flags;           /* div., see below              */
        unsigned short addr;            /* chip address - NOTE: 7bit    */
                                        /* addresses are stored in the  */
                                        /* _LOWER_ 7 bits               */
+       char name[I2C_NAME_SIZE];
        struct i2c_adapter *adapter;    /* the adapter we sit on        */
        struct i2c_driver *driver;      /* and our access routines      */
        int usage_count;                /* How many accesses currently  */
                                        /* to the client                */
        struct device dev;              /* the device structure         */
+       int irq;                        /* irq issued by device (or -1) */
+       char driver_name[KOBJ_NAME_LEN];
        struct list_head list;
-       char name[I2C_NAME_SIZE];
        struct completion released;
 };
 #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
@@ -179,6 +193,76 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
        dev_set_drvdata (&dev->dev, data);
 }
 
+/**
+ * struct i2c_board_info - template for device creation
+ * @driver_name: identifies the driver to be bound to the device
+ * @type: optional chip type information, to initialize i2c_client.name
+ * @flags: to initialize i2c_client.flags
+ * @addr: stored in i2c_client.addr
+ * @platform_data: stored in i2c_client.dev.platform_data
+ * @irq: stored in i2c_client.irq
+
+ * I2C doesn't actually support hardware probing, although controllers and
+ * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
+ * a device at a given address.  Drivers commonly need more information than
+ * that, such as chip type, configuration, associated IRQ, and so on.
+ *
+ * i2c_board_info is used to build tables of information listing I2C devices
+ * that are present.  This information is used to grow the driver model tree
+ * for "new style" I2C drivers.  For mainboards this is done statically using
+ * i2c_register_board_info(), where @bus_num represents an adapter that isn't
+ * yet available.  For add-on boards, i2c_new_device() does this dynamically
+ * with the adapter already known.
+ */
+struct i2c_board_info {
+       char            driver_name[KOBJ_NAME_LEN];
+       char            type[I2C_NAME_SIZE];
+       unsigned short  flags;
+       unsigned short  addr;
+       void            *platform_data;
+       int             irq;
+};
+
+/**
+ * I2C_BOARD_INFO - macro used to list an i2c device and its driver
+ * @driver: identifies the driver to use with the device
+ * @dev_addr: the device's address on the bus.
+ *
+ * This macro initializes essential fields of a struct i2c_board_info,
+ * declaring what has been provided on a particular board.  Optional
+ * fields (such as the chip type, its associated irq, or device-specific
+ * platform_data) are provided using conventional syntax.
+ */
+#define I2C_BOARD_INFO(driver,dev_addr) \
+       .driver_name = (driver), .addr = (dev_addr)
+
+
+/* Add-on boards should register/unregister their devices; e.g. a board
+ * with integrated I2C, a config eeprom, sensors, and a codec that's
+ * used in conjunction with the primary hardware.
+ */
+extern struct i2c_client *
+i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
+
+/* If you don't know the exact address of an I2C device, use this variant
+ * instead, which can probe for device presence in a list of possible
+ * addresses.
+ */
+extern struct i2c_client *
+i2c_new_probed_device(struct i2c_adapter *adap,
+                     struct i2c_board_info *info,
+                     unsigned short const *addr_list);
+
+extern void i2c_unregister_device(struct i2c_client *);
+
+/* Mainboard arch_initcall() code should register all its I2C devices.
+ * This is done at arch_initcall time, before declaring any i2c adapters.
+ * Modules for add-on boards must use other calls.
+ */
+extern int
+i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n);
+
+
 /*
  * The following structs are for those who like to implement new bus drivers:
  * i2c_algorithm is the interface to a class of hardware solutions which can
@@ -228,17 +312,14 @@ struct i2c_adapter {
        int timeout;
        int retries;
        struct device dev;              /* the adapter device */
-       struct class_device class_dev;  /* the class device */
 
        int nr;
        struct list_head clients;
        struct list_head list;
-       char name[I2C_NAME_SIZE];
+       char name[48];
        struct completion dev_released;
-       struct completion class_dev_released;
 };
-#define dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
-#define class_dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, class_dev)
+#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
 static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
 {
@@ -290,9 +371,10 @@ struct i2c_client_address_data {
  */
 extern int i2c_add_adapter(struct i2c_adapter *);
 extern int i2c_del_adapter(struct i2c_adapter *);
+extern int i2c_add_numbered_adapter(struct i2c_adapter *);
 
 extern int i2c_register_driver(struct module *, struct i2c_driver *);
-extern int i2c_del_driver(struct i2c_driver *);
+extern void i2c_del_driver(struct i2c_driver *);
 
 static inline int i2c_add_driver(struct i2c_driver *driver)
 {
@@ -365,6 +447,7 @@ struct i2c_msg {
 #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 */
        __u16 len;              /* msg length                           */
        __u8 *buf;              /* pointer to msg data                  */
 };
index 1b0ddbb8a8045ea85fc8fb028b81919dc7ca6baf..5a48e963d06b5bf8b0d9046da97193ba5c983886 100644 (file)
 #define PCI_DEVICE_ID_NVIDIA_NVENET_16              0x03E5
 #define PCI_DEVICE_ID_NVIDIA_NVENET_17              0x03E6
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA      0x03E7
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS            0x03EB
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE       0x03EC
 #define PCI_DEVICE_ID_NVIDIA_NVENET_18              0x03EE
 #define PCI_DEVICE_ID_NVIDIA_NVENET_19              0x03EF
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2     0x03F6
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3     0x03F7
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS            0x0446
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE      0x0448
 #define PCI_DEVICE_ID_NVIDIA_NVENET_20              0x0450
 #define PCI_DEVICE_ID_NVIDIA_NVENET_21              0x0451
index 0f43451f8bb3599db431e12789cd498b71ecc168..05b9569ef1c893cb4a2129f790c6cb6bbfb272fe 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
-#include <linux/i2c.h>
 
 /* --------------------------------- */
 /*           ENUMERATIONS            */
index a41ac41113acb5c5a2ff7e964bfc00b48fe2466e..6dcf3c45707d637518aef5b74d700fe8b2d261d7 100644 (file)
@@ -23,6 +23,7 @@
 #define _TUNER_H
 
 #include <linux/videodev2.h>
+#include <linux/i2c.h>
 #include <media/tuner-types.h>
 
 extern int tuner_debug;
index dccae3a40e01a4c32bd0712fc617e7929b2b76c9..9d12b373b4a9e78be3addf531ec80e3a4fc6bc97 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _TAS_IOCTL_H_
 #define _TAS_IOCTL_H_
 
-#include <linux/i2c.h>
 #include <linux/soundcard.h>