1.l2c总线设备驱动模型
首先写出左边l2c控制器驱动程序用来收发数据,还要写出右边设备驱动,左边可以认为是总线驱动,Adapter设备器。 左边驱动程序通过操作里面寄存器来收发l2c数据,右边会用到控制器来读写上面东西。
在设备驱动那层阅读设备芯片手册来知道发送什么命令,数据,在编写驱动程序时重点放在具体芯片怎么操作上面,至于硬件操作细节由总线驱动来实现,分层分为3层。 实际上对于单片机也是相同思想,当操作具体硬件时,如下图底层提供l2c处理细节,而发什么内容有OLED芯片决定。
(1)AT24 C02芯片:知道发什么,读什么 (2)l2c实现怎么发怎么读
1.主控芯片有很多i2c控制器,接到哪条i2c总线上,指定设备地址在设备树上指定这两点也就足够了。 看硬件图接在I2C1总线下面于是在设备树这个节点下面新增加这个节点。
这个节点内容reg内容 看原理图后3位都是000 1010000=0x50 reg = <0x50>
对于每个clientd的addr来自于设备树的reg,adapter适配器也就是这个i2c设备挂载在那个i2c总线。适配器有I2C算法里面有传输函数。
I2c_driver用来与I2c_client设备匹配注册进给链表,当发现匹配的设备后会调用proble函数,
在这里插
static struct i2c_driver at24c02_drv = {
.driver = {
.name = "my24c02",
.of_match_table = at24c02_of_match,
},
.probe = at24c02_probe,
.remove = at24c02_remove,
.id_table = at24c02_ids,
};
入代码片
.id_table 表示来说我支持哪些i2c设备 优先使用.of_match_table = at24c02_of_match匹配,不行的话再使用.id_table匹配
i2c驱动主体框架
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/log2.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
static int at24c02_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
static int at24c02_remove(struct i2c_client *client)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
static const struct of_device_id at24c02_of_match[] = {
{.compatible = "100ask,at24c02"},
{}
};
static const struct i2c_device_id at24c02_ids[] = {
{ "xxxxyyy", (kernel_ulong_t)NULL },
{ }
};
static struct i2c_driver at24c02_drv = {
.driver = {
.name = "my24c02",
.of_match_table = at24c02_of_match,
},
.probe = at24c02_probe,
.remove = at24c02_remove,
.id_table = at24c02_ids,
};
static int at24c02_init(void)
{
int err;
err = i2c_add_driver(&at24c02_drv);
printk("%s %s %d, err = %d\n", __FILE__, __FUNCTION__, __LINE__, err);
return err;
}
static void at24c02_exit(void)
{
i2c_del_driver(&at24c02_drv);
}
module_init(at24c02_init);
module_exit(at24c02_exit);
MODULE_LICENSE("GPL");
这里插入代码片
|