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

ab8500: Add devicetree support for fuelgauge

- This patch adds device tree support for fuelgauge driver
- optimize bm devices platform_data usage and of_probe(...)
Note: of_probe() routine for battery managed devices is made
common across all bm drivers.
- test status:
- interrupt numbers assigned differs between legacy and FDT mode.

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
e0f1abeb e9f14c18

+668 -97
+6 -1
Documentation/devicetree/bindings/mfd/ab8500.txt
··· 24 24 ab8500-btemp : : : Battery Temperature 25 25 ab8500-charger : : : Battery Charger 26 26 ab8500-codec : : : Audio Codec 27 - ab8500-fg : : : Fuel Gauge 27 + ab8500-fg : : vddadc : Fuel Gauge 28 + : NCONV_ACCU : : Accumulate N Sample Conversion 29 + : BATT_OVV : : Battery Over Voltage 30 + : LOW_BAT_F : : LOW threshold battery voltage 31 + : CC_INT_CALIB : : Coulomb Counter Internal Calibration 32 + : CCEOC : : Coulomb Counter End of Conversion 28 33 ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter 29 34 SW_CONV_END : : 30 35 ab8500-gpio : : : GPIO Controller
+58
Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
··· 1 + === AB8500 Fuel Gauge Driver === 2 + 3 + AB8500 is a mixed signal multimedia and power management 4 + device comprising: power and energy-management-module, 5 + wall-charger, usb-charger, audio codec, general purpose adc, 6 + tvout, clock management and sim card interface. 7 + 8 + Fuelgauge support is part of energy-management-modules, other 9 + components of this module are: 10 + main-charger, usb-combo-charger and battery-temperature-monitoring. 11 + 12 + The properties below describes the node for fuelgauge driver. 13 + 14 + Required Properties: 15 + - compatible = This shall be: "stericsson,ab8500-fg" 16 + - battery = Shall be battery specific information 17 + Example: 18 + ab8500_fg { 19 + compatible = "stericsson,ab8500-fg"; 20 + battery = <&ab8500_battery>; 21 + }; 22 + 23 + dependent node: 24 + ab8500_battery: ab8500_battery { 25 + }; 26 + This node will provide information on 'thermistor interface' and 27 + 'battery technology type' used. 28 + 29 + Properties of this node are: 30 + thermistor-on-batctrl: 31 + A boolean value indicating thermistor interface to battery 32 + 33 + Note: 34 + 'btemp' and 'batctrl' are the pins interfaced for battery temperature 35 + measurement, 'btemp' signal is used when NTC(negative temperature 36 + coefficient) resister is interfaced external to battery whereas 37 + 'batctrl' pin is used when NTC resister is internal to battery. 38 + 39 + Example: 40 + ab8500_battery: ab8500_battery { 41 + thermistor-on-batctrl; 42 + }; 43 + indicates: NTC resister is internal to battery, 'batctrl' is used 44 + for thermal measurement. 45 + 46 + The absence of property 'thermal-on-batctrl' indicates 47 + NTC resister is external to battery and 'btemp' signal is used 48 + for thermal measurement. 49 + 50 + battery-type: 51 + This shall be the battery manufacturing technology type, 52 + allowed types are: 53 + "UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn" 54 + Example: 55 + ab8500_battery: ab8500_battery { 56 + stericsson,battery-type = "LIPO"; 57 + } 58 +
+11 -1
arch/arm/boot/dts/dbx5x0.dtsi
··· 352 352 vddadc-supply = <&ab8500_ldo_tvout_reg>; 353 353 }; 354 354 355 - ab8500-usb { 355 + ab8500_battery: ab8500_battery { 356 + stericsson,battery-type = "LIPO"; 357 + thermistor-on-batctrl; 358 + }; 359 + 360 + ab8500_fg { 361 + compatible = "stericsson,ab8500-fg"; 362 + battery = <&ab8500_battery>; 363 + }; 364 + 365 + ab8500_usb { 356 366 compatible = "stericsson,ab8500-usb"; 357 367 interrupts = < 90 0x4 358 368 96 0x4
+5
drivers/mfd/ab8500-core.c
··· 1051 1051 }, 1052 1052 { 1053 1053 .name = "ab8500-fg", 1054 + .of_compatible = "stericsson,ab8500-fg", 1054 1055 .num_resources = ARRAY_SIZE(ab8500_fg_resources), 1055 1056 .resources = ab8500_fg_resources, 1057 + #ifndef CONFIG_OF 1058 + .platform_data = &ab8500_bm_data, 1059 + .pdata_size = sizeof(ab8500_bm_data), 1060 + #endif 1056 1061 }, 1057 1062 { 1058 1063 .name = "ab8500-chargalg",
+1 -1
drivers/power/Makefile
··· 38 38 obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o 39 39 obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o 40 40 obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o 41 - obj-$(CONFIG_AB8500_BM) += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o 41 + obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o 42 42 obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o 43 43 obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o 44 44 obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
+521
drivers/power/ab8500_bmdata.c
··· 1 + #include <linux/export.h> 2 + #include <linux/power_supply.h> 3 + #include <linux/of.h> 4 + #include <linux/mfd/abx500.h> 5 + #include <linux/mfd/abx500/ab8500.h> 6 + #include <linux/mfd/abx500/ab8500-bm.h> 7 + 8 + /* 9 + * These are the defined batteries that uses a NTC and ID resistor placed 10 + * inside of the battery pack. 11 + * Note that the res_to_temp table must be strictly sorted by falling resistance 12 + * values to work. 13 + */ 14 + static struct abx500_res_to_temp temp_tbl_A_thermistor[] = { 15 + {-5, 53407}, 16 + { 0, 48594}, 17 + { 5, 43804}, 18 + {10, 39188}, 19 + {15, 34870}, 20 + {20, 30933}, 21 + {25, 27422}, 22 + {30, 24347}, 23 + {35, 21694}, 24 + {40, 19431}, 25 + {45, 17517}, 26 + {50, 15908}, 27 + {55, 14561}, 28 + {60, 13437}, 29 + {65, 12500}, 30 + }; 31 + 32 + static struct abx500_res_to_temp temp_tbl_B_thermistor[] = { 33 + {-5, 165418}, 34 + { 0, 159024}, 35 + { 5, 151921}, 36 + {10, 144300}, 37 + {15, 136424}, 38 + {20, 128565}, 39 + {25, 120978}, 40 + {30, 113875}, 41 + {35, 107397}, 42 + {40, 101629}, 43 + {45, 96592}, 44 + {50, 92253}, 45 + {55, 88569}, 46 + {60, 85461}, 47 + {65, 82869}, 48 + }; 49 + 50 + static struct abx500_v_to_cap cap_tbl_A_thermistor[] = { 51 + {4171, 100}, 52 + {4114, 95}, 53 + {4009, 83}, 54 + {3947, 74}, 55 + {3907, 67}, 56 + {3863, 59}, 57 + {3830, 56}, 58 + {3813, 53}, 59 + {3791, 46}, 60 + {3771, 33}, 61 + {3754, 25}, 62 + {3735, 20}, 63 + {3717, 17}, 64 + {3681, 13}, 65 + {3664, 8}, 66 + {3651, 6}, 67 + {3635, 5}, 68 + {3560, 3}, 69 + {3408, 1}, 70 + {3247, 0}, 71 + }; 72 + 73 + static struct abx500_v_to_cap cap_tbl_B_thermistor[] = { 74 + {4161, 100}, 75 + {4124, 98}, 76 + {4044, 90}, 77 + {4003, 85}, 78 + {3966, 80}, 79 + {3933, 75}, 80 + {3888, 67}, 81 + {3849, 60}, 82 + {3813, 55}, 83 + {3787, 47}, 84 + {3772, 30}, 85 + {3751, 25}, 86 + {3718, 20}, 87 + {3681, 16}, 88 + {3660, 14}, 89 + {3589, 10}, 90 + {3546, 7}, 91 + {3495, 4}, 92 + {3404, 2}, 93 + {3250, 0}, 94 + }; 95 + 96 + static struct abx500_v_to_cap cap_tbl[] = { 97 + {4186, 100}, 98 + {4163, 99}, 99 + {4114, 95}, 100 + {4068, 90}, 101 + {3990, 80}, 102 + {3926, 70}, 103 + {3898, 65}, 104 + {3866, 60}, 105 + {3833, 55}, 106 + {3812, 50}, 107 + {3787, 40}, 108 + {3768, 30}, 109 + {3747, 25}, 110 + {3730, 20}, 111 + {3705, 15}, 112 + {3699, 14}, 113 + {3684, 12}, 114 + {3672, 9}, 115 + {3657, 7}, 116 + {3638, 6}, 117 + {3556, 4}, 118 + {3424, 2}, 119 + {3317, 1}, 120 + {3094, 0}, 121 + }; 122 + 123 + /* 124 + * Note that the res_to_temp table must be strictly sorted by falling 125 + * resistance values to work. 126 + */ 127 + static struct abx500_res_to_temp temp_tbl[] = { 128 + {-5, 214834}, 129 + { 0, 162943}, 130 + { 5, 124820}, 131 + {10, 96520}, 132 + {15, 75306}, 133 + {20, 59254}, 134 + {25, 47000}, 135 + {30, 37566}, 136 + {35, 30245}, 137 + {40, 24520}, 138 + {45, 20010}, 139 + {50, 16432}, 140 + {55, 13576}, 141 + {60, 11280}, 142 + {65, 9425}, 143 + }; 144 + 145 + /* 146 + * Note that the batres_vs_temp table must be strictly sorted by falling 147 + * temperature values to work. 148 + */ 149 + static struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { 150 + { 40, 120}, 151 + { 30, 135}, 152 + { 20, 165}, 153 + { 10, 230}, 154 + { 00, 325}, 155 + {-10, 445}, 156 + {-20, 595}, 157 + }; 158 + 159 + /* 160 + * Note that the batres_vs_temp table must be strictly sorted by falling 161 + * temperature values to work. 162 + */ 163 + static struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = { 164 + { 60, 300}, 165 + { 30, 300}, 166 + { 20, 300}, 167 + { 10, 300}, 168 + { 00, 300}, 169 + {-10, 300}, 170 + {-20, 300}, 171 + }; 172 + 173 + /* battery resistance table for LI ION 9100 battery */ 174 + static struct batres_vs_temp temp_to_batres_tbl_9100[] = { 175 + { 60, 180}, 176 + { 30, 180}, 177 + { 20, 180}, 178 + { 10, 180}, 179 + { 00, 180}, 180 + {-10, 180}, 181 + {-20, 180}, 182 + }; 183 + 184 + static struct abx500_battery_type bat_type_thermistor[] = { 185 + [BATTERY_UNKNOWN] = { 186 + /* First element always represent the UNKNOWN battery */ 187 + .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, 188 + .resis_high = 0, 189 + .resis_low = 0, 190 + .battery_resistance = 300, 191 + .charge_full_design = 612, 192 + .nominal_voltage = 3700, 193 + .termination_vol = 4050, 194 + .termination_curr = 200, 195 + .recharge_vol = 3990, 196 + .normal_cur_lvl = 400, 197 + .normal_vol_lvl = 4100, 198 + .maint_a_cur_lvl = 400, 199 + .maint_a_vol_lvl = 4050, 200 + .maint_a_chg_timer_h = 60, 201 + .maint_b_cur_lvl = 400, 202 + .maint_b_vol_lvl = 4000, 203 + .maint_b_chg_timer_h = 200, 204 + .low_high_cur_lvl = 300, 205 + .low_high_vol_lvl = 4000, 206 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), 207 + .r_to_t_tbl = temp_tbl, 208 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), 209 + .v_to_cap_tbl = cap_tbl, 210 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 211 + .batres_tbl = temp_to_batres_tbl_thermistor, 212 + }, 213 + { 214 + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, 215 + .resis_high = 53407, 216 + .resis_low = 12500, 217 + .battery_resistance = 300, 218 + .charge_full_design = 900, 219 + .nominal_voltage = 3600, 220 + .termination_vol = 4150, 221 + .termination_curr = 80, 222 + .recharge_vol = 4130, 223 + .normal_cur_lvl = 700, 224 + .normal_vol_lvl = 4200, 225 + .maint_a_cur_lvl = 600, 226 + .maint_a_vol_lvl = 4150, 227 + .maint_a_chg_timer_h = 60, 228 + .maint_b_cur_lvl = 600, 229 + .maint_b_vol_lvl = 4100, 230 + .maint_b_chg_timer_h = 200, 231 + .low_high_cur_lvl = 300, 232 + .low_high_vol_lvl = 4000, 233 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A_thermistor), 234 + .r_to_t_tbl = temp_tbl_A_thermistor, 235 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A_thermistor), 236 + .v_to_cap_tbl = cap_tbl_A_thermistor, 237 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 238 + .batres_tbl = temp_to_batres_tbl_thermistor, 239 + 240 + }, 241 + { 242 + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, 243 + .resis_high = 165418, 244 + .resis_low = 82869, 245 + .battery_resistance = 300, 246 + .charge_full_design = 900, 247 + .nominal_voltage = 3600, 248 + .termination_vol = 4150, 249 + .termination_curr = 80, 250 + .recharge_vol = 4130, 251 + .normal_cur_lvl = 700, 252 + .normal_vol_lvl = 4200, 253 + .maint_a_cur_lvl = 600, 254 + .maint_a_vol_lvl = 4150, 255 + .maint_a_chg_timer_h = 60, 256 + .maint_b_cur_lvl = 600, 257 + .maint_b_vol_lvl = 4100, 258 + .maint_b_chg_timer_h = 200, 259 + .low_high_cur_lvl = 300, 260 + .low_high_vol_lvl = 4000, 261 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B_thermistor), 262 + .r_to_t_tbl = temp_tbl_B_thermistor, 263 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B_thermistor), 264 + .v_to_cap_tbl = cap_tbl_B_thermistor, 265 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 266 + .batres_tbl = temp_to_batres_tbl_thermistor, 267 + }, 268 + }; 269 + 270 + static struct abx500_battery_type bat_type_ext_thermistor[] = { 271 + [BATTERY_UNKNOWN] = { 272 + /* First element always represent the UNKNOWN battery */ 273 + .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, 274 + .resis_high = 0, 275 + .resis_low = 0, 276 + .battery_resistance = 300, 277 + .charge_full_design = 612, 278 + .nominal_voltage = 3700, 279 + .termination_vol = 4050, 280 + .termination_curr = 200, 281 + .recharge_vol = 3990, 282 + .normal_cur_lvl = 400, 283 + .normal_vol_lvl = 4100, 284 + .maint_a_cur_lvl = 400, 285 + .maint_a_vol_lvl = 4050, 286 + .maint_a_chg_timer_h = 60, 287 + .maint_b_cur_lvl = 400, 288 + .maint_b_vol_lvl = 4000, 289 + .maint_b_chg_timer_h = 200, 290 + .low_high_cur_lvl = 300, 291 + .low_high_vol_lvl = 4000, 292 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), 293 + .r_to_t_tbl = temp_tbl, 294 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), 295 + .v_to_cap_tbl = cap_tbl, 296 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 297 + .batres_tbl = temp_to_batres_tbl_thermistor, 298 + }, 299 + /* 300 + * These are the batteries that doesn't have an internal NTC resistor to measure 301 + * its temperature. The temperature in this case is measure with a NTC placed 302 + * near the battery but on the PCB. 303 + */ 304 + { 305 + .name = POWER_SUPPLY_TECHNOLOGY_LIPO, 306 + .resis_high = 76000, 307 + .resis_low = 53000, 308 + .battery_resistance = 300, 309 + .charge_full_design = 900, 310 + .nominal_voltage = 3700, 311 + .termination_vol = 4150, 312 + .termination_curr = 100, 313 + .recharge_vol = 4130, 314 + .normal_cur_lvl = 700, 315 + .normal_vol_lvl = 4200, 316 + .maint_a_cur_lvl = 600, 317 + .maint_a_vol_lvl = 4150, 318 + .maint_a_chg_timer_h = 60, 319 + .maint_b_cur_lvl = 600, 320 + .maint_b_vol_lvl = 4100, 321 + .maint_b_chg_timer_h = 200, 322 + .low_high_cur_lvl = 300, 323 + .low_high_vol_lvl = 4000, 324 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), 325 + .r_to_t_tbl = temp_tbl, 326 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), 327 + .v_to_cap_tbl = cap_tbl, 328 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 329 + .batres_tbl = temp_to_batres_tbl_thermistor, 330 + }, 331 + { 332 + .name = POWER_SUPPLY_TECHNOLOGY_LION, 333 + .resis_high = 30000, 334 + .resis_low = 10000, 335 + .battery_resistance = 300, 336 + .charge_full_design = 950, 337 + .nominal_voltage = 3700, 338 + .termination_vol = 4150, 339 + .termination_curr = 100, 340 + .recharge_vol = 4130, 341 + .normal_cur_lvl = 700, 342 + .normal_vol_lvl = 4200, 343 + .maint_a_cur_lvl = 600, 344 + .maint_a_vol_lvl = 4150, 345 + .maint_a_chg_timer_h = 60, 346 + .maint_b_cur_lvl = 600, 347 + .maint_b_vol_lvl = 4100, 348 + .maint_b_chg_timer_h = 200, 349 + .low_high_cur_lvl = 300, 350 + .low_high_vol_lvl = 4000, 351 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), 352 + .r_to_t_tbl = temp_tbl, 353 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), 354 + .v_to_cap_tbl = cap_tbl, 355 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 356 + .batres_tbl = temp_to_batres_tbl_thermistor, 357 + }, 358 + { 359 + .name = POWER_SUPPLY_TECHNOLOGY_LION, 360 + .resis_high = 95000, 361 + .resis_low = 76001, 362 + .battery_resistance = 300, 363 + .charge_full_design = 950, 364 + .nominal_voltage = 3700, 365 + .termination_vol = 4150, 366 + .termination_curr = 100, 367 + .recharge_vol = 4130, 368 + .normal_cur_lvl = 700, 369 + .normal_vol_lvl = 4200, 370 + .maint_a_cur_lvl = 600, 371 + .maint_a_vol_lvl = 4150, 372 + .maint_a_chg_timer_h = 60, 373 + .maint_b_cur_lvl = 600, 374 + .maint_b_vol_lvl = 4100, 375 + .maint_b_chg_timer_h = 200, 376 + .low_high_cur_lvl = 300, 377 + .low_high_vol_lvl = 4000, 378 + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), 379 + .r_to_t_tbl = temp_tbl, 380 + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), 381 + .v_to_cap_tbl = cap_tbl, 382 + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), 383 + .batres_tbl = temp_to_batres_tbl_thermistor, 384 + }, 385 + }; 386 + 387 + static const struct abx500_bm_capacity_levels cap_levels = { 388 + .critical = 2, 389 + .low = 10, 390 + .normal = 70, 391 + .high = 95, 392 + .full = 100, 393 + }; 394 + 395 + static const struct abx500_fg_parameters fg = { 396 + .recovery_sleep_timer = 10, 397 + .recovery_total_time = 100, 398 + .init_timer = 1, 399 + .init_discard_time = 5, 400 + .init_total_time = 40, 401 + .high_curr_time = 60, 402 + .accu_charging = 30, 403 + .accu_high_curr = 30, 404 + .high_curr_threshold = 50, 405 + .lowbat_threshold = 3100, 406 + .battok_falling_th_sel0 = 2860, 407 + .battok_raising_th_sel1 = 2860, 408 + .user_cap_limit = 15, 409 + .maint_thres = 97, 410 + }; 411 + 412 + static const struct abx500_maxim_parameters maxi_params = { 413 + .ena_maxi = true, 414 + .chg_curr = 910, 415 + .wait_cycles = 10, 416 + .charger_curr_step = 100, 417 + }; 418 + 419 + static const struct abx500_bm_charger_parameters chg = { 420 + .usb_volt_max = 5500, 421 + .usb_curr_max = 1500, 422 + .ac_volt_max = 7500, 423 + .ac_curr_max = 1500, 424 + }; 425 + 426 + struct abx500_bm_data ab8500_bm_data = { 427 + .temp_under = 3, 428 + .temp_low = 8, 429 + .temp_high = 43, 430 + .temp_over = 48, 431 + .main_safety_tmr_h = 4, 432 + .temp_interval_chg = 20, 433 + .temp_interval_nochg = 120, 434 + .usb_safety_tmr_h = 4, 435 + .bkup_bat_v = BUP_VCH_SEL_2P6V, 436 + .bkup_bat_i = BUP_ICH_SEL_150UA, 437 + .no_maintenance = false, 438 + .adc_therm = ABx500_ADC_THERM_BATCTRL, 439 + .chg_unknown_bat = false, 440 + .enable_overshoot = false, 441 + .fg_res = 100, 442 + .cap_levels = &cap_levels, 443 + .bat_type = bat_type_thermistor, 444 + .n_btypes = 3, 445 + .batt_id = 0, 446 + .interval_charging = 5, 447 + .interval_not_charging = 120, 448 + .temp_hysteresis = 3, 449 + .gnd_lift_resistance = 34, 450 + .maxi = &maxi_params, 451 + .chg_params = &chg, 452 + .fg_params = &fg, 453 + }; 454 + 455 + int __devinit 456 + bmdevs_of_probe(struct device *dev, 457 + struct device_node *np, 458 + struct abx500_bm_data **battery) 459 + { 460 + struct abx500_battery_type *btype; 461 + struct device_node *np_bat_supply; 462 + struct abx500_bm_data *bat; 463 + const char *btech; 464 + char bat_tech[8]; 465 + int i, thermistor; 466 + 467 + *battery = &ab8500_bm_data; 468 + 469 + /* get phandle to 'battery-info' node */ 470 + np_bat_supply = of_parse_phandle(np, "battery", 0); 471 + if (!np_bat_supply) { 472 + dev_err(dev, "missing property battery\n"); 473 + return -EINVAL; 474 + } 475 + if (of_property_read_bool(np_bat_supply, 476 + "thermistor-on-batctrl")) 477 + thermistor = NTC_INTERNAL; 478 + else 479 + thermistor = NTC_EXTERNAL; 480 + 481 + bat = *battery; 482 + if (thermistor == NTC_EXTERNAL) { 483 + bat->n_btypes = 4; 484 + bat->bat_type = bat_type_ext_thermistor; 485 + bat->adc_therm = ABx500_ADC_THERM_BATTEMP; 486 + } 487 + btech = of_get_property(np_bat_supply, 488 + "stericsson,battery-type", NULL); 489 + if (!btech) { 490 + dev_warn(dev, "missing property battery-name/type\n"); 491 + strcpy(bat_tech, "UNKNOWN"); 492 + } else { 493 + strcpy(bat_tech, btech); 494 + } 495 + 496 + if (strncmp(bat_tech, "LION", 4) == 0) { 497 + bat->no_maintenance = true; 498 + bat->chg_unknown_bat = true; 499 + bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600; 500 + bat->bat_type[BATTERY_UNKNOWN].termination_vol = 4150; 501 + bat->bat_type[BATTERY_UNKNOWN].recharge_vol = 4130; 502 + bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520; 503 + bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200; 504 + } 505 + /* select the battery resolution table */ 506 + for (i = 0; i < bat->n_btypes; ++i) { 507 + btype = (bat->bat_type + i); 508 + if (thermistor == NTC_EXTERNAL) { 509 + btype->batres_tbl = 510 + temp_to_batres_tbl_ext_thermistor; 511 + } else if (strncmp(bat_tech, "LION", 4) == 0) { 512 + btype->batres_tbl = 513 + temp_to_batres_tbl_9100; 514 + } else { 515 + btype->batres_tbl = 516 + temp_to_batres_tbl_thermistor; 517 + } 518 + } 519 + of_node_put(np_bat_supply); 520 + return 0; 521 + }
+4 -12
drivers/power/ab8500_btemp.c
··· 93 93 struct ab8500 *parent; 94 94 struct ab8500_gpadc *gpadc; 95 95 struct ab8500_fg *fg; 96 - struct abx500_btemp_platform_data *pdata; 96 + struct abx500_bmdevs_plat_data *pdata; 97 97 struct abx500_bm_data *bat; 98 98 struct power_supply btemp_psy; 99 99 struct ab8500_btemp_events events; ··· 962 962 963 963 static int __devinit ab8500_btemp_probe(struct platform_device *pdev) 964 964 { 965 + struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data; 966 + struct ab8500_btemp *di; 965 967 int irq, i, ret = 0; 966 968 u8 val; 967 - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; 968 - struct ab8500_btemp *di; 969 969 970 970 if (!plat_data) { 971 971 dev_err(&pdev->dev, "No platform data\n"); ··· 982 982 di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 983 983 984 984 /* get btemp specific platform data */ 985 - di->pdata = plat_data->btemp; 985 + di->pdata = plat_data; 986 986 if (!di->pdata) { 987 987 dev_err(di->dev, "no btemp platform data supplied\n"); 988 - ret = -EINVAL; 989 - goto free_device_info; 990 - } 991 - 992 - /* get battery specific platform data */ 993 - di->bat = plat_data->battery; 994 - if (!di->bat) { 995 - dev_err(di->dev, "no battery platform data supplied\n"); 996 988 ret = -EINVAL; 997 989 goto free_device_info; 998 990 }
+4 -12
drivers/power/ab8500_charger.c
··· 220 220 bool autopower; 221 221 struct ab8500 *parent; 222 222 struct ab8500_gpadc *gpadc; 223 - struct abx500_charger_platform_data *pdata; 223 + struct abx500_bmdevs_plat_data *pdata; 224 224 struct abx500_bm_data *bat; 225 225 struct ab8500_charger_event_flags flags; 226 226 struct ab8500_charger_usb_state usb_state; ··· 2533 2533 2534 2534 static int __devinit ab8500_charger_probe(struct platform_device *pdev) 2535 2535 { 2536 - int irq, i, charger_status, ret = 0; 2537 - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; 2536 + struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data; 2538 2537 struct ab8500_charger *di; 2538 + int irq, i, charger_status, ret = 0; 2539 2539 2540 2540 if (!plat_data) { 2541 2541 dev_err(&pdev->dev, "No platform data\n"); ··· 2555 2555 spin_lock_init(&di->usb_state.usb_lock); 2556 2556 2557 2557 /* get charger specific platform data */ 2558 - di->pdata = plat_data->charger; 2558 + di->pdata = plat_data; 2559 2559 if (!di->pdata) { 2560 2560 dev_err(di->dev, "no charger platform data supplied\n"); 2561 - ret = -EINVAL; 2562 - goto free_device_info; 2563 - } 2564 - 2565 - /* get battery specific platform data */ 2566 - di->bat = plat_data->battery; 2567 - if (!di->bat) { 2568 - dev_err(di->dev, "no battery platform data supplied\n"); 2569 2561 ret = -EINVAL; 2570 2562 goto free_device_info; 2571 2563 }
+42 -40
drivers/power/ab8500_fg.c
··· 22 22 #include <linux/platform_device.h> 23 23 #include <linux/power_supply.h> 24 24 #include <linux/kobject.h> 25 - #include <linux/mfd/abx500/ab8500.h> 26 - #include <linux/mfd/abx500.h> 27 25 #include <linux/slab.h> 28 - #include <linux/mfd/abx500/ab8500-bm.h> 29 26 #include <linux/delay.h> 30 - #include <linux/mfd/abx500/ab8500-gpadc.h> 31 - #include <linux/mfd/abx500.h> 32 27 #include <linux/time.h> 28 + #include <linux/of.h> 33 29 #include <linux/completion.h> 30 + #include <linux/mfd/core.h> 31 + #include <linux/mfd/abx500.h> 32 + #include <linux/mfd/abx500/ab8500.h> 33 + #include <linux/mfd/abx500/ab8500-bm.h> 34 + #include <linux/mfd/abx500/ab8500-gpadc.h> 34 35 35 36 #define MILLI_TO_MICRO 1000 36 37 #define FG_LSB_IN_MA 1627 ··· 173 172 * @avg_cap: Average capacity filter 174 173 * @parent: Pointer to the struct ab8500 175 174 * @gpadc: Pointer to the struct gpadc 176 - * @pdata: Pointer to the abx500_fg platform data 177 175 * @bat: Pointer to the abx500_bm platform data 178 176 * @fg_psy: Structure that holds the FG specific battery properties 179 177 * @fg_wq: Work queue for running the FG algorithm ··· 212 212 struct ab8500_fg_avg_cap avg_cap; 213 213 struct ab8500 *parent; 214 214 struct ab8500_gpadc *gpadc; 215 - struct abx500_fg_platform_data *pdata; 216 215 struct abx500_bm_data *bat; 217 216 struct power_supply fg_psy; 218 217 struct workqueue_struct *fg_wq; ··· 2428 2429 flush_scheduled_work(); 2429 2430 power_supply_unregister(&di->fg_psy); 2430 2431 platform_set_drvdata(pdev, NULL); 2431 - kfree(di); 2432 2432 return ret; 2433 2433 } 2434 2434 ··· 2440 2442 {"CCEOC", ab8500_fg_cc_data_end_handler}, 2441 2443 }; 2442 2444 2445 + static char *supply_interface[] = { 2446 + "ab8500_chargalg", 2447 + "ab8500_usb", 2448 + }; 2449 + 2443 2450 static int __devinit ab8500_fg_probe(struct platform_device *pdev) 2444 2451 { 2452 + struct device_node *np = pdev->dev.of_node; 2453 + struct ab8500_fg *di; 2445 2454 int i, irq; 2446 2455 int ret = 0; 2447 - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; 2448 - struct ab8500_fg *di; 2449 2456 2450 - if (!plat_data) { 2451 - dev_err(&pdev->dev, "No platform data\n"); 2452 - return -EINVAL; 2453 - } 2454 - 2455 - di = kzalloc(sizeof(*di), GFP_KERNEL); 2456 - if (!di) 2457 + di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); 2458 + if (!di) { 2459 + dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__); 2457 2460 return -ENOMEM; 2461 + } 2462 + di->bat = pdev->mfd_cell->platform_data; 2463 + if (!di->bat) { 2464 + if (np) { 2465 + ret = bmdevs_of_probe(&pdev->dev, np, &di->bat); 2466 + if (ret) { 2467 + dev_err(&pdev->dev, 2468 + "failed to get battery information\n"); 2469 + return ret; 2470 + } 2471 + } else { 2472 + dev_err(&pdev->dev, "missing dt node for ab8500_fg\n"); 2473 + return -EINVAL; 2474 + } 2475 + } else { 2476 + dev_info(&pdev->dev, "falling back to legacy platform data\n"); 2477 + } 2458 2478 2459 2479 mutex_init(&di->cc_lock); 2460 2480 ··· 2481 2465 di->parent = dev_get_drvdata(pdev->dev.parent); 2482 2466 di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 2483 2467 2484 - /* get fg specific platform data */ 2485 - di->pdata = plat_data->fg; 2486 - if (!di->pdata) { 2487 - dev_err(di->dev, "no fg platform data supplied\n"); 2488 - ret = -EINVAL; 2489 - goto free_device_info; 2490 - } 2491 - 2492 - /* get battery specific platform data */ 2493 - di->bat = plat_data->battery; 2494 - if (!di->bat) { 2495 - dev_err(di->dev, "no battery platform data supplied\n"); 2496 - ret = -EINVAL; 2497 - goto free_device_info; 2498 - } 2499 - 2500 2468 di->fg_psy.name = "ab8500_fg"; 2501 2469 di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY; 2502 2470 di->fg_psy.properties = ab8500_fg_props; 2503 2471 di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props); 2504 2472 di->fg_psy.get_property = ab8500_fg_get_property; 2505 - di->fg_psy.supplied_to = di->pdata->supplied_to; 2506 - di->fg_psy.num_supplicants = di->pdata->num_supplicants; 2473 + di->fg_psy.supplied_to = supply_interface; 2474 + di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface), 2507 2475 di->fg_psy.external_power_changed = ab8500_fg_external_power_changed; 2508 2476 2509 2477 di->bat_cap.max_mah_design = MILLI_TO_MICRO * ··· 2506 2506 di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq"); 2507 2507 if (di->fg_wq == NULL) { 2508 2508 dev_err(di->dev, "failed to create work queue\n"); 2509 - ret = -ENOMEM; 2510 - goto free_device_info; 2509 + return -ENOMEM; 2511 2510 } 2512 2511 2513 2512 /* Init work for running the fg algorithm instantly */ ··· 2605 2606 } 2606 2607 free_inst_curr_wq: 2607 2608 destroy_workqueue(di->fg_wq); 2608 - free_device_info: 2609 - kfree(di); 2610 - 2611 2609 return ret; 2612 2610 } 2611 + 2612 + static const struct of_device_id ab8500_fg_match[] = { 2613 + { .compatible = "stericsson,ab8500-fg", }, 2614 + { }, 2615 + }; 2613 2616 2614 2617 static struct platform_driver ab8500_fg_driver = { 2615 2618 .probe = ab8500_fg_probe, ··· 2621 2620 .driver = { 2622 2621 .name = "ab8500-fg", 2623 2622 .owner = THIS_MODULE, 2623 + .of_match_table = ab8500_fg_match, 2624 2624 }, 2625 2625 }; 2626 2626
+3 -5
drivers/power/abx500_chargalg.c
··· 231 231 struct abx500_chargalg_charger_info chg_info; 232 232 struct abx500_chargalg_battery_data batt_data; 233 233 struct abx500_chargalg_suspension_status susp_status; 234 - struct abx500_chargalg_platform_data *pdata; 234 + struct abx500_bmdevs_plat_data *pdata; 235 235 struct abx500_bm_data *bat; 236 236 struct power_supply chargalg_psy; 237 237 struct ux500_charger *ac_chg; ··· 1802 1802 1803 1803 static int __devinit abx500_chargalg_probe(struct platform_device *pdev) 1804 1804 { 1805 - struct abx500_bm_plat_data *plat_data; 1805 + struct abx500_bmdevs_plat_data *plat_data; 1806 1806 int ret = 0; 1807 1807 1808 1808 struct abx500_chargalg *di = ··· 1812 1812 1813 1813 /* get device struct */ 1814 1814 di->dev = &pdev->dev; 1815 - 1816 1815 plat_data = pdev->dev.platform_data; 1817 - di->pdata = plat_data->chargalg; 1818 - di->bat = plat_data->battery; 1816 + di->pdata = plat_data; 1819 1817 1820 1818 /* chargalg supply */ 1821 1819 di->chargalg_psy.name = "abx500_chargalg";
+13 -25
include/linux/mfd/abx500.h
··· 267 267 int gnd_lift_resistance; 268 268 const struct abx500_maxim_parameters *maxi; 269 269 const struct abx500_bm_capacity_levels *cap_levels; 270 - const struct abx500_battery_type *bat_type; 270 + struct abx500_battery_type *bat_type; 271 271 const struct abx500_bm_charger_parameters *chg_params; 272 272 const struct abx500_fg_parameters *fg_params; 273 273 }; 274 274 275 - struct abx500_chargalg_platform_data { 276 - char **supplied_to; 277 - size_t num_supplicants; 275 + extern struct abx500_bm_data ab8500_bm_data; 276 + 277 + struct abx500_bmdevs_plat_data { 278 + char **supplied_to; 279 + size_t num_supplicants; 280 + bool autopower_cfg; 278 281 }; 279 282 280 - struct abx500_charger_platform_data { 281 - char **supplied_to; 282 - size_t num_supplicants; 283 - bool autopower_cfg; 283 + enum { 284 + NTC_EXTERNAL = 0, 285 + NTC_INTERNAL, 284 286 }; 285 287 286 - struct abx500_btemp_platform_data { 287 - char **supplied_to; 288 - size_t num_supplicants; 289 - }; 290 - 291 - struct abx500_fg_platform_data { 292 - char **supplied_to; 293 - size_t num_supplicants; 294 - }; 295 - 296 - struct abx500_bm_plat_data { 297 - struct abx500_bm_data *battery; 298 - struct abx500_charger_platform_data *charger; 299 - struct abx500_btemp_platform_data *btemp; 300 - struct abx500_fg_platform_data *fg; 301 - struct abx500_chargalg_platform_data *chargalg; 302 - }; 288 + int bmdevs_of_probe(struct device *dev, 289 + struct device_node *np, 290 + struct abx500_bm_data **battery); 303 291 304 292 int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, 305 293 u8 value);