linux内核驱动子系统,linux内核中的MFD子系统
分析用的内核版本为5.1.3
1.MFD全称
Multi-function Device,多功能设备
2. 为何会出现MFD子系统
由于出现了一类具有多种功能的外围设备或cpu内部集成的硬件模块
3. 有哪些多功能设备呢?
3.1 PMIC,电源管理芯片
da9063: 调节器,led控制器,看门狗,实时时钟控制器,温度传感器,震动马达驱动,长按关机功能(ON key)
max77843: 调节器,充电器,燃油量表,触觉反馈,led控制器,micro USB接口控制器
wm831x: 调节器,时钟,实时时钟控制器,看门狗,触摸控制器,温度传感器,背光控制器,状态led控制器,GPIO,长按关机功能(ON key),ADC
其它: 甚至具有codec功能
3.2 atmel-hlcdc: 显示控制器和背光pwm
3.3 Diolan DLN2: USB转I2C,SPI和GPIO控制器
3.4 Realtek PCI-E读卡器: SD/MMC和记忆棒读取器
4. MFD子系统解决的主要问题
在不同的内核子系统中注册这些驱动。特别是外部外围设备仅仅由一个结构体struct device(或是指定的i2c_client或spi_device)呈现
5. MFD子系统的优点有哪些?
5.1 允许在多个子系统中注册相同的设备
5.2 MFD驱动必须能否复用总线(主要是关于锁的处理)和处理中断请求
5.3 处理时钟
5.4 需要配置IP
5.5 允许驱动重用,多个多功能设备能重用其它子系统中的驱动
6. MFD提供的API
int mfd_add_devices(struct device *parent,int id,
const struct mfd_cell *cells, int n_devs,
struct resource *mem_base,
int irq_base, struct irq_domain *irq_domain);
extern void mfd_remove_devices(struct device *parent);
这些接口定义在include/linux/mfd/core.h中,在drivers/mfd/mtd-core.c中被实现
7. MFD提供的结构体
struct mfd_cell {
const char *name;
int id;
/* refcounting for multiple drivers to use a single cell */
atomic_t *usage_count;
int (*enable)(struct platform_device *dev);
int (*disable)(struct platform_device *dev);
int (*suspend)(struct platform_device *dev);
int (*resume)(struct platform_device *dev);
/* platform data passed to the sub devices drivers */
void *platform_data;
size_t pdata_size;
/* device properties passed to the sub devices drivers */
struct property_entry *properties;
/*
* Device Tree compatible string
* See: Documentation/devicetree/usage-model.txt Chapter 2.2 for details
*/
const char *of_compatible;
/* Matches ACPI */
const struct mfd_cell_acpi_match *acpi_match;
/*
* These resources can be specified relative to the parent device.
* For accessing hardware you should use resources from the platform dev
*/
int num_resources;
const struct resource *resources;
/* don't check for resource conflicts */
bool ignore_resource_conflicts;
/*
* Disable runtime PM callbacks for this subdevice - see
* pm_runtime_no_callbacks().
*/
bool pm_runtime_no_callbacks;
/* A list of regulator supplies that should be mapped to the MFD
* device rather than the child device when requested
*/
const char * const *parent_supplies;
int num_parent_supplies;
};
8. 示例分析
8.1 分析tps6507x的多功能驱动
8.1.1 涉及的文件
drivers/mfd/tps6507x.c
include/linux/mfd/tps6507x.h
drivers/regulator/tps6507x-regulator.c
drivers/input/touchscreen/tps6507x-ts.c
8.1.2 涉及的结构体
static const struct mfd_cell tps6507x_devs[] = {
{
.name = "tps6507x-pmic",
},
{
.name = "tps6507x-ts",
},
};
从以上结构体可以得出,tps6507x系列芯片提供两种功能: 电源管理功能(regulator)+触摸屏功能(touchscreen)
static struct i2c_driver tps6507x_i2c_driver = {
.driver = {
.name = "tps6507x",
.of_match_table = of_match_ptr(tps6507x_of_match),
},
.probe = tps6507x_i2c_probe,
.id_table = tps6507x_i2c_id,
};
这个结构体为tps6507x提供探测函数tps6507x_i2c_probe
struct tps6507x_dev {
struct device *dev;
struct i2c_client *i2c_client;
int (*read_dev)(struct tps6507x_dev *tps6507x, char reg, int size,
void *dest);
int (*write_dev)(struct tps6507x_dev *tps6507x, char reg, int size,
void *src);
/* Client devices */
struct tps6507x_pmic *pmic;
};
tps6507x 的读写接口就是放在这个结构体中,这也就是所谓的共性
8.1.3 对tps6507x进行初始化
subsys_initcall(tps6507x_i2c_init);
调用路径如下:
tps6507x_i2c_init->i2c_add_driver
8.1.4 探测函数tps6507x_i2c_probe做了些什么?
注册tps6507x的读写函数: tps6507x_i2c_read_device和tps6507x_i2c_write_device到结构体struct tps6507x_dev中
8.1.5 tps6507x的两种功能实现在哪里呢?
drivers/regulator/tps6507x-regulator.c,这里面实现电源管理功能(电压调节器驱动)
drivers/input/touchscreen/tps6507x-ts.c,这里面实现触摸屏功能
8.1.6 tps6507x电压调节器驱动
8.1.6.1 调用路径
subsys_initcall(tps6507x_pmic_init);
tps6507x_pmic_init->platform_driver_register
8.1.6.2 探测函数tps6507x_pmic_probe干了些什么?
获取共用的结构体struct tps6507x_dev
再注册相关的结构体以便提供pmic的相关操作接口,如下:
static struct regulator_ops tps6507x_pmic_ops = {
.is_enabled = tps6507x_pmic_is_enabled, 检查tps6507x的pmic功能是否已经使能了
.enable = tps6507x_pmic_enable, 使能tps6507x的pmic功能
.disable = tps6507x_pmic_disable, 禁用tsp6507x的pmic功能
.get_voltage_sel = tps6507x_pmic_get_voltage_sel, 获取电压值
.set_voltage_sel = tps6507x_pmic_set_voltage_sel, 设置电压值
.list_voltage = regulator_list_voltage_table, 列出电压表
.map_voltage = regulator_map_voltage_ascend,
};
8.1.7 tps6507x触摸屏驱动
8.1.7.1 驱动在哪里?
drivers/input/touchscreen/tps6507x-ts.c
8.1.7.2 分析probe函数都做了些什么?
获取公用的结构体struct tps6507x_dev
填充结构体struct tps6507x_ts,关键是注册了函数tps6507x_ts_poll
参考资料:
标签:MFD,struct,int,tps6507x,内核,linux,device,i2c,pmic
来源: https://www.cnblogs.com/dakewei/p/10991941.html
linux内核驱动子系统,linux内核中的MFD子系统相关推荐
- 【翻译】【linux设备驱动】linux地址类型
[翻译][linux设备驱动]linux地址类型 Linux中使用的地址类型列表: 用户虚拟地址(User virtual addresses) 用户空间程序可见的普通地址.用户虚拟地址的长度为32位 ...
- linux 设备驱动总结,linux设备驱动归纳总结.doc
linux设备驱动归纳总结 linux设备驱动归纳总结 内核:用于管理软硬件资源,并提供运行环境.如分配4G虚拟空间等. linux设备驱动:是连接硬件和内核之间的桥梁. linux系统按个人理解可按 ...
- Linux设备驱动---OMAP3630 Linux I2C总线驱动分析(1)
原文地址:http://blog.csdn.net/kellycan/article/details/6394737 1 Linux I2C驱动架构 Linux下I2C驱动的架构图如下: 图1.1 L ...
- linux设备驱动模型-linux驱动开发第5部分-朱有鹏-专题视频课程
linux设备驱动模型-linux驱动开发第5部分-4285人已学习 课程介绍 本课程是linux驱动开发的第5个课程,主要内容是linux的设备驱动模型,包括总线.类.设备.驱动等概 ...
- linux蜂鸣器驱动指令,linux蜂鸣器驱动 蜂鸣器--LINUX.doc
linux蜂鸣器驱动 蜂鸣器--LINUX 导读:就爱阅读网友为您分享以下"蜂鸣器--LINUX"的资讯,希望对您有所帮助,感谢您对92的支持! //mux = 1/16 tcfg ...
- linux 驱动 include .h 路径 control,linux内核中的MFD子系统
分析用的内核版本为5.1.3 1.MFD全称 Multi-function Device,多功能设备 2. 为何会出现MFD子系统 由于出现了一类具有多种功能的外围设备或cpu内部集成的硬件模块 3. ...
- [Linux 基础] -- Linux 内核中的 MFD 子系统
一.MFD全称 Multi-function Device:多功能设备 二.为何会出现 MFD 子系统 由于出现了一类具有多种功能的外围设备或 cpu 内部集成的硬件模块 三.有哪些多功能设备 3.1 ...
- linux 内核驱动模型,linux设备驱动模型架构分析 一
linux设备驱动模型架构分析 一 发布时间:2018-07-04 15:14, 浏览次数:584 , 标签: linux 概述 LDD3中说:"Linux内核需要一个对系统结构的一般性描述 ...
- Linux系统驱动之分析内核自带的LCD驱动程序_基于IMX6ULL
百问网技术交流群,百万嵌入式工程师聚集地: https://www.100ask.net/page/2248041 资料下载 coding无法使用浏览器打开,必须用git工具下载: git clone ...
最新文章
- 在CentOS 6.3 64bit上使用 smartmontools和MageCli 监测硬盘的健康状态
- kvo实现原理_KVC、KVO实现原理
- AI大军又添猛将:海云数据宣布“双亿元AI扶持计划”
- Could not obtain transaction-synchronized Session for current thread
- TCP/IP 广播的发送和接收
- Android studio中不同颜色代表什么意思
- java基础---集合collection的方法介绍
- windows mysql 备份_Windows下MySQL数据库备份脚本(二) | 系统运维
- word之八大文本替换技巧
- python rpc_对python调用RPC接口的实例详解
- NUC1399 Sum It Up【DFS】
- Java二级知识总结
- RTX 2080 Ti 刚捂热,卡皇3080Ti 就要来了?
- 笔记本电脑外接显示器投屏问题
- TC358779XBG,HDMI转MIPI DSI,支持全高清,东芝转接芯片
- 【jenkins】创建一个project基础配置、自动化邮件发送、pytest_terminal_summary收集结果
- 编程中无穷大的设定 很多人可能设为0x7fffffff,这个数的确是32-bit int的最大值,符号位为0,其他的都是1 但在很多情况下,0x7fffffff会出现错误,比如溢出,这样两个无穷大数相
- 修改header-隐藏身份
- 连接大智慧数据库接口
- 2018世界人工智能大会开幕 森亿智能张少典谈AI与医疗融合
热门文章
- int a[5]={1,2,3,4,5}; int *p=(int*)(a+1); printf(%d,*(p-1)); 答案为什么是5?
- 【转】Android android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)...
- opencv 在工业中的应用:blob分析
- WebLogic12.1.1中跨域问题的探讨以及几种常见中间件中跨域问题的解决方法
- VS启动调试速度异常的缓慢问题
- 《2020信息消费战“疫”案例集》发布 邬贺铨院士作序推荐(附下载连接)
- 电商平台需要怎样的推荐系统?
- pytorch查缺补漏之CUDA,自动求导
- mysql 时间类型转化_Mysql 字段类型转化 和 时间类型相关处理
- 搜狗浏览器收藏夹在哪_搜狗浏览器居然流氓到操作我的微博账号