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, a client structure specific information like the actual I2C
address.

static struct i2c_driver foo_driver = {
	.owner		= THIS_MODULE,
	.name		= "Foo version 2.3 driver",
	.flags		= I2C_DF_NOTIFY,
	.attach_adapter	= &foo_attach_adapter,
	.detach_client	= &foo_detach_client,
	.command	= &foo_command /* may be NULL */
}
 
The name can be chosen freely, and may be upto 40 characters long. Please
use something descriptive here.

Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
means that your driver will be notified when new adapters are found.
This is almost always what you want.

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

There use to be two additional fields in this structure, inc_use et dec_use,
for module usage count, but these fields were obsoleted and removed.


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

The client structure has a special `data' field that can point to any
structure at all. You can use this to keep client-specific data. You
do not always need this, but especially for `sensors' drivers, it can
be very useful.

An example structure is below.

  struct foo_data {
    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 */
      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 */
    
    /* Note that we reserve some space for foo_data too. If you don't
       need it, remove it. We do it here to help to lessen memory
       fragmentation. */
    if (! (new_client = kmalloc(sizeof(struct i2c_client) + 
                                sizeof(struct foo_data),
                                GFP_KERNEL))) {
      err = -ENOMEM;
      goto ERROR0;
    }

    /* This is tricky, but it will set the data to the right value. */
    client->data = new_client + 1;
    data = (struct foo_data *) (client->data);

    new_client->addr = address;
    new_client->data = data;
    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(new_client);
    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(client); /* Frees client data too, if allocated at the same time */
    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.

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

A generic ioctl-like function call back is supported. You will seldom
need this. You may even set it to NULL.

  /* No commands defined */
  int foo_command(struct i2c_client *client, unsigned int cmd, void *arg)
  {
    return 0;
  }


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);

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_i2c_block_data(struct i2c_client * client,
                                           u8 command, u8 *values);
  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]);
      }
    }
  }
