Linux I2C驱动

Linux I2C 驱动结构

i2c体系结构由三部分组成

  • i2C core
    i2c core提供了i2c 总线驱动 和 设备驱动的注册,注销方法
    i2C and SMBus protocol 实现
  • i2C “bus” driver
    algorithm driver
    adapter driver
  • i2c device driver
    chip drivers, 包括多种类型,如RTC, EEPROM, I/O expander, hardware monitoring, sound, video等

这里写图片描述

i2c adapter 和 i2C algorithm

i2c adapter对应于物理上的适配器。 i2C algorithm对应一套通信方法。

i2c 设备驱动

i2c 设备驱动要使用i2c_driver 和i2c_client数据结构并填充i2c_driver中的成员函数

/**
 * struct i2c_driver - represent an I2C device driver
 * @class: What kind of i2c device we instantiate (for detect)
 * @attach_adapter: Callback for bus addition (deprecated)
 * @probe: Callback for device binding - soon to be deprecated
 * @probe_new: New callback for device binding
 * @remove: Callback for device unbinding
 * @shutdown: Callback for device shutdown
 * @alert: Alert callback, for example for the SMBus alert protocol
 * @command: Callback for bus-wide signaling (optional)
 * @driver: Device driver model driver
 * @id_table: List of I2C devices supported by this driver
 * @detect: Callback for device detection
 * @address_list: The I2C addresses to probe (for detect)
 * @clients: List of detected clients we created (for i2c-core use only)
 * @disable_i2c_core_irq_mapping: Tell the i2c-core to not do irq-mapping
 *
 * 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_list 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 {
    unsigned int class;
    /* Notifies the driver that a new bus has appeared. You should avoid
     * using this, it will be removed in a near future.
     */
    int (*attach_adapter)(struct i2c_adapter *) __deprecated;
    /* Standard driver model interfaces */
    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
    int (*remove)(struct i2c_client *);
    /* New driver model interface to aid the seamless removal of the
     * current probe()'s, more commonly unused than used second parameter.
     */
    int (*probe_new)(struct i2c_client *);
    /* driver model interfaces that don't relate to enumeration  */
    void (*shutdown)(struct i2c_client *);
    /* Alert callback, for example for the SMBus alert protocol.
     * The format and meaning of the data value depends on the protocol.
     * For the SMBus alert protocol, there is a single bit of data passed
     * as the alert response's low bit ("event flag").
     * For the SMBus Host Notify protocol, the data corresponds to the
     * 16-bit payload data reported by the slave device acting as master.
     */
    void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol,
              unsigned int data);
    /* a ioctl like command that can be used to perform specific functions
     * with the device.
     */
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
    struct device_driver driver;
    const struct i2c_device_id *id_table;
    /* Device detection callback for automatic device creation */
    int (*detect)(struct i2c_client *, struct i2c_board_info *);
    const unsigned short *address_list;
    struct list_head clients;
    bool disable_i2c_core_irq_mapping;
};

看一下RTC设备的驱动
Browse the source code of linux/drivers/rtc/rtc-ds1307.c

static struct i2c_driver ds1307_driver = {
    .driver = {
        .name   = "rtc-ds1307",
        .of_match_table = of_match_ptr(ds1307_of_match),
        .acpi_match_table = ACPI_PTR(ds1307_acpi_ids),
    },
    .probe      = ds1307_probe,
    .id_table   = ds1307_id,
};

reference

https://i2c.wiki.kernel.org/index.php/Driver_Architecture

原文地址:https://www.cnblogs.com/feiwatson/p/9478198.html