linux驱动子系统之i2c(5) -凯发app官方网站

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

慢行者

文章分类

全部博文(146)

文章存档

2013年(145)

2012年(1)

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

分类: linux

2013-05-10 16:17:19

5 客户驱动

5.1 概述

i2c客户驱动是对i2c从设备的实现,一个具体的i2c客户驱动包括两个部分:一部分是i2c_driver,用于将设备挂接于i2c总线;另一部分是设备本身的驱动。

i2c客户驱动程序主要由i2c_driver和i2c_client来描述。


5.2 实例源码分析

好了,我们来深入了解客户驱动代码的实现,drivers/misc/eeprom/at24.c文件支持大多数i2c接口的eeprom

i2c_driver实现


[cpp]
  1. staticstruct i2c_driver at24_driver = { 
  2.          .driver= { 
  3.                    .name= "at24"
  4.                    .owner= this_module, 
  5.          }, 
  6.          .probe= at24_probe,  /* 当i2c_client和i2c_driver匹配时调用 */ 
  7.          .remove= __devexit_p(at24_remove), /* 注销时调用 */ 
  8.          .id_table= at24_ids,   /* i2c_driver支持的i2c_client类型 */ 
  9. }; 




初始化和卸载


[cpp]
  1. staticint __init at24_init(void
  2.          returni2c_add_driver(&at24_driver); 
  3.   
  4. staticvoid __exit at24_exit(void
  5.          i2c_del_driver(&at24_driver); 




at24_probe函数


[cpp]
  1. staticint at24_probe(struct i2c_client*client, conststruct i2c_device_id *id) 
  2.          …… 
  3.          
  4.          /*
  5.           * export the eeprom bytes through sysfs, sincethat's convenient.
  6.           * by default, only root should see the data(maybe passwords etc)
  7.           */ 
  8.          sysfs_bin_attr_init(&at24->bin); 
  9.          at24->bin.attr.name= "eeprom"
  10.          at24->bin.attr.mode= chip.flags & at24_flag_irugo ? s_irugo : s_irusr; 
  11.          at24->bin.read= at24_bin_read; 
  12.          at24->bin.size= chip.byte_len; 
  13.   
  14.          at24->macc.read= at24_macc_read; 
  15.         writable = !(chip.flags &at24_flag_readonly); 
  16.          if(writable) { 
  17.                    if(!use_smbus || i2c_check_functionality(client->adapter, 
  18.                                      i2c_func_smbus_write_i2c_block)){ 
  19.   
  20.                             unsignedwrite_max = chip.page_size; 
  21.   
  22.                             at24->macc.write= at24_macc_write; 
  23.   
  24.                             at24->bin.write= at24_bin_write; 
  25.                             at24->bin.attr.mode|= s_iwusr; 
  26.                             …… 
  27.          } 
  28. …… 
  29.          
  30. err = sysfs_create_bin_file(&client->dev.kobj,&at24->bin); 
  31.          if(err) 
  32.                    gotoerr_clients; 
  33.   
  34.          i2c_set_clientdata(client,at24); 
  35.          …… 



probe函数主要的工作是在sys目录下创建bin节点文件,用户可以同此节点文件来操作eeprom,并提供操作方法(read,write)


5.3  i2c_client实现

at24c不依赖于具体的cpu和i2c控制器硬件特性,因此如果电路板包含该外设,只需要添加对应的i2c_board_info,下面是at24c08 i2c_client在板文件中的实现:


[cpp]
  1. staticstruct at24_platform_data at24c08 ={ 
  2.          .byte_len = sz_8k / 8,   /* eeprom的存储大小,单位byte */ 
  3.          .page_size        = 16,      /* 页大小 byte */ 
  4. }; 
  5.   
  6. staticstruct i2c_board_infomini2440_i2c_devs[] __initdata = { 
  7.          { 
  8.                    i2c_board_info("24c08",0x50),          /* 24c08设备名,0x50设备地址 */ 
  9.                    .platform_data= &at24c08,              /* 赋值给client->dev->platform_data */ 
  10.          }, 
  11. }; 
  12. staticvoid __init mini2440_init(void
  13.          …… 
  14.          i2c_register_board_info(0,mini2440_i2c_devs,    /* busnum = 0,busnum是适配器编号,用来识别从设备使用的哪个适配器 */ 
  15.                                      array_size(mini2440_i2c_devs)); 
  16.          …… 



i2c_register_board_info函数会把i2c从设备硬件特性信息注册到全局链表__i2c_board_list,在调用i2c_add_adapter函数时,会遍历__i2c_board_list获得从设备信息来构造i2c_client。


i2c_client的构建

我们调用i2c_register_board_info函数会把i2c从设备硬件特性信息注册到全局链表__i2c_board_list,但是还没有构建出一个i2c_client结构体,也没有注册进i2c总线。我们来分析一下构造的过程,调用i2c_add_adapter函数时,会遍历__i2c_board_list获得从设备信息来构造i2c_client:i2c_register_adapter()->i2c_scan_static_board_info()->i2c_new_device()->device_register()。


5.4  i2c_driver和i2c_client的match

在调用i2c_add_driver注册i2c_driver和构建i2c_client时,都会调用i2c bus中注册的i2c_device_match()->i2c_match_id()函数通过i2c_driver->id_table->name和client->name来匹配


[cpp]
  1. staticconststruct i2c_device_id*i2c_match_id(conststruct i2c_device_id *id, 
  2.                                                         conststruct i2c_client *client) 
  3.          while(id->name[0]) { 
  4.                    if(strcmp(client->name, id->name) == 0) 
  5.                             returnid; 
  6.                    id ; 
  7.          } 
  8.          returnnull; 



5.5 测试

已在mini2440上实验成功,在/sys/bus/i2c/devices/0-0050/目录下(50代表从设备地址)会产生一个eeprom文件,这个文件相当于是硬件设备eeprom的映射,我们可以像普通文件一样对eeprom文件进行操作,实质上就是就硬件eeprom的操作。重启开发板,你会发现对eeprom文件修改过的内容不会改变,这就证明实验成功了,要知道sys文件系统是无法对数据保存的。

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