mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
i2c: Add detection capability to new-style drivers
Add a mechanism to let new-style i2c drivers optionally autodetect devices they would support on selected buses and ask i2c-core to instantiate them. This is a replacement for legacy i2c drivers, much cleaner. Where drivers had to implement both a legacy i2c_driver and a new-style i2c_driver so far, this mechanism makes it possible to get rid of the legacy i2c_driver and implement both enumerated and detected device support with just one (new-style) i2c_driver. Here is a quick conversion guide for these drivers, step by step: * Delete the legacy driver definition, registration and removal. Delete the attach_adapter and detach_client methods of the legacy driver. * Change the prototype of the legacy detect function from static int foo_detect(struct i2c_adapter *adapter, int address, int kind); to static int foo_detect(struct i2c_client *client, int kind, struct i2c_board_info *info); * Set the new-style driver detect callback to this new function, and set its address_data to &addr_data (addr_data is generally provided by I2C_CLIENT_INSMOD.) * Add the appropriate class to the new-style driver. This is typically the class the legacy attach_adapter method was checking for. Class checking is now mandatory (done by i2c-core.) See <linux/i2c.h> for the list of available classes. * Remove the i2c_client allocation and freeing from the detect function. A pre-allocated client is now handed to you by i2c-core, and is freed automatically. * Make the detect function fill the type field of the i2c_board_info structure it was passed as a parameter, and return 0, on success. If the detection fails, return -ENODEV. Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
8508159e2f
commit
4735c98f84
3 changed files with 272 additions and 16 deletions
|
@ -45,6 +45,7 @@ struct i2c_adapter;
|
|||
struct i2c_client;
|
||||
struct i2c_driver;
|
||||
union i2c_smbus_data;
|
||||
struct i2c_board_info;
|
||||
|
||||
/*
|
||||
* The master routines are the ones normally used to transmit data to devices
|
||||
|
@ -94,15 +95,33 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
|
|||
u8 command, u8 length,
|
||||
const u8 *values);
|
||||
|
||||
/*
|
||||
* A driver is capable of handling one or more physical devices present on
|
||||
* I2C adapters. This information is used to inform the driver of adapter
|
||||
* events.
|
||||
/**
|
||||
* struct i2c_driver - represent an I2C device driver
|
||||
* @class: What kind of i2c device we instantiate (for detect)
|
||||
* @detect: Callback for device detection
|
||||
* @address_data: The I2C addresses to probe, ignore or force (for detect)
|
||||
* @clients: List of detected clients we created (for i2c-core use only)
|
||||
*
|
||||
* The driver.owner field should be set to the module owner of this driver.
|
||||
* The driver.name field should be set to the name of this driver.
|
||||
*
|
||||
* For automatic device detection, both @detect and @address_data must
|
||||
* be defined. @class should also be set, otherwise only devices forced
|
||||
* with module parameters will be created. The detect function must
|
||||
* fill at least the name field of the i2c_board_info structure it is
|
||||
* handed upon successful detection, and possibly also the flags field.
|
||||
*
|
||||
* If @detect is missing, the driver will still work fine for enumerated
|
||||
* devices. Detected devices simply won't be supported. This is expected
|
||||
* for the many I2C/SMBus devices which can't be detected reliably, and
|
||||
* the ones which can always be enumerated in practice.
|
||||
*
|
||||
* The i2c_client structure which is handed to the @detect callback is
|
||||
* not a real i2c_client. It is initialized just enough so that you can
|
||||
* call i2c_smbus_read_byte_data and friends on it. Don't do anything
|
||||
* else with it. In particular, calling dev_dbg and friends on it is
|
||||
* not allowed.
|
||||
*/
|
||||
|
||||
struct i2c_driver {
|
||||
int id;
|
||||
unsigned int class;
|
||||
|
@ -142,6 +161,11 @@ struct i2c_driver {
|
|||
|
||||
struct device_driver driver;
|
||||
const struct i2c_device_id *id_table;
|
||||
|
||||
/* Device detection callback for automatic device creation */
|
||||
int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *);
|
||||
const struct i2c_client_address_data *address_data;
|
||||
struct list_head clients;
|
||||
};
|
||||
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
|
||||
|
||||
|
@ -157,6 +181,7 @@ struct i2c_driver {
|
|||
* @dev: Driver model device node for the slave.
|
||||
* @irq: indicates the IRQ generated by this device (if any)
|
||||
* @list: list of active/busy clients (DEPRECATED)
|
||||
* @detected: member of an i2c_driver.clients list
|
||||
* @released: used to synchronize client releases & detaches and references
|
||||
*
|
||||
* An i2c_client identifies a single device (i.e. chip) connected to an
|
||||
|
@ -174,6 +199,7 @@ struct i2c_client {
|
|||
struct device dev; /* the device structure */
|
||||
int irq; /* irq issued by device */
|
||||
struct list_head list; /* DEPRECATED */
|
||||
struct list_head detected;
|
||||
struct completion released;
|
||||
};
|
||||
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue