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 field must match the driver name, including the case. It must not
contain spaces, and may be up to 31 characters long.

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.


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 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(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(data);
    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);
  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]);
      }
    }
  }
