This is a small guide for those who want to write kernel drivers for I2C
or SMBus devices.

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
guide, not as a rule book!


General remarks
===============

Try to keep the kernel namespace as clean as possible. The best way to
do this is to use a unique prefix for all global symbols. This is 
especially important for exported symbols, but it is a good idea to do
it for non-exported symbols too. We will use the prefix `foo_' in this
tutorial, and `FOO_' for preprocessor variables.


The driver structure
====================

Usually, you will implement a single driver structure, and instantiate
all clients from it. Remember, a driver structure contains general access 
routines, and should be zero-initialized except for fields with data you
provide.  A client structure holds device-specific information like the
driver model device node, and its I2C address.

static struct i2c_driver foo_driver = {
	.driver = {
		.name	= "foo",
	},
	.attach_adapter	= foo_attach_adapter,
	.detach_client	= foo_detach_client,
	.shutdown	= foo_shutdown,	/* optional */
	.suspend	= foo_suspend,	/* optional */
	.resume		= foo_resume,	/* optional */
	.command	= foo_command,	/* optional */
}
 
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.

All other fields are for call-back functions which will be explained 
below.


Extra client data
=================

Each client structure has a special `data' field that can point to any
structure at all.  You should use this to keep device-specific data,
especially in drivers that handle multiple I2C or SMBUS devices.  You
do not always need this, but especially for `sensors' drivers, it can
be very useful.

	/* store the value */
	void i2c_set_clientdata(struct i2c_client *client, void *data);

	/* retrieve the value */
	void *i2c_get_clientdata(struct i2c_client *client);

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,
                                     another process should not update the
                                     below information */
    char valid;                   /* != 0 if the following fields are valid. */
    unsigned long last_updated;   /* In jiffies */
    /* Add the read information here too */
  };


Accessing the client
====================

Let's say we have a valid client structure. At some time, we will need
to gather information from the client, or write new information to the
client. How we will export this information to user-space is less 
important at this moment (perhaps we do not need to do this at all for
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).

The below functions are simple examples, and should not be copied
literally.

  int foo_read_value(struct i2c_client *client, u8 reg)
  {
    if (reg < 0x10) /* byte-sized register */
      return i2c_smbus_read_byte_data(client,reg);
    else /* word-sized register */
      return i2c_smbus_read_word_data(client,reg);
  }

  int foo_write_value(struct i2c_client *client, u8 reg, u16 value)
  {
    if (reg == 0x10) /* Impossible to write - driver error! */ {
      return -1;
    else if (reg < 0x10) /* byte-sized register */
      return i2c_smbus_write_byte_data(client,reg,value);
    else /* word-sized register */
      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
=====================

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
registers). Some devices are usually on a specific address, but not always;
and some are even more tricky. So you will probably need to scan several
i2c addresses for your clients, and do some sort of detection to see
whether it is actually a device supported by your driver.

To give the user a maximum of possibilities, some default module parameters
are defined to help determine what addresses are scanned. Several macros
are defined in i2c.h to help you support them, as well as a generic
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
---------------

All parameters are given as lists of unsigned 16-bit integers. Lists are
terminated by I2C_CLIENT_END.
The following lists are used internally:

  normal_i2c: filled in by the module writer. 
     A list of I2C addresses which should normally be examined.
   probe: insmod parameter. 
     A list of pairs. The first value is a bus number (-1 for any I2C bus), 
     the second is the address. These addresses are also probed, as if they 
     were in the 'normal' list.
   ignore: insmod parameter.
     A list of pairs. The first value is a bus number (-1 for any I2C bus), 
     the second is the I2C address. These addresses are never probed. 
     This parameter overrules the 'normal_i2c' list only.
   force: insmod parameter. 
     A list of pairs. The first value is a bus number (-1 for any I2C bus),
     the second is the I2C address. A device is blindly assumed to be on
     the given address, no probing is done. 

Additionally, kind-specific force lists may optionally be defined if
the driver supports several chip kinds. They are grouped in a
NULL-terminated list of pointers named forces, those first element if the
generic force list mentioned above. Each additional list correspond to an
insmod parameter of the form force_<kind>.

Fortunately, as a module writer, you just have to define the `normal_i2c' 
parameter. The complete declaration could look like this:

  /* Scan 0x37, and 0x48 to 0x4f */
  static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
                                         0x4d, 0x4e, 0x4f, I2C_CLIENT_END };

  /* Magic definition of all other variables and things */
  I2C_CLIENT_INSMOD;
  /* Or, if your driver supports, say, 2 kind of devices: */
  I2C_CLIENT_INSMOD_2(foo, bar);

If you use the multi-kind form, an enum will be defined for you:
  enum chips { any_chip, foo, bar, ... }
You can then (and certainly should) use it in the driver code.

Note that you *have* to call the defined variable `normal_i2c',
without any prefix!


Attaching to an adapter
-----------------------

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
time to determine what devices are present on the adapter, and to register
a client for each of them.

The attach_adapter callback is really easy: we just call the generic
detection function. This function will scan the bus for us, using the
information as defined in the lists explained above. If a device is
detected at a specific address, another callback is called.

  int foo_attach_adapter(struct i2c_adapter *adapter)
  {
    return i2c_probe(adapter,&addr_data,&foo_detect_client);
  }

Remember, structure `addr_data' is defined by the macros explained above,
so you do not have to define it yourself.

The i2c_probe function will call the foo_detect_client
function only for those i2c addresses that actually have a device on
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 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
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 err = 0;
    int i;
    struct i2c_client *new_client;
    struct foo_data *data;
    const char *client_name = ""; /* For non-`sensors' drivers, put the real
                                     name here! */
   
    /* 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 */
    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 */
    
    if (!(data = kzalloc(sizeof(struct foo_data), GFP_KERNEL))) {
      err = -ENOMEM;
      goto ERROR0;
    }

    new_client = &data->client;
    i2c_set_clientdata(new_client, data);

    new_client->addr = address;
    new_client->adapter = adapter;
    new_client->driver = &foo_driver;
    new_client->flags = 0;

    /* Now, we do the remaining detection. If no `force' parameter is used. */

    /* First, the generic detection (if any), that is skipped if any force
       parameter was used. */
    if (kind < 0) {
      /* The below is of course bogus */
      if (foo_read(new_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);
      if (i == FOO_TYPE_1) 
        kind = chip1; /* As defined in the enum */
      else if (i == FOO_TYPE_2)
        kind = chip2;
      else {
        printk("foo: Ignoring 'force' parameter for unknown chip at "
               "adapter %d, address 0x%02x\n",i2c_adapter_id(adapter),address);
        goto ERROR1;
      }
    }

    /* Now set the type and chip names */
    if (kind == chip1) {
      type_name = "chip1"; /* For /proc entry */
      client_name = "CHIP 1";
    } else if (kind == chip2) {
      type_name = "chip2"; /* For /proc entry */
      client_name = "CHIP 2";
    }
   
    /* 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 */
    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 */

    /* 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);
    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:
      return err;
  }


Removing the client
===================

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
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 */

    /* 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;
  }


Initializing the module or kernel
=================================

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)
  {
    if (foo_initialized == 1) {
      if ((res = i2c_del_driver(&foo_driver))) {
        printk("foo: Driver registration failed, module not removed.\n");
        return;
      }
      foo_initialized --;
    }
  }

  /* Substitute your own name and email address */
  MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
  MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");

  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
kernel booting (or module loading) is completed.


Power Management
================

If your I2C device needs special handling when entering a system low
power state -- like putting a transceiver into a low power mode, or
activating a system wakeup mechanism -- do that in the suspend() method.
The resume() method should reverse what the suspend() method does.

These are standard driver model calls, and they work just like they
would for any other driver stack.  The calls can sleep, and can use
I2C messaging to the device being suspended or resumed (since their
parent I2C adapter is active when these calls are issued, and IRQs
are still enabled).


System Shutdown
===============

If your I2C device needs special handling when the system shuts down
or reboots (including kexec) -- like turning something off -- use a
shutdown() method.

Again, this is a standard driver model call, working just like it
would for any other driver stack:  the calls can sleep, and can use
I2C messaging.


Command function
================

A generic ioctl-like function call back is supported. You will seldom
need this, and its use is deprecated anyway, so newer design should not
use it. Set it to NULL.


Sending and receiving
=====================

If you want to communicate with your device, there are several functions
to do this. You can find all of them in i2c.h.

If you can choose between plain i2c communication and SMBus level
communication, please use the last. All adapters understand SMBus level
commands, but only some of them understand plain i2c!


Plain i2c communication
-----------------------

  extern int i2c_master_send(struct i2c_client *,const char* ,int);
  extern int i2c_master_recv(struct i2c_client *,char* ,int);

These routines read and write some bytes from/to a client. The client
contains the i2c address, so you do not have to include it. The second
parameter contains the bytes the read/write, the third the length of the
buffer. Returned is the actual number of bytes read/written.
  
  extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,
                          int num);

This sends a series of messages. Each message can be a read or write,
and they can be mixed in any way. The transactions are combined: no
stop bit is sent between transaction. The i2c_msg structure contains
for each message the client address, the number of bytes of the message
and the message data itself.

You can read the file `i2c-protocol' for more information about the
actual i2c protocol.


SMBus communication
-------------------

  extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, 
                             unsigned short flags,
                             char read_write, u8 command, int size,
                             union i2c_smbus_data * data);

  This is the generic SMBus function. All functions below are implemented
  in terms of it. Never use this function directly!


  extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
  extern s32 i2c_smbus_read_byte(struct i2c_client * client);
  extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
  extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
  extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
                                       u8 command, u8 value);
  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);
  extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
                                        u8 command, u8 length,
                                        u8 *values);
  extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
                                           u8 command, u8 *values);

These ones were removed in Linux 2.6.10 because they had no users, but could
be added back later if needed:

  extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
                                       u8 command, u8 *values);
  extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
                                            u8 command, u8 length,
                                            u8 *values);
  extern s32 i2c_smbus_process_call(struct i2c_client * client,
                                    u8 command, u16 value);
  extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
                                          u8 command, u8 length,
                                          u8 *values)

All these transactions return -1 on failure. The 'write' transactions 
return 0 on success; the 'read' transactions return the read value, except 
for read_block, which returns the number of values read. The block buffers 
need not be longer than 32 bytes.

You can read the file `smbus-protocol' for more information about the
actual SMBus protocol.


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.
   */
  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]);
      }
    }
  }
