This is a small guide for those who want to write kernel drivers for I2C
-or SMBus devices.
+or SMBus devices, using Linux as the protocol host/master (not slave).
To set up a driver, you need to do several things. Some are optional, and
some things can be done slightly or completely different. Use this as a
===============
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
+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.
+tutorial.
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.
+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_device_id foo_idtable[] = {
+ { "foo", my_id_for_foo },
+ { "bar", my_id_for_bar },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, foo_idtable);
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 */
+ .driver = {
+ .name = "foo",
+ },
+
+ .id_table = foo_ids,
+ .probe = foo_probe,
+ .remove = foo_remove,
+ /* if device autodetection is needed: */
+ .class = I2C_CLASS_SOMETHING,
+ .detect = foo_detect,
+ .address_list = normal_i2c,
+
+ .shutdown = foo_shutdown, /* optional */
+ .suspend = foo_suspend, /* optional */
+ .resume = foo_resume, /* optional */
+ .command = foo_command, /* optional, deprecated */
}
-
-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.
+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. If the driver name doesn't match the module
+name, the module won't be automatically loaded (hotplug/coldplug).
-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
+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 */
- };
+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.
+
+ /* store the value */
+ void i2c_set_clientdata(struct i2c_client *client, void *data);
+
+ /* retrieve the value */
+ void *i2c_get_clientdata(const struct i2c_client *client);
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.
+client.
-I have found it useful to define foo_read and foo_write function for this.
+I have found it useful to define foo_read and foo_write functions for this.
For some cases, it will be easier to call the i2c functions directly,
but many chips have some kind of register-value idea that can easily
-be encapsulated. Also, some chips have both ISA and I2C interfaces, and
-it useful to abstract from this (only for `sensors' drivers).
+be encapsulated.
The below functions are simple examples, and should not be copied
literally.
- 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.
+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 -EINVAL;
+ 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);
+}
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.
+The Linux I2C stack was originally written to support access to hardware
+monitoring chips on PC motherboards, and thus used to embed some assumptions
+that were more appropriate to SMBus (and PCs) than to I2C. One of these
+assumptions was that most adapters and devices drivers support the SMBUS_QUICK
+protocol to probe device presence. Another was that devices and their drivers
+can be sufficiently configured using only such probe primitives.
-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.
+As Linux and its I2C stack became more widely used in embedded systems
+and complex components such as DVB adapters, those assumptions became more
+problematic. Drivers for I2C devices that issue interrupts need more (and
+different) configuration information, as do drivers handling chip variants
+that can't be distinguished by protocol probing, or which need some board
+specific information to operate correctly.
-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.
+Device/Driver Binding
+---------------------
+System infrastructure, typically board-specific initialization code or
+boot firmware, reports what I2C devices exist. For example, there may be
+a table, in the kernel or from the boot loader, identifying I2C devices
+and linking them to board-specific configuration information about IRQs
+and other wiring artifacts, chip type, and so on. That could be used to
+create i2c_client objects for each I2C device.
+
+I2C device drivers using this binding model work just like any other
+kind of driver in Linux: they provide a probe() method to bind to
+those devices, and a remove() method to unbind.
+
+ static int foo_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+ static int foo_remove(struct i2c_client *client);
+
+Remember that the i2c_driver does not create those client handles. The
+handle may be used during foo_probe(). If foo_probe() reports success
+(zero not a negative status code) it may save the handle and use it until
+foo_remove() returns. That binding model is used by most Linux drivers.
+
+The probe function is called when an entry in the id_table name field
+matches the device's name. It is passed the entry that was matched so
+the driver knows which one in the table matched.
+
+
+Device Creation
+---------------
+
+If you know for a fact that an I2C device is connected to a given I2C bus,
+you can instantiate that device by simply filling an i2c_board_info
+structure with the device address and driver name, and calling
+i2c_new_device(). This will create the device, then the driver core will
+take care of finding the right driver and will call its probe() method.
+If a driver supports different device types, you can specify the type you
+want using the type field. You can also specify an IRQ and platform data
+if needed.
+
+Sometimes you know that a device is connected to a given I2C bus, but you
+don't know the exact address it uses. This happens on TV adapters for
+example, where the same driver supports dozens of slightly different
+models, and I2C device addresses change from one model to the next. In
+that case, you can use the i2c_new_probed_device() variant, which is
+similar to i2c_new_device(), except that it takes an additional list of
+possible I2C addresses to probe. A device is created for the first
+responsive address in the list. If you expect more than one device to be
+present in the address range, simply call i2c_new_probed_device() that
+many times.
+
+The call to i2c_new_device() or i2c_new_probed_device() typically happens
+in the I2C bus driver. You may want to save the returned i2c_client
+reference for later use.
+
+
+Device Detection
+----------------
+
+Sometimes you do not know in advance which I2C devices are connected to
+a given I2C bus. This is for example the case of hardware monitoring
+devices on a PC's SMBus. In that case, you may want to let your driver
+detect supported devices automatically. This is how the legacy model
+was working, and is now available as an extension to the standard
+driver model.
+
+You simply have to define a detect callback which will attempt to
+identify supported devices (returning 0 for supported ones and -ENODEV
+for unsupported ones), a list of addresses to probe, and a device type
+(or class) so that only I2C buses which may have that type of device
+connected (and not otherwise enumerated) will be probed. For example,
+a driver for a hardware monitoring chip for which auto-detection is
+needed would set its class to I2C_CLASS_HWMON, and only I2C adapters
+with a class including I2C_CLASS_HWMON would be probed by this driver.
+Note that the absence of matching classes does not prevent the use of
+a device of that type on the given I2C adapter. All it prevents is
+auto-detection; explicit instantiation of devices is still possible.
+
+Note that this mechanism is purely optional and not suitable for all
+devices. You need some reliable way to identify the supported devices
+(typically using device-specific, dedicated identification registers),
+otherwise misdetections are likely to occur and things can get wrong
+quickly. Keep in mind that the I2C protocol doesn't include any
+standard way to detect the presence of a chip at a given address, let
+alone a standard way to identify devices. Even worse is the lack of
+semantics associated to bus transfers, which means that the same
+transfer can be seen as a read operation by a chip and as a write
+operation by another chip. For these reasons, explicit device
+instantiation should always be preferred to auto-detection where
+possible.
+
+
+Device Deletion
+---------------
+
+Each I2C device which has been created using i2c_new_device() or
+i2c_new_probed_device() can be unregistered by calling
+i2c_unregister_device(). If you don't call it explicitly, it will be
+called automatically before the underlying I2C bus itself is removed, as a
+device can't survive its parent in the device driver model.
+
+
+Initializing the driver
+=======================
+
+When the kernel is booted, or when your foo driver module is inserted,
+you have to do some initializing. Fortunately, just registering the
+driver module is usually enough.
+
+static int __init foo_init(void)
+{
+ return i2c_add_driver(&foo_driver);
+}
+static void __exit foo_cleanup(void)
+{
+ i2c_del_driver(&foo_driver);
+}
-Probing classes (i2c)
----------------------
+/* Substitute your own name and email address */
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
+MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
-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 '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_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;
-
-Note that you *have* to call the defined variable `normal_i2c',
-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_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
- A list of ISA addresses which should normally be examined.
- 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.
- 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.
-
-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_i2c'
-and `normal_isa' parameters, and define what chip names are used.
-The complete declaration could look like this:
- /* Scan i2c addresses 0x37, and 0x48 to 0x4f */
- static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
- 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
- /* Scan ISA address 0x290 */
- static unsigned int normal_isa[] = {0x0290,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
------------------------
+/* a few non-GPL license types are also allowed */
+MODULE_LICENSE("GPL");
+
+module_init(foo_init);
+module_exit(foo_cleanup);
+
+Note that some functions are marked by `__init'. These functions can
+be removed after kernel booting (or module loading) is completed.
+Likewise, functions marked by `__exit' are dropped by the compiler when
+the code is built into the kernel, as they would never be called.
+
+
+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.
-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;
- }
+need this, and its use is deprecated anyway, so newer design should not
+use it.
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.
+to do this. You can find all of them in <linux/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!
+If you can choose between plain I2C communication and SMBus level
+communication, please use the latter. All adapters understand SMBus level
+commands, but only some of them understand plain I2C!
-Plain i2c communication
+Plain I2C communication
-----------------------
- extern int i2c_master_send(struct i2c_client *,const char* ,int);
- extern int i2c_master_recv(struct i2c_client *,char* ,int);
+ int i2c_master_send(struct i2c_client *client, const char *buf,
+ int count);
+ int i2c_master_recv(struct i2c_client *client, char *buf, int count);
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);
+parameter contains the bytes to read/write, the third the number of bytes
+to read/write (must be less than the length of the buffer, also should be
+less than 64k since msg.len is u16.) Returned is the actual number of bytes
+read/written.
+
+ 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
and the message data itself.
You can read the file `i2c-protocol' for more information about the
-actual i2c protocol.
+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
+ 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!
+
+ s32 i2c_smbus_read_byte(struct i2c_client *client);
+ s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);
+ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command);
+ s32 i2c_smbus_write_byte_data(struct i2c_client *client,
+ u8 command, u8 value);
+ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);
+ s32 i2c_smbus_write_word_data(struct i2c_client *client,
+ u8 command, u16 value);
+ s32 i2c_smbus_process_call(struct i2c_client *client,
+ u8 command, u16 value);
+ s32 i2c_smbus_read_block_data(struct i2c_client *client,
+ u8 command, u8 *values);
+ s32 i2c_smbus_write_block_data(struct i2c_client *client,
+ u8 command, u8 length, const u8 *values);
+ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
+ u8 command, u8 length, u8 *values);
+ s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
+ u8 command, u8 length,
+ const u8 *values);
+
+These ones were removed from i2c-core 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.
+ s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value);
+ s32 i2c_smbus_block_process_call(struct i2c_client *client,
+ u8 command, u8 length, u8 *values);
+
+All these transactions return a negative errno value on failure. The 'write'
+transactions return 0 on success; the 'read' transactions return the read
+value, except for block transactions, which return 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.
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]);
- }
- }
- }
+ /* Return the adapter number for a specific adapter */
+ int i2c_adapter_id(struct i2c_adapter *adap);