Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ab8500: Add devicetree support for btemp

This patch adds device tree support for battery-temperature-monitor driver

Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>

authored by

Rajanikanth H.V and committed by
Anton Vorontsov
bd9e8ab2 e0f1abeb

+73 -36
+6
Documentation/devicetree/bindings/mfd/ab8500.txt
··· 30 30 : LOW_BAT_F : : LOW threshold battery voltage 31 31 : CC_INT_CALIB : : Coulomb Counter Internal Calibration 32 32 : CCEOC : : Coulomb Counter End of Conversion 33 + ab8500-btemp : : vtvout : Battery Temperature 34 + : BAT_CTRL_INDB : : Battery Removal Indicator 35 + : BTEMP_LOW : : Btemp < BtempLow, if battery temperature is lower than -10°C 36 + : BTEMP_LOW_MEDIUM : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C 37 + : BTEMP_MEDIUM_HIGH : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and“MaxTemp 38 + : BTEMP_HIGH : : Btemp > BtempHigh, if battery temperature is higher than “MaxTemp 33 39 ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter 34 40 SW_CONV_END : : 35 41 ab8500-gpio : : : GPIO Controller
+16
Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
··· 1 + === AB8500 Battery Temperature Monitor Driver === 2 + 3 + The properties below describes the node for btemp driver. 4 + 5 + Required Properties: 6 + - compatible = Shall be: "stericsson,ab8500-btemp" 7 + - battery = Shall be battery specific information 8 + 9 + Example: 10 + ab8500_btemp { 11 + compatible = "stericsson,ab8500-btemp"; 12 + battery = <&ab8500_battery>; 13 + }; 14 + 15 + For information on battery specific node, Ref: 16 + Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
+5
arch/arm/boot/dts/dbx5x0.dtsi
··· 362 362 battery = <&ab8500_battery>; 363 363 }; 364 364 365 + ab8500_btemp { 366 + compatible = "stericsson,ab8500-btemp"; 367 + battery = <&ab8500_battery>; 368 + }; 369 + 365 370 ab8500_usb { 366 371 compatible = "stericsson,ab8500-usb"; 367 372 interrupts = < 90 0x4
+5
drivers/mfd/ab8500-core.c
··· 1046 1046 }, 1047 1047 { 1048 1048 .name = "ab8500-btemp", 1049 + .of_compatible = "stericsson,ab8500-btemp", 1049 1050 .num_resources = ARRAY_SIZE(ab8500_btemp_resources), 1050 1051 .resources = ab8500_btemp_resources, 1052 + #ifndef CONFIG_OF 1053 + .platform_data = &ab8500_bm_data, 1054 + .pdata_size = sizeof(ab8500_bm_data), 1055 + #endif 1051 1056 }, 1052 1057 { 1053 1058 .name = "ab8500-fg",
-6
drivers/power/Kconfig
··· 346 346 help 347 347 Say Y to include support for AB8500 battery management. 348 348 349 - config AB8500_BATTERY_THERM_ON_BATCTRL 350 - bool "Thermistor connected on BATCTRL ADC" 351 - depends on AB8500_BM 352 - help 353 - Say Y to enable battery temperature measurements using 354 - thermistor connected on BATCTRL ADC. 355 349 endif # POWER_SUPPLY 356 350 357 351 source "drivers/power/avs/Kconfig"
+2 -2
drivers/power/ab8500_bmdata.c
··· 30 30 }; 31 31 32 32 static struct abx500_res_to_temp temp_tbl_B_thermistor[] = { 33 - {-5, 165418}, 33 + {-5, 200000}, 34 34 { 0, 159024}, 35 35 { 5, 151921}, 36 36 {10, 144300}, ··· 240 240 }, 241 241 { 242 242 .name = POWER_SUPPLY_TECHNOLOGY_LIPO, 243 - .resis_high = 165418, 243 + .resis_high = 200000, 244 244 .resis_low = 82869, 245 245 .battery_resistance = 300, 246 246 .charge_full_design = 900,
+39 -28
drivers/power/ab8500_btemp.c
··· 20 20 #include <linux/power_supply.h> 21 21 #include <linux/completion.h> 22 22 #include <linux/workqueue.h> 23 - #include <linux/mfd/abx500/ab8500.h> 23 + #include <linux/jiffies.h> 24 + #include <linux/of.h> 25 + #include <linux/mfd/core.h> 24 26 #include <linux/mfd/abx500.h> 27 + #include <linux/mfd/abx500/ab8500.h> 25 28 #include <linux/mfd/abx500/ab8500-bm.h> 26 29 #include <linux/mfd/abx500/ab8500-gpadc.h> 27 - #include <linux/jiffies.h> 28 30 29 31 #define VTVOUT_V 1800 30 32 ··· 78 76 * @parent: Pointer to the struct ab8500 79 77 * @gpadc: Pointer to the struct gpadc 80 78 * @fg: Pointer to the struct fg 81 - * @pdata: Pointer to the abx500_btemp platform data 82 79 * @bat: Pointer to the abx500_bm platform data 83 80 * @btemp_psy: Structure for BTEMP specific battery properties 84 81 * @events: Structure for information about events triggered ··· 94 93 struct ab8500 *parent; 95 94 struct ab8500_gpadc *gpadc; 96 95 struct ab8500_fg *fg; 97 - struct abx500_bmdevs_plat_data *pdata; 98 96 struct abx500_bm_data *bat; 99 97 struct power_supply btemp_psy; 100 98 struct ab8500_btemp_events events; ··· 955 955 flush_scheduled_work(); 956 956 power_supply_unregister(&di->btemp_psy); 957 957 platform_set_drvdata(pdev, NULL); 958 - kfree(di); 959 958 960 959 return 0; 961 960 } 962 961 962 + static char *supply_interface[] = { 963 + "ab8500_chargalg", 964 + "ab8500_fg", 965 + }; 966 + 963 967 static int __devinit ab8500_btemp_probe(struct platform_device *pdev) 964 968 { 965 - struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data; 969 + struct device_node *np = pdev->dev.of_node; 966 970 struct ab8500_btemp *di; 967 971 int irq, i, ret = 0; 968 972 u8 val; 969 973 970 - if (!plat_data) { 971 - dev_err(&pdev->dev, "No platform data\n"); 972 - return -EINVAL; 973 - } 974 - 975 - di = kzalloc(sizeof(*di), GFP_KERNEL); 976 - if (!di) 974 + di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); 975 + if (!di) { 976 + dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__); 977 977 return -ENOMEM; 978 + } 979 + di->bat = pdev->mfd_cell->platform_data; 980 + if (!di->bat) { 981 + if (np) { 982 + ret = bmdevs_of_probe(&pdev->dev, np, &di->bat); 983 + if (ret) { 984 + dev_err(&pdev->dev, 985 + "failed to get battery information\n"); 986 + return ret; 987 + } 988 + } else { 989 + dev_err(&pdev->dev, "missing dt node for ab8500_btemp\n"); 990 + return -EINVAL; 991 + } 992 + } else { 993 + dev_info(&pdev->dev, "falling back to legacy platform data\n"); 994 + } 978 995 979 996 /* get parent data */ 980 997 di->dev = &pdev->dev; 981 998 di->parent = dev_get_drvdata(pdev->dev.parent); 982 999 di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 983 - 984 - /* get btemp specific platform data */ 985 - di->pdata = plat_data; 986 - if (!di->pdata) { 987 - dev_err(di->dev, "no btemp platform data supplied\n"); 988 - ret = -EINVAL; 989 - goto free_device_info; 990 - } 991 1000 992 1001 /* BTEMP supply */ 993 1002 di->btemp_psy.name = "ab8500_btemp"; ··· 1004 995 di->btemp_psy.properties = ab8500_btemp_props; 1005 996 di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props); 1006 997 di->btemp_psy.get_property = ab8500_btemp_get_property; 1007 - di->btemp_psy.supplied_to = di->pdata->supplied_to; 1008 - di->btemp_psy.num_supplicants = di->pdata->num_supplicants; 998 + di->btemp_psy.supplied_to = supply_interface; 999 + di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface); 1009 1000 di->btemp_psy.external_power_changed = 1010 1001 ab8500_btemp_external_power_changed; 1011 1002 ··· 1015 1006 create_singlethread_workqueue("ab8500_btemp_wq"); 1016 1007 if (di->btemp_wq == NULL) { 1017 1008 dev_err(di->dev, "failed to create work queue\n"); 1018 - ret = -ENOMEM; 1019 - goto free_device_info; 1009 + return -ENOMEM; 1020 1010 } 1021 1011 1022 1012 /* Init work for measuring temperature periodically */ ··· 1093 1085 } 1094 1086 free_btemp_wq: 1095 1087 destroy_workqueue(di->btemp_wq); 1096 - free_device_info: 1097 - kfree(di); 1098 - 1099 1088 return ret; 1100 1089 } 1090 + 1091 + static const struct of_device_id ab8500_btemp_match[] = { 1092 + { .compatible = "stericsson,ab8500-btemp", }, 1093 + { }, 1094 + }; 1101 1095 1102 1096 static struct platform_driver ab8500_btemp_driver = { 1103 1097 .probe = ab8500_btemp_probe, ··· 1109 1099 .driver = { 1110 1100 .name = "ab8500-btemp", 1111 1101 .owner = THIS_MODULE, 1102 + .of_match_table = ab8500_btemp_match, 1112 1103 }, 1113 1104 }; 1114 1105