在Linux内核模块中操作I2C设备

转载 2013年12月04日 14:07:22


近期公司项目较为空闲,抽空做了一些学习性质的研发内容,其中涉及到在Linux内核模块中使用I2C对外部器件进行控制的操作。虽然在Linux中操作使用I2C设备并不复杂,但本人接触Linux内核驱动开发时间并不算长,此次学习中也算较为系统的了解了Linux中对I2C设备的操控方式,谨在此做下记录。

通过Linux内核文档中关于操作I2C设备的文章后不难看出Linux中注册使用I2C设备一般通过四种方法1

  1. 通过总线号声明设备
  2. 立即探测设备
  3. 通过Probe探测相应设备
  4. 在用户空间立即探测

简单来说,第一种方式一般应用在嵌入式设备中。因为对于嵌入式设备来说,外围器件基本都是固定的,只需提供有限几款器件的支持即可。使用这种方式的时候,需要在板级配置文件中定义并设置 i2c_board_info 这个结构体的内容。其中需要配置设备名称和设备地址,此外设备中断和私有数据结构也可以选择设置。然后使用 i2c_register_board_info 这个接口对设置的设备进行注册使用。需要注意的是这种方法注册的设备是在注册I2C总线驱动时进行驱动适配的。

第二种方法可以通过给定的I2C适配器以及相应的I2C板级结构体,自行通过 i2c_new_device 接口进行添加注册所需的设备。这种方法灵活性要较第一种方法大,可以很方便的在模块中使用。

第三种方法是 2.6 内核之前的做法,使用 detect 方法去探测总线上的设备驱动。因为探测机制的原因,会导致一些副作用的发生,所以不建议使用,除非真的没有别的办法。

第四种方法是在Linux的控制台上,在用户空间通过sysfs,使用 /sys/bus/i2c/devices/i2c-3/new_device 节点进行设备的添加注册。

从上面可以看出,如果需要在Linux内核中以模块的方式对I2C设备进行驱动控制的话,第二种方法是比较推荐的。通过测试,在module的init中使用

1
2
3
4
5
struct i2c_adapter *i2c_adap;
struct i2c_client *i2c_client;
i2c_adap = i2c_get_adapter(1);
i2c_client = i2c_new_device(i2c_adap, &i2c_device);
i2c_put_adapter(i2c_adap);
即可成功注册I2C设备。其中:
1
2
3
static struct i2c_board_info ft5306_i2c_device = {
    I2C_BOARD_INFO("test_i2c", 0x11),
};
以上,对于如何在模块中注册使用I2C设备简单做了描述。那么如何在另外的模块中对已经注册的I2C设备进行反注册呢?由于内核中操作I2C设备都是通过 i2c_client 结构进行,所以问题可以抽象为如何在内核中获取指定设备的 i2c_client 结构指针。通过查阅内核API,也找到了一个方法可以达到这样的目的,如下:
1
2
3
4
5
6
7
8
struct i2c_client *i2c_client;
struct device *i2c_dev;

i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, "1-0011");
if(i2c_dev)
    i2c_client  =  container_of(i2c_dev, struct i2c_client, dev);
if(i2c_client)
    i2c_unregister_device(i2c_client);
该反注册例子的内容就是对前面注册的 0x11 地址的设备进行反注册。注意bus_find_device_by_name 函数中第三项参数,该参数是需要查找的设备在总线上注册的名称。”1”代表着1号适配器,”0011”是16位的I2C地址。如此便可方便的在内核模块中对I2C设备进行挂载和解挂了。

Footnotes:

1 参考Linux内核目录下的Documentation/i2c/instantiating-devices

中断处理程序里不能操作I2C操作接口

在内核里中断处理程序里不能操作I2C操作接口,因为操作I2C_transfer时transfer内部也会有中断产生的。所以中断套中断这样就会死锁。...
  • qq160816
  • qq160816
  • 2011年12月29日 11:25
  • 675

linux下I2C的读写

1.在linux下提供另种I2C读写方式:  a.  一种是带寄存器读写的方式。(因为很多I2C设备的操作都是读写寄存器,所以Linux提供了这样一种接口)  b.一种是纯粹的数据发送。(a实际上调用...
  • tea1896
  • tea1896
  • 2016年06月23日 12:13
  • 2918

中断中处理延时及一些函数的调用规则(中断调i2c驱动有感)

转自:http://blog.csdn.net/xiyu_1986/article/details/6996927 1,中断处理程序中不能使用有睡眠功能的函数,如ioremap,kmalloc,ms...
  • fskwypfsk
  • fskwypfsk
  • 2012年08月26日 00:08
  • 3354

kernel I2C框架

kernel中的I2C驱动框架,笼统的概括,可以分为三个部分:core、adapter、client。其中core负责维护i2c_bus,匹配已经存在的adapter/driver/client;ad...
  • rikeyone
  • rikeyone
  • 2016年08月01日 13:54
  • 854

实例解析linux内核I2C体系结构

一、概述 谈到在linux系统下编写I2C驱动,目前主要有两种方式,一种是把I2C设备当作一个普通的字符设备来处理,另一种是利用linux I2C驱动体系结构来完成。下面比较下这两种驱动。 ...
  • yhf19881015
  • yhf19881015
  • 2012年11月16日 23:02
  • 1444

Openwrt环境下I2C操作

一、          环境介绍 软件环境:openwrt稳定发行版 barrier_breaker 硬件环境:主控芯片 MT7620n   eeprom 24c02   本文主要介绍,在openwr...
  • stone8761
  • stone8761
  • 2014年11月09日 12:21
  • 4135

Linux应用层的i2c读写

i2c通道在开发过程中使用是非常的方便的,主要是由于其简单的结构,i2c主要有SCL,SDA两条通道,一个时钟线,一个数据线,这也是i2c之所以应用如此普遍的原因。i2c的时序如下: 实现上述时序,...
  • wangweiqiang1325
  • wangweiqiang1325
  • 2016年09月02日 10:35
  • 3507

linux通过I2C地址查看设备名称

 root@android:/sys/bus/i2c # cd devices cd devices root@android:/sys/bus/i2c/devices # ls ls ...
  • weiqifa0
  • weiqifa0
  • 2015年04月17日 10:22
  • 4519

在Linux内核模块中操作I2C设备

近期公司项目较为空闲,抽空做了一些学习性质的研发内容,其中涉及到在Linux内核模块中使用I2C对外部器件进行控制的操作。虽然在Linux中操作使用I2C设备并不复杂,但本人接触Linux内核驱动开发...
  • daniel117
  • daniel117
  • 2013年12月04日 14:07
  • 777

i2c-tools的使用方法及举例

i2c-tools的使用方法     最近在调试ADV7401,调试的过程难免要反复修改寄存器,然后看结果现象。传统的做法是修改驱动代码寄存器值->编译->下载->运行->看结果,这一过程比较费时间,...
  • mantis_1984
  • mantis_1984
  • 2014年01月14日 09:39
  • 15016
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在Linux内核模块中操作I2C设备
举报原因:
原因补充:

(最多只允许输入30个字)