xfortune 发表于 2012-10-22 09:11

linux I2C 驱动编写笔记

I2C驱动组成有三部分:
A.i2c 核心驱动   B. i2c总线驱动C. i2c设备驱动
I2C驱动相关的重要结构:
1.
/**
* 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)
* @detach_adapter: Callback for bus removal (deprecated)
* @probe: Callback for device binding
* @remove: Callback for device unbinding
* @shutdown: Callback for device shutdown
* @suspend: Callback for device suspend
* @resume: Callback for device resume
* @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)
*
* 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 {
        unsigned int class;

        /* Notifies the driver that a new bus has appeared or is about to be
       * removed. You should avoid using this, it will be removed in a
       * near future.
       */
        int (*attach_adapter)(struct i2c_adapter *) __deprecated;
        int (*detach_adapter)(struct i2c_adapter *) __deprecated;

        /* Standard driver model interfaces */
        int (*probe)(struct i2c_client *, const struct i2c_device_id *);
        int (*remove)(struct i2c_client *);

        /* driver model interfaces that don't relate to enumeration*/
        void (*shutdown)(struct i2c_client *);
        int (*suspend)(struct i2c_client *, pm_message_t mesg);
        int (*resume)(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").
       */
        void (*alert)(struct i2c_client *, 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;
};
2.
/**
* struct i2c_client - represent an I2C slave device
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
*        I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
* @addr: Address used on the I2C bus connected to the parent adapter.
* @name: Indicates the type of the device, usually a chip name that's
*        generic enough to hide second-sourcing and compatible revisions.
* @adapter: manages the bus segment hosting this I2C device
* @driver: device's driver, hence pointer to access routines
* @dev: Driver model device node for the slave.
* @irq: indicates the IRQ generated by this device (if any)
* @detected: member of an i2c_driver.clients list or i2c-core's
*        userspace_devices list
*
* An i2c_client identifies a single device (i.e. chip) connected to an
* i2c bus. The behaviour exposed to Linux is defined by the driver
* managing the device.
*/
struct i2c_client {
        unsigned short flags;                /* div., see below                */
        unsigned short addr;                /* chip address - NOTE: 7bit        */
                                        /* addresses are stored in the        */
                                        /* _LOWER_ 7 bits                */
        char name;
        struct i2c_adapter *adapter;        /* the adapter we sit on        */
        struct i2c_driver *driver;        /* and our access routines        */
        struct device dev;                /* the device structure                */
        int irq;                        /* irq issued by device                */
        struct list_head detected;
};
3.
*
* i2c_adapter is the structure used to identify a physical i2c bus along
* with the access algorithms necessary to access it.
*/
struct i2c_adapter {
        struct module *owner;
        unsigned int class;                  /* classes to allow probing for */
        const struct i2c_algorithm *algo; /* the algorithm to access the bus */
        void *algo_data;

        /* data fields that are valid for all devices        */
        struct rt_mutex bus_lock;

        int timeout;                        /* in jiffies */
        int retries;
        struct device dev;                /* the adapter device */

        int nr;
        char name;
        struct completion dev_released;

        struct mutex userspace_clients_lock;
        struct list_head userspace_clients;
};
4.
/*
* The following structs are for those who like to implement new bus drivers:
* i2c_algorithm is the interface to a class of hardware solutions which can
* be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
* to name two of the most common.
*/
struct i2c_algorithm {
        /* If an adapter algorithm can't do I2C-level access, set master_xfer
           to NULL. If an adapter algorithm can do SMBus access, set
           smbus_xfer. If set to NULL, the SMBus protocol is simulated
           using common I2C messages */
        /* master_xfer should return the number of messages successfully
           processed, or a negative value on error */
        int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
                           int num);
        int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
                           unsigned short flags, char read_write,
                           u8 command, int size, union i2c_smbus_data *data);

        /* To determine what the adapter supports */
        u32 (*functionality) (struct i2c_adapter *);
};

xfortune 发表于 2012-10-22 09:40

问题1:i2c_adapter结构中rt_mutex 和 mutex 结构的区别

/**
* The rt_mutex structure
*
* @wait_lock:        spinlock to protect the structure
* @wait_list:        pilist head to enqueue waiters in priority order
* @owner:        the mutex owner
*/
struct rt_mutex {
        raw_spinlock_t                wait_lock;
        struct plist_head        wait_list;
        struct task_struct        *owner;
#ifdef CONFIG_DEBUG_RT_MUTEXES
        int                        save_state;
        const char                 *name, *file;
        int                        line;
        void                        *magic;
#endif
};

struct mutex {
        /* 1: unlocked, 0: locked, negative: locked, possible waiters */
        atomic_t                count;
        spinlock_t                wait_lock;
        struct list_head        wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
        struct thread_info        *owner;
#endif
#ifdef CONFIG_DEBUG_MUTEXES
        const char                 *name;
        void                        *magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
        struct lockdep_map        dep_map;
#endif
};

xfortune 发表于 2012-10-22 18:10

问题2:master_xfer()完成了 驱动和硬件的直接通信。
具体是怎么实现的?

xfortune 发表于 2012-10-22 18:11

问题3:各各结构之间的关系,是什么样的?
要查看结构体之间的联系,需要知道I2C驱动 的构架/

xfortune 发表于 2012-11-01 10:08

在论坛找到很好的一个资源
http://blog.chinaunix.net/u3/91522/showart_1886369.html

txgc_wm 发表于 2013-04-10 10:53

楼主在linux i2c驱动编写方面有经验吗?    后续有问题想请教请教。

xfortune 发表于 2013-04-10 16:33

回复 6# txgc_wm


    很久之前做的。。说说看,不知能不能帮你

txgc_wm 发表于 2013-04-10 17:57

回复 7# xfortune

暂时没有,以后做了可能会遇到问题。这里,事先打个招呼嘛。^_^
   
页: [1]
查看完整版本: linux I2C 驱动编写笔记