I2C设备驱动挂载

编程入门 行业动态 更新时间:2024-10-21 16:36:11

I2C<a href=https://www.elefans.com/category/jswz/34/1769313.html style=设备驱动挂载"/>

I2C设备驱动挂载

一、 概述:

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的 patible一致,不然注册不成功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[] = {{ patible = "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() 函数等

更多推荐

I2C设备驱动挂载

本文发布于:2024-02-06 16:39:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1750340.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:设备   I2C

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!