Linux内核中USB充电器的解决方案
来源:岁月联盟
时间:2012-07-02
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.2cto.com 方案二: 无需在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 <heikki.krogerus@linux.intel.com>--- 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.cindex 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.2cto.com ++ 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.hindex 204c18d..0dd89bf 100644 www.2cto.com --- 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文件权限