I2C设备驱动挂载

image2021-9-18_10-56-22.png

一、 概述:

image2021-9-18_10-56-22.png

I2C工作原理:

        I2C总线标准的两根传输线,SDA是数据线,Scl是时钟线,当SCL为高,SDA由高到低时,发送启动信息,发送9个脉冲,1-7是地址,8是读写控制位,9是ACK应答位,所以挂在I2C上的被控设备都接受所发送的信息,并把接收到的7位地址与自己的地址进行比较,如果相同ACK就会反馈应答。当SCL为低,SDA由低-à高,则发送停止信号。

Linux的I2C构架分为三个部分:

1)I2C core框架

        提供了核心数据结构的定义和相关接口函数,用来实现I2C适配器

        驱动和设备驱动的注册、注销管理,以及I2C通信方法上层的、与具体适配器无关的代码,为系统中每个I2C总线增加相应的读写方法。

2) I2C总线驱动

        定义描述具体I2C总线适配器的i2c_adapter数据结构、实现在具体I2C适配器上的I2C总线通信方法,并由i2c_algorithm数据结构进行描述。 经过I2C总线驱动的的代码,可以为我们控制I2C产生开始位、停止位、读写周期以及从设备的读写、产生ACK等。

3) I2C 设备驱动

        是对具体I2C硬件驱动的实现。I2C 设备驱动通过I2C适配器与CPU通信。其中主要包含i2c_driver和i2c_client数据结构,i2c_driver结构对应一套具体的驱动方法,例如:probe、remove、suspend等,需要自己申明。i2c_client数据结构由内核根据具体的设备注册信息自动生成,设备驱动根据硬件具体情况填充。

编写具体的I2C驱动时,工程师需要处理的主要工作如下:
 
  1).提供I2C适配器的硬件驱动,探测,初始化I2C适配器(如申请I2C的I/O地址和中断号),驱动CPU控制的I2C适配器从硬件上产生。
  2).提供I2C控制的algorithm, 用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋给i2c_adapter的algo指针。
  3).实现I2C设备驱动中的i2c_driver接口,用具体yyy的yyy_probe(),yyy_remove(),yyy_suspend(),yyy_resume()函数指针和i2c_device_id设备ID表赋给i2c_driver的probe,remove,suspend,resume和id_table指针。
  4).实现I2C设备所对应类型的具体 ,i2c_driver只是实现设备与总线的挂接。
  

二、下面详细描述I2C设备驱动如何挂载到总线。

  下面以GPIO模拟i2c总线的驱动为例,来介绍实现I2C设备驱动如何挂载到总线上

1)  i2c-gpio总线和i2c设备驱动设备树

首先要添加 i2c-gpio总线和i2c设备驱动设备树节点,总线设备树节点无需添加,只需在添加设备驱动时,将对应的的I2C总线打开,添加节点内容在不同平台所相对应的设备树dts文件里,做法如下:

&i2c4 {status = "okay";<name>[@<unit_address>]@{    //其中name就是设备名,最长可以是31个字符长度。unit_address一般是设备地址,用来唯一标识一个节点compatible = "name2";    //需要与name_ids的 .compatible一致,不然注册不成功reg = <unit_address>;irq_gpio = <&gpio7 GPIO_B2 IRQ_TYPE_LEVEL_LOW>;//中断脚GPIOreset_gpio = <&gpio7 GPIO_B1 GPIO_ACTIVE_HIGH>;  //复位脚GPIO};}

2)  i2c-gpio总线和i2c设备驱动注册

i2c总线注册无需自己注册,把i2c设备驱动注册到i2c-gpio总线。做法如下,

I2C设备树
做法如下。首先定义设备ID:static const struct i2c_device_id name_id[] = {{ "name1", 0 },//设备名和设备是有数据长度{ }};
设备树名称:
static struct of_device_id name_ids[] = {{ .compatible = "name2" },//需要与设备树compatible一致,不然注册不成功{ }
};然后声明i2c_driver结构:static struct i2c_driver name_driver = {.probe     = name_probe, .remove        = name_remove,.suspend   = name_suspend,.resume        = name_resume,//上面4个函数根据具体情况取舍.id_table = name_id,.driver        = {.name    = "name1",  //需要与name_id里的设备名一致.of_match_table = of_match_ptr(name_ids),},};
最后调用static inline int i2c_add_driver(struct i2c_driver *driver)注册name驱动到I2C总线,如下:static int __init name_init(void){return i2c_add_driver(&name_driver);//注册name_driver};module_init(name_init);

3) 实现设备与总线的挂接

i2c_driver实现设备与总线的挂接。用具体yyy的yyy_probe(),yyy_remove(),yyy_suspend(),yyy_resume()函数指针和i2c_device_id设备ID表赋给i2c_driver的probe,remove,suspend,resume和id_table指针。其中.probe指针所对应的yyy_probe()函数指针则判断上电时序、I2C是否读取正确,返回值正确才能够实现I2C驱动设备的使用。

yyy_probe()函数指针判断大致流程如下,以上面缩写的设备树为例:

第一步;从设备数获取指定GPIO属性信息irq_gpio = of_get_named_gpio(np, "irq_gpio",0);reset_gpio = of_get_named_gpio(np, "irq_gpio", 0);
第二步:申请GPIO管脚ret = gpio_request(reset_gpio, "touch_gpio_reset");ret += gpio_request(irq_gpio, "touch_gpio_irq");
第三步:判断上电时序
不同设备有不同的上电时序,根绝供应商所提供的资料编写
第四步:读取I2C
s32 name_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
{struct i2c_msg msgs[2];s32 ret=-1;s32 retries = 0;GTP_DEBUG_FUNC();msgs[0].flags = !I2C_M_RD;msgs[0].addr  = client->addr;msgs[0].len   = GTP_ADDR_LENGTH;msgs[0].buf   = &buf[0];
#ifdef CONFIG_I2C_ROCKCHIP_COMPATmsgs[0].scl_rate=200 * 1000;//msgs[0].scl_rate = 300 * 1000;    // for Rockchip, etc.
#endifmsgs[1].flags = I2C_M_RD;msgs[1].addr  = client->addr;msgs[1].len   = len - GTP_ADDR_LENGTH;msgs[1].buf   = &buf[GTP_ADDR_LENGTH];
#ifdef CONFIG_I2C_ROCKCHIP_COMPATmsgs[1].scl_rate=200 * 1000;//msgs[1].scl_rate = 300 * 1000;    // for Rockchip, etc.
#endifwhile(retries < 5){ret = i2c_transfer(client->adapter, msgs, 2);if(ret == 2)break;retries++;}if((retries >= 5)){printk("I2C Read: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret);}return ret;
}
第五步:读取到正确的I2C,将GPIO管脚释放gpio_free(reset_gpio);gpio_free(irq_gpio);

4) 实现I2C设备所对应类型的具体

        实现 I2C 设备驱动的文件操作接口,即实现具体设备 yyy 的 yyy_read() 、 yyy_write() 和 yyy_ioctl() 函数等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/80746.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

骨传导耳机会头疼吗?骨传导耳机会对身体不好吗

一般情况下&#xff0c;骨传导耳机不会引起头疼。由于骨传导耳机的工作原理是通过将声音传导到颞骨和耳部周围的骨骼来传达音频信号&#xff0c;而不是直接进入耳道&#xff0c;因此不会对耳朵造成压力或产生耳疼的感觉。 然而&#xff0c;每个人的感受和体验可能不同&#xff…

PowerJob容器的使用(创建一个外置动态加载的任务)

1.使用容器的模板生成功能 2. 解压导入到IDEA中&#xff0c;下载依赖&#xff0c;添加处理器 3. 打包成jar 4. 上传项目到容器 5. 启动容器--部署jar 6. 复制一份上篇文章写的测试单机执行的任务实例&#xff0c;把执行配置修改从外置&#xff08;动态加载&#xff09; &…

浅谈开关柜绝缘状态检测与故障诊断

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要:电力开关柜作为电力系统的关键设备广泛应用于输电配电网络&#xff0c;其运行可靠性直接影响着电力系统供电质量及安全性能。开关柜绝缘状态检测与故障诊断是及时维修、更换和预防绝缘故障的重要技术手段。在阐述开关柜绝…

报名开启 | HarmonyOS第一课“营”在暑期系列直播

<HarmonyOS第一课>2023年再次启航&#xff01; 特邀HarmonyOS布道师云集华为开发者联盟直播间 聚焦HarmonyOS 4版本新特性 邀您一同学习赢好礼&#xff01; 你准备好了吗&#xff1f; ↓↓↓预约报名↓↓↓ 点击关注了解更多资讯&#xff0c;报名学习

如何使用CSS实现一个拖拽排序效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 实现拖拽排序效果的CSS和JavaScript示例⭐ HTML 结构⭐ CSS 样式 (styles.css)⭐ JavaScript 代码 (script.js)⭐ 实现说明⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦…

面试题(一)

目录 一.@Transactional 原理和常见的坑 前期准备 事务不生效的几种 Case 原理 源码解读 @Transactional 执行机制 private 导致事务不生效原因 异常不匹配原因 两种 @Transactional Spring @Transactional javax.transaction.Transactional 二.@Autowired 和 @R…

pytorch下的scatter、sparse安装

知道自己下载的torch配置 import torch print(torch.__version__) print(torch.version.cuda)进入网站&#xff0c;选择自己配置 https://pytorch-geometric.com/whl/下载相应的包 安装 pip install ******.whl

Windows:解决MySQL登录ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using passwor=YES)问题

我在下载的MySQL是8.0.32版本&#xff0c;刚下的时候没什么问题第二天启动MySQL服务就出现了 ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES) 或 ERROR 1045 (28000): Access denied for user rootlocalhost (using password: NO) 这样的问题…

IC芯片 trustzone学习

搭建Airplay TA环境需要在IC的TrustZone中进行。TrustZone是一种安全技术&#xff0c;用于隔离安全和非安全环境&#xff0c;并保护敏感文件。在TrustZone中&#xff0c;我们需要编写一个叫做TA&#xff08;Trusted Application&#xff09;的应用程序来控制这些私密文档。 &am…

Springboot中sharding-jdbc的API模式并使用自定义算法

Springboot中sharding-jdbc的API模式并使用自定义算法 可配合AbstractRoutingData使用切换数据源 程序用到了AbstractRoutingData来切换数据源&#xff08;数据源是自定义的格式编写并没有用springboot的自动装配的格式写&#xff09;&#xff0c;但是又用到sharding-jdbc进行…

uniapp-form表单

<template><view class"ptb-20 plr-30 bg min100"><view class"bg-white radius-20 pd-30"><view class"bold mt-30 mb-50 size-32">选择方式&#xff1a;</view><u--form labelPosition"left" :mod…

轻松实现文件夹名互换,快速批量改名高手工具助您高效管理!

亲爱的用户们&#xff0c;您是否曾经需要将文件夹的名称进行互换&#xff0c;但手动一个一个改名太过繁琐&#xff1f;现在&#xff0c;我们为您推出一款高效的文件夹批量改名工具&#xff0c;让您轻松实现文件夹名的互换&#xff0c;帮助您更好地管理文件&#xff01; 首先&a…