这里介绍power_supply_register注册的几个结构体
/kernel-4.14/include/linux/power_supply.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/* Description of power supply */ struct power_supply_desc { const char *name; enum power_supply_type type; enum power_supply_property *properties; size_t num_properties; /* * Functions for drivers implementing power supply class. * These shouldn't be called directly by other drivers for accessing * this power supply. Instead use power_supply_*() functions (for * example power_supply_get_property()). */ int (*get_property)(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val); int (*set_property)(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val); /* * property_is_writeable() will be called during registration * of power supply. If this happens during device probe then it must * not access internal data of device (because probe did not end). */ int (*property_is_writeable)(struct power_supply *psy, enum power_supply_property psp); void (*external_power_changed)(struct power_supply *psy); void (*set_charged)(struct power_supply *psy); /* * Set if thermal zone should not be created for this power supply. * For example for virtual supplies forwarding calls to actual * sensors or other supplies. */ bool no_thermal; /* For APM emulation, think legacy userspace. */ int use_for_apm; };
battery_common.c 以前的代码是这样的
1 2 3 4 5 6 7 8 9 10 11
/* ac_data initialization */ static struct ac_data ac_main = { .psd = { .name = "ac", .type = POWER_SUPPLY_TYPE_MAINS, .properties = ac_props, .num_properties = ARRAY_SIZE(ac_props), .get_property = ac_get_property, }, .AC_ONLINE = 0, };
/kernel-4.14/include/linux/power_supply.h
1 2 3 4 5 6 7 8 9
/* Run-time specific power supply configuration */ struct power_supply_config { struct device_node *of_node; /* Driver private data */ void *drv_data; char **supplied_to; size_t num_supplicants; };
/kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* Power Supply */ //现在相当于struct usb_data、struct ac_data合并在一起 struct mt_charger { struct device *dev; struct power_supply_desc chg_desc; //power_supply相关属性、函数 struct power_supply_config chg_cfg; //GM3.0新增的结构体,成员drv_data用来保存mt_charger指针 struct power_supply *chg_psy; //power_supply_register注册后返回值,上报用 struct power_supply_desc ac_desc; struct power_supply_config ac_cfg; struct power_supply *ac_psy; struct power_supply_desc usb_desc; struct power_supply_config usb_cfg; struct power_supply *usb_psy; struct chg_type_info *cti; #ifdef CONFIG_EXTCON_USB_CHG struct usb_extcon_info *extcon_info; struct delayed_work extcon_work; #endif bool chg_online; /* Has charger in or not */ enum charger_type chg_type; };
/kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
static int mt_charger_probe(struct platform_device *pdev) { int ret = 0; struct chg_type_info *cti = NULL; struct mt_charger *mt_chg = NULL; #ifdef CONFIG_EXTCON_USB_CHG struct usb_extcon_info *info; #endif pr_info("%s\n", __func__); mt_chg = devm_kzalloc(&pdev->dev, sizeof(*mt_chg), GFP_KERNEL); if (!mt_chg) return -ENOMEM; mt_chg->dev = &pdev->dev; mt_chg->chg_online = false; mt_chg->chg_type = CHARGER_UNKNOWN; mt_chg->chg_desc.name = "charger"; //这是GM3.0新增的 mt_chg->chg_desc.type = POWER_SUPPLY_TYPE_UNKNOWN ; mt_chg->chg_desc.properties = mt_charger_properties; mt_chg->chg_desc.num_properties = ARRAY_SIZE(mt_charger_properties); mt_chg->chg_desc.set_property = mt_charger_set_property; mt_chg->chg_desc.get_property = mt_charger_get_property; mt_chg->chg_cfg.drv_data = mt_chg; mt_chg->ac_desc.name = "ac"; //相当于以前battery_common.c的static struct ac_data ac_main mt_chg->ac_desc.type = POWER_SUPPLY_TYPE_MAINS ; mt_chg->ac_desc.properties = mt_ac_properties; mt_chg->ac_desc.num_properties = ARRAY_SIZE(mt_ac_properties); mt_chg->ac_desc.get_property = mt_ac_get_property; mt_chg->ac_cfg.drv_data = mt_chg; mt_chg->usb_desc.name = "usb"; //相当于以前battery_common.c的static struct usb_data usb_main mt_chg->usb_desc.type = POWER_SUPPLY_TYPE_USB ; mt_chg->usb_desc.properties = mt_usb_properties; mt_chg->usb_desc.num_properties = ARRAY_SIZE(mt_usb_properties); mt_chg->usb_desc.get_property = mt_usb_get_property; mt_chg->usb_cfg.drv_data = mt_chg; mt_chg->chg_psy = power_supply_register(&pdev->dev, &mt_chg->chg_desc, &mt_chg->chg_cfg); if (IS_ERR(mt_chg->chg_psy)) { dev_notice(&pdev->dev, "Failed to register power supply: %ld\n", PTR_ERR(mt_chg->chg_psy)); ret = PTR_ERR(mt_chg->chg_psy); return ret; } mt_chg->ac_psy = power_supply_register(&pdev->dev, &mt_chg->ac_desc, &mt_chg->ac_cfg); if (IS_ERR(mt_chg->ac_psy)) { dev_notice(&pdev->dev, "Failed to register power supply: %ld\n", PTR_ERR(mt_chg->ac_psy)); ret = PTR_ERR(mt_chg->ac_psy); goto err_ac_psy; } mt_chg->usb_psy = power_supply_register(&pdev->dev, &mt_chg->usb_desc, &mt_chg->usb_cfg); if (IS_ERR(mt_chg->usb_psy)) { dev_notice(&pdev->dev, "Failed to register power supply: %ld\n", PTR_ERR(mt_chg->usb_psy)); ret = PTR_ERR(mt_chg->usb_psy); goto err_usb_psy; } ... }
===============================================================
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_internal.h
1 2 3 4 5 6 7 8 9 10 11 12
struct battery_data { struct power_supply_desc psd; struct power_supply *psy; int BAT_STATUS; int BAT_HEALTH; int BAT_PRESENT; int BAT_TECHNOLOGY; int BAT_CAPACITY; /* Add for Battery Service */ int BAT_batt_vol; int BAT_batt_temp; };
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* battery_data initialization */ struct battery_data battery_main = { .psd = { .name = "battery", //相当于以前battery_common.c的struct battery_data battery_main .type = POWER_SUPPLY_TYPE_BATTERY , .properties = battery_props, .num_properties = ARRAY_SIZE(battery_props), .get_property = battery_get_property, }, .BAT_STATUS = POWER_SUPPLY_STATUS_DISCHARGING, .BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD, .BAT_PRESENT = 1, .BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION, .BAT_CAPACITY = -1, .BAT_batt_vol = 0, .BAT_batt_temp = 0, };
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
static int __init battery_probe(struct platform_device *dev) { ... /* Power supply class */ #if !defined(CONFIG_MTK_DISABLE_GAUGE) battery_main.psy = power_supply_register(&(dev->dev), &battery_main.psd, NULL); if (IS_ERR(battery_main.psy)) { bm_err("[BAT_probe] power_supply_register Battery Fail !!\n"); ret = PTR_ERR(battery_main.psy); return ret; } bm_err("[BAT_probe] power_supply_register Battery Success !!\n"); #endif ... }
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#ifdef CONFIG_OF static const struct of_device_id mtk_bat_of_match[] = { {.compatible = "mediatek,bat_gm30",}, {}, }; MODULE_DEVICE_TABLE(of, mtk_bat_of_match); #endif static struct platform_driver battery_driver_probe = { .probe = battery_probe, .remove = NULL, .shutdown = battery_shutdown, .suspend = battery_suspend, .resume = battery_resume, .driver = { .name = "battery", #ifdef CONFIG_OF .of_match_table = mtk_bat_of_match, #endif }, };