I2C驱动

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; //转接到底层的函数

时间: 2024-08-07 18:45:49

I2C驱动的相关文章

TQ2440学习笔记——Linux上I2C驱动的两种实现方法(1)

作者:彭东林 邮箱:[email protected] 内核版本:Linux-3.14 u-boot版本:U-Boot 2015.04 硬件:TQ2440 (NorFlash:2M   NandFlash:256M  内存:64M) 摘要 这里并不深入分析Linux下I2C驱动的实现,只是以TQ2440硬件平台为例分析I2C驱动的两种方法. 第一种方法: 使用S3C2440自带的I2C控制器实现,这个kernel已经支持,我们只需要配置即可. 第二种方法: 使用GPIO模拟,这个在kernel中

I2C驱动框架之probe方式

基于Linux的I2C驱动,采用probe方式.按照如下这个框架可以写出任何支持I2C总线的器件的Linux驱动. I2C器件连接至cpu的特定的i2c的接口,也就是挂载在cpu的i2c适配器上,i2c器件要和cpu进行信息交换必须要通过cpu操作适配器来交互.cpu上有1个或多个适配器,每个适配器上可以挂载256个设备地址不一样的i2c器件,通过i2c驱动就可以让cpu和适配器上的多个不一样的i2c器件通信而不会产生冲突. 驱动包括两个文件,dev.c和drive.c,其中dev.c是构建I2

I2C驱动框架(四)

参考:I2C子系统之platform_driver初始化--I2C_adap_s3c_init() 在完成platform_device的添加之后,i2c子系统将进行platform_driver的注册过程.platform_driver的注册通过调用初始化函数i2c_adapter_s3c_init函数来完成. static struct platform_device_id s3c24xx_driver_ids[] = { { .name = "s3c2410-i2c", .dri

20150503 imx257下实现I2C驱动的四种方法

20150503 imx257下实现I2C驱动的四种方法 2015-05-3 Lover雪儿 时间过得好快,转眼间五一假期就即将结束了,假期期间,大家都潇洒的去玩了,徒留辛辛苦苦的程序员还是窝在宿舍乖乖的敲着代码... 好啦,开开玩笑,辛酸史每家都有一大本,还是要积极的面对生活!!! 今天我们的任务是简单的入门linux内核下i2c设备驱动分离的四种写法. 一.一个简单的i2c驱动 和以前的驱动程序不同,i2c驱动分为drv驱动和dev设备驱动两个文件,不懂的可以参考我以前写的<20150313

Linux I2C驱动编写要点

继续上一篇博文没讲完的内容“针对 RepStart 型i2c设备的驱动模型”,其中涉及的内容有:i2c_client 的注册.i2c_driver 的注册.驱动程序的编写. 一.i2c 设备的注册分析:在新版本内核的i2c驱动模型中,支持多种方式来注册 i2c 设备,在Documentation/i2c/instantiating-devices文件中有讲到,在内核中对应的抽象数据结构就是 struct i2c_client. (1)Declare the I2C devices by bus

I2C驱动详解

I2C讲解: 在JZ2440开发板上,I2C是由两条数据线构成的SCL,SDA:SCL作为时钟总线,SDA作为数据总线:两条线上可挂载I2C设备,如:AT24C08 两条线连接ARM9 I2C控制器,通过控制来控制I2C设备的识别设备地址.读.写操作:如图所示 从中所知:I2C线上可以挂载很多个I2C设备:挂载简单,只需要一根数据线和一根时钟线就可以挂载上去,通过地址来去别每个设备的区别: I2C操作: 对I2C操作主要思想为:1.找到设备  2.进行读写操作 主要原理为: 1.发送开始信号S

驱动: i2c驱动

1. IIC协议: <<um_s3c2440a_rev10.pdf>>  p481 Figure 20-3. IIC-Bus Interface Data Format<<AT24C08_DataSheet.pdf>>  Figure 1-12 Bus Timing and Device operations iic总线里的角色:    主机(Master):初始化发送.产生时钟信号和终止发送的器件     从机(Slave):被主机寻址的器件 I2C的原则

MSP430G2553 Launchpad 硬件I2C驱动

一.USCI I2C 驱动介绍 对于MSP430G2553,硬件I2C由外设USCI(Universal Serial Communication Interface)提供.USCI又分为USCI_A和USCI_B,其中USCI_A支持UART/IrDA/LIN/SPI通讯,USCI_B支持I2C/SPI通讯.MSP430G2553带有一个USCI_A和一个USCI_B,硬件I2C对应的管脚为P1.6(UCB0SCL)和P1.7(UCB0SDA). 由于Launchpad上P1.6连接到了LED

Linux的i2c驱动详解

目录(?)[-] 简介 架构 设备注册 I2C关键数据结构和详细注册流程 关键数据结构 详细注册流程 使用I2C子系统资源函数操作I2C设备 Gpio模拟i2c总线的通用传输算法 总结 理清i2c中的个结构体关系 i2c驱动的编写建议 1 简介 I2C 总线仅仅使用 SCL . SDA 两根信号线就实现了设备之间的数据交互,极大地简化对硬件资源和 PCB 板布线空间的占用.因此, I2C 总线被非常广泛地应用在 EEPROM .实时钟.小型 LCD 等设备与 CPU 的接口中. Linux I2