Sunxi I2C 总线驱动使用文档 文档版本号 :V1.0 发布日期 :

Similar documents
第 1 页共 9 页 文档履历 版本号日期制 / 修订人内容描述 V 正式版本

Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provided by SUNPLUS TECHNOLO

T stg -40 to 125 C V cc 3.8V V dc RH 0 to 100 %RH T a -40 to +125 C -0.3 to 3.6V V -0.3 to VDD+0.3 V -10 to +10 ma = 25 = 3V) VDD

Panaboard Overlayer help

1. 請 先 檢 查 包 裝 內 容 物 AC750 多 模 式 無 線 分 享 器 安 裝 指 南 安 裝 指 南 CD 光 碟 BR-6208AC 電 源 供 應 器 網 路 線 2. 將 設 備 接 上 電 源, 即 可 使 用 智 慧 型 無 線 裝 置 進 行 設 定 A. 接 上 電 源

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco

CC213

Microsoft Word - Atmel-45136A-Pick-Best-Microcontroller-Strom-Eiland-Flodell_Article_CS

C/C++ - 文件IO

Applied Biosystems StepOne™ Real-Time PCR System Quick Reference Card for Installation

PCM-3386用户手册.doc

自然辩证法索引

SPHE8202R Design Guide Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provi

关 于 瓶 装 水, 你 不 得 不 知 的 8 件 事 情 关 于 瓶 装 水, 你 不 得 不 知 的 8 件 事 情 1 水 质 : 瓶 装 的, 不 一 定 就 是 更 好 的 2 生 产 : 监 管 缺 位, 消 费 者 暴 露 于 风 险 之 中 人 们 往 往 假 定 瓶 装 水 是

Contents

C/C++ - 函数

Chn 116 Neh.d.01.nis

1.ai

Guide to Install SATA Hard Disks

概述

Microsoft Word - 正文.doc

<4D F736F F D20C4CFBEA9D0C2B0D9A3A A3A9A3BAC7C9BDB3BFAAB3F6BAC3D3F1C0B4A3ACB9D8D7A2D2B5CEF1BDE1B9B9B5F7D5FBA3BBCDB6D7CAC6C0BCB6A1B0BDF7C9F7CDC6BCF6A1B12E646F63>

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

:5-6

封面及首頁.doc

Microsoft Word - 山西焦化(600740)--焦炭价格上涨提升业绩,市场整合带来机会 doc

Microsoft Word - CVersion doc

API参考

Bus Hound 5

AL-MX200 Series

C/C++ - 字符串与字符串函数

截 至 2016 年 3 月 23 日, 农 林 牧 渔 板 块 累 计 涨 幅 为 %, 在 申 万 28 个 一 级 行 业 分 类 中 排 名 第 八, 在 年 初 至 今 所 有 板 块 全 线 下 跌 的 情 况 下, 农 林 牧 渔 板 块 跌 幅 相 对 较 小 主 要 原


发行说明, 版

华恒家庭网关方案

Microsoft Word - Xinhua Far East_Methodology_gb_2003.doc


T

Microsoft Word - 实用案例.doc

K7VT2_QIG_v3


1377_SNAP_Selection_Guide.fm

untitled

样 本 基 金 平 均 仓 位 微 升 近 3 月 仓 位 水 平 变 化 不 大 根 据 我 们 金 元 证 券 的 基 金 仓 位 监 测 模 型,69 只 样 本 基 金 的 仓 位 ( 截 止 日 期 : ) 为 82.48%, 处 于 历 史 均 值 之 上, 相 比 上

DVK530/531扩展板

% 6.% 9.6% % 7.% 1.8% % 68.7% 14.5% : 15.8% 57.9% 4.7%

Contents

MICROCHIP EVM Board : APP APP001 PICmicro Microchip APP001 40pin PDIP PICmicro Design Tips Character LCM Temperature Sensor Application I/O Pi

untitled

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor

PCMCIA Compact Flash GPRS GPS PCMCIA Personal Computer Memory Card International Association CF Compact Flash PCMCIA CF PCMCIA/CF

C/C++ - 字符输入输出和字符确认

封面.PDF

QQGQ2.E Power Supplies, Information Technology Equipment Including Ele... 1/10

Go构建日请求千亿微服务最佳实践的副本

图 书 在 版 编 目 (CIP) 数 据 临 床 肿 瘤 学 : 全 2 册 /( 美 ) 尼 德 胡 贝 尔 (Niederhuber,J.E.) 等 原 著 ; 孙 燕 译. -- 北 京 : 人 民 军 医 出 版 社, ISBN Ⅰ.1 临

Logitech Wireless Combo MK45 English

Microsoft PowerPoint - IAS 21 - IFRS宣導會.pptx

Microsoft Word - Functional_Notes_3.90_CN.doc

BC04 Module_antenna__ doc

2

2/80 2

經濟部智慧財產局

EMC® VNX® Series VNX8000™ Block 安装指南

Serial ATA ( Silicon Image SiI3114)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 5 (4) S A T A... 8 (5) S A T A... 10

KPMG KPMG International Cooperative ( KPMG International ). KPMG International provides no client services and is a Sw

精 神 與 自 然 : 楊 慈 湖 心 學 研 究 趙 燦 鵬 哲 學 博 士 嶺 南 大 學 二 零 零 五 年

ebook14-4

目 錄 使 用 者 介 面... 3 檔 案 頁 籤... 3 配 置... 4 狀 態 列... 4 功 能 區... 5 說 明... 5 文 件... 7 修 訂 雲 形... 7 標 註... 8 文 字... 9 幾 何 中 心 點 的 物 件 鎖 點 等 角 製 圖 格 線.

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def

Microsoft Word - A_Daily

急激な市場変化の中でのテクノロジー投資

mvc

Microsoft Word - A_Daily

* * 2

Microsoft Word - A_Daily

¬¬

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C Project 30 C Project 3 60 Project 40

Microsoft Word - LR1122B-B.doc

% 29.9%.7% % 2% 2.1% % 45.2% 4.9% % 42.5% 14.8% % 41.5% 23.4%... 2

嵌入式Linux块设备驱动开发解析

A B C D RRC350 RRC Roteo 35/35G

chap-1_NEW.PDF

1

IEC 传输帧格式

JLX

Microsoft Word - (web)_F.1_Notes_&_Application_Form(Chi)(non-SPCCPS)_16-17.doc

untitled

运动员治疗用药豁免申报审批办法

LH_Series_Rev2014.pdf

2

06-4.indd

Chapter #

Huawei Technologies Co

Autodesk Product Design Suite Standard 系统统需求 典型用户户和工作流 Autodesk Product Design Suite Standard 版本为为负责创建非凡凡产品的设计师师和工程师提供供基本方案设计和和制图工具, 以获得令人惊叹叹的产品

Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Microsoft Win

要改变我们的文化 仅说我们是维护生命运动倡导者是不够的 我们必须 解释为什么我们是维护生命运动的倡导者 这本书恰恰是极佳的资源 弗兰克 帕沃 为了生活 教会的教牧主席 全国维护生命宗教理事 会全国总监 一个深思熟虑且彻底的分析 为什么保护所有人的生命不仅是正确的 立场 而且也是我们作为一个社会唯一应

Xear 3D USB CH-IN-2 SPKs 2 6 :

untitled

Transcription:

文档版本号 :V1.0 发布日期 :2017.09.22

版权所有 珠海全志科技股份有限公司 2017 保留一切权利 非经本公司书面许可, 任何单位和个人不得擅自摘抄 复制本文档内容的部分或全部, 并不得以任 何形式传播 商标声明 全志和其他全志商标均为珠海全志科技股份有限公司的商标 本文档提及的其他所有商标或注册商标, 由各自的所有人拥有 注意您购买的产品 服务或特性等应受全志公司商业合同和条款的约束, 本文档中描述的全部或部分产品 服务或特性可能不在您的购买或使用范围之内 除非合同另有约定, 全志公司对本文档内容不做任何明示或默示的声明或保证 由于产品版本升级或其他原因, 本文档内容会不定期进行更新 除非另有约定, 本文档仅作为使用指导, 本文档中的所有陈述 信息和建议不构成任何明示或暗示的担保

前言 前言 概述 介绍 Linux 内核中 I2C 子系统的接口及使用方法, 为 I2C 设备驱动的开发提供参考 产品版本 产品名称 产品版本 读者对象 本文档 ( 本指南 ) 主要适用于以下工程师 : I2C 设备驱动 I2C 总线驱动的开发 / 维护人员 修订记录 版本号修订日期修订内容 V0.1 2013-06-26 建立初始版本 V1.0 2015-02-16 Linux 内核版本从 3.4 变更到 3.10, 支持 64 位硬件平 台, 支持 Device Tree, 更新 sys_config 配置项 Copyright by Allwinner. All rights reserved i

目录 目录 1. 概述... 1 1.1. 编写目的... 1 1.2. 适用范围... 1 1.3. 相关人员... 1 2. 模块介绍... 2 2.1. 模块功能介绍... 2 2.2. 相关术语介绍... 3 2.3. 模块配置介绍... 3 2.3.1 sys_config.fex 配置说明... 3 2.3.2 menuconfig 配置说明... 3 2.4. 源码结构介绍... 6 3. 接口描述... 7 3.1. 设备注册接口... 7 3.1.1 i2c_add_driver()... 7 3.1.2 i2c_del_driver()... 8 3.1.3 i2c_register_board_info()... 8 3.2. 数据传输接口... 9 3.2.1 i2c_transfer()... 9 3.2.2 i2c_master_recv()... 9 3.2.3 i2c_master_send()... 10 3.2.4 i2c_smbus_read_byte()... 10 3.2.5 i2c_smbus_write_byte()... 10 3.2.6 i2c_smbus_read_byte_data()... 10 3.2.7 i2c_smbus_write_byte_data()... 10 3.2.8 i2c_smbus_read_word_data()... 11 3.2.9 i2c_smbus_write_word_data()... 11 3.2.10 i2c_smbus_read_block_data()... 11 3.2.11 i2c_smbus_write_block_data()... 11 4. demo... 13 4.1. i2c_register_board_info()... 13 4.2. bma250... 18 5. Declaration... 20 Copyright by Allwinner. All rights reserved ii

1.1. 编写目的 1. 概述 1 概述 介绍 Linux 内核中 I2C 子系统的接口及使用方法, 为 I2C 设备驱动的开发提供参考 1.2. 适用范围 适用于 A64 B100/G102 A20E/V40 T7 H5 V5 H6 硬件平台 1.3. 相关人员 I2C 设备驱动 I2C 总线驱动的开发 / 维护人员 Copyright by Allwinner. All rights reserved 1

2.1. 模块功能介绍 2. 模块介绍 2 模块介绍 Linux 中 I2C 体系结构图 2.1 所示, 图中用分割线分成了三个层次 : 1. 用户空间, 包括所有使用 I2C 设备的应用程序 ; 2. 内核, 也就是驱动部分 ; 3. 硬件, 指实际物理设备, 包括了 I2C 控制器和 I2C 外设 User space Appilcatiion I2C Client Driver Kernel I2C Core I2C Adapter Driver Hardware I2C Controller I2C device I2C device I2C device 图 2.1 Linux I2C 体系结构图其中,Linux 内核中的 I2C 驱动程序从逻辑上又可以分为 3 个部分 : 1. I2C 核心 (I2C Core): 实现对 I2C 总线驱动及 I2C 设备驱动的管理 ; 2. I2C 总线驱动 (I2C adapter driver): 针对不同类型的 I2C 控制器, 实现对 I2C 总线访问的具体方法 ; 3. I2C 设备驱动 (I2C client driver): 针对特定的 I2C 设备, 实现具体的功能, 包括 read,write 以及 ioctl 等对用户层操作的接口 I2C 总线驱动主要实现了适用于特定 I2C 控制器的总线读写方法, 并注册到 Linux 内核的 I2C 架构,I2C 外设就可以通过 I2C 架构完成设备和总线的适配 但是总线驱动本身并不会进行任何的通讯, 它只是提供通讯的实现, 等待设备驱动来调用其函数 I2C Core 的管理正好屏蔽了 I2C 总线驱动的差异, 使得 I2C 设备驱动可以忽略各种总线控制器的不同, 不用考虑其如何与硬件设备通讯的细节 Copyright by Allwinner. All rights reserved 2

2 模块介绍 2.2. 相关术语介绍 术语 解释说明 Sunxi I2C TWI I2C Adapter I2C Client smbus 指 Allwinner 的一系列 SOC 硬件平台 Inter-Integrated Circuit, 用于 CPU 与外设通信的一种串行总线 Normal Two Wire Interface,Sunxi 平台中的 I2C 控制器名称 I2C Core 将所有 I2C 控制器称作 I2C 适配器, 可以理解成控制器的软件名称 指 I2C 从设备 System Management Bus, 系统管理总线, 基于 I2C 操作原理, 是一个两线接 口, 通过它各设备之间以及设备与系统的其他部分之间可以互相通信 2.3. 模块配置介绍 2.3.1 sys_config.fex 配置说明 在不同的 Sunxi 硬件平台中,TWI 控制器的数目也不同, 但对于每一个 TWI 控制器来说, 在 sys_config.fex 中配置参数相似, 如下 : [twi0] twi0_used = 1 twi0_scl twi0_sda = port:ph14<2><default><default><default> = port:ph15<2><default><default><default> 其中,twi0_used 置为 1 表示使能,0 表示不使能 ;twi0_scl 和 twi0_sda 用于配置相应的 GPIO 对于 I2C 设备, 可以把设备节点填充作为相应 TWI 控制器的子节点 TWI 控制器驱动的 probe 函数透过 of_i2c_register_devices(), 自动展开作为其子节点的 I2C 设备 [twi0/twi_board0] compatible = "atmel,24c16"; reg = 0x50; 其中 : 1.twi0/twi_board0: 表示挂在总线 twi0 下的设备 twi_board0;; 2.compatible: 表征具体的设备, 用于驱动和设备的绑定 ; 3.reg: 设备使用的地址 ; 2.3.2 menuconfig 配置说明 在命令行中进入内核根目录, 执行 make ARCH=arm menuconfig 进入配置主界面, 并按以下步骤操作 : 首先, 选择 Device Drivers 选项进入下一级配置, 如下图所示 : Copyright by Allwinner. All rights reserved 3

2 模块介绍 图 2.2 Device Drivers 选项配置 然后, 选择 I2C support 选项, 进入下一级配置, 如下图所示 : 图 2.3 I2C support 选项配置 接着, 选择 I2C HardWare Bus support 选项, 进入下一级配置, 如下图 : Copyright by Allwinner. All rights reserved 4

2 模块介绍 图 2.4 I2C HardWare Bus support 选项配置 选择 SUNXI I2C controller 选项, 可选择直接编译进内核, 也可编译成模块 如下图 : 图 2.5 SUNXI I2C controller 选项配置 如果当前的配置是给 FPGA 使用, 因为 FPGA 板上只有一个 TWI 控制器, 还需要多做一项配置, 配置 I2C 外设要使用哪个 TWI 通道 如下图 : Copyright by Allwinner. All rights reserved 5

2 模块介绍 图 2.6 为 FGPA 板选择一个 TWI 通道 2.4. 源码结构介绍 I2C 总线驱动的源代码位于内核在 drivers/i2c/buesses 目录下 : drivers/i2c/ busses i2c-sunxi.c // Sunxi 平台的 I2C 控制器驱动代码 i2c-sunxi.h // 为 Sunxi 平台的 I2C 控制器驱动定义了一些宏 数据结构 Copyright by Allwinner. All rights reserved 6

3.1. 设备注册接口 3. 接口描述 3 接口描述 定义在 include\linux\i2c.h 3.1.1 i2c_add_driver() 函数原型 :#define i2c_add_driver(driver) i2c_register_driver(this_module, driver) int i2c_register_driver(struct module *owner, struct i2c_driver *driver) 功能描述 : 注册一个 I2C 设备驱动 从代码可以看带 i2c_add_driver() 是一个宏, 由函数 i2c_register_driver() 实现 参数说明 :driver,i2c_driver 类型的指针, 其中包含了 I2C 设备的名称 probe detect 等接口信息 返回值 :0, 成功 ; 其他值, 失败 其中, 结构 i2c_driver 的定义如下 : struct i2c_device_id char name[i2c_name_size]; kernel_ulong_t driver_data /* Data private to the driver */ attribute ((aligned(sizeof(kernel_ulong_t)))); ; struct i2c_driver unsigned int class; /* Notifies the driver that a new bus has appeared or is about to be * removed. You should avoid using this, it will be removed in a * near future. */ int (*attach_adapter)(struct i2c_adapter *) deprecated; int (*detach_adapter)(struct i2c_adapter *) deprecated; /* Standard driver model interfaces */ int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); /* driver model interfaces that don't relate to enumeration */ void (*shutdown)(struct i2c_client *); int (*suspend)(struct i2c_client *, pm_message_t mesg); int (*resume)(struct i2c_client *); /* Alert callback, for example for the SMBus alert protocol. * The format and meaning of the data value depends on the protocol. Copyright by Allwinner. All rights reserved 7

* For the SMBus alert protocol, there is a single bit of data passed * as the alert response's low bit ("event flag"). */ void (*alert)(struct i2c_client *, unsigned int data); 3 接口描述 /* a ioctl like command that can be used to perform specific functions * with the device. */ int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); struct device_driver driver; const struct i2c_device_id *id_table; /* Device detection callback for automatic device creation */ int (*detect)(struct i2c_client *, struct i2c_board_info *); const unsigned short *address_list; struct list_head clients; ; I2C 设备驱动可能支持多种型号的设备, 可以在.id_table 中给出所有支持的设备信息 3.1.2 i2c_del_driver() 函数原型 :void i2c_del_driver(struct i2c_driver *driver) 功能描述 : 注销一个 I2C 设备驱动 参数说明 :driver,i2c_driver 类型的指针, 包含有待卸载的 I2C 驱动信息 返回值 : 无 i2c.h 中还给出了快速注册的 I2C 设备驱动的宏 :module_i2c_driver(), 定义如下 : #define module_i2c_driver( i2c_driver) \ module_driver( i2c_driver, i2c_add_driver, \ i2c_del_driver) 3.1.3 i2c_register_board_info() 函数原型 :int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n) 功能描述 : 向某个 I2C 总线注册 I2C 设备信息,I2C 子系统通过此接口保存 I2C 总线和 I2C 设备的适配关系 参数说明 :busnum,i2c 控制器编号 info, 提供 I2C 设备名称 I2C 设备地址信息 n, 要注册的 I2C 设备个数 返回值 :0, 成功 ; 其他值, 失败 Copyright by Allwinner. All rights reserved 8

3 接口描述注意 : 注册 I2C 设备信息的方式除了 i2c_register_board_info(), 还可以通过 I2C 设备驱动的 detect 接口实现, 此接口会在 I2C 子系统注册一个 I2C adapter( 即 I2C 控制器 ) 或注册一个 I2C 设备驱动时调用 3.2. 数据传输接口 I2C 设备驱动使用 "struct i2c_msg" 向 I2C 总线请求读写 I/O 一个 i2c_msg 中包含了一个 I2C 操作, 通过调用 i2c_transfer() 接口触发 I2C 总线的数据收发 i2c_transfer() 支持多个 i2c_msg, 处理时按串行的顺序依次执行 i2c_msg 的定义也在 i2c.h 中 : struct i2c_msg u16 addr; /* slave address */ u16 flags; #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ #define I2C_M_RD 0x0001 /* read data, from slave to master */ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ u16 len; /* msg length */ u8 *buf; /* pointer to msg data */ ; 3.2.1 i2c_transfer() 函数原型 :int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 功能描述 : 完成 I2C 总线和 I2C 设备之间的一定数目的 I2C message 交互 参数说明 :adap, 指向所属的 I2C 总线控制器 msgs,i2c_msg 类型的指针 num, 表示一次需要处理几个 I2C msg 返回值 :>0, 已经处理的 msg 个数 ;<0, 失败 3.2.2 i2c_master_recv() 函数原型 :int i2c_master_recv(const struct i2c_client *client, char *buf, int count) 功能描述 : 通过封装 i2c_transfer() 完成一次 I2c 接收操作 Copyright by Allwinner. All rights reserved 9

参数说明 :client, 指向当前 I2C 设备的实例 buf, 用于保存接收到的数据缓存 count, 数据缓存 buf 的长度 返回值 :>0, 成功接收的字节数 ;<0, 失败 3 接口描述 3.2.3 i2c_master_send() 函数原型 :int i2c_master_send(const struct i2c_client *client, const char *buf, int count) 功能描述 : 通过封装 i2c_transfer() 完成一次 I2c 发送操作 参数说明 :client, 指向当前 I2C 从设备的实例 buf, 要发送的数据 count, 要发送的数据长度 返回值 :>0, 成功发送的字节数 ;<0, 失败 3.2.4 i2c_smbus_read_byte() 函数原型 :s32 i2c_smbus_read_byte(const struct i2c_client *client) 功能描述 : 从 I2C 总线读取一个字节 ( 内部是通过 i2c_transfer() 实现, 以下几个接口同 ) 参数说明 :client, 指向当前的 I2C 从设备 返回值 :>0, 读取到的数据 ;<0, 失败 3.2.5 i2c_smbus_write_byte() 函数原型 :s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) 功能描述 : 从 I2C 总线写入一个字节 参数说明 :client, 指向当前的 I2C 从设备 value, 要写入的数值 返回值 :0, 成功 ;<0, 失败 3.2.6 i2c_smbus_read_byte_data() 函数原型 :s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) 功能描述 : 从 I2C 设备指定偏移处读取一个字节 参数说明 :client, 指向当前的 I2C 从设备 command,i2c 协议数据的第 0 字节命令码 ( 即偏移值 ) 返回值 :>0, 读取到的数据 ;<0, 失败 3.2.7 i2c_smbus_write_byte_data() 函数原型 :s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value) 功能描述 : 从 I2C 设备指定偏移处写入一个字节 Copyright by Allwinner. All rights reserved 10

参数说明 :client, 指向当前的 I2C 从设备 3 接口描述 command,i2c 协议数据的第 0 字节命令码 ( 即偏移值 ) value, 要写入的数值 返回值 :0, 成功 ;<0, 失败 3.2.8 i2c_smbus_read_word_data() 函数原型 :s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) 功能描述 : 从 I2C 设备指定偏移处读取一个 word 数据 ( 两个字节, 适用于 I2C 设备寄存器是 16 位的情况 ) 参数说明 :client, 指向当前的 I2C 从设备 command,i2c 协议数据的第 0 字节命令码 ( 即偏移值 ) 返回值 :>0, 读取到的数据 ;<0, 失败 3.2.9 i2c_smbus_write_word_data() 函数原型 :s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value) 功能描述 : 从 I2C 设备指定偏移处写入一个 word 数据 ( 两个字节 ) 参数说明 :client, 指向当前的 I2C 从设备 command,i2c 协议数据的第 0 字节命令码 ( 即偏移值 ) value, 要写入的数值 返回值 :0, 成功 ;<0, 失败 3.2.10 i2c_smbus_read_block_data() 函数原型 :s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values) 功能描述 : 从 I2C 设备指定偏移处读取一块数据 参数说明 :client, 指向当前的 I2C 从设备 command,i2c 协议数据的第 0 字节命令码 ( 即偏移值 ) values, 用于保存读取到的数据 返回值 :>0, 读取到的数据长度 ;<0, 失败 3.2.11 i2c_smbus_write_block_data() 函数原型 :s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values) 功能描述 : 从 I2C 设备指定偏移处写入一块数据 ( 长度最大 32 字节 ) 参数说明 :client, 指向当前的 I2C 从设备 Copyright by Allwinner. All rights reserved 11

command,i2c 协议数据的第 0 字节命令码 ( 即偏移值 ) 3 接口描述 length, 要写入的数据长度 values, 要写入的数据 返回值 :0, 成功 ;<0, 失败 Copyright by Allwinner. All rights reserved 12

4.1. i2c_register_board_info() 4. demo 4 demo 在 I2C 总线驱动和 I2C 设备驱动的初始化之前需要调用此接口 : static struct i2c_board_info eeprom_i2c_board_info[] = I2C_BOARD_INFO("24c16", 0x50), ; void sunxi_i2c_test(void) int ret = 0;; ret = i2c_register_board_info(config_twi_chan_num, eeprom_i2c_board_info, ARRAY_SIZE(eeprom_i2c_board_info)); if (ret < 0) printk("%s()%d - EEPROM init failed!\n", func, LINE ); else printk("%s()%d - EEPROM init successed!\n", func, LINE ); 下面是一个 EEPROM 的 I2C 设备驱动, 该设备只为了验证 I2C 总线驱动, 所以其中通过 sysfs 节点实现读写访问 #define EEPROM_ATTR(_name) \ \.attr =.name = #_name,.mode = 0444, \.show = _name##_show, \ struct i2c_client *this_client; static const struct i2c_device_id at24_ids[] = "24c16", 0, /* END OF LIST */ Copyright by Allwinner. All rights reserved 13

; 4 demo MODULE_DEVICE_TABLE(i2c, at24_ids); static int eeprom_i2c_rxdata(char *rxdata, int length) int ret; struct i2c_msg msgs[] =.addr = this_client->addr,.flags = 0,.len = 1,.buf = &rxdata[0],,.addr.flags = this_client->addr, = I2C_M_RD,.len = length,.buf = &rxdata[1],, ; ret = i2c_transfer(this_client->adapter, msgs, 2); if (ret < 0) pr_info("%s i2c read eeprom error: %d\n", func, ret); return ret; static int eeprom_i2c_txdata(char *txdata, int length) int ret; Copyright by Allwinner. All rights reserved 14

struct i2c_msg msg[] = 4 demo.addr = this_client->addr,.flags = 0,.len = length,.buf = txdata,, ; ret = i2c_transfer(this_client->adapter, msg, 1); if (ret < 0) pr_err("%s i2c write eeprom error: %d\n", func, ret); return 0; static ssize_t read_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) int i; u8 rxdata[4]; rxdata[0] = 0x1; eeprom_i2c_rxdata(rxdata, 3); for(i=0;i<4;i++) printk("rxdata[%d]: 0x%x\n", i, rxdata[i]); return sprintf(buf, "%s\n", "read end!"); static ssize_t write_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) int i; Copyright by Allwinner. All rights reserved 15

static u8 txdata[4] = 0x1, 0xAA, 0xBB, 0xCC; 4 demo for(i=0;i<4;i++) printk("txdata[%d]: 0x%x\n", i, txdata[i]); eeprom_i2c_txdata(txdata,4); txdata[1]++; txdata[2]++; txdata[3]++; return sprintf(buf, "%s\n", "write end!"); static struct kobj_attribute read static struct kobj_attribute write = EEPROM_ATTR(read); = EEPROM_ATTR(write); static const struct attribute *test_attrs[] = &read.attr, &write.attr, NULL, ; static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) int err; this_client = client; printk("1..at24_probe \n"); err = sysfs_create_files(&client->dev.kobj,test_attrs); printk("2..at24_probe \n"); if(err) printk("sysfs_create_files failed\n"); Copyright by Allwinner. All rights reserved 16

printk("3..at24_probe \n"); 4 demo return 0; static int at24_remove(struct i2c_client *client) return 0; static struct i2c_driver at24_driver =.driver =.name = "at24",.owner = THIS_MODULE,,.probe = at24_probe,.remove = at24_remove,.id_table = at24_ids, ; static int init at24_init(void) printk("%s %d\n", func, LINE ); return i2c_add_driver(&at24_driver); module_init(at24_init); static void exit at24_exit(void) printk("%s()%d - \n", func, LINE ); i2c_del_driver(&at24_driver); module_exit(at24_exit); Copyright by Allwinner. All rights reserved 17

4 demo 4.2. bma250 此 I2C 设备是一个 Gsensor, 使用 detect 方式完成 I2C 设备和 I2C 总线的适配, 代码如下, 主要目的是完成 info->type 的赋值 static int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info) struct i2c_adapter *adapter = client->adapter; int ret; if (twi_id == adapter->nr) for (i2c_num = 0; i2c_num < (sizeof(i2c_address)/sizeof(i2c_address[0]));i2c_num++) client->addr = i2c_address[i2c_num]; pr_info("%s:addr= 0x%x,i2c_num:%d\n", func,client->addr,i2c_num); ret = i2c_smbus_read_byte_data(client,bma250_chip_id_reg); pr_info("read ID value is :%d",ret); if ((ret &0x00FF) == BMA250_CHIP_ID) pr_info("bosch Sensortec Device detected!\n" ); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; else if((ret &0x00FF) == BMA150_CHIP_ID) pr_info("bosch Sensortec Device detected!\n" \ "BMA150 registered I2C driver!\n"); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; else if((ret &0x00FF) == BMA250E_CHIP_ID) pr_info("bosch Sensortec Device detected!\n" \ "BMA250E registered I2C driver!\n"); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); Copyright by Allwinner. All rights reserved 18

return 0; 4 demo pr_info("%s:bosch Sensortec Device not found, \ maybe the other gsensor equipment! \n", func ); return -ENODEV; else return -ENODEV; bma250.c 将 Gsensor 注册成一个 input 设备, 定时向上层报告坐标数据, 这样应用层就可以采用类似鼠标键盘设备的方式读取到坐标数据 可以看出,input 接口是 Gsensor 这个设备和上层应用的接口, 而第 3 章所描述的 I2C 接口是 Gsensor 和 I2C adapter 总线控制器的接口 在参考这个例子上, 重点关注 I2C 接口的使用即可 Copyright by Allwinner. All rights reserved 19

5 Declaration 5. Declaration This document is the original work and copyrighted property of Allwinner Technology ( Allwinner ). Reproduction in whole or in part must obtain the written approval of Allwinner and give clear acknowledgement to the copyright owner. The information furnished by Allwinner is believed to be accurate and reliable. Allwinner reserves the right to make changes in circuit design and/or specifications at any time without notice. Allwinner does not assume any responsibility and liability for its use. Nor for any infringements of patents or other rights of the third parties which may result from its use. No license is granted by implication or otherwise under any patent or patent rights of Allwinner. This datasheet neither states nor implies warranty of any kind, including fitness for any particular application. Copyright by Allwinner. All rights reserved 20