免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1311 | 回复: 0
打印 上一主题 下一主题

Linux I2C设备驱动--数据结构及驱动函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-11 01:40 |只看该作者 |倒序浏览
===========================================
=======================数据结构==============
struct i2c_adapter {
struct module *module;
unsigned int id;//algorithm 的类型
unsigned int class;
struct i2c_algorithm *algo;//总线通信方法的结构体指针
void *algo_data;
int (*client_register)(struct i2c_client *);
int (*client_unregister)(struct i2c_client *);
struct semaphore bus_lock;
struct semaphore clist_lock;
int timeout;
int retries;
struct device dev;//适配器
struct class_device class_device;
int nr;
struct list_head clients;
struct list_head list;
char name[I2C_NAME_SIZE];//适配器名称
struct completion dev_release;
struct completion class_dev_release;
};
struct i2c_algorithm {
int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msg,int num);
int (*smbus_xfer)(struct i2c_adapter *adap,u16 addr,unsigned short flags,
char read_write,u8 command, int size,union i2c_smbus_data *data);
int (*slave_send)(struct i2c_adapter *,char *, int);
int (*slave_recv)(struct i2c_adapter *,char *,int);
int (*algo_control)(struct i2c_adapter *, unsigned int , unsigned long);
u32 (*functionality)(struct i2c_adapter *);//返回适配器支持的功能
};
struct i2c_driver{
int  id;
unsigned int class;
int (*attach_adapter)(struct i2c_adapter *);
int (*detach_adapter)(struct i2c_adapter *);
int (*command)(struct i2c_client, unsigned int cmd, void *arg);
struct device_driver driver;
struct list_head list;
};
struct i2c_client {
unsigned int flag;
unsigned short addr;//低7位芯片地址
struct i2c_adapter *adapter;//依附的
struct i2c_driver *driver;//依附的
int usage_count ;
struct device dev;
struct list_head list;
char name[I2C_NAME_SIZE];
struct completion released;
};
//////////关系////////////////////
i2c_adapter 对应于物理上的适配器 i2c_algorithm 对应一套通信方法。
i2c_algorithm 中的关键函数master_xfer()用于产生 i2c 访问周期所需要的信号。
struct i2c_msg {
__u16 addr;
__u16 flags;
__u16 len;
__u8 *buf
};
i2c_driver 对应驱动方法 i2c_client 对应真实的物理设备,一般包含在字符设备私有信息结构中
i2c_driver attach_adapter()时候attach_adapter会探测物理设备,i2c_client的adapter指向
i2c_adapter,driver 指向对应的i2c_driver,并调用i2c_adapter的client_register().
i2c_adaprer对应多个client
///////////驱动任务///////////////////////////////
1 提供i2c适配器的硬件驱动,探测初始化 I2C适配器,申请IO中断,驱动CPU 控制i2c适配器从硬件
上产生各种信号以及处理I2C中断
2 提供I2C适配器的algorithm , 用具体适配器的xxx_xfer()函数填充i2c_algorithm 的master_xfer
并吧i2c_algorithm的的指针赋值给i2c_adpter的algo 指针
3实现i2c设备驱动与i2c_dirver接口,用具体设备的yyy的yyy_attach_adapter()函数指针
  yyy_detach_client() yyy_command()函数指针赋值给i2c_driver
4实现i2c设备的文件操作接口,即实现具体设备的yyy的yyy_read(),yyy_write()等
前2个属于总线驱动,后两个设备驱动
==============================================
==============================驱动函数=========
I2C core
主要函数
int i2c_add_adapter(struct i2c_adapter *adap);
int i2c_del_adapter(struct i2c_adapter *adap);
int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
int i2c_del_driver(struct i2c_driver *driver);
inline int i2c_add_driver(struct struct  i2c_driver *driver);
int i2c_attach_client(struct i2c_client *client );//设备和sysfs将被注册
int i2c_detach_client(struct i2c_client *client );
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
int  i2c_master_send(struct i2c_client *client, const char *buf, int count);
int i2c_master_recv(struct i2c_client *client, char *buf, int count);
int i2c_control(struct i2c_client *client , unsigned int cmd, unsigned long arg);
void i2c_client_command(struct i2c_adapter *adap, unsigned int cmd, void *arg);
//////////////////////////////////////////
I2C 总线驱动
加载卸载:初始化硬件(IO 中断号) i2c_add_adapter()
通信方法: 主要实现 i2c_algorithm 的 functionality()-返回通信协议:
I2C_FUNC_I2C I2C_FUNC_10BIT_ADDR  I2C_FUNC_SMBUS_READ_BYTE  I2C_FUNC_SMBUS_WRITE_BUS
master_xfer()模板
static int i2c_adapter_xxx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
...
for(i= 0; iflags &I2C_M_READ)
{
i2c_adapter_xxx_setaddr((msg->addrbuf, msgs->len);//
} else
{
i2c_adapter_xxx_setaddr((msg->addrbuf, msgs->len);
}
  }
  i2c_adapter_xxx_stop();//产生停止位
}
//////////////////////////////////////////////
I2C 设备驱动
加载和卸载:register_chrdev() i2c_add_driver()
i2c_add_driver(&yyy_driver)的执行会引发yyy_attach_adapter()调用核心
i2c_probe(adapter, &addr_data, yyy_detect);
要探测的地址实际列表在一个16位无符号整型数组中,数组以I2C_CLIENT_END为最后一个元素。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/69624/showart_1078437.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP