I2C设备驱动流程

Linux I2C设备驱动编写(二) 在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter、i2c_driver、i2c_client。三者的关系也在上一节进行了描述。应该已经算是对Linux I2C子系统有了初步的了解。下面再对他们之间的关系进行代码层的深入分析,我认为对他们的关系了解的越好,越有助于I2C设备的驱动开发及调试。 带着问题去分析可能会更有帮助吧,通过对(一)的了解后,可能会产生以下的 阅读详情

I2C设备驱动流程

一、I2C设备驱动流程

1) i2c_register_board_info定义I2C器件信息(Name,Address,etc.)

static struct i2c_board_info __initdata pi2c_board_info[] = {

       {

              I2C_BOARD_INFO("max1586", 0x14),

              .platform_data = &max1587a_info,

       },

};

 

i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));

/* 1表示该I2C设备挂在I2C-1上 ,注册I2C adapt时相应的id = 1 */

 

/* i2c */

static struct i2c_gpio_platform_data i2c_bus_data = {

       .sda_pin = VIPER_RTC_I2C_SDA_GPIO,

       .scl_pin = VIPER_RTC_I2C_SCL_GPIO,

       .udelay  = 10,

       .timeout = HZ,

};

 

static struct platform_device i2c_bus_device = {

       .name          = "i2c-gpio",

       .id         = 1,   /* /sys/class/i2c-adapt/i2c-1  */

       .dev = {

              .platform_data = &i2c_bus_data,

       }

};

 

将I2C器件信息注册到I2C的器件列表中:

struct i2c_devinfo {

       struct list_head list;                   /* 双向链表   */

       int                busnum;

       struct i2c_board_info     board_info;     /* i2c器件信息 */

};

 

int __init

i2c_register_board_info(int busnum,

       struct i2c_board_info const *info, unsigned len)

{

       int status;

       down_write(&__i2c_board_lock);

 

       /* dynamic bus numbers will be assigned after the last static one */

       if (busnum >= __i2c_first_dynamic_bus_num)

              __i2c_first_dynamic_bus_num = busnum + 1;

       for (status = 0; len; len--, info++) {

              struct i2c_devinfo   *devinfo;

              devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);

              if (!devinfo) {

                     pr_debug("i2c-core: can't register boardinfo!/n");

                     status = -ENOMEM;

                     break;

              }

 

              devinfo->busnum = busnum;

              devinfo->board_info = *info;

              list_add_tail(&devinfo->list, &__i2c_board_list);

              /* 加入__i2c_board_list 链表中 */

       }

       up_write(&__i2c_board_lock);

       return status;

}

 

2) 注册I2C device

i2c_register_adapter -> i2c_scan_static_board_info -> i2c_new_device

struct i2c_client *

i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)

{

       struct i2c_client       *client;

       int                status;

       client = kzalloc(sizeof *client, GFP_KERNEL);

       if (!client)

              return NULL;

       client->adapter = adap;

       client->dev.platform_data = info->platform_data;

       if (info->archdata)

              client->dev.archdata = *info->archdata;

 

       client->flags = info->flags;

       client->addr = info->addr;   /* 取得I2C器件地址 */

       client->irq = info->irq;

       strlcpy(client->name, info->type, sizeof(client->name));

 

       /* Check for address validity */

       status = i2c_check_client_addr_validity(client);

       if (status) {

              dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx/n",

                     client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);

              goto out_err_silent;

       }

       /* Check for address business */

       status = i2c_check_addr_busy(adap, client->addr);

       if (status)

              goto out_err;

       client->dev.parent = &client->adapter->dev;

       client->dev.bus = &i2c_bus_type;

       client->dev.type = &i2c_client_type;

 

       dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),

                   client->addr);

       status = device_register(&client->dev);   /* 注册器件 */

       if (status)

              goto out_err;

    …

}

 

3) I2C读写

static inline int pm860x_read_device(struct i2c_client *i2c,

                                 int reg, int bytes, void *dest)

{

       unsigned char data;

       int ret;

       data = (unsigned char)reg;

       ret = i2c_master_send(i2c, &data, 1);  /* 写地址 */

       if (ret < 0)

              return ret;

       ret = i2c_master_recv(i2c, dest, bytes);  /* 读数据 */

       if (ret < 0)

              return ret;

       return 0;

}

 

static inline int pm860x_write_device(struct i2c_client *i2c,

                                  int reg, int bytes, void *src)

{

       unsigned char buf[bytes + 1];

       int ret;

       buf[0] = (unsigned char)reg;

       memcpy(&buf[1], src, bytes);

       ret = i2c_master_send(i2c, buf, bytes + 1);  /* 写地址&数据 */

       if (ret < 0)

              return ret;

       return 0;

}

 

/* i2c-core.c 函数 */

int i2c_master_send(struct i2c_client *client, const char *buf, int count)

{

       int ret;

       struct i2c_adapter *adap = client->adapter;

       struct i2c_msg msg;

       msg.addr = client->addr;  /*  I2C器件地址 */

       msg.flags = client->flags & I2C_M_TEN;

       msg.len = count;

       msg.buf = (char *)buf;

       ret = i2c_transfer(adap, &msg, 1);

 

       /* If everything went ok (i.e. 1 msg transmitted), return #bytes

          transmitted, else error code. */

       return (ret == 1) ? count : ret;

}

 

int i2c_master_recv(struct i2c_client *client, char *buf, int count)

{

       struct i2c_adapter *adap = client->adapter;

       struct i2c_msg msg;

       int ret;

       msg.addr = client->addr;

       msg.flags = client->flags & I2C_M_TEN;

       msg.flags |= I2C_M_RD;

       msg.len = count;

       msg.buf = buf;

       ret = i2c_transfer(adap, &msg, 1);

 

       /* If everything went ok (i.e. 1 msg transmitted), return #bytes

          transmitted, else error code. */

       return (ret == 1) ? count : ret;

}

 

 

 

 

二、I2C时序

1)  START/STOP时序

 

 

2)  I2C器件地址结构(bit7~Bit1)

 

 

FIXME:”1” Read, “0” Write

3) 字节写

START + ( Device address +W ) + (Register Address) + (Data) + STOP

 

4) 多字节写

 

5) *读操作

 

START + (Device Address + w) + (Register Address) +RESTART + (Device Address + R) +(Data) +STOP

【linux iic子系统】i2c设备的添加方法(四) I2C设备的4种添加方法 分为静态注册、动态注册、用户空间注册及i2c驱动扫描注册 1.静态注册 静态注册就是在架构板级文件或初始化文件中添加i2c设备信息,并注册到特定位置(__i2c_board_list链表)上就可以了,如arm架构下board-xxx-yyy.c文件,x86架构下xxx-yyy-init-zzz.c文件。当系统静态注册i2c控制器(adapter)时,将会去查找这个链表,并实例化i2c设备添加到i2c总线上。注意:一定要赶在i2c控制器注册前将i2c设备信息添加到链表上。... 阅读详情

相关推荐

I2C 设备驱动编写流程: I2C 设备数据收发处理流程

I2C 设备驱动编写流程: I2C 设备数据收发处理流程

wojiaxiaohuang2014的博客 865

I2C设备注册的4种方法

I2C设备的4种添加方法:1)静态注册2)动态注册3)用户空间注册4)i2c驱动扫描注册。

uunubt的专栏 3369

I2C设备驱动Input设备注册流程实例

在一般的外设中i2c接口是比较常用的,android驱动设备中,重力感应,光感,ctp等等外设通常都是注册为input设备进行操作的,现在就来 举例注册一个input设备的流程 注册成一个I2C设备驱动 include include include include

softwoker的专栏 740

关于i2c_register_board_info()函数

i2c_register_board_info()函数用于往__i2c_board_list这条链表添加一条i2c设备信息,在i2c adapter注册的时候,会扫描__i2c_board_list链表,然后调用i2c_new_device()函数来注册i2c设备,注意,要先于i2c adapter注册之前就添加好i2c设备信息,否则会出现调用了i2c_register_board_info()函

Tracy Mcgrady的专栏 1万+

linux IIC设备驱动开发

1、通过module_i2c_driver注册对应的I2C驱动,此时内核会遍历挂载在I2C总线上的设备,通过总线的match方法对驱动和设备进行匹配,匹配原则可以是1、基于设备树of_driver_match_device方法,对应的结构为定义的驱动结构体是否含有of_match_table成员 2、基于id_table的匹配,对应为驱动是否定义id_table成员 3、基于名字的匹配,匹配原则为驱动的name是否和设备的name相同 4、基于ACPI风格的匹配,使用较少。参数msgs是需要发送的数据。

wangjie36的博客 2529

Camera AF和FF

Camera按对焦功能可以分为FF(Fixed Focus)和AF(Auto Focus),即固定对焦和自动对焦。固定对焦顾名思义就是焦距是固定的,而自动对焦可以通过移动镜头位置来改变焦距从而实现自动对焦。以前摄像的功能机大多是固定对焦,现在的手机都带有自动对焦功能。 FF模组包括镜头(Lens),传感器(Sensor),红外滤色器(IR Filter),电路板(PCB),镜头支撑(Lens Holder),连接器(Connector)。 Fig 1. FF Module AF模组包括FF模组,音圈马达(V

Coppa的博客 1万+

linux I2C设备驱动流程

一、I2C设备驱动流程 1) i2c_register_board_info定义I2C器件信息(Name,Address,etc.) static struct i2c_board_info __initdata pi2c_board_info[] = {        {               I2C_BOARD_INFO("max1586", 0x14),

gooogleman#foxmail.com 2790

树莓派4B学习笔记一

树莓派4b烧录Ubuntu20.04&&配置Ubuntu桌面

m0_55202222的博客 3634

I2C 设备驱动编写流程:设备节点信息描述

I2C 设备驱动编写流程:设备节点信息描述 无设备树支持时与有设备树文件支持的两种情况下

wojiaxiaohuang2014的博客 586

告别社区5级:一个脚本搞定小米/红米BL解锁的账号绑定限制(附资源下载与避坑指南)

本文提供了一种绕过小米/红米设备Bootloader解锁社区等级限制的技术方案,适用于MIUI 12.5-14和HyperOS 1.0系统。通过自动化脚本临时修改系统组件,用户可快速完成账号绑定和设备解锁流程,附详细操作指南和常见问题解决方案。

weixin_27330481的博客 725

腾讯云CodeBuddy+微信小程序:5分钟开发番茄小闹钟

番茄钟是一种简单的时间管理方法。这个方法很简单:你专注工作25分钟,然后休息5分钟。这样可以让你更专心,不容易分心,还能防止过度疲劳。 很多人用番茄钟来提高工作效率,因为它能帮助你更好地管理时间。不过,市面上的一些免费番茄钟应用常常会有广告弹出来,影响使用体验。这就是为什么我们要开发一个没有广告的番茄钟小程序,让用户可以专心工作,不被打扰。

2201_75366661的博客 1689

I2C设备驱动之I2C驱动构建流程

I2C设备驱动之I2C驱动构建流程

2301_76587520的博客 259

宇树G1二次开发资料汇总

宇树科技G1是一款29自由度的商业级人形机器人,配备NVIDIA Jetson Orin NX计算平台和完整SDK生态。本文系统介绍了G1的硬件架构、29个关节配置、传感器外设、双计算单元设计等关键信息,并详细解析了软件生态体系,包括C++/Python SDK、ROS2接口、仿真工具和AI框架。开发者可通过DDS通信实现高层运动控制或底层关节级精确控制,支持快速二次开发。文档提供了网络配置、接口调用示例等实用指南,帮助开发者高效利用该平台进行人形机器人应用开发。

m0_47999117的博客 1310

I2C 设备驱动编写流程

I2C 设备驱动编写流程

qq_66485945的博客 1546

[Python人工智能] 三十六.基于Transformer的商品评论情感分析 (2)keras构建多头自注意力(Transformer)模型

本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前一篇文章利用Keras构建深度学习模型并实现了情感分析。这篇文章将介绍Transformer基础知识,并通过Keras构建多头自注意力(Transformer)模型,实现IMDB电影影评数据情感分析。基础性文章,希望对您有所帮助!...

杨秀璋的专栏 4908

PyQt5数据库开发3 6 QSqlQuery完整实操案例【图文详解】

PyQt5数据库开发3 6.1 QSqlQuery实操案例【多图详解】,本文有点长,主要每一个步骤都有对应的图文教程!!!

qq_53317005的博客 2961

i.MX6ULL终结者Linux I2C驱动实验I2C设备驱动编写流程

文章目录1 设备信息描述2 I2C设备的数据收发和处理 I2C总线驱动一般是不用用户自己编写的,而I2C设备驱动则需要用户自己编写。每个设备的驱动都不相同,但是编写流程是一样的。下面就来具体分析一下。 1 设备信息描述 1、不使用设备树文件 当开始编写I2C设备驱动时,首先要添加设备信息。先来看一下在不使用设备树,使用平台文件时,如何在平台文件中添加I2C设备信息。 在平台文件中通过i2c_board_info 结构体来描述一个具体的 I2C 设备。i2c_board_info 结构体如下: 295 str

weixin_46635880的博客 331

手把手教您如何群晖/飞牛NAS等服务器上一键部署洛雪音乐同步服务,手机电脑无缝同步歌单,支持外网访问

🎵 手机电脑歌单不同步?用Docker在群晖/飞牛NAS等服务器上搭个同步服务器, 3分钟搞定 !支持docker-compose一键部署,手机、电脑、平板收藏夹实时同步,外出也能用域名远程访问 ~ ✨

XiaoqiangClub的博客 4601

Day67 Linux I²C 总线与设备驱动架构、开发流程与调试

I²C 驱动 = 总线驱动 + 设备驱动开发流程:设备树声明 → 应用层验证 → 编写驱动 → 测试关键匹配:DTS 中compatible必须与驱动id_table一致数据读取:先写寄存器地址,再读数据(LM75);先写内存地址,再读/写(AT24C08)调试原则:先通逻辑,再写驱动;硬件问题优先排查“不是重复造轮子,而是把轮子装到车上。—— 内核提供 I²C 通信“轮子”,开发者只需将设备逻辑“装上车”

oareen的博客 932

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: 常用git命令及注意事项
下一篇: linux软中断的小结
计算机与认知
博客等级 码龄14年 31粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值