I2C驱动框架(三)
参考:I2C子系统之platform_device初始化——smdk2440_machine_init()
I2C驱动框架还应用了另一种总线-设备-驱动模型,平台设备总线platform_bus_type。内核已经注册好了平台总线,驱动程序只需向平台总线添加平台设备和平台驱动。这节主要介绍如何添加平台设备。
/*********"/arch/arm/mach-s3c64xx/mach-smdk6410.c"**********************/
//2./arch/arm/mach-s3c2440/mach-smdk2440.c中的函数:smdk2440_machine_init() arch_initcall级别
static void __init smdk6410_machine_init(void)
-->s3c_i2c0_set_platdata(NULL);
-->i2c_register_board_info(, i2c_devs0, ARRAY_SIZE(i2c_devs0));
-->i2c_register_board_info(, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-->platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
-->platform_device_register(&s3c_device_i2c0); /*注册平台设备*/
s3c_device_i2c0定义如下:
/*********"/arch/arm/plat-samsung/dev-i2c0.c"**********************/
static struct resource s3c_i2c_resource[] = {
[] = {
.start = S3C_PA_IIC,
.end = S3C_PA_IIC + SZ_4K - ,
.flags = IORESOURCE_MEM,
},
[] = {
.start = IRQ_IIC,
.end = IRQ_IIC,
.flags = IORESOURCE_IRQ,
},
};
/*
内核用adapter来表示主机,I2C驱动框架中的adapter就是指s3c6410的i2c控制器。
内核中通过platform_device来描述。具体如下:
*/
struct platform_device s3c_device_i2c0 = {
.name = "s3c2410-i2c",
.id = ,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
/*s3c_device_i2c0.dev.platform_data = &default_i2c_data0;*/
};
通过s3c_set_platdata(NULL)进一步设置s3c_device_i2c0的成员变量
static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
.flags = ,
.slave_addr = 0x10,
.frequency = *,
.sda_delay = ,
}; void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S3C64XX_GPB(), S3C64XX_GPB5_I2C_SCL0);
s3c_gpio_cfgpin(S3C64XX_GPB(), S3C64XX_GPB6_I2C_SDA0);
s3c_gpio_setpull(S3C64XX_GPB(), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPB(), S3C_GPIO_PULL_UP);
} void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
if (!pd)
pd = &default_i2c_data0;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd->cfg_gpio)
npd->cfg_gpio = s3c_i2c0_cfg_gpio;
s3c_device_i2c0.dev.platform_data = npd;
}
最后调用platform_device_register(&s3c_device_i2c0)注册平台设备,其中s3c_device_i2c0包含了s3c6410上i2c相关寄存器的地址,以及地址资源,还包括i2c时钟线所需的时钟频率,i2c设备的从地址等信息,即获取了系统i2c控制器的信息,后面需要使用这些信息去初始化i2c adapter结构体。具体描述如下图所示:
smdk6410_machine_init(void)中做的另一项工作是通过i2c_register_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 + ; for (status = ; len; len--, info++) { /*
#include <linux/rwsem.h>
*/
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);
} up_write(&__i2c_board_lock); return status;
}
/*
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
*/
struct i2c_board_info {
char type[I2C_NAME_SIZE];
unsigned short flags;
unsigned short addr;
void *platform_data;
struct dev_archdata *archdata;
struct device_node *of_node;
int irq;
};
struct i2c_devinfo {
struct list_head list;
int busnum;
struct i2c_board_info board_info;
};
#define I2C_BOARD_INFO(dev_type, dev_addr) .type = dev_type, .addr = (dev_addr)
static struct i2c_board_info i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), },
{ I2C_BOARD_INFO("wm8580", 0x1b), }, { I2C_BOARD_INFO("ov965x", 0x30), }, // gjl
}; static struct i2c_board_info i2c_devs1[] __initdata = {
{ I2C_BOARD_INFO("24c128", 0x57), }, /* Samsung S524AD0XD1 */
};
执行完i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));这两个函数后,建立起如下的一个i2c_devinfo结构体类型的链表,链表头为__i2c_board_list,创建i2c_client结构体时会使用这些信息,每一个i2c_devinfo结构体对应一个i2c_client设备:
I2C驱动框架(三)的更多相关文章
- I2C驱动框架(四)
参考:I2C子系统之platform_driver初始化——I2C_adap_s3c_init() 在完成platform_device的添加之后,i2c子系统将进行platform_driver的注 ...
- I2C驱动框架 (kernel-3.4.2)
先用韦老师的图: 注: 新版本内核的i2c驱动框架采用了 i2c_client -------> i2c_bus_type <-------- i2c_driver 框架 如 ...
- Linux I2C驱动分析(三)----i2c_dev驱动和应用层分析 【转】
本文转载自:http://blog.chinaunix.net/uid-21558711-id-3959287.html 分类: LINUX 原文地址:Linux I2C驱动分析(三)----i2c_ ...
- STC8H开发(七): I2C驱动MPU6050三轴加速度+三轴角速度检测模块
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- I2C驱动框架(kernel-2.6.22.6)
以用i2c通信的实时时钟为例 框架入口源文件:i2c_m41t11.c (可根据入口源文件,再按着框架到内核走一遍) 内核版本:linux_2.6.22.6 硬件平台:JZ2440 以下是驱动框架 ...
- Linux 驱动框架---i2c驱动框架
i2c驱动在Linux通过一个周的学习后发现i2c总线的驱动框架还是和Linux整体的驱动框架是相同的,思想并不特殊比较复杂的内容如i2c核心的内容都是内核驱动框架实现完成的,今天我们暂时只分析驱动开 ...
- 【Linux高级驱动】I2C驱动框架分析
1.i2c-dev.c(i2c设备驱动组件层) 功能:1)给用户提供接口 i2c_dev_init //入口函数 /*申请主设备号*/ register_chrdev(I2C_MAJOR(), &q ...
- I2C驱动框架(二)
参考:I2C子系统之I2C bus初始化——I2C_init() 在linux内核启动的时候最先执行的和I2C子系统相关的函数应该是driver/i2c/i2c-core.c文件中的i2c_init( ...
- Linux I2C驱动框架
Linux的I2C体系结构分为3个组成部分: I2C核心( i2c-core.c ): I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法.I2C通信方法("algorithm&qu ...
随机推荐
- python 基础(四) 函数
函数 一.什么是函数? 函数是可以实现一些特定功能的 小方法 或者是小程序 优点: 提高 了代码的后期维护 增加了代码的重复使用率 减少了代码量 提高了代码可读性 二.函数的定义 使用 def关键+函 ...
- django 之 rest framework
一 二 三 四 五 六 七 八
- p标签中的文本换行
参考文章 word-break:break-all和word-wrap:break-word的区别 CSS自动换行.强制不换行.强制断行.超出显示省略号 属性介绍 white-space: 如何处理元 ...
- 114 Flatten Binary Tree to Linked List 二叉树转换链表
给定一个二叉树,使用原地算法将它 “压扁” 成链表.示例:给出: 1 / \ 2 5 / \ \ 3 4 6压扁后变成如下: ...
- EDAS提交论文字体未嵌入
一.深夜更一波,刚刚在EDAS提交论文,提示格式不通过,说我有字体未嵌入.但是之前一直都没有问题,这次只是在LaTeX中嵌图的时候把eps换成PDF了.所以问题应该是出在我的PDF图里,里面有字体未被 ...
- React项目搭建基于Karma的CI环境
简介 在浏览Github的时候是否经常看到这样的CI图标呢? 本文即为介绍如何为基于React的项目配置CircleCI的自动化测试环境 源码在此 本地实现 项目依赖如下: "devDepe ...
- AJPFX关于延迟加载的单例模式的安全问题解决
请写一个延迟加载的单例模式?写懒汉式:当出现多线程访问时怎么解决?加同步,解决安全问题:效率高吗?不高:怎样解决?通过双重判断的形式解决.懒汉式:延迟加载方式.当多线程访问懒汉式时,因为懒汉式的方法内 ...
- Hadoop2.6.2的Eclipse插件的使用
欢迎转载,且请注明出处,在文章页面明显位置给出原文连接. 本文链接:http://www.cnblogs.com/zdfjf/p/5178197.html 首先给出eclipse插件的下载地址:htt ...
- ThreadLocal遇到线程池时, 各线程间的数据会互相干扰, 串来串去
最近遇到一个比较隐蔽而又简单地问题,在使用ThreadLocal时发现出现多个线程中值串来串去,排查一番,确定问题为线程池的问题,线程池中的线程是会重复利用的,而ThreadLocal是用线程来做Ke ...
- CSS-学习笔记四
1.*用于匹配任何的标记 2.>用于指定父子节点关系 3.E+F毗邻元素选择器,匹配所以紧随E元素之后的同级元素F 4.E~F匹配所以E元素之后的同级元素F 5.名称[表达式] [att=val ...