linux i2c smbus驱动

article/2025/9/14 20:25:51

目录

目录

数据收发流程

驱动层 收发接口

驱动层注册

smbus控制器

i2c控制器 

协议接口使用

总体流程

数据收发关键数据结构

使用示例--eeprom的读写

使用示例--smbus的读写接口


数据收发流程

驱动层 收发接口

首先了解,驱动层向协议(算法)层注册的接口。

注释写的清楚:

1)如果不支持I2C 层级的访问,则设置i2c收发接口master_xfer为空,否则设置I2C控制器的接口;

2)如果控制器支持smbus协议,则对应的驱动设置收发接口smbus_xfer.

struct i2c_algorithm {/** If an adapter algorithm can't do I2C-level access, set master_xfer* to NULL. If an adapter algorithm can do SMBus access, set* smbus_xfer. If set to NULL, the SMBus protocol is simulated* using common I2C messages.** master_xfer should return the number of messages successfully* processed, or a negative value on error*/int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,int num);int (*master_xfer_atomic)(struct i2c_adapter *adap,struct i2c_msg *msgs, int num);int (*smbus_xfer)(struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union i2c_smbus_data *data);int (*smbus_xfer_atomic)(struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union i2c_smbus_data *data);/* To determine what the adapter supports */u32 (*functionality)(struct i2c_adapter *adap);#if IS_ENABLED(CONFIG_I2C_SLAVE)int (*reg_slave)(struct i2c_client *client);int (*unreg_slave)(struct i2c_client *client);
#endif
};

驱动层注册

对于此数据结构的使用,内核i801(intel smbus控制器)和 imx i2c 驱动,给出了示例:

smbus控制器

static const struct i2c_algorithm smbus_algorithm = {//由于控制器芯片支持smbus,不支持i2c级别。所以这里采用smbus_xfer接口.smbus_xfer	= i801_access,   .functionality	= i801_func,
};

i2c控制器 

static const struct i2c_algorithm i2c_imx_algo = {//i2c 控制器,实现i2c级别数据传输,不支持smbus接口。.master_xfer = i2c_imx_xfer,.master_xfer_atomic = i2c_imx_xfer_atomic,.functionality = i2c_imx_func,.reg_slave	= i2c_imx_reg_slave,.unreg_slave	= i2c_imx_unreg_slave,
};

协议接口使用

对于注册接口的不同,在  drivers\i2c \ i2c-core-smbus.c    __i2c_smbus_xfer 接口可以看出。


s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,unsigned short flags, char read_write,u8 command, int protocol, union i2c_smbus_data *data)
{int (*xfer_func)(struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union i2c_smbus_data *data);unsigned long orig_jiffies;int try;s32 res;res = __i2c_check_suspended(adapter);if (res)return res;/* If enabled, the following two tracepoints are conditional on* read_write and protocol.*/trace_smbus_write(adapter, addr, flags, read_write,command, protocol, data);trace_smbus_read(adapter, addr, flags, read_write,command, protocol);flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;//查看控制器向协议层注册的smbus_xfer接口xfer_func = adapter->algo->smbus_xfer; if (i2c_in_atomic_xfer_mode()) {if (adapter->algo->smbus_xfer_atomic)xfer_func = adapter->algo->smbus_xfer_atomic;else if (adapter->algo->master_xfer_atomic)xfer_func = NULL; /* fallback to I2C emulation */}if (xfer_func) { //对于smbus(i801),此接口不为空,则调用i801驱动接口收发数据/* Retry automatically on arbitration loss */orig_jiffies = jiffies;for (res = 0, try = 0; try <= adapter->retries; try++) {res = xfer_func(adapter, addr, flags, read_write,command, protocol, data);if (res != -EAGAIN)break;if (time_after(jiffies,orig_jiffies + adapter->timeout))break;}//如果不是i2c控制器驱动,即master_xfer为空,则直接跳转到trace,// 不会调用i2c_smbus_xfer_emulated接口进行smbus协议生成。// if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)goto trace;/** Fall back to i2c_smbus_xfer_emulated if the adapter doesn't* implement native support for the SMBus operation.*/}res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,command, protocol, data);trace:/* If enabled, the reply tracepoint is conditional on read_write. */trace_smbus_reply(adapter, addr, flags, read_write,command, protocol, data, res);trace_smbus_result(adapter, addr, flags, read_write,command, protocol, res);return res;
}

总体流程

  

                                           图 1  i2c /smbus 数据传输路径 

数据收发关键数据结构

    以上描述了i2c smbus从应用层到驱动控制器的数据流转路径。

   本章描述在此路径上流转所采用的数据载体形式。在整个i2c 驱动中采用了如下数据结构,此数据结构表示一帧 i2c/smbus数据。

struct i2c_msg {__u16 addr;     //i2c slave device address__u16 flags;
#define I2C_M_RD		0x0001	/* guaranteed to be 0x0001! */
#define I2C_M_TEN		0x0010	/* use only if I2C_FUNC_10BIT_ADDR */
#define I2C_M_DMA_SAFE		0x0200	/* use only in kernel space */
#define I2C_M_RECV_LEN		0x0400	/* use only if I2C_FUNC_SMBUS_READ_BLOCK_DATA */
#define I2C_M_NO_RD_ACK		0x0800	/* use only if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK	0x1000	/* use only if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR	0x2000	/* use only if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART		0x4000	/* use only if I2C_FUNC_NOSTART */
#define I2C_M_STOP		0x8000	/* use only if I2C_FUNC_PROTOCOL_MANGLING */__u16 len;   //传输的数据长度,即i2c一帧数据中,data的个数。__u8 *buf;   //存放数据的缓存。
};

使用示例--eeprom的读写

假设我们采用的eeprom 地址是16位的,eeprom期望的时序(报文协议)如下:

 可以看到此处有两个START,则需要两个i2c_msg数据结构分别携带此两段数据。其中:

  • 第一个start,为写,i2c_msg的字段填写为:   
  i2c_msg.addr = slave_addr;  i2c_msg .flags = I2C_M_WR;        i2c_msg.len = 2;  //在第一个START中,数据data即为两个字节的地址,因而这里填写2              i2c_msg.buf[0] = (eep_byte_addr >> 8) & 0x0ff; i2c_msg.buf[1] = eep_byte_addr  & 0x0ff;
  •  第二个start,为读, i2cmsg的字段信息填写为
  i2c_msg.addr = slave_addr;  i2c_msg .flags = I2C_M_RD;        i2c_msg.len = 需要读取的数据长度;  //i2c_msg.buf = 存放读取回来的数据

使用示例--smbus的读写接口

i2cdetect程序里面提供了一套读写接口,最终调用驱动的代码。此处采用两个i2c_msg,即可以支持读,又可以支持写。通常读采用两个i2c_msg完成;写采用一个,可以看到默认msg[1].len=0。

i2c_smbus_xfer_emulatedstruct i2c_msg msg[2] = {{.addr = addr,.flags = flags,.len = 1,.buf = msgbuf0,}, {.addr = addr,.flags = flags | I2C_M_RD,.len = 0,        .buf = msgbuf1,},};

在smbus的协议中,不论是读,还是写,都存在一个command字段,例如写字节的协议报文

此协议只是I2C协议的具体实现,因而其中的command code字段也占用结构体i2c_msg中的buf字段,为buf[0] ,明确这点后就更容易理解i2cdetect的代码实现。

command code既可以表示某个寄存器偏移量,例如要访问slave device 的寄存器 0xa,则在向slave device 发送命令时,此处command code字段填写 0xa.


http://chatgpt.dhexx.cn/article/kDk9I1Qb.shtml

相关文章

初学 SMBus

(这篇主要对象为固件工程师&#xff0c;简单介绍SMBus的一些基本概念而已) 概述 System Management Bus (简称SMBus或是SMB) &#xff0c;是1995年由Intel提出的&#xff0c;用来访问主机板上的设备(EEPROM、温度感测器、电压感测器等) 并收集相应的资讯(SPD、温度、电压、版…

SMBus协议

SMBus协议 文章目录 SMBus协议参考资料&#xff1a;一、 SMBus是I2C协议的一个子集二、 SMBus协议分析2.1 symbols(符号)2.2 SMBus Quick Command2.3 SMBus Receive Byte2.4 SMBus Send Byte2.5 SMBus Read Byte2.6 SMBus Read Word2.7 SMBus Write Byte2.8 SMBus Write Word2.…

系统管理总线(SMBus)介绍

SMBus介绍 系统管理总线协议概要系统管理总线 关键标记表SMBus接口函数1. SMBus Quick Command2. SMBus接收字节函数&#xff1a;i2c_smbus_read_byte()3. SMBus发送字节函数&#xff1a;i2c_smbus_write_byte()4. SMBus读取字节函数&#xff1a;i2c_smbus_read_byte_data()5. …

SMBus学习记录

SMBus学习记录 注&#xff1a;本文基于对于smb3.0 spec的学习总结。更多时序要求需要查阅spec。 SMBus 是 System Management Bus 的缩写&#xff0c;译为系统管理总线&#xff0c;SMBus是一种二线制串行总线&#xff0c;1996年第一版规范开始商用。它大部分基于I2C总线规范。…

SMBus通信,与IIC通信的差异

SMbus总线 SMBus是System Management Bus的缩写&#xff0c;它是一种简单的串行通信总线&#xff0c;用于连接计算机上的系统管理芯片和其他设备&#xff0c;如电池、风扇、温度传感器等。SMBus是由英特尔公司开发的&#xff0c;它基于I2C总线协议&#xff0c;但是增加了一些额…

【Linux】特别篇--SMBus 协议

【Linux】特别篇--SMBus 协议 一、SMBus 简介二、SMBus 与 I2C 区别三、SMBus协议分析3.1 符号含义3.2 SMBus Quick Command3.3 SMBus Receive Byte3.4 SMBus Send Byte3.5 SMBus Read Byte3.6 SMBus Read Word3.7 SMBus Write Byte3.8 SMBus Write Word3.9 SMBus Block Read3.…

SMBUS的介绍与访问

博文是为了总结自己在bios学习上面的点点滴滴&#xff0c;并且加深印象&#xff0c;由于本人水平有限&#xff0c;难免存在不足之处&#xff0c;望指正&#xff0c;同时感谢CSDN提供的平台。本文主要介绍的是SMBUS。 1 SMBUS的简介 特点&#xff1a; SMBUS&#xff0c;System …

java完整开发环境搭建_如何搭建一个完整的Java开发环境

这篇文章主要教大家如何搭建一个完整的Java开发环境&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下 作为一个Java程序员&#xff0c;配置一个java开发环境是必备的技能&#xff0c;今天给广大菜鸟初学者补上一课。环境的配置&#xff0c;大概就分三个…

1.1-java开发环境搭建

java开发环境搭建 回到第一章&#xff1a;目录 文章目录 java开发环境搭建前言一、下载jdk1.安装前检查 二、安装jdk1.安装2.配置环境变量3.验证安装 前言 本节内容是搭建java的开发环境。 分为三步&#xff1a;下载jdk&#xff1b;安装jdk&#xff1b;配置环境变量&#xff…

Windows Java开发环境搭建

1.下载安装配置 JDK 8 打开 https://developer.oracle.com/找到 Java8 下载位置&#xff0c;点击下载链接&#xff0c;下载JDK 8 下载后如下图所示&#xff0c;双击安装一直选择选择下一步 2.下载安装 Eclipse点击官网下载 Eclipse下载后就是一个压缩包&#xff0c;只需解压即…

基于Centos7的Java开发环境搭建

基于Centos7的Java服务器搭建 前提&#xff1a;Centos常用命令安装 1. 安装wget yum -y install wget2. 安装gcc yum -y install gcc1. Centos7下的防火墙操作 systemctl status firewalld # 查看防火墙状态 systemctl start firewalld # 开启防火墙 systemctl stop fi…

Java开发环境的搭建与配置

Java开发环境的搭建与配置 1、JDK、JRE、JVM的关系 2、JDK的下载&#xff1a;http://java.sun.com 3、JDK安装&#xff1a;可以自定义安装路径 4、JDK环境变量配置&#xff1a; 鼠标右击【计算机】->【属性】->【高级系统设置】->【高级】->【环境变量】 系统变…

Java开发环境搭建实践

前言 刚刚弄完python的环境搭建&#xff0c;今年打算也要好好学习Java&#xff0c;所以把Java的环境弄起来 搭建过程 jdk下载和安装 下载 官网&#xff1a;Oracle 甲骨文中国 | 云应用和云平台 打开官网 点击产品后下拉找到Java点进去。 下载Java 我就下载最新的jdk把…

程序员福音 【完整的Java开发环境搭建】 系列篇

原文地址 BY Jason 文章目录 原文地址Java开发环境搭建统一问题解决&#xff08;更新中&#xff09;1. vim常用操作命令2. 关于Linux防火墙开放端口问题 环境安装目录&#xff08;更新中&#xff09;Docker安装容器安装SSHJDK安装MySQL安装Redis安装RabbitMQ安装 Java开发环境…

Windows下Java开发环境搭建

本文以Win7操作系统解压版Eclipse安装版JDK1.7为例&#xff0c;展示如何搭建初级Java开发环境。 第一步&#xff1a;根据自己电脑的操作系统的位数选择相应版本的安装包进行安装&#xff1a; &#xff08;1&#xff09;查看自己电脑操作系统位数&#xff1a;找到“计算机”图标…

Java开发环境搭建详细教程(JDK+Eclipse)

前言 学习 Java 编程的第一件事情就是把开发环境搭建起来&#xff0c;这样才能开始快乐的编程学习之旅。然而&#xff0c;很多萌新经常因为种种问题无法搭建好开发环境&#xff0c;导致自己信心受挫&#xff0c;学习兴趣和激情也大减&#xff0c;甚至因此彻底放弃学习 Java 编…

【Java编程进阶】Java开发环境搭建

文章详细讲述了 Java 开发环境的搭建,编写并运行第一个 Java 程序,为后续的 Java 学习做了准备工作。 推荐学习专栏:Java编程进阶之路 文章目录 1. 为什么安装JDK?2. JDK的下载安装3. 配置环境变量4. 第一个Java程序1. 为什么安装JDK? 什么是JDK? JDK是java软件开发包,…

Java开发环境搭建超全详解

在项目产品开发中&#xff0c;开发环境搭建是软件开发的首要阶段&#xff0c;也是必须阶段&#xff0c;只有开发环境搭建好了&#xff0c;方可进行开发&#xff0c;良好的开发环境搭建&#xff0c;为后续的开发工作带来极大便利。 对于大公司来说&#xff0c;软件开发环境搭建工…

JAVA开发环境的搭建(最新版)【2019.2.12】

JAVA环境搭建 JAVA(咖啡)这个名字很有意思这里我会教大家来找到泡咖啡需要的用品 一、下载环境包&#xff08;找到茶杯&#xff09; 首先&#xff0c;我们需要到Oracle官网去下载开发环境步骤如下 主页操作如下(可能会随着时间的变化网页布局会改变&#xff0c;不要慌&#…

Java开发环境搭建:Windows

Java开发环境搭建:Windows JDK下载安装JDK下载设置环境变量测试是否安装成功 开发工具下载安装:IdeaIdea下载Idea安装 Idea开发JAVA推荐一波 JDK下载安装 JDK下载 JDK官网下载点这里 根据自己的电脑操作系统选择JDK 的安装包。 需要记住安装位置&#xff0c;后面设置环境变量…