Android PowerSupply (三)power_supply_sys
目录
Android PowerSupply (二)power_supply_core
Android PowerSupply (三)power_supply_sys
Android PowerSupply (四)ChargeIC SGM41511 IC driver调试
Android PowerSupply (五)ChargeIC SGM41511 IC简介
Android Healthd BartteryMonitor
通过power supply class类的加载 了解其过程
static int __init power_supply_class_init(void)
{
power_supply_class = class_create(THIS_MODULE, "power_supply");
//!< 注册powersupply类,路径 /sys/class/powersupply By: jixuan 2021年6月15日
power_supply_class->dev_uevent = power_supply_uevent;
//!< uevent处理 By: jixuan 2021年6月15日
power_supply_init_attrs(&power_supply_dev_type);
//!< 伴随powersupply类创建的节点属性 By: jixuan 2021年6月15日
return 0;
}
void power_supply_init_attrs(struct device_type *dev_type)
{
int i;
dev_type->groups = power_supply_attr_groups;
for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++)
__power_supply_attrs[i] = &power_supply_attrs[i].attr;
}
static const struct attribute_group *power_supply_attr_groups[] = {
&power_supply_attr_group,
NULL,
};
static struct attribute_group power_supply_attr_group = {
.attrs = __power_supply_attrs,
.is_visible = power_supply_attr_is_visible,
//!< 在实际新增加的powersupply中 会设置其可见性,仅展示所需要的proerty By: jixuan 2021年6月15日
};
/* Must be in the same order as POWER_SUPPLY_PROP_* */
//!< 顺序必须与枚举定义的类型顺序一致,是判断可见性的依据 By: jixuan 2021年6月15日
static struct device_attribute power_supply_attrs[] = {
/* Properties of type `int' */
POWER_SUPPLY_ATTR(status),
POWER_SUPPLY_ATTR(charge_type),
POWER_SUPPLY_ATTR(health),
POWER_SUPPLY_ATTR(present),
POWER_SUPPLY_ATTR(online)
POWER_SUPPLY_ATTR(cycle_count),
POWER_SUPPLY_ATTR(voltage_max),
POWER_SUPPLY_ATTR(voltage_min)
POWER_SUPPLY_ATTR(voltage_now),
POWER_SUPPLY_ATTR(voltage_avg),
POWER_SUPPLY_ATTR(voltage_ocv),
POWER_SUPPLY_ATTR(voltage_boot),
POWER_SUPPLY_ATTR(current_max),
POWER_SUPPLY_ATTR(current_now),
POWER_SUPPLY_ATTR(power_now),
POWER_SUPPLY_ATTR(power_avg),
POWER_SUPPLY_ATTR(charge_full)
POWER_SUPPLY_ATTR(capacity)
POWER_SUPPLY_ATTR(capacity_raw),
POWER_SUPPLY_ATTR(temp),
POWER_SUPPLY_ATTR(temp_max)
POWER_SUPPLY_ATTR(battery_type),
POWER_SUPPLY_ATTR(cycle_counts),
......
......
//!< power_supply 类中具有N多属性,仅展示部分,实际在init过程中会指明这些属性是否可见 By: jixuan 2021年6月15日
};
//!< 通过POWR_SUPPLY_ATTR宏 定义show shore函数 By: jixuan 2021年6月15日
#define POWER_SUPPLY_ATTR(_name) \
{ \
.attr = { .name = #_name }, \
.show = power_supply_show_property, \
.store = power_supply_store_property, \
}
//!< 以 show函数为例 By: jixuan 2021年6月15日
static ssize_t power_supply_show_property(struct device *dev,
struct device_attribute *attr,
char *buf) {
static char *type_text[] = {
"Unknown", "Battery", "UPS", "Mains", "USB", "USB_DCP",
"USB_CDP", "USB_ACA", "USB_HVDCP", "USB_HVDCP_3", "USB_PD",
"Wireless", "USB_FLOAT", "BMS", "Parallel", "Main", "Wipower",
"TYPEC", "TYPEC_UFP", "TYPEC_DFP"
};
/*
这里以 type为例, 类似的解析还有:
status_text
charge_type
health_text
technology_text
scope_text
*/
struct power_supply *psy = dev_get_drvdata(dev);
const ptrdiff_t off = attr - power_supply_attrs;
power_supply_get_property(psy, off, &value);
//!< 核心函数调用,通过driver中注册的回调,获取当前powersupply的具体属性 By: jixuan 2021年6月15日
else if (off == POWER_SUPPLY_PROP_TYPE ||
off == POWER_SUPPLY_PROP_REAL_TYPE)
return scnprintf(buf, PAGE_SIZE, "%s\n",
type_text[value.intval]);
//!< 以type为例,通过回调获取到返回的 num号,对应到上面定义的type类型的字符串 By: jixuan 2021年6月15日
//!< 这里显然需要 确保 枚举的type种类和 上面定义的字符串顺序要一一对应 By: jixuan 2021年6月15日 、
//!< 其他属性 和 type的解析类似 By: jixuan 2021年6月15日
}
所有的属性如下图这些,实际在驱动的解析过程中,会根据注册的powersupply有的存在的属性去设置其可见性,通过统一的show shore方法读写;
在sysfs中uevent的处理
int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct power_supply *psy = dev_get_drvdata(dev);
int ret = 0, j;
char *prop_buf;
char *attrname;
dev_dbg(dev, "uevent\n");
dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->desc->name);
ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->desc->name);
prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
for (j = 0; j < psy->desc->num_properties; j++) {
struct device_attribute *attr;
char *line;
attr = &power_supply_attrs[psy->desc->properties[j]];
ret = power_supply_show_property(dev, attr, prop_buf);
//!< 主动调用show property将获取的属性值转换为对应的字符串 By: jixuan 2021年6月15日
line = strchr(prop_buf, '\n');
attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
//!< 添加uevent By: jixuan 2021年6月15日
}
return ret;
}
例如 barttery 类powersupply 通过uevent上报的信息