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",
	.id		= I2C_DRIVERID_FOO, /* from i2c-id.h, optional */
	.flags		= I2C_DF_NOTIFY,
	.attach_adapter	= &foo_attach_adapter,
	.detach_client	= &foo_detach_client,
	.command	= &foo_command /* may be NULL */
}
 
The name can be chosen freely, and may be upto 40 characters long. Please
use something descriptive here.

If used, the id should be a unique ID. The range 0xf000 to 0xffff is
reserved for local use, and you can use one of those until you start
distributing the driver, at which time you should contact the i2c authors
to get your own ID(s). Note that most of the time you don't need an ID
at all so you can just omit it.

Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
means that your driver will be notified when new adapters are found.
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() (or i2c_detect()) if you don't.

NOTE: If you want to write a `sensors' driver, the interface is slightly
      different! See below.



Probing classes (i2c)
---------------------

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.
   normal_i2c_range: filled in by the module writer.
     A list of pairs of I2C addresses, each pair being an inclusive range of
     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.
   probe_range: insmod parameter. 
     A list of triples. The first value is a bus number (-1 for any I2C bus), 
     the second and third are addresses.  These form an inclusive range of 
     addresses that 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 'normal' and 'probe', but not the 'force' lists.
   ignore_range: insmod parameter. 
     A list of triples. The first value is a bus number (-1 for any I2C bus), 
     the second and third are addresses. These form an inclusive range of 
     I2C addresses that are never probed.
     This parameter overrules 'normal' and 'probe', but not the 'force' lists.
   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. 

Fortunately, as a module writer, you just have to define the `normal' 
and/or `normal_range' parameters. The complete declaration could look
like this:

  /* Scan 0x20 to 0x2f, 0x37, and 0x40 to 0x4f */
  static unsigned short normal_i2c[] = { 0x37,I2C_CLIENT_END }; 
  static unsigned short normal_i2c_range[] = { 0x20, 0x2f, 0x40, 0x4f, 
                                               I2C_CLIENT_END };

  /* Magic definition of all other variables and things */
  I2C_CLIENT_INSMOD;

Note that you *have* to call the two defined variables `normal_i2c' and
`normal_i2c_range', without any prefix!


Probing classes (sensors)
-------------------------

If you write a `sensors' driver, you use a slightly different interface.
As well as I2C addresses, we have to cope with ISA addresses. Also, we
use a enum of chip types. Don't forget to include `sensors.h'.

The following lists are used internally. They are all lists of integers.

   normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
     A list of I2C addresses which should normally be examined.
   normal_i2c_range: filled in by the module writer. Terminated by 
     SENSORS_I2C_END
     A list of pairs of I2C addresses, each pair being an inclusive range of
     addresses which should normally be examined.
   normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
     A list of ISA addresses which should normally be examined.
   normal_isa_range: filled in by the module writer. Terminated by 
     SENSORS_ISA_END
     A list of triples. The first two elements are ISA addresses, being an
     range of addresses which should normally be examined. The third is the
     modulo parameter: only addresses which are 0 module this value relative
     to the first address of the range are actually considered.
   probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
     the ISA bus, -1 for any I2C bus), the second is the address. These
     addresses are also probed, as if they were in the 'normal' list.
   probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
     values.
     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
     These form an inclusive range of addresses that are also probed, as
     if they were in the 'normal' list.
   ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
     the ISA bus, -1 for any I2C bus), the second is the I2C address. These
     addresses are never probed. This parameter overrules 'normal' and 
     'probe', but not the 'force' lists.
   ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
      values.
     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
     These form an inclusive range of I2C addresses that are never probed.
     This parameter overrules 'normal' and 'probe', but not the 'force' lists.

Also used is a list of pointers to sensors_force_data structures:
   force_data: insmod parameters. A list, ending with an element of which
     the force field is NULL.
     Each element contains the type of chip and a list of pairs.
     The first value is a bus number (SENSORS_ISA_BUS for the ISA bus, 
     -1 for any I2C bus), the second is the address. 
     These are automatically translated to insmod variables of the form
     force_foo.

So we have a generic insmod variabled `force', and chip-specific variables
`force_CHIPNAME'.

Fortunately, as a module writer, you just have to define the `normal' 
and/or `normal_range' parameters, and define what chip names are used. 
The complete declaration could look like this:
  /* Scan i2c addresses 0x20 to 0x2f, 0x37, and 0x40 to 0x4f
  static unsigned short normal_i2c[] = {0x37,SENSORS_I2C_END};
  static unsigned short normal_i2c_range[] = {0x20,0x2f,0x40,0x4f,
                                              SENSORS_I2C_END};
  /* Scan ISA address 0x290 */
  static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END};
  static unsigned int normal_isa_range[] = {SENSORS_ISA_END};

  /* Define chips foo and bar, as well as all module parameters and things */
  SENSORS_INSMOD_2(foo,bar);

If you have one chip, you use macro SENSORS_INSMOD_1(chip), if you have 2
you use macro SENSORS_INSMOD_2(chip1,chip2), etc. If you do not want to
bother with chip types, you can use SENSORS_INSMOD_0.

A enum is automatically defined as follows:
  enum chips { any_chip, chip1, chip2, ... }


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

For `sensors' drivers, use the i2c_detect function instead:
  
  int foo_attach_adapter(struct i2c_adapter *adapter)
  { 
    return i2c_detect(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 or i2c_detect 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 or i2c_detect.
The `kind' parameter contains 0 if this call is due to a `force'
parameter, and -1 otherwise (for i2c_detect, it contains 0 if
this call is due to the generic `force' parameter, and the chip type
number if it is due to a specific `force' parameter).

Below, some things are only needed if this is a `sensors' driver. Those
parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */
markers. 

This function should only return an error (any value != 0) if there is
some reason why no more detection should be done anymore. If the
detection just fails for this address, return 0.

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

    if (is_isa) {

      /* If this client can't be on the ISA bus at all, we can stop now
         (call `goto ERROR0'). But for kicks, we will assume it is all
         right. */

      /* 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))) {
      printk("foo.o: Client deregistration failed, client not detached.\n");
      return err;
    }

    /* SENSORS ONLY START */
    if i2c_is_isa_client(client)
      release_region(client->addr,LM78_EXTENT);
    /* SENSORS 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]);
      }
    }
  }
