3.4.2内核下的I2C驱动框架解析
at24cxx_drv.c源码:
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
static int __devinit at24cxx_probe(struct i2c_client *client,
{
}
static int __devexit at24cxx_remove(struct i2c_client *client)
{
}
static const struct i2c_device_id at24cxx_id_table[] = {
};
// 1. 分配/设置i2c_driver //
static struct i2c_driver at24cxx_driver = {
};
static int at24cxx_drv_init(void)
{
}
static void at24cxx_drv_exit(void)
{
}
module_init(at24cxx_drv_init);
module_exit(at24cxx_drv_exit);
MODULE_LICENSE("GPL");
at24cxx_dev.c源码:
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
static struct i2c_board_info at24cxx_info = {
};
static struct i2c_client *at24cxx_client;
static int at24cxx_dev_init(void)
{
}
static void at24cxx_dev_exit(void)
{
}
module_init(at24cxx_dev_init);
module_exit(at24cxx_dev_exit);
MODULE_LICENSE("GPL");
===============================================================
第二种方法:
at24cxx_drv.c源码:
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
static int __devinit at24cxx_probe(struct i2c_client *client,
{
}
static int __devexit at24cxx_remove(struct i2c_client *client)
{
}
static const struct i2c_device_id at24cxx_id_table[] = {
};
// 1. 分配/设置i2c_driver //
static struct i2c_driver at24cxx_driver = {
};
static int at24cxx_drv_init(void)
{
}
static void at24cxx_drv_exit(void)
{
}
module_init(at24cxx_drv_init);
module_exit(at24cxx_drv_exit);
MODULE_LICENSE("GPL");
at24cxx_dev.c源码:
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
static struct i2c_client *at24cxx_client;
static const unsigned short addr_list[] = { 0x60, 0x50, I2C_CLIENT_END };
static int at24cxx_dev_init(void)
{
}
static void at24cxx_dev_exit(void)
{
}
module_init(at24cxx_dev_init);
module_exit(at24cxx_dev_exit);
MODULE_LICENSE("GPL");
=============================================================
第四种方法:
at24cxx_drv.c源码:
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
static int __devinit at24cxx_probe(struct i2c_client *client,
{
}
static int __devexit at24cxx_remove(struct i2c_client *client)
{
}
static const struct i2c_device_id at24cxx_id_table[] = {
};
static int at24cxx_detect(struct i2c_client *client,
{
}
static const unsigned short addr_list[] = { 0x60, 0x50, I2C_CLIENT_END };
// 1. 分配/设置i2c_driver //
static struct i2c_driver at24cxx_driver = {
};
static int at24cxx_drv_init(void)
{
}
static void at24cxx_drv_exit(void)
{
}
module_init(at24cxx_drv_init);
module_exit(at24cxx_drv_exit);
MODULE_LICENSE("GPL");
===============================================================
1. 框架
1.1 硬件协议简介
1.2 驱动框架
1.3 bus-drv-dev模型及写程序
a. 设备的4种构建方法(对于以下4种方法建议使用前3种,第四种方法迫不得已情况下使用)
a.1 定义一个i2c_board_info, 里面有:名字, 设备地址
a.2 直接i2c_new_device, i2c_new_probed_device
a.2.1 i2c_new_device : 认为设备肯定存在
a.2.2 i2c_new_probed_device :对于"已经识别出来的设备"(probed_device),才会创建("new")
i2c_new_probed_device
a.3 从用户空间创建设备
创建设备
echo at24c08 0x50 > /sys/class/i2c-adapter/i2c-0/new_device
导致i2c_new_device被调用
删除设备
echo 0x50 > /sys/class/i2c-adapter/i2c-0/delete_device
导致i2c_unregister_device
a.4 前面的3种方法都要事先确定适配器(I2C总线,I2C控制器)
static struct i2c_driver at24cxx_driver = {
};
去"class表示的这一类"I2C适配器,用"detect函数"来确定能否找到"address_list里的设备",
如果能找到就调用i2c_new_device来注册i2c_client, 这会和i2c_driver的id_table比较,
如果匹配,调用probe
i2c_add_driver
b. 驱动的写法
2. 完善设备驱动程序
3. 不自己写驱动直接访问
Device Drivers
4. 编写"总线(适配器adapter)"驱动
Device Drivers
nfs 30000000 192.168.1.123:/work/nfs_root/uImage_noi2cbus; bootm 30000000
评论