码迷,mamicode.com
首页 > 其他好文 > 详细

I2C驱动

时间:2016-05-07 06:54:24      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

Linux2.6.30/driver/i2c/
1.algos: 协议算法相关的东西
2.busses: 各种平台的i2c总线驱动(i2c控制器驱动/i2c适配器驱动)
3.chips: 各种i2c设备驱动(e2prom/某种传感器/触摸屏)
4.i2c-core.c i2c-dev.c: i2c子系统的通用文件(i2c核心层,提供一些通用函数接口)



应用层app: open("设备文件") write read
====================================================================
  内核的核心部分 VFS:sys_open sys_write sys_read


  向上提供操作驱动的接口: 1.申请主设备号,注册通用接口 register——chrdev
     2.构建file_operations结构体
      .open
      .write -->利用子系统核心层的函数来找到下层的操作方法
      .read
   (工作层) 3.i2c设备驱动层(e2prom驱动/触摸屏驱动/传感器驱动) :提供策略

  2.i2c核心层(i2c-core.c)提供一些通用函数接口,提供了注册/注销的方法

  1.i2c总线驱动层(i2c控制器驱动/i2c适配器驱动) :提供操作一个硬件的能力
    做准备工作--》1.构建一个适配器结构体struct i2c_adapter(用来描述一个i2c设备)
         1. 成员:任何一个控制器都应该有套算法
         const struct i2c_algorithm *algo;
         2. 任何一套算法都应该有一套函数来实现
         *master_xfer //实现这个函数--》实现读写操作方法
       2.初始化控制器--》会用到平台设备驱动机制
       3.注册到子系统当中去 i2c_add_adapter
======================================================================
硬件: i2c控制器设备
  ||
  \/
i2c设备(e2prom)



应用层app: open("设备文件") write read
====================================================================
                  VFS:sys_open      sys_write          sys_read
     

   1.i2c设备驱动: 两种写法 (1)万能接口驱动(i2c-dev.c)
    (2)e2prom驱动、传感器驱动
1.构建file_operations结构体
      .open
      .write
      .read
         2.创建设备文件

kernel:

驱动: 2.i2c核心层

 3.i2c总线驱动


===========================================================================
                   i2c控制器
     
         e2prom             传感器





i2c-dev.c文件分析:
==========================================================
static struct i2c_driver i2cdev_dirver = {
 .driver = {
      .name = "dev_driver",
 },
 .attach_adapter = i2cdev_attach_adapter,
 .detach_adapter = i2cdev_detach_adapter,
};

入口函数:
 i2c_dev_init
  /*注册*/
  1.register_chrdev();
  /*创建一个类*/
  2.class_create();
  /*加载i2c驱动*/
  3.i2c_add_driver();
   1.加载i2c设备驱动结构体,加载到一个链表中
   2.搜索i2c_adapter链表,每搜索一个都会调用.attach_adapter


i2cdev_attach_adapter 函数分析:
===========================================open("dev/i2c-1");
创建一个设备文件
1.device_create(); //底层有几个i2c适配器就会创建几个设备文件,而且创建的设备文件名为:i2c-0,i2c-1 ...


如何来用i2c通用接口驱动
=================================================
open
sys_open
 file_operations--> i2cdev_fops.open = i2cdev_open
      /*1.获取次设备号*/
      unsigned int minor = iminor(inode);

      /*2.创建三个结构体*/
      struct i2c_client *client;
      struct i2c_adapter *adap;
      struct i2c_dev *i2c_dev;

      /*3.获取i2c_dev*/
      i2c_dev = i2c_dev_get_by_minor();

      /*4.获取i2c配置*/
      adap = i2c_get_adapter();

      /*5.设置i2c-client*/
             client->adapter = adap;
      file->private_data = client;


ioctl(fd, I2C_SLAVE, addr)
  sys_ioctl
 file_operations --> i2cdev_fops.ioctl = i2cdev_ioctl
   /*1.从file->private_data里面取出i2c_client*/
   struct i2c_client *client = (struct i2c_client *)file->private_data;
   case I2C_SLAVE:
    client->addr = arg;
   
write
        sys_write
 file_operations--> i2cdev_fops.write = i2cdev_write            //i2c设备层
  /*1.从file->private_data里面取出i2c_client*/
  struct i2c_client *client = (struct i2c_client *)file->private_data;
  /*2.发送数据*/
  ret = i2c_master_send();                            //开始进入i2c核心层
   struct i2c_adapter *adap = client->adapter;
   struct i2c_msg msg;                      //构建一个写消息结构体
   msg.addr = client->addr;            //上面ioctl写入
   msg.flags = client->flags *I2C_M_TEN;
   msg.len = count;
   msg.buf = (char *)buf;
  /*转接到底层的函数*/
  i2c_transfer();
       adap->algo->master_xfer();             //开始进入总线驱动层
read
        sys_read
 file_operations--> i2cdev_fops.read = i2cdev_read          //i2c设备层
  /*1.从file->private_data里面取出i2c_client*/
  struct i2c_client *client = (struct i2c_client *)file->private_data;
  tmp = kmalloc(count, GFP_KERNEL);
  ret = i2c_master_recv();
   struct i2c_adapter *adap = client->adapter;
   struct i2c_msg msg;                   //构建一个写消息结构体
   msg.addr = client->addr;          //上面ioctl写入
   msg.flags = client->flags *I2C_M_TEN;
   msg.flags |= I2C_M_RD;            //将标记改为读
   msg.len = count;
   msg.buf = (char *)buf;
  copy_to_user(buf, tmp, count);

i2c子系统涉及的函数接口与重要结构体
===================================================================
1.struct i2c_driver                 //描述一个i2c设备驱动
2.struct i2c_adapter             //描述一个i2c控制器/i2c适配器
3.struct i2c_client *client;    //描述一个i2c设备(如:e2prom)
  .addr = 0xa0
  .adapter =
  .driver
4.struct i2c_msg         //描述一个i2c消息
  .__u16 addr;    /*器件地址*/
  .__u16 flags;    /*要读还是写*/0:写 1:读
  .__u16 len;       /*数据长度*/
  .__u8 *buf;       /*要写入的数据,或者读出来的数据放在这里*/
 
函数接口:
1.i2c_add_driver       //加载i2c设备驱动结构体,加载到一个链表里面
2.i2c_add_adapter    //加载i2c适配器结构体到适配器链表
3.i2c_master_send //发送数据函数
4.i2c_transfer; //转接到底层的函数


































I2C驱动

标签:

原文地址:http://blog.csdn.net/chengtong222/article/details/51335759

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!