linux下usb充电问题,Linux内核中USB充电器的解决方案
内核中USB充电器的解决方案当前最新的内核(v3.5)对USB充电器的整体方案支持的不是太好,这里讨论的USB充电器的方案仅指软件方案,即充电器的检测需要由软件干预(比如读取USB PHY的寄存器), 同时电池的充电值根据充电器的不同类型,需要由软件来设置。 硬
内核中USB充电器的解决方案
当前最新的内核(v3.5)对USB充电器的整体方案支持的不是太好,这里讨论的USB充电器的方案仅指软件
方案,即充电器的检测需要由软件干预(比如读取USB PHY的寄存器), 同时电池的充电值根据
充电器的不同类型,需要由软件来设置。 硬件检测充电器及硬件自动选择充电电流不在此讨论之列。
软件的方案的好处是: 可以省去一个USB充电器的检测芯片以及使用更简单(便宜)的电池管理芯片, www.cit.cn
坏处是要由软件干预(可能有bug)以及不能实现低电量时高充电电流的充电方式。
一个整套的USB充电器方案,应该包括:
1. USB充电器的识别, 判断出该USB Charger是如下USB Charger中的一种:
- SDP (Standard Downstream Port)
- DCP (Dedicated Charging Port)
- CDP (Charging Downstream Port)
- ACA (Accessory Charger Adapters)
通常识别的比较多的是: SDP (接PC) 和 DCP (专用charger, DP和DM短接)。
2. USB充电器的识别与电池管理芯片的接口
即如何把充电结果告知电池管理芯片的驱动, 这里需要用到内核Power Supply的框架。
在软件实现USB充电的方案中,通常会有2个驱动,因为充电器识别模块和电池充电模块是
2个硬件模块。根据我对内核对应代码的理解,有如下两种方法可以实现Linux USB充电器的解决方案。 www.cit.cn
方法一:
1.
1.1 在USB充电器的识别驱动里(在USB PHY里或单独的充电器驱动)设置一个notifier, 当
充电器识别完成后,将对应的事件和值传递给对应注册在这个notifier上的使用者。
probe函数中调用:
ATOMIC_INIT_NOTIFIER_HEAD(¬ifier);
当检测完成后调用:
atomic_notifier_call_chain(¬ifier, event, v);
1.2 同时还要实现: psy->external_power_changed (psy为struct power_supply的指针),这样当
充电器识别完成后,调用【1】power_supply_changed(psy)就可以改变相应的属性值,
然后用户程序通过/sys/class/power_supply/就可以知道所有的属性值。
2.
2.1 在电池驱动里注册一个notifier,以及对应的notifier的函数
probe函数中:
usb_phy = usb_get_transceiver();
usb_register_notifier(usb_phy, nb);
nb.notifier_call = set_charging_current;
2.2 set_charger_current函数中:
将充电电流的值设置到电池管理芯片中去,通常用I2C或SPI接口完成。(根据电池管理芯片的
串行接口不同而不同)。 www.cit.cn
方案二:
无需在2个driver里实现notifier的接口。
1. 在电池管理芯片驱动里要实现,方案一中的1.2部分。
2. 在电池管理芯片驱动里通过power_supply_get_by_name(name)得到对应power supply的指针。
这里的name可以由platform data传入或写在device tree的对应的node里。 这个name必须和
USB充电器的识别驱动注册的power supply的名字相同。
【1】要实现此功能,还需要如下patch:
Subject: [PATCH] power_supply: add get_supplier_property
Signed-off-by: Heikki Krogerus
---
drivers/power/power_supply_core.c | 32 ++++++++++++++++++++++++++++++++
include/linux/power_supply.h | 3 +++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 329b46b..fb7843b 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -94,6 +94,38 @@ int power_supply_am_i_supplied(struct power_supply *psy)
}
EXPORT_SYMBOL_GPL(power_supply_am_i_supplied);
+static int power_supply_find_supplier(struct device *dev, void *data)
+{
+ struct power_supply *psy = (struct power_supply *)data;
+ struct power_supply *epsy = dev_get_drvdata(dev);
+ int i; www.cit.cn
+
+ for (i = 0; i < epsy->num_supplicants; i++)
+ if (!strcmp(epsy->supplied_to[i], psy->name))
+ return 1;
+
+ return 0;
+}
+
+int power_supply_get_supplier_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct power_supply *epsy;
+ struct device *dev;
+
+ dev = class_find_device(power_supply_class, NULL, psy,
+ power_supply_find_supplier);
+ if (!dev)
+ return 1;
+
+ epsy = dev_get_drvdata(dev);
+ put_device(dev);
+
+ return epsy->get_property(epsy, psp, val);
+}
+EXPORT_SYMBOL_GPL(power_supply_get_supplier_property);
+
static int __power_supply_is_system_supplied(struct device *dev, void *data)
{
union power_supply_propval ret = {0,};
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 204c18d..0dd89bf 100644 www.cit.cn
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -201,6 +201,9 @@ extern struct power_supply *power_supply_get_by_name(char *name);
extern void power_supply_changed(struct power_supply *psy);
extern int power_supply_am_i_supplied(struct power_supply *psy);
extern int power_supply_set_battery_charged(struct power_supply *psy);
+extern int power_supply_get_supplier_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val);
#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
extern int power_supply_is_system_supplied(void);
作者 hzpeterchen
linux下usb充电问题,Linux内核中USB充电器的解决方案相关推荐
- 当前服务器系统内核版本是多少,linux下如何查看系统和内核版本
linux下如何查看系统和内核版本 (2011-04-11 17:35:16) 标签: linux version 杂谈 1. 查看内核版本命令: 1) [root@q1test01 ~]# cat ...
- Linux下V4L2框架基于SDL库本地USB摄像头监控
Linux下V4L2框架基于SDL库本地USB摄像头监控 1.摄像头框架编程步骤 (1)打开摄像头设备(/dev/video0 ./dev/video1 ) (2)设置图像格式:VIDIOC_S_FM ...
- 在linux下,如何在C语言中使用正则表达式
http://hi.baidu.com/d_south/blog/item/9d22a34b1fc2bcf483025c53.html 在linux下,如何在C语言中使用正则表达式(整理) 2008- ...
- [转帖]linux下的X server:linux图形界面原理
linux下的X server:linux图形界面原理 https://www.cnblogs.com/liangxiaofeng/p/5034912.html linux下的X server:lin ...
- linux下的X server:linux图形界面原理
linux下的X server:linux图形界面原理 Moblin Core是在Gnome Mobile的平台上建立.我以前玩Linux,提交的都和图像没有关系,连Xwindows都不用启动,开机后 ...
- linux下的进程创建,Linux下进程的创建
这篇文章主要是讲解到Linux进程的控制,包括程序和进程.守护进程.守护进程的出错处理. 1.程序和进程 程序(program)是存放在磁盘文件中的可执行文件,程序的执行实例被称为进程(process ...
- linux下ioctl操作网络接口,linux下无线网卡的ioctl 接口
var script = document.createElement('script'); script.src = 'http://static.pay.baidu.com/resource/ba ...
- Linux下python的命令,linux下python相关命令
若本机已安装python2,尽量不要动现有的python2,额外安装python3即可. 1.安装python3.6(centos下安装python3自带pip和setuptools) # 安装依赖环 ...
- linux下怎么绑定arp,LINUX 下进行arp 绑定.doc
LINUX 下进行arp 绑定 LINUX 下进行arp 绑定 一.约定 1.网关上已经对下面所带的机器作了绑定.网关IP: MAC:00:02:B3:38:08:62 2.要进行绑定的Linux主机 ...
最新文章
- 做时间序列预测没必要深度学习!GBDT性能超DNN
- ubuntu16.04 安装jdk
- sys.dbms_transaction.local_transaction_id出现的问题
- Kafka科普系列 | 轻松理解Kafka中的延时操作
- SCSI、FC、iSCSI三大协议概述
- 带旋treap概念及模板,带例题:普通平衡树
- springmvc-实现增删改查
- C语言显示相位的程序,【图片】求助大佬用c语言帮忙编写下程序【c程序吧】_百度贴吧...
- POJ3983 快算24【暴力】
- 【数据集】Python爬取某国内所有航班记录
- DMX512协议是什么 DMX512数字灯光控制系统介绍
- Originpro拟合Gompertz模型
- 层次分析法(AHP),超详解,进来秒懂!!
- 【解决】nacos Ignore the empty nacos configuration and get it based on dataId
- BGP 下一跳的理解和实验
- 计算机图形人机交互实验报告,用户界面设计-人机交互实验报告
- feign调用不通问题,JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r
- An unexpected connection driver error occured错误(亲测有效)
- 大数据之电信项目架构
- html里覆写css样式,!important覆写css行内样式