linux内核i2c子系统驱动(一) -凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 1125409
  • 博文数量: 146
  • 博客积分: 190
  • 博客等级: 入伍新兵
  • 技术积分: 5225
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-06 08:24
个人简介

慢行者

文章分类

全部博文(146)

文章存档

2013年(145)

2012年(1)

相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: linux

2013-05-10 20:11:40

i2c子系统驱动(一)

一、i2c体系结构

      linux的i2c体系结构分为3个组成部分:i2c核心、i2c总线驱动、i2c设备驱动,如下图所示。i2c核心提供总线驱动和设备驱动的注册、注销方法,algorithm;i2c总线驱动对硬件体系结构中适配器的实现,主要包括适配器i2c_adapter、适配器通信算法i2c_algorithm,如果cpu集成了i2c控制器并且linux内核支持这个cpu,那么总线驱动就不用管,比如s3c2440就属于这类情况,在后文中我们将分析它的总线驱动;i2c设备驱动是具体的一个设备(如at24c02),挂接在cpu控制的i2c适配器的设备驱动,有了这部分驱动才能使用控制器操作该设备,设备驱动主要包括i2c_driver 和i2c_client数据结构。

      在linux-2.6.32.2的include/linux/i2c.h中定义了i2c_adapter、i2c_algorithm、i2c_driver、i2c_client数据结构如下所示,这4个结构体相互之间的关系。

[cpp]
  1. struct i2c_adapter { 
  2.     struct module *owner;
  3.     unsignedint id;
  4.     unsignedintclass;      /* classes to allow probing for */
  5.     conststruct i2c_algorithm *algo;/* the algorithm to access the bus总线通信方法结构体指针 */
  6.     void *algo_data;                 /* algorithm数据 */
  7.  
  8.     /* data fields that are valid for all devices   */
  9.     u8 level;          /* nesting level for lockdep */
  10.     struct mutex bus_lock;
  11.  
  12.     int timeout;           /* in jiffies */
  13.     int retries;                   /* 重试次数 */
  14.     struct device dev;     /* the adapter device */
  15.  
  16.     int nr;
  17.     char name[48];
  18.     struct completion dev_released;
  19. }; 
  20. struct i2c_algorithm { 
  21.     int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
  22.               int num);              /*i2c传输函数指针*/
  23.     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, 
  24.                unsignedshort flags,char read_write,
  25.                u8 command,int size,union i2c_smbus_data *data);   /*smbus传输函数指针*/
  26.  
  27.     /* to determine what the adapter supports */
  28.     u32 (*functionality) (struct i2c_adapter *);            /*返回适配器支持的功能*/
  29. }; 
  30. struct i2c_driver { 
  31.     unsignedintclass;
  32.  
  33.     int (*attach_adapter)(struct i2c_adapter *);       /*依附i2c_adapter函数指针*/
  34.     int (*detach_adapter)(struct i2c_adapter *);       /*脱离i2c_adapter函数指针*/
  35.  
  36.     /* standard driver model interfaces */
  37.     int (*probe)(struct i2c_client *, conststruct i2c_device_id *);
  38.     int (*remove)(struct i2c_client *); 
  39.  
  40.     /* driver model interfaces that don't relate to enumeration  */
  41.     void (*shutdown)(struct i2c_client *); 
  42.     int (*suspend)(struct i2c_client *, pm_message_t mesg); 
  43.     int (*resume)(struct i2c_client *);        /* probe,remove,suspend,resume驱动方法重要成员函数 */
  44.  
  45.     /* a ioctl like command that can be used to perform specific functions
  46.      * with the device.
  47.      */
  48.     int (*command)(struct i2c_client *client, unsigned int cmd,void *arg);  /*类似ioctl*/
  49.   
  50.     struct device_driver driver;
  51.     conststruct i2c_device_id *id_table;  /* 驱动支持多个设备,这里面就要包含这些设备的id */
  52.  
  53.     /* device detection callback for automatic device creation */
  54.     int (*detect)(struct i2c_client *, int kind,struct i2c_board_info *);  /*i2c client脱离函数指针*/
  55.     conststruct i2c_client_address_data *address_data;
  56.     struct list_head clients;
  57. }; 
  58. struct i2c_client { 
  59.     unsignedshort flags;      /* div., see below      */
  60.     unsignedshort addr;       /* chip address - note: 7bit  芯片地址  */
  61.                    /* addresses are stored in the  */
  62.                    /* _lower_ 7 bits       */
  63.     char name[i2c_name_size];
  64.     struct i2c_adapter *adapter;   /* the adapter we sit on  依附的i2c_adapter    */
  65.     struct i2c_driver *driver; /* and our access routines 依附的i2c_driver    */
  66.     struct device dev;     /* the device structure     */
  67.     int irq;           /* irq issued by device     */
  68.     struct list_head detected;
  69. }; 

1、i2c_adapter 与i2c_algorithm,i2c_adapter 对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个i2c适配器需要i2c_algorithm中提供的通信函数来控制适配器上产生特定的访问周期。缺少i2c_algorithm 的i2c_adapter 什么也做不了,因此i2c_adapter 中包含其使用的i2c_algorithm的指针。i2c_algorithm 中的关键函数master_xfer()用于产生i2c 访问周期需要的信号,以i2c_msg(即i2c消息)为单位。i2c_msg结构体也非常关键。

struct i2c_msg {

       __u16 addr;    /* slave address                    */

       __u16 flags;

#define i2c_m_ten            0x0010    /* this is a ten bit chip address */

#define i2c_m_rd              0x0001    /* read data, from slave to master */

#define i2c_m_nostart           0x4000    /* if i2c_func_protocol_mangling */

#define i2c_m_rev_dir_addr 0x2000    /* if i2c_func_protocol_mangling */

#define i2c_m_ignore_nak    0x1000    /* if i2c_func_protocol_mangling */

#define i2c_m_no_rd_ack             0x0800    /* if i2c_func_protocol_mangling */

#define i2c_m_recv_len         0x0400    /* length will be first received byte */

       __u16 len;             /* msg length                       */

       __u8 *buf;             /* pointer to msg data                  */

};

2、i2c_driver 与i2c_client,i2c_driver 对应一套驱动方法,是纯粹的用于辅助作用的数据结构,它不对应于任何的物理实体。i2c_client对应于真实的物理设备,每个i2c设备都需要一个i2c_client来描述。i2c_client一般被包含在i2c字符设备的私有信息结构体中。

3、i2c_adpater 与i2c_client,i2c_adpater 与i2c_client 的关系与i2c 硬件体系中适配器和设备的关系一致,即i2c_client 依附于i2c_adpater。

二、i2c核心

    i2c核心是总线驱动和设备驱动的纽带,源码位于drivers/i2c/i2c-core.c,它并不依赖于硬件平台的接口函数,i2c核心中一些重要函数如下:

增加/删除i2c_adapter

int i2c_add_adapter(struct i2c_adapter *adapter)

int i2c_del_adapter(struct i2c_adapter *adapter)

增加/删除i2c_driver

int i2c_register_driver(struct module *owner, struct i2c_driver *driver)

int i2c_add_driver(struct i2c_driver *driver)         //调用i2c_register_driver

void i2c_del_driver(struct i2c_driver *driver)

增加/删除i2c_client

struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)

void i2c_unregister_device(struct i2c_client *client)

      注:在2.6.30版本之前使用的是i2c_attach_client()和i2c_detach_client()函数。之后attach被merge到了i2c_new_device中,而detach直接被unresister取代。实际上这两个函数内部都是调用了device_register()和device_unregister()

i2c传输、发送接收

int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)

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)

      i2c_transfer()函数用于进行i2c 适配器和i2c 设备之间的一组消息交互,i2c_master_send()函数和i2c_master_recv()函数内部会调用i2c_transfer()函数分别完成一条写消息和一条读消息,i2c_transfer()本身不能喝硬件完成消息交互,它寻找i2c_adapter对应的i2c_algorithm,要实现数据传送就要实现i2c_algorithm的master_xfer(),在总线驱动中就是重点。

阅读(6213) | 评论(0) | 转发(10) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图