1.i2c-dev.c(i2c设备驱动组件层)

功能:1)给用户提供接口

i2c_dev_init  //入口函数
 /*申请主设备号*/

register_chrdev(I2C_MAJOR(), "i2c", &i2cdev_fops);
 /*创建一个设备类*/
 i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
 /*注册一个i2c驱动*/
 i2c_add_driver(&i2cdev_driver);
  i2c_register_driver(THIS_MODULE, driver);
   /*指定总线类型*/
   driver->driver.bus = &i2c_bus_type;
   /*驱动注册
    *1.将i2c驱动加入i2c总线的驱动链表
    *2.搜索设备链表,实现匹配,根据i2c总线的匹配原理:必须要求i2c驱动结构体中实现id_table
    *  但是,i2c驱动结构体中并没有实现id_table,所以永远都匹配失败
    */
   driver_register(&driver->driver);
    
   /*搜索适配器链表,每搜索一个适配器,都会调用__process_new_driver函数
    *在此函数中,又会调用i2c驱动中的,attach_adapter函数
    */
   bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);
   __process_new_driver  //此函数可能会被调用多次
    i2c_do_add_adapter(data, to_i2c_adapter(dev));
     if (driver->attach_adapter) {
      /* We ignore the return code; if it fails, too bad */
      driver->attach_adapter(adap);    //i2cdev_attach_adapter
     }

static const struct file_operations i2cdev_fops = {
 .owner  = THIS_MODULE,
 .llseek  = no_llseek,
 .read  = i2cdev_read,
 .write  = i2cdev_write,
 .unlocked_ioctl = i2cdev_ioctl,
 .open  = i2cdev_open,
 .release = i2cdev_release,
};
static struct i2c_driver i2cdev_driver = {
 .driver = {
  .name = "dev_driver",
 },
 .attach_adapter = i2cdev_attach_adapter,
 .detach_adapter = i2cdev_detach_adapter,
};

2.i2c-core.c(i2c核心层组件)

功能:1)注册一条i2c总线
         2)提供基本的接口函数,用来建立上层与下层的连接

i2c_init  ;
 driver ]) {
     )
      ;
}

涉及的重要结构体:

struct i2c_client {     //表示一个i2c设备
 unsigned short flags;   /* div., see below  */
 unsigned short addr;   /*器件地址*/
 char name[I2C_NAME_SIZE];  /*名字*/
 struct i2c_adapter *adapter; /*所属适配器,所属控制器*/
 struct i2c_driver *driver;  /*设备驱动*/
 struct device dev;    /* the device structure  */
 int irq;      /* irq issued by device  */
 struct list_head detected;
};
struct i2c_driver {     //用来表示i2c驱动
 unsigned int class;
 /* Notifies the driver that a new bus has appeared or is about to be
  * removed. You should avoid using this if you can, it will probably
  * be removed in a near future.
  */
 int (*attach_adapter)(struct i2c_adapter *);
 int (*detach_adapter)(struct i2c_adapter *);
 /*probe函数:初始化工作,设备检测,*/
 int (*probe)(struct i2c_client *, const struct i2c_device_id *);
 int (*remove)(struct i2c_client *);
 struct device_driver driver;    //设备驱动
 const struct i2c_device_id *id_table;  //指定此驱动能为哪些设备服务
 ...
 ...
};
struct i2c_adapter {    //表示一个i2c适配器/i2c控制器
 const struct i2c_algorithm *algo; /* the algorithm to access the bus */
  /*操作方法*/
  int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,int num);
 int nr;     /*适配器的号码*/
 ...
 ...
};
struct i2c_msg {     //表示一个i2c数据包
 __u16 addr;      /*设备地址*/
 __u16 flags;     /*表示:1-表示读包 0-表示写包*/
 __u16 len;      /*数据包的长度*/
 __u8 *buf;      /*真正的数据*/
 ...
 ...
};

涉及的重要函数接口:

/*注册一个i2c控制器*/
int i2c_add_adapter(struct i2c_adapter *adapter)
int i2c_del_adapter(struct i2c_adapter *adap)
/*注册i2c驱动*/
int i2c_add_driver(struct i2c_driver *driver)
int i2c_add_numbered_adapter(struct i2c_adapter *adap)
int i2c_del_numbered_adapter(struct i2c_adapter *adap)
extern int i2c_del_driver(struct i2c_driver *driver);
/*接收i2c数据包*/
int i2c_master_recv(struct i2c_client *client, char *buf, int count)
/*发送i2c数据包*/
int i2c_master_send(struct i2c_client *client, const char *buf, int count)
/*提交i2c数据包到总线驱动层*/
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)

3.busses目录:i2c总线驱动/i2c控制器驱动/i2c适配器驱动

i2c-s3c2410.c

功能:1)实现对i2c控制器的初始化
         2)实现操作方法(实现i2c协议,完成数据的发送)

如何用通用接口驱动来操作i2c设备

open

app:  open("/dev/i2c-0", O_RDWR);
=====================================
sys:  sys_open
   ...
   ...
i2c-dev.c struct file_operations i2cdev_fops
    .open  = i2cdev_open,
     /*构建一个i2c_client*/
     struct i2c_client *client; 
     struct i2c_adapter *adap;  
     /*获取适配器*/
     adap = i2c_get_adapter(i2c_dev->adap->nr);
     client = kzalloc(sizeof(*client), GFP_KERNEL);
     client->driver = &i2cdev_driver;  //指定i2c设备驱动
     client->adapter = adap;     //指定适配器
     file->private_data = client;

ioctl

app位寻址的设备
       ) && arg > 0x7f))
        return -EINVAL;
       client->addr = arg;  //0x48
     }

write

app)
);
       if (adap->algo->master_xfer) 
i2c_s3c2410.c      adap->algo->master_xfer(adap, msgs, num);   //s3c24xx_i2c_xfer
         s3c24xx_i2c_xfer
          

@成鹏致远

(blogs:http://lcw.cnblogs.com)

(emailwwwlllll@126.com)

【Linux高级驱动】I2C驱动框架分析的更多相关文章

  1. Linux的操作系统I2C驱动架构解说

    Linux的操作系统I2C驱动架构解说 发布时间:2006.10.16 04:52 来源:赛迪网技术社区 作者:LoneStar 最近因为工作需要涉及到了I2C总线.虽然我过去用过I2c,但看了 Li ...

  2. Linux内核调用I2C驱动_驱动嵌套驱动方法

    禁止转载!!!! Linux内核调用I2C驱动_以MPU6050为例 0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于 ...

  3. 驱动: i2c驱动 >>>>

    1. IIC协议: <<um_s3c2440a_rev10.pdf>>  p481 Figure 20-3. IIC-Bus Interface Data Format< ...

  4. linux 高级字符设备驱动 ioctl操作介绍 例程分析实现【转】

    转自:http://my.oschina.net/u/274829/blog/285014 1,ioctl介绍 ioctl控制设备读写数据以及关闭等. 用户空间函数原型:int ioctl(int f ...

  5. Linux高级字符设备驱动

    转载:http://www.linuxidc.com/Linux/2012-05/60469p4.htm 1.什么是Poll方法,功能是什么? 2.Select系统调用(功能)      Select ...

  6. Linux高级字符设备驱动 poll方法(select多路监控原理与实现)

    1.什么是Poll方法,功能是什么? 2.Select系统调用(功能)      Select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程.      int selec ...

  7. linux内核中i2c驱动中slave模式接口的调用

    1. 关注unreg_slave接口 1.1 这个接口在哪里被调用呢? 在drivers/i2c/i2c-core-slave.c中 int i2c_slave_unregister(struct i ...

  8. Linux内核跟踪之trace框架分析【转】

    转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html   ---------------------------------------- ...

  9. 基于Tiny4412的I2C驱动分析

    本文以tiny4412平台上到三轴加速度器为例简单分析了Linux下到i2c驱动编程. http://pan.baidu.com/s/1c0H5vRq

  10. 4412 i2c驱动

    1.Linux主机驱动和外设驱动分离思想 外设驱动→API→主机驱动→板机逻辑--具体的i2c设备(camera,ts,eeprom等等) 2.主机驱动 根据控制器硬件手册,操作具体的寄存器,产生波形 ...

随机推荐

  1. 洛谷 P1352 没有上司的舞会【树形DP】(经典)

    <题目链接> <转载于>>> > 题目描述: 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...

  2. 一次webapck4 配置文件无效的解决历程

    前言 升级webpack4,一定要去看文档,特别是更新说明,不要自持用过原本webpack就自己开始折腾.折腾到后面,可能就默默流下眼泪了. webpack4的变化 webpack-cli抽离 web ...

  3. Android应用开发-数据存储和界面展现(一)

    常见布局 相对布局(RelativeLayout) 相对布局下控件默认位置都是左上角(左对齐.顶部对齐父元素),控件之间可以重叠 可以相对于父元素上下左右对齐,相对于父元素水平居中.竖直居中.水平竖直 ...

  4. 安卓工作室 android studio文件和代码模板,以及汉化出错问题

    安卓工作室 android studio文件和代码模板,以及汉化出错问题 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313 ...

  5. jQueryPrint 的简单使用

    jQueryPrint 的简单使用 一.为什么要使用 jQueryPrint?  1.当然是方便的要死尼,相比于其他的方法. 2.打印整个页面或者局部页面都是非常的可以的,使用很方便. 3.如果要导出 ...

  6. crm的知识点整理

    ''' # 1. 通过ChangeList封装好多数据 # 2. 销售中公共资源:Q查询,3天 15天 from django.db.models import F,Q F 使用查询条件的值,专门取对 ...

  7. centos7 修改同步时间

    同步时间安装ntp软件 [root@node2 ~]# yum install ntp 将ntp设为开机启动 [root@node2 ~]# systemctl enable ntpd 修改启动参数, ...

  8. 初识CocosCreator的一些问题

    本文的cocos creator版本为v1.9.0,除此外大部分都是以v1.9.3版本 1.color赋值 cc.Label组件并没有颜色相关的属性,但是Node有color的属性. //如果4个参数 ...

  9. Qt.常用代码整理

    窗口全屏化(此方法只对顶级窗口有效,对子窗口无效) window.showFullScreen() 字符串处理 Qt还提供了一种方便的字符串组合方式,使用QString::arg()函数,此函数的重载 ...

  10. mongodb group操作 以及管道 aggregate 分组排序分页

    分组获取数据: db.express_info.group({ "key":{"express_code":true}, "initial" ...