打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
迅为iTOP-i.MX6ULL开发板I2C驱动程序实现 I2C通信
在第 67.1 章节学习 i2c 的时候,我们是在应用层操作设备节点对 i2c 设备进行读写的,那么如果我们在
驱动里面对 i2c 设备进行读写要怎么办呢?本章节我们将来学习。
我们复制第 67.3 章节的代码,在此基础上进行修改。我们在应用里面对 i2c 进行读写,最重要的是对
我们数据包的封包的操作,封装了一个 i2c_rdwr_ioctl_data 数据包,才对 i2c 进行读写,同样在驱动里面,
我们也可以使用这种方法。
我们对某个可读可写的寄存器进行读写操作,我们打开触摸芯片 ft5x06 的数据手册,打开 2.1 章节,如
下图所示:

完整的代码如下所示:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/i2c.h>

static struct i2c_client *ft5x06_client;

static void ft5x06_write_reg(u8 reg_addr, u8 data, u8 len);

static int ft5x06_read_reg(u8 reg_addr);

//读寄存器函数

static int ft5x06_read_reg(u8 reg_addr)

{

u8 data;

struct i2c_msg msgs[] = {

[0] = {

.addr = ft5x06_client->addr,

.flags = 0,

.len = sizeof(reg_addr),

.buf = &reg_addr,

},

[1] = {

.addr = ft5x06_client->addr,

.flags = 1,

.len = sizeof(data),

.buf = &data,

},

};

i2c_transfer(ft5x06_client->adapter, msgs, 2);

return data;

}

//写寄存器函数

static void ft5x06_write_reg(u8 reg_addr, u8 data, u8 len)

{

u8 buff[256];

struct i2c_msg msgs[] = {

[0] = {

.addr = ft5x06_client->addr,

.flags = 0,

.len = len + 1,

.buf = buff,

},

};

buff[0] = reg_addr;

memcpy(&buff[1], &data, len);

i2c_transfer(ft5x06_client->adapter, msgs, 1);

}

//与设备树的 compatible 匹配

static const struct of_device_id ft5x06_id[] = {

{.compatible = "edt,edt-ft5306", 0},

{.compatible = "edt,edt-ft5x06", 0},

{.compatible = "edt,edt-ft5406", 0},

{}};

// 无设备树的时候匹配 ID 表

static const struct i2c_device_id ft5x06_id_ts[] = {

{"xxxxx", 0},

{}};

/* i2c 驱动的 remove 函数 */

int ft5x06_remove(struct i2c_client *i2c_client)

{

return 0;

}

/* i2c 驱动的 probe 函数 */

int ft5x06_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id)

{

int ret;

printk("This is ft5x06_probe\n");

//因为我们要在别的函数里面使用 client,所以我们要把他复制出来

ft5x06_client = i2c_client;

//往地址为 0x80 的寄存器里面写入数据 0x4b

ft5x06_write_reg(0x80, 0x4b, 1);

//读出 0x80 寄存器的值

ret = ft5x06_read_reg(0x80);

//打印 0x80 寄存器的值

printk("ret is %#x\n", ret);

return 0;

}

//定义一个 i2c_driver 的结构体

static struct i2c_driver ft5x06_driver = {

.driver = {

.owner = THIS_MODULE,

.name = "ft5x06_test",

// 采用设备树的时候驱动使用的匹配表

.of_match_table = ft5x06_id,

},

.probe = ft5x06_probe,

.remove = ft5x06_remove,

.id_table = ft5x06_id_ts};

/* 驱动入口函数 */

static int ft5x06_driver_init(void)

{

int ret;

//注册 i2c_driver

ret = i2c_add_driver(&ft5x06_driver);

if (ret < 0)

{

printk(" i2c_add_driver is error \n");

return ret;

}

printk("This is ft5x06_driver_init\n");

return 0;

}

/* 驱动出口函数 */

static void ft5x06_driver_exit(void)

{

i2c_del_driver(&ft5x06_driver);

printk("This is ft5x06_driver_exit\n");

}

module_init(ft5x06_driver_init);

module_exit(ft5x06_driver_exit);

MODULE_LICENSE("GPL");

我们参考第三十九章 Linux 内核模块将刚刚编写的驱动代码编译为驱动模块,编译完如下图所示:

我们进入共享目录并且加载驱动模块,共享目录的搭建参考第三十七章 37.2.3 搭建 nfs 共享目录,

如下图所示:

如上图所示,我们可以看到读写函数是没问题的,可以对寄存器进行正常的读写操作。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux驱动开发|电容触摸屏
Linux设备驱动之I2C架构分析
i2c设备驱动实例分析
Linux的i2c驱动详解
驱动模块使用I2C总线范例
Linux I2C驱动分析与实现(二)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服