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

Merge tag 'for-v3.8-merged' of git://git.infradead.org/battery-2.6

Pull battery subsystem updates from Anton Vorontsov:
"Highlights:

- Two new drivers from Pali Rohár and N900 hackers: rx51_battery and
bq2415x_charger. The drivers are a part of a solution to replace
the proprietary Nokia BME stack

- Power supply core now registers devices with a thermal cooling
subsystem, so we can now automatically throttle charging. Thanks
to Ramakrishna Pallala!

- Device tree support for ab8500 and max8925_power drivers

- Random fixups and enhancements for a bunch of drivers."

* tag 'for-v3.8-merged' of git://git.infradead.org/battery-2.6: (22 commits)
max8925_power: Add support for device-tree initialization
ab8500: Add devicetree support for chargalg
ab8500: Add devicetree support for charger
ab8500: Add devicetree support for btemp
ab8500: Add devicetree support for fuelgauge
twl4030_charger: Change TWL4030_MODULE_* ids to TWL_MODULE_*
jz4740-battery: Use devm_request_and_ioremap
jz4740-battery: Use devm_kzalloc
bq27x00_battery: Fixup nominal available capacity reporting
bq2415x_charger: Fix style issues
bq2415x_charger: Add Kconfig/Makefile entries
power_supply: Add bq2415x charger driver
power_supply: Add new Nokia RX-51 (N900) power supply battery driver
max17042_battery: Fix missing verify_model_lock() return value check
ds2782_battery: Fix signedness bug in ds278x_read_reg16()
lp8788-charger: Fix ADC channel names
lp8788-charger: Fix wrong ADC conversion
lp8788-charger: Use consumer device name on setting IIO channels
power_supply: Register power supply for thermal cooling device
power_supply: Add support for CHARGE_CONTROL_* attributes
...

+3124 -281
+26 -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 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 39 + ab8500-charger : : vddadc : Charger interface 40 + : MAIN_CH_UNPLUG_DET : : main charger unplug detection management (not in 8505) 41 + : MAIN_CHARGE_PLUG_DET : : main charger plug detection management (not in 8505) 42 + : MAIN_EXT_CH_NOT_OK : : main charger not OK 43 + : MAIN_CH_TH_PROT_R : : Die temp is above main charger 44 + : MAIN_CH_TH_PROT_F : : Die temp is below main charger 45 + : VBUS_DET_F : : VBUS falling detected 46 + : VBUS_DET_R : : VBUS rising detected 47 + : USB_LINK_STATUS : : USB link status has changed 48 + : USB_CH_TH_PROT_R : : Die temp is above usb charger 49 + : USB_CH_TH_PROT_F : : Die temp is below usb charger 50 + : USB_CHARGER_NOT_OKR : : allowed USB charger not ok detection 51 + : VBUS_OVV : : Overvoltage on Vbus ball detected (USB charge is stopped) 52 + : CH_WD_EXP : : Charger watchdog detected 28 53 ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter 29 54 SW_CONV_END : : 30 55 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
+16
Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
··· 1 + === AB8500 Charging Algorithm Driver === 2 + 3 + The properties below describes the node for chargalg driver. 4 + 5 + Required Properties: 6 + - compatible = Shall be: "stericsson,ab8500-chargalg" 7 + - battery = Shall be battery specific information 8 + 9 + Example: 10 + ab8500_chargalg { 11 + compatible = "stericsson,ab8500-chargalg"; 12 + battery = <&ab8500_battery>; 13 + }; 14 + 15 + For information on battery specific node, Ref: 16 + Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
+25
Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
··· 1 + === AB8500 Charger Driver === 2 + 3 + Required Properties: 4 + - compatible = Shall be "stericsson,ab8500-charger" 5 + - battery = Shall be battery specific information 6 + Example: 7 + ab8500_charger { 8 + compatible = "stericsson,ab8500-charger"; 9 + battery = <&ab8500_battery>; 10 + }; 11 + 12 + - vddadc-supply: Supply for USB and Main charger 13 + Example: 14 + ab8500-charger { 15 + vddadc-supply = <&ab8500_ldo_tvout_reg>; 16 + } 17 + - autopower_cfg: 18 + Boolean value depicting the presence of 'automatic poweron after powerloss' 19 + Example: 20 + ab8500-charger { 21 + autopower_cfg; 22 + }; 23 + 24 + For information on battery specific node, Ref: 25 + Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
+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 +
+3
Documentation/power/power_supply_class.txt
··· 123 123 CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the 124 124 power supply object. 125 125 126 + CHARGE_CONTROL_LIMIT - current charge control limit setting 127 + CHARGE_CONTROL_LIMIT_MAX - maximum charge control limit setting 128 + 126 129 ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. 127 130 128 131 CAPACITY - capacity in percents.
+27 -1
arch/arm/boot/dts/dbx5x0.dtsi
··· 340 340 vddadc-supply = <&ab8500_ldo_tvout_reg>; 341 341 }; 342 342 343 - ab8500-usb { 343 + ab8500_battery: ab8500_battery { 344 + stericsson,battery-type = "LIPO"; 345 + thermistor-on-batctrl; 346 + }; 347 + 348 + ab8500_fg { 349 + compatible = "stericsson,ab8500-fg"; 350 + battery = <&ab8500_battery>; 351 + }; 352 + 353 + ab8500_btemp { 354 + compatible = "stericsson,ab8500-btemp"; 355 + battery = <&ab8500_battery>; 356 + }; 357 + 358 + ab8500_charger { 359 + compatible = "stericsson,ab8500-charger"; 360 + battery = <&ab8500_battery>; 361 + vddadc-supply = <&ab8500_ldo_tvout_reg>; 362 + }; 363 + 364 + ab8500_chargalg { 365 + compatible = "stericsson,ab8500-chargalg"; 366 + battery = <&ab8500_battery>; 367 + }; 368 + 369 + ab8500_usb { 344 370 compatible = "stericsson,ab8500-usb"; 345 371 interrupts = < 90 0x4 346 372 96 0x4
+20
drivers/mfd/ab8500-core.c
··· 1036 1036 static struct mfd_cell ab8500_bm_devs[] = { 1037 1037 { 1038 1038 .name = "ab8500-charger", 1039 + .of_compatible = "stericsson,ab8500-charger", 1039 1040 .num_resources = ARRAY_SIZE(ab8500_charger_resources), 1040 1041 .resources = ab8500_charger_resources, 1042 + #ifndef CONFIG_OF 1043 + .platform_data = &ab8500_bm_data, 1044 + .pdata_size = sizeof(ab8500_bm_data), 1045 + #endif 1041 1046 }, 1042 1047 { 1043 1048 .name = "ab8500-btemp", 1049 + .of_compatible = "stericsson,ab8500-btemp", 1044 1050 .num_resources = ARRAY_SIZE(ab8500_btemp_resources), 1045 1051 .resources = ab8500_btemp_resources, 1052 + #ifndef CONFIG_OF 1053 + .platform_data = &ab8500_bm_data, 1054 + .pdata_size = sizeof(ab8500_bm_data), 1055 + #endif 1046 1056 }, 1047 1057 { 1048 1058 .name = "ab8500-fg", 1059 + .of_compatible = "stericsson,ab8500-fg", 1049 1060 .num_resources = ARRAY_SIZE(ab8500_fg_resources), 1050 1061 .resources = ab8500_fg_resources, 1062 + #ifndef CONFIG_OF 1063 + .platform_data = &ab8500_bm_data, 1064 + .pdata_size = sizeof(ab8500_bm_data), 1065 + #endif 1051 1066 }, 1052 1067 { 1053 1068 .name = "ab8500-chargalg", 1069 + .of_compatible = "stericsson,ab8500-chargalg", 1054 1070 .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), 1055 1071 .resources = ab8500_chargalg_resources, 1072 + #ifndef CONFIG_OF 1073 + .platform_data = &ab8500_bm_data, 1074 + .pdata_size = sizeof(ab8500_bm_data), 1075 + #endif 1056 1076 }, 1057 1077 }; 1058 1078
+17 -7
drivers/power/Kconfig
··· 245 245 Say Y here to enable the battery driver on Intel MID 246 246 platforms. 247 247 248 + config BATTERY_RX51 249 + tristate "Nokia RX-51 (N900) battery driver" 250 + depends on TWL4030_MADC 251 + help 252 + Say Y here to enable support for battery information on Nokia 253 + RX-51, also known as N900 tablet. 254 + 248 255 config CHARGER_ISP1704 249 256 tristate "ISP1704 USB Charger Detection" 250 257 depends on USB_OTG_UTILS ··· 322 315 Say Y to enable support for the battery charger control sysfs and 323 316 platform data of MAX8998/LP3974 PMICs. 324 317 318 + config CHARGER_BQ2415X 319 + tristate "TI BQ2415x battery charger driver" 320 + depends on I2C 321 + help 322 + Say Y to enable support for the TI BQ2415x battery charger 323 + PMICs. 324 + 325 + You'll need this driver to charge batteries on e.g. Nokia 326 + RX-51/N900. 327 + 325 328 config CHARGER_SMB347 326 329 tristate "Summit Microelectronics SMB347 Battery Charger" 327 330 depends on I2C ··· 345 328 depends on AB8500_CORE && AB8500_GPADC 346 329 help 347 330 Say Y to include support for AB8500 battery management. 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 331 356 332 source "drivers/power/reset/Kconfig" 357 333
+3 -1
drivers/power/Makefile
··· 37 37 obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o 38 38 obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o 39 39 obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o 40 - obj-$(CONFIG_AB8500_BM) += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o 40 + obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o 41 + obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o 41 42 obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o 42 43 obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o 43 44 obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o ··· 48 47 obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o 49 48 obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o 50 49 obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o 50 + obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o 51 51 obj-$(CONFIG_POWER_AVS) += avs/ 52 52 obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o 53 53 obj-$(CONFIG_POWER_RESET) += reset/
+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, 200000}, 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 = 200000, 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 + }
+40 -37
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_btemp_platform_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 ab8500_btemp_probe(struct platform_device *pdev) 964 968 { 969 + struct device_node *np = pdev->dev.of_node; 970 + struct ab8500_btemp *di; 965 971 int irq, i, ret = 0; 966 972 u8 val; 967 - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; 968 - struct ab8500_btemp *di; 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->btemp; 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 - 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 - ret = -EINVAL; 997 - goto free_device_info; 998 - } 999 1000 1000 1001 /* BTEMP supply */ 1001 1002 di->btemp_psy.name = "ab8500_btemp"; ··· 1004 1003 di->btemp_psy.properties = ab8500_btemp_props; 1005 1004 di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props); 1006 1005 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; 1006 + di->btemp_psy.supplied_to = supply_interface; 1007 + di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface); 1009 1008 di->btemp_psy.external_power_changed = 1010 1009 ab8500_btemp_external_power_changed; 1011 1010 ··· 1015 1014 create_singlethread_workqueue("ab8500_btemp_wq"); 1016 1015 if (di->btemp_wq == NULL) { 1017 1016 dev_err(di->dev, "failed to create work queue\n"); 1018 - ret = -ENOMEM; 1019 - goto free_device_info; 1017 + return -ENOMEM; 1020 1018 } 1021 1019 1022 1020 /* Init work for measuring temperature periodically */ ··· 1093 1093 } 1094 1094 free_btemp_wq: 1095 1095 destroy_workqueue(di->btemp_wq); 1096 - free_device_info: 1097 - kfree(di); 1098 - 1099 1096 return ret; 1100 1097 } 1098 + 1099 + static const struct of_device_id ab8500_btemp_match[] = { 1100 + { .compatible = "stericsson,ab8500-btemp", }, 1101 + { }, 1102 + }; 1101 1103 1102 1104 static struct platform_driver ab8500_btemp_driver = { 1103 1105 .probe = ab8500_btemp_probe, ··· 1109 1107 .driver = { 1110 1108 .name = "ab8500-btemp", 1111 1109 .owner = THIS_MODULE, 1110 + .of_match_table = ab8500_btemp_match, 1112 1111 }, 1113 1112 }; 1114 1113
+46 -38
drivers/power/ab8500_charger.c
··· 23 23 #include <linux/err.h> 24 24 #include <linux/workqueue.h> 25 25 #include <linux/kobject.h> 26 + #include <linux/of.h> 27 + #include <linux/mfd/core.h> 26 28 #include <linux/mfd/abx500/ab8500.h> 27 29 #include <linux/mfd/abx500.h> 28 30 #include <linux/mfd/abx500/ab8500-bm.h> ··· 183 181 * @vbat Battery voltage 184 182 * @old_vbat Previously measured battery voltage 185 183 * @autopower Indicate if we should have automatic pwron after pwrloss 184 + * @autopower_cfg platform specific power config support for "pwron after pwrloss" 186 185 * @parent: Pointer to the struct ab8500 187 186 * @gpadc: Pointer to the struct gpadc 188 - * @pdata: Pointer to the abx500_charger platform data 189 187 * @bat: Pointer to the abx500_bm platform data 190 188 * @flags: Structure for information about events triggered 191 189 * @usb_state: Structure for usb stack information ··· 220 218 int vbat; 221 219 int old_vbat; 222 220 bool autopower; 221 + bool autopower_cfg; 223 222 struct ab8500 *parent; 224 223 struct ab8500_gpadc *gpadc; 225 - struct abx500_charger_platform_data *pdata; 226 224 struct abx500_bm_data *bat; 227 225 struct ab8500_charger_event_flags flags; 228 226 struct ab8500_charger_usb_state usb_state; ··· 324 322 static void ab8500_power_supply_changed(struct ab8500_charger *di, 325 323 struct power_supply *psy) 326 324 { 327 - if (di->pdata->autopower_cfg) { 325 + if (di->autopower_cfg) { 328 326 if (!di->usb.charger_connected && 329 327 !di->ac.charger_connected && 330 328 di->autopower) { ··· 2528 2526 power_supply_unregister(&di->usb_chg.psy); 2529 2527 power_supply_unregister(&di->ac_chg.psy); 2530 2528 platform_set_drvdata(pdev, NULL); 2531 - kfree(di); 2532 2529 2533 2530 return 0; 2534 2531 } 2535 2532 2533 + static char *supply_interface[] = { 2534 + "ab8500_chargalg", 2535 + "ab8500_fg", 2536 + "ab8500_btemp", 2537 + }; 2538 + 2536 2539 static int ab8500_charger_probe(struct platform_device *pdev) 2537 2540 { 2538 - int irq, i, charger_status, ret = 0; 2539 - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; 2541 + struct device_node *np = pdev->dev.of_node; 2540 2542 struct ab8500_charger *di; 2543 + int irq, i, charger_status, ret = 0; 2541 2544 2542 - if (!plat_data) { 2543 - dev_err(&pdev->dev, "No platform data\n"); 2544 - return -EINVAL; 2545 - } 2546 - 2547 - di = kzalloc(sizeof(*di), GFP_KERNEL); 2548 - if (!di) 2545 + di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); 2546 + if (!di) { 2547 + dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__); 2549 2548 return -ENOMEM; 2549 + } 2550 + di->bat = pdev->mfd_cell->platform_data; 2551 + if (!di->bat) { 2552 + if (np) { 2553 + ret = bmdevs_of_probe(&pdev->dev, np, &di->bat); 2554 + if (ret) { 2555 + dev_err(&pdev->dev, 2556 + "failed to get battery information\n"); 2557 + return ret; 2558 + } 2559 + di->autopower_cfg = of_property_read_bool(np, "autopower_cfg"); 2560 + } else { 2561 + dev_err(&pdev->dev, "missing dt node for ab8500_charger\n"); 2562 + return -EINVAL; 2563 + } 2564 + } else { 2565 + dev_info(&pdev->dev, "falling back to legacy platform data\n"); 2566 + di->autopower_cfg = false; 2567 + } 2550 2568 2551 2569 /* get parent data */ 2552 2570 di->dev = &pdev->dev; ··· 2575 2553 2576 2554 /* initialize lock */ 2577 2555 spin_lock_init(&di->usb_state.usb_lock); 2578 - 2579 - /* get charger specific platform data */ 2580 - di->pdata = plat_data->charger; 2581 - if (!di->pdata) { 2582 - dev_err(di->dev, "no charger platform data supplied\n"); 2583 - ret = -EINVAL; 2584 - goto free_device_info; 2585 - } 2586 - 2587 - /* get battery specific platform data */ 2588 - di->bat = plat_data->battery; 2589 - if (!di->bat) { 2590 - dev_err(di->dev, "no battery platform data supplied\n"); 2591 - ret = -EINVAL; 2592 - goto free_device_info; 2593 - } 2594 2556 2595 2557 di->autopower = false; 2596 2558 ··· 2585 2579 di->ac_chg.psy.properties = ab8500_charger_ac_props; 2586 2580 di->ac_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_ac_props); 2587 2581 di->ac_chg.psy.get_property = ab8500_charger_ac_get_property; 2588 - di->ac_chg.psy.supplied_to = di->pdata->supplied_to; 2589 - di->ac_chg.psy.num_supplicants = di->pdata->num_supplicants; 2582 + di->ac_chg.psy.supplied_to = supply_interface; 2583 + di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), 2590 2584 /* ux500_charger sub-class */ 2591 2585 di->ac_chg.ops.enable = &ab8500_charger_ac_en; 2592 2586 di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; ··· 2603 2597 di->usb_chg.psy.properties = ab8500_charger_usb_props; 2604 2598 di->usb_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_usb_props); 2605 2599 di->usb_chg.psy.get_property = ab8500_charger_usb_get_property; 2606 - di->usb_chg.psy.supplied_to = di->pdata->supplied_to; 2607 - di->usb_chg.psy.num_supplicants = di->pdata->num_supplicants; 2600 + di->usb_chg.psy.supplied_to = supply_interface; 2601 + di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), 2608 2602 /* ux500_charger sub-class */ 2609 2603 di->usb_chg.ops.enable = &ab8500_charger_usb_en; 2610 2604 di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; ··· 2620 2614 create_singlethread_workqueue("ab8500_charger_wq"); 2621 2615 if (di->charger_wq == NULL) { 2622 2616 dev_err(di->dev, "failed to create work queue\n"); 2623 - ret = -ENOMEM; 2624 - goto free_device_info; 2617 + return -ENOMEM; 2625 2618 } 2626 2619 2627 2620 /* Init work for HW failure check */ ··· 2762 2757 regulator_put(di->regu); 2763 2758 free_charger_wq: 2764 2759 destroy_workqueue(di->charger_wq); 2765 - free_device_info: 2766 - kfree(di); 2767 - 2768 2760 return ret; 2769 2761 } 2762 + 2763 + static const struct of_device_id ab8500_charger_match[] = { 2764 + { .compatible = "stericsson,ab8500-charger", }, 2765 + { }, 2766 + }; 2770 2767 2771 2768 static struct platform_driver ab8500_charger_driver = { 2772 2769 .probe = ab8500_charger_probe, ··· 2778 2771 .driver = { 2779 2772 .name = "ab8500-charger", 2780 2773 .owner = THIS_MODULE, 2774 + .of_match_table = ab8500_charger_match, 2781 2775 }, 2782 2776 }; 2783 2777
+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 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
+38 -18
drivers/power/abx500_chargalg.c
··· 21 21 #include <linux/completion.h> 22 22 #include <linux/workqueue.h> 23 23 #include <linux/kobject.h> 24 + #include <linux/of.h> 25 + #include <linux/mfd/core.h> 24 26 #include <linux/mfd/abx500.h> 25 27 #include <linux/mfd/abx500/ux500_chargalg.h> 26 28 #include <linux/mfd/abx500/ab8500-bm.h> ··· 207 205 * @chg_info: information about connected charger types 208 206 * @batt_data: data of the battery 209 207 * @susp_status: current charger suspension status 210 - * @pdata: pointer to the abx500_chargalg platform data 211 208 * @bat: pointer to the abx500_bm platform data 212 209 * @chargalg_psy: structure that holds the battery properties exposed by 213 210 * the charging algorithm ··· 232 231 struct abx500_chargalg_charger_info chg_info; 233 232 struct abx500_chargalg_battery_data batt_data; 234 233 struct abx500_chargalg_suspension_status susp_status; 235 - struct abx500_chargalg_platform_data *pdata; 236 234 struct abx500_bm_data *bat; 237 235 struct power_supply chargalg_psy; 238 236 struct ux500_charger *ac_chg; ··· 1795 1795 flush_scheduled_work(); 1796 1796 power_supply_unregister(&di->chargalg_psy); 1797 1797 platform_set_drvdata(pdev, NULL); 1798 - kfree(di); 1799 1798 1800 1799 return 0; 1801 1800 } 1802 1801 1802 + static char *supply_interface[] = { 1803 + "ab8500_fg", 1804 + }; 1805 + 1803 1806 static int abx500_chargalg_probe(struct platform_device *pdev) 1804 1807 { 1805 - struct abx500_bm_plat_data *plat_data; 1808 + struct device_node *np = pdev->dev.of_node; 1809 + struct abx500_chargalg *di; 1806 1810 int ret = 0; 1807 1811 1808 - struct abx500_chargalg *di = 1809 - kzalloc(sizeof(struct abx500_chargalg), GFP_KERNEL); 1810 - if (!di) 1812 + di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); 1813 + if (!di) { 1814 + dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__); 1811 1815 return -ENOMEM; 1816 + } 1817 + di->bat = pdev->mfd_cell->platform_data; 1818 + if (!di->bat) { 1819 + if (np) { 1820 + ret = bmdevs_of_probe(&pdev->dev, np, &di->bat); 1821 + if (ret) { 1822 + dev_err(&pdev->dev, 1823 + "failed to get battery information\n"); 1824 + return ret; 1825 + } 1826 + } else { 1827 + dev_err(&pdev->dev, "missing dt node for ab8500_chargalg\n"); 1828 + return -EINVAL; 1829 + } 1830 + } else { 1831 + dev_info(&pdev->dev, "falling back to legacy platform data\n"); 1832 + } 1812 1833 1813 1834 /* get device struct */ 1814 1835 di->dev = &pdev->dev; 1815 - 1816 - plat_data = pdev->dev.platform_data; 1817 - di->pdata = plat_data->chargalg; 1818 - di->bat = plat_data->battery; 1819 1836 1820 1837 /* chargalg supply */ 1821 1838 di->chargalg_psy.name = "abx500_chargalg"; ··· 1840 1823 di->chargalg_psy.properties = abx500_chargalg_props; 1841 1824 di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props); 1842 1825 di->chargalg_psy.get_property = abx500_chargalg_get_property; 1843 - di->chargalg_psy.supplied_to = di->pdata->supplied_to; 1844 - di->chargalg_psy.num_supplicants = di->pdata->num_supplicants; 1826 + di->chargalg_psy.supplied_to = supply_interface; 1827 + di->chargalg_psy.num_supplicants = ARRAY_SIZE(supply_interface), 1845 1828 di->chargalg_psy.external_power_changed = 1846 1829 abx500_chargalg_external_power_changed; 1847 1830 ··· 1861 1844 create_singlethread_workqueue("abx500_chargalg_wq"); 1862 1845 if (di->chargalg_wq == NULL) { 1863 1846 dev_err(di->dev, "failed to create work queue\n"); 1864 - goto free_device_info; 1847 + return -ENOMEM; 1865 1848 } 1866 1849 1867 1850 /* Init work for chargalg */ ··· 1902 1885 power_supply_unregister(&di->chargalg_psy); 1903 1886 free_chargalg_wq: 1904 1887 destroy_workqueue(di->chargalg_wq); 1905 - free_device_info: 1906 - kfree(di); 1907 - 1908 1888 return ret; 1909 1889 } 1890 + 1891 + static const struct of_device_id ab8500_chargalg_match[] = { 1892 + { .compatible = "stericsson,ab8500-chargalg", }, 1893 + { }, 1894 + }; 1910 1895 1911 1896 static struct platform_driver abx500_chargalg_driver = { 1912 1897 .probe = abx500_chargalg_probe, ··· 1916 1897 .suspend = abx500_chargalg_suspend, 1917 1898 .resume = abx500_chargalg_resume, 1918 1899 .driver = { 1919 - .name = "abx500-chargalg", 1900 + .name = "ab8500-chargalg", 1920 1901 .owner = THIS_MODULE, 1902 + .of_match_table = ab8500_chargalg_match, 1921 1903 }, 1922 1904 }; 1923 1905
+1670
drivers/power/bq2415x_charger.c
··· 1 + /* 2 + * bq2415x charger driver 3 + * 4 + * Copyright (C) 2011-2012 Pali Rohár <pali.rohar@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + /* 22 + * Datasheets: 23 + * http://www.ti.com/product/bq24150 24 + * http://www.ti.com/product/bq24150a 25 + * http://www.ti.com/product/bq24152 26 + * http://www.ti.com/product/bq24153 27 + * http://www.ti.com/product/bq24153a 28 + * http://www.ti.com/product/bq24155 29 + */ 30 + 31 + #include <linux/version.h> 32 + #include <linux/kernel.h> 33 + #include <linux/module.h> 34 + #include <linux/param.h> 35 + #include <linux/err.h> 36 + #include <linux/workqueue.h> 37 + #include <linux/sysfs.h> 38 + #include <linux/platform_device.h> 39 + #include <linux/power_supply.h> 40 + #include <linux/idr.h> 41 + #include <linux/i2c.h> 42 + #include <linux/slab.h> 43 + 44 + #include <linux/power/bq2415x_charger.h> 45 + 46 + /* timeout for resetting chip timer */ 47 + #define BQ2415X_TIMER_TIMEOUT 10 48 + 49 + #define BQ2415X_REG_STATUS 0x00 50 + #define BQ2415X_REG_CONTROL 0x01 51 + #define BQ2415X_REG_VOLTAGE 0x02 52 + #define BQ2415X_REG_VENDER 0x03 53 + #define BQ2415X_REG_CURRENT 0x04 54 + 55 + /* reset state for all registers */ 56 + #define BQ2415X_RESET_STATUS BIT(6) 57 + #define BQ2415X_RESET_CONTROL (BIT(4)|BIT(5)) 58 + #define BQ2415X_RESET_VOLTAGE (BIT(1)|BIT(3)) 59 + #define BQ2415X_RESET_CURRENT (BIT(0)|BIT(3)|BIT(7)) 60 + 61 + /* status register */ 62 + #define BQ2415X_BIT_TMR_RST 7 63 + #define BQ2415X_BIT_OTG 7 64 + #define BQ2415X_BIT_EN_STAT 6 65 + #define BQ2415X_MASK_STAT (BIT(4)|BIT(5)) 66 + #define BQ2415X_SHIFT_STAT 4 67 + #define BQ2415X_BIT_BOOST 3 68 + #define BQ2415X_MASK_FAULT (BIT(0)|BIT(1)|BIT(2)) 69 + #define BQ2415X_SHIFT_FAULT 0 70 + 71 + /* control register */ 72 + #define BQ2415X_MASK_LIMIT (BIT(6)|BIT(7)) 73 + #define BQ2415X_SHIFT_LIMIT 6 74 + #define BQ2415X_MASK_VLOWV (BIT(4)|BIT(5)) 75 + #define BQ2415X_SHIFT_VLOWV 4 76 + #define BQ2415X_BIT_TE 3 77 + #define BQ2415X_BIT_CE 2 78 + #define BQ2415X_BIT_HZ_MODE 1 79 + #define BQ2415X_BIT_OPA_MODE 0 80 + 81 + /* voltage register */ 82 + #define BQ2415X_MASK_VO (BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)) 83 + #define BQ2415X_SHIFT_VO 2 84 + #define BQ2415X_BIT_OTG_PL 1 85 + #define BQ2415X_BIT_OTG_EN 0 86 + 87 + /* vender register */ 88 + #define BQ2415X_MASK_VENDER (BIT(5)|BIT(6)|BIT(7)) 89 + #define BQ2415X_SHIFT_VENDER 5 90 + #define BQ2415X_MASK_PN (BIT(3)|BIT(4)) 91 + #define BQ2415X_SHIFT_PN 3 92 + #define BQ2415X_MASK_REVISION (BIT(0)|BIT(1)|BIT(2)) 93 + #define BQ2415X_SHIFT_REVISION 0 94 + 95 + /* current register */ 96 + #define BQ2415X_MASK_RESET BIT(7) 97 + #define BQ2415X_MASK_VI_CHRG (BIT(4)|BIT(5)|BIT(6)) 98 + #define BQ2415X_SHIFT_VI_CHRG 4 99 + /* N/A BIT(3) */ 100 + #define BQ2415X_MASK_VI_TERM (BIT(0)|BIT(1)|BIT(2)) 101 + #define BQ2415X_SHIFT_VI_TERM 0 102 + 103 + 104 + enum bq2415x_command { 105 + BQ2415X_TIMER_RESET, 106 + BQ2415X_OTG_STATUS, 107 + BQ2415X_STAT_PIN_STATUS, 108 + BQ2415X_STAT_PIN_ENABLE, 109 + BQ2415X_STAT_PIN_DISABLE, 110 + BQ2415X_CHARGE_STATUS, 111 + BQ2415X_BOOST_STATUS, 112 + BQ2415X_FAULT_STATUS, 113 + 114 + BQ2415X_CHARGE_TERMINATION_STATUS, 115 + BQ2415X_CHARGE_TERMINATION_ENABLE, 116 + BQ2415X_CHARGE_TERMINATION_DISABLE, 117 + BQ2415X_CHARGER_STATUS, 118 + BQ2415X_CHARGER_ENABLE, 119 + BQ2415X_CHARGER_DISABLE, 120 + BQ2415X_HIGH_IMPEDANCE_STATUS, 121 + BQ2415X_HIGH_IMPEDANCE_ENABLE, 122 + BQ2415X_HIGH_IMPEDANCE_DISABLE, 123 + BQ2415X_BOOST_MODE_STATUS, 124 + BQ2415X_BOOST_MODE_ENABLE, 125 + BQ2415X_BOOST_MODE_DISABLE, 126 + 127 + BQ2415X_OTG_LEVEL, 128 + BQ2415X_OTG_ACTIVATE_HIGH, 129 + BQ2415X_OTG_ACTIVATE_LOW, 130 + BQ2415X_OTG_PIN_STATUS, 131 + BQ2415X_OTG_PIN_ENABLE, 132 + BQ2415X_OTG_PIN_DISABLE, 133 + 134 + BQ2415X_VENDER_CODE, 135 + BQ2415X_PART_NUMBER, 136 + BQ2415X_REVISION, 137 + }; 138 + 139 + enum bq2415x_chip { 140 + BQUNKNOWN, 141 + BQ24150, 142 + BQ24150A, 143 + BQ24151, 144 + BQ24151A, 145 + BQ24152, 146 + BQ24153, 147 + BQ24153A, 148 + BQ24155, 149 + BQ24156, 150 + BQ24156A, 151 + BQ24158, 152 + }; 153 + 154 + static char *bq2415x_chip_name[] = { 155 + "unknown", 156 + "bq24150", 157 + "bq24150a", 158 + "bq24151", 159 + "bq24151a", 160 + "bq24152", 161 + "bq24153", 162 + "bq24153a", 163 + "bq24155", 164 + "bq24156", 165 + "bq24156a", 166 + "bq24158", 167 + }; 168 + 169 + struct bq2415x_device { 170 + struct device *dev; 171 + struct bq2415x_platform_data init_data; 172 + struct power_supply charger; 173 + struct delayed_work work; 174 + enum bq2415x_mode reported_mode;/* mode reported by hook function */ 175 + enum bq2415x_mode mode; /* current configured mode */ 176 + enum bq2415x_chip chip; 177 + const char *timer_error; 178 + char *model; 179 + char *name; 180 + int autotimer; /* 1 - if driver automatically reset timer, 0 - not */ 181 + int automode; /* 1 - enabled, 0 - disabled; -1 - not supported */ 182 + int id; 183 + }; 184 + 185 + /* each registered chip must have unique id */ 186 + static DEFINE_IDR(bq2415x_id); 187 + 188 + static DEFINE_MUTEX(bq2415x_id_mutex); 189 + static DEFINE_MUTEX(bq2415x_timer_mutex); 190 + static DEFINE_MUTEX(bq2415x_i2c_mutex); 191 + 192 + /**** i2c read functions ****/ 193 + 194 + /* read value from register */ 195 + static int bq2415x_i2c_read(struct bq2415x_device *bq, u8 reg) 196 + { 197 + struct i2c_client *client = to_i2c_client(bq->dev); 198 + struct i2c_msg msg[2]; 199 + u8 val; 200 + int ret; 201 + 202 + if (!client->adapter) 203 + return -ENODEV; 204 + 205 + msg[0].addr = client->addr; 206 + msg[0].flags = 0; 207 + msg[0].buf = &reg; 208 + msg[0].len = sizeof(reg); 209 + msg[1].addr = client->addr; 210 + msg[1].flags = I2C_M_RD; 211 + msg[1].buf = &val; 212 + msg[1].len = sizeof(val); 213 + 214 + mutex_lock(&bq2415x_i2c_mutex); 215 + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 216 + mutex_unlock(&bq2415x_i2c_mutex); 217 + 218 + if (ret < 0) 219 + return ret; 220 + 221 + return val; 222 + } 223 + 224 + /* read value from register, apply mask and right shift it */ 225 + static int bq2415x_i2c_read_mask(struct bq2415x_device *bq, u8 reg, 226 + u8 mask, u8 shift) 227 + { 228 + int ret; 229 + 230 + if (shift > 8) 231 + return -EINVAL; 232 + 233 + ret = bq2415x_i2c_read(bq, reg); 234 + if (ret < 0) 235 + return ret; 236 + return (ret & mask) >> shift; 237 + } 238 + 239 + /* read value from register and return one specified bit */ 240 + static int bq2415x_i2c_read_bit(struct bq2415x_device *bq, u8 reg, u8 bit) 241 + { 242 + if (bit > 8) 243 + return -EINVAL; 244 + return bq2415x_i2c_read_mask(bq, reg, BIT(bit), bit); 245 + } 246 + 247 + /**** i2c write functions ****/ 248 + 249 + /* write value to register */ 250 + static int bq2415x_i2c_write(struct bq2415x_device *bq, u8 reg, u8 val) 251 + { 252 + struct i2c_client *client = to_i2c_client(bq->dev); 253 + struct i2c_msg msg[1]; 254 + u8 data[2]; 255 + int ret; 256 + 257 + data[0] = reg; 258 + data[1] = val; 259 + 260 + msg[0].addr = client->addr; 261 + msg[0].flags = 0; 262 + msg[0].buf = data; 263 + msg[0].len = ARRAY_SIZE(data); 264 + 265 + mutex_lock(&bq2415x_i2c_mutex); 266 + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 267 + mutex_unlock(&bq2415x_i2c_mutex); 268 + 269 + /* i2c_transfer returns number of messages transferred */ 270 + if (ret < 0) 271 + return ret; 272 + else if (ret != 1) 273 + return -EIO; 274 + 275 + return 0; 276 + } 277 + 278 + /* read value from register, change it with mask left shifted and write back */ 279 + static int bq2415x_i2c_write_mask(struct bq2415x_device *bq, u8 reg, u8 val, 280 + u8 mask, u8 shift) 281 + { 282 + int ret; 283 + 284 + if (shift > 8) 285 + return -EINVAL; 286 + 287 + ret = bq2415x_i2c_read(bq, reg); 288 + if (ret < 0) 289 + return ret; 290 + 291 + ret &= ~mask; 292 + ret |= val << shift; 293 + 294 + return bq2415x_i2c_write(bq, reg, ret); 295 + } 296 + 297 + /* change only one bit in register */ 298 + static int bq2415x_i2c_write_bit(struct bq2415x_device *bq, u8 reg, 299 + bool val, u8 bit) 300 + { 301 + if (bit > 8) 302 + return -EINVAL; 303 + return bq2415x_i2c_write_mask(bq, reg, val, BIT(bit), bit); 304 + } 305 + 306 + /**** global functions ****/ 307 + 308 + /* exec command function */ 309 + static int bq2415x_exec_command(struct bq2415x_device *bq, 310 + enum bq2415x_command command) 311 + { 312 + int ret; 313 + 314 + switch (command) { 315 + case BQ2415X_TIMER_RESET: 316 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_STATUS, 317 + 1, BQ2415X_BIT_TMR_RST); 318 + case BQ2415X_OTG_STATUS: 319 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_STATUS, 320 + BQ2415X_BIT_OTG); 321 + case BQ2415X_STAT_PIN_STATUS: 322 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_STATUS, 323 + BQ2415X_BIT_EN_STAT); 324 + case BQ2415X_STAT_PIN_ENABLE: 325 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_STATUS, 1, 326 + BQ2415X_BIT_EN_STAT); 327 + case BQ2415X_STAT_PIN_DISABLE: 328 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_STATUS, 0, 329 + BQ2415X_BIT_EN_STAT); 330 + case BQ2415X_CHARGE_STATUS: 331 + return bq2415x_i2c_read_mask(bq, BQ2415X_REG_STATUS, 332 + BQ2415X_MASK_STAT, BQ2415X_SHIFT_STAT); 333 + case BQ2415X_BOOST_STATUS: 334 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_STATUS, 335 + BQ2415X_BIT_BOOST); 336 + case BQ2415X_FAULT_STATUS: 337 + return bq2415x_i2c_read_mask(bq, BQ2415X_REG_STATUS, 338 + BQ2415X_MASK_FAULT, BQ2415X_SHIFT_FAULT); 339 + 340 + case BQ2415X_CHARGE_TERMINATION_STATUS: 341 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL, 342 + BQ2415X_BIT_TE); 343 + case BQ2415X_CHARGE_TERMINATION_ENABLE: 344 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 345 + 1, BQ2415X_BIT_TE); 346 + case BQ2415X_CHARGE_TERMINATION_DISABLE: 347 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 348 + 0, BQ2415X_BIT_TE); 349 + case BQ2415X_CHARGER_STATUS: 350 + ret = bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL, 351 + BQ2415X_BIT_CE); 352 + if (ret < 0) 353 + return ret; 354 + else 355 + return ret > 0 ? 0 : 1; 356 + case BQ2415X_CHARGER_ENABLE: 357 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 358 + 0, BQ2415X_BIT_CE); 359 + case BQ2415X_CHARGER_DISABLE: 360 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 361 + 1, BQ2415X_BIT_CE); 362 + case BQ2415X_HIGH_IMPEDANCE_STATUS: 363 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL, 364 + BQ2415X_BIT_HZ_MODE); 365 + case BQ2415X_HIGH_IMPEDANCE_ENABLE: 366 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 367 + 1, BQ2415X_BIT_HZ_MODE); 368 + case BQ2415X_HIGH_IMPEDANCE_DISABLE: 369 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 370 + 0, BQ2415X_BIT_HZ_MODE); 371 + case BQ2415X_BOOST_MODE_STATUS: 372 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL, 373 + BQ2415X_BIT_OPA_MODE); 374 + case BQ2415X_BOOST_MODE_ENABLE: 375 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 376 + 1, BQ2415X_BIT_OPA_MODE); 377 + case BQ2415X_BOOST_MODE_DISABLE: 378 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 379 + 0, BQ2415X_BIT_OPA_MODE); 380 + 381 + case BQ2415X_OTG_LEVEL: 382 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_VOLTAGE, 383 + BQ2415X_BIT_OTG_PL); 384 + case BQ2415X_OTG_ACTIVATE_HIGH: 385 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE, 386 + 1, BQ2415X_BIT_OTG_PL); 387 + case BQ2415X_OTG_ACTIVATE_LOW: 388 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE, 389 + 0, BQ2415X_BIT_OTG_PL); 390 + case BQ2415X_OTG_PIN_STATUS: 391 + return bq2415x_i2c_read_bit(bq, BQ2415X_REG_VOLTAGE, 392 + BQ2415X_BIT_OTG_EN); 393 + case BQ2415X_OTG_PIN_ENABLE: 394 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE, 395 + 1, BQ2415X_BIT_OTG_EN); 396 + case BQ2415X_OTG_PIN_DISABLE: 397 + return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE, 398 + 0, BQ2415X_BIT_OTG_EN); 399 + 400 + case BQ2415X_VENDER_CODE: 401 + return bq2415x_i2c_read_mask(bq, BQ2415X_REG_VENDER, 402 + BQ2415X_MASK_VENDER, BQ2415X_SHIFT_VENDER); 403 + case BQ2415X_PART_NUMBER: 404 + return bq2415x_i2c_read_mask(bq, BQ2415X_REG_VENDER, 405 + BQ2415X_MASK_PN, BQ2415X_SHIFT_PN); 406 + case BQ2415X_REVISION: 407 + return bq2415x_i2c_read_mask(bq, BQ2415X_REG_VENDER, 408 + BQ2415X_MASK_REVISION, BQ2415X_SHIFT_REVISION); 409 + } 410 + return -EINVAL; 411 + } 412 + 413 + /* detect chip type */ 414 + static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) 415 + { 416 + struct i2c_client *client = to_i2c_client(bq->dev); 417 + int ret = bq2415x_exec_command(bq, BQ2415X_PART_NUMBER); 418 + 419 + if (ret < 0) 420 + return ret; 421 + 422 + switch (client->addr) { 423 + case 0x6b: 424 + switch (ret) { 425 + case 0: 426 + if (bq->chip == BQ24151A) 427 + return bq->chip; 428 + else 429 + return BQ24151; 430 + case 1: 431 + if (bq->chip == BQ24150A || 432 + bq->chip == BQ24152 || 433 + bq->chip == BQ24155) 434 + return bq->chip; 435 + else 436 + return BQ24150; 437 + case 2: 438 + if (bq->chip == BQ24153A) 439 + return bq->chip; 440 + else 441 + return BQ24153; 442 + default: 443 + return BQUNKNOWN; 444 + } 445 + break; 446 + 447 + case 0x6a: 448 + switch (ret) { 449 + case 0: 450 + if (bq->chip == BQ24156A) 451 + return bq->chip; 452 + else 453 + return BQ24156; 454 + case 2: 455 + return BQ24158; 456 + default: 457 + return BQUNKNOWN; 458 + } 459 + break; 460 + } 461 + 462 + return BQUNKNOWN; 463 + } 464 + 465 + /* detect chip revision */ 466 + static int bq2415x_detect_revision(struct bq2415x_device *bq) 467 + { 468 + int ret = bq2415x_exec_command(bq, BQ2415X_REVISION); 469 + int chip = bq2415x_detect_chip(bq); 470 + 471 + if (ret < 0 || chip < 0) 472 + return -1; 473 + 474 + switch (chip) { 475 + case BQ24150: 476 + case BQ24150A: 477 + case BQ24151: 478 + case BQ24151A: 479 + case BQ24152: 480 + if (ret >= 0 && ret <= 3) 481 + return ret; 482 + else 483 + return -1; 484 + case BQ24153: 485 + case BQ24153A: 486 + case BQ24156: 487 + case BQ24156A: 488 + case BQ24158: 489 + if (ret == 3) 490 + return 0; 491 + else if (ret == 1) 492 + return 1; 493 + else 494 + return -1; 495 + case BQ24155: 496 + if (ret == 3) 497 + return 3; 498 + else 499 + return -1; 500 + case BQUNKNOWN: 501 + return -1; 502 + } 503 + 504 + return -1; 505 + } 506 + 507 + /* return chip vender code */ 508 + static int bq2415x_get_vender_code(struct bq2415x_device *bq) 509 + { 510 + int ret; 511 + 512 + ret = bq2415x_exec_command(bq, BQ2415X_VENDER_CODE); 513 + if (ret < 0) 514 + return 0; 515 + 516 + /* convert to binary */ 517 + return (ret & 0x1) + 518 + ((ret >> 1) & 0x1) * 10 + 519 + ((ret >> 2) & 0x1) * 100; 520 + } 521 + 522 + /* reset all chip registers to default state */ 523 + static void bq2415x_reset_chip(struct bq2415x_device *bq) 524 + { 525 + bq2415x_i2c_write(bq, BQ2415X_REG_CURRENT, BQ2415X_RESET_CURRENT); 526 + bq2415x_i2c_write(bq, BQ2415X_REG_VOLTAGE, BQ2415X_RESET_VOLTAGE); 527 + bq2415x_i2c_write(bq, BQ2415X_REG_CONTROL, BQ2415X_RESET_CONTROL); 528 + bq2415x_i2c_write(bq, BQ2415X_REG_STATUS, BQ2415X_RESET_STATUS); 529 + bq->timer_error = NULL; 530 + } 531 + 532 + /**** properties functions ****/ 533 + 534 + /* set current limit in mA */ 535 + static int bq2415x_set_current_limit(struct bq2415x_device *bq, int mA) 536 + { 537 + int val; 538 + 539 + if (mA <= 100) 540 + val = 0; 541 + else if (mA <= 500) 542 + val = 1; 543 + else if (mA <= 800) 544 + val = 2; 545 + else 546 + val = 3; 547 + 548 + return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CONTROL, val, 549 + BQ2415X_MASK_LIMIT, BQ2415X_SHIFT_LIMIT); 550 + } 551 + 552 + /* get current limit in mA */ 553 + static int bq2415x_get_current_limit(struct bq2415x_device *bq) 554 + { 555 + int ret; 556 + 557 + ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL, 558 + BQ2415X_MASK_LIMIT, BQ2415X_SHIFT_LIMIT); 559 + if (ret < 0) 560 + return ret; 561 + else if (ret == 0) 562 + return 100; 563 + else if (ret == 1) 564 + return 500; 565 + else if (ret == 2) 566 + return 800; 567 + else if (ret == 3) 568 + return 1800; 569 + return -EINVAL; 570 + } 571 + 572 + /* set weak battery voltage in mV */ 573 + static int bq2415x_set_weak_battery_voltage(struct bq2415x_device *bq, int mV) 574 + { 575 + int val; 576 + 577 + /* round to 100mV */ 578 + if (mV <= 3400 + 50) 579 + val = 0; 580 + else if (mV <= 3500 + 50) 581 + val = 1; 582 + else if (mV <= 3600 + 50) 583 + val = 2; 584 + else 585 + val = 3; 586 + 587 + return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CONTROL, val, 588 + BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV); 589 + } 590 + 591 + /* get weak battery voltage in mV */ 592 + static int bq2415x_get_weak_battery_voltage(struct bq2415x_device *bq) 593 + { 594 + int ret; 595 + 596 + ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL, 597 + BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV); 598 + if (ret < 0) 599 + return ret; 600 + return 100 * (34 + ret); 601 + } 602 + 603 + /* set battery regulation voltage in mV */ 604 + static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq, 605 + int mV) 606 + { 607 + int val = (mV/10 - 350) / 2; 608 + 609 + if (val < 0) 610 + val = 0; 611 + else if (val > 94) /* FIXME: Max is 94 or 122 ? Set max value ? */ 612 + return -EINVAL; 613 + 614 + return bq2415x_i2c_write_mask(bq, BQ2415X_REG_VOLTAGE, val, 615 + BQ2415X_MASK_VO, BQ2415X_SHIFT_VO); 616 + } 617 + 618 + /* get battery regulation voltage in mV */ 619 + static int bq2415x_get_battery_regulation_voltage(struct bq2415x_device *bq) 620 + { 621 + int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_VOLTAGE, 622 + BQ2415X_MASK_VO, BQ2415X_SHIFT_VO); 623 + 624 + if (ret < 0) 625 + return ret; 626 + return 10 * (350 + 2*ret); 627 + } 628 + 629 + /* set charge current in mA (platform data must provide resistor sense) */ 630 + static int bq2415x_set_charge_current(struct bq2415x_device *bq, int mA) 631 + { 632 + int val; 633 + 634 + if (bq->init_data.resistor_sense <= 0) 635 + return -ENOSYS; 636 + 637 + val = (mA * bq->init_data.resistor_sense - 37400) / 6800; 638 + if (val < 0) 639 + val = 0; 640 + else if (val > 7) 641 + val = 7; 642 + 643 + return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CURRENT, val, 644 + BQ2415X_MASK_VI_CHRG | BQ2415X_MASK_RESET, 645 + BQ2415X_SHIFT_VI_CHRG); 646 + } 647 + 648 + /* get charge current in mA (platform data must provide resistor sense) */ 649 + static int bq2415x_get_charge_current(struct bq2415x_device *bq) 650 + { 651 + int ret; 652 + 653 + if (bq->init_data.resistor_sense <= 0) 654 + return -ENOSYS; 655 + 656 + ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT, 657 + BQ2415X_MASK_VI_CHRG, BQ2415X_SHIFT_VI_CHRG); 658 + if (ret < 0) 659 + return ret; 660 + return (37400 + 6800*ret) / bq->init_data.resistor_sense; 661 + } 662 + 663 + /* set termination current in mA (platform data must provide resistor sense) */ 664 + static int bq2415x_set_termination_current(struct bq2415x_device *bq, int mA) 665 + { 666 + int val; 667 + 668 + if (bq->init_data.resistor_sense <= 0) 669 + return -ENOSYS; 670 + 671 + val = (mA * bq->init_data.resistor_sense - 3400) / 3400; 672 + if (val < 0) 673 + val = 0; 674 + else if (val > 7) 675 + val = 7; 676 + 677 + return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CURRENT, val, 678 + BQ2415X_MASK_VI_TERM | BQ2415X_MASK_RESET, 679 + BQ2415X_SHIFT_VI_TERM); 680 + } 681 + 682 + /* get termination current in mA (platform data must provide resistor sense) */ 683 + static int bq2415x_get_termination_current(struct bq2415x_device *bq) 684 + { 685 + int ret; 686 + 687 + if (bq->init_data.resistor_sense <= 0) 688 + return -ENOSYS; 689 + 690 + ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT, 691 + BQ2415X_MASK_VI_TERM, BQ2415X_SHIFT_VI_TERM); 692 + if (ret < 0) 693 + return ret; 694 + return (3400 + 3400*ret) / bq->init_data.resistor_sense; 695 + } 696 + 697 + /* set default value of property */ 698 + #define bq2415x_set_default_value(bq, prop) \ 699 + do { \ 700 + int ret = 0; \ 701 + if (bq->init_data.prop != -1) \ 702 + ret = bq2415x_set_##prop(bq, bq->init_data.prop); \ 703 + if (ret < 0) \ 704 + return ret; \ 705 + } while (0) 706 + 707 + /* set default values of all properties */ 708 + static int bq2415x_set_defaults(struct bq2415x_device *bq) 709 + { 710 + bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE); 711 + bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE); 712 + bq2415x_exec_command(bq, BQ2415X_CHARGE_TERMINATION_DISABLE); 713 + 714 + bq2415x_set_default_value(bq, current_limit); 715 + bq2415x_set_default_value(bq, weak_battery_voltage); 716 + bq2415x_set_default_value(bq, battery_regulation_voltage); 717 + 718 + if (bq->init_data.resistor_sense > 0) { 719 + bq2415x_set_default_value(bq, charge_current); 720 + bq2415x_set_default_value(bq, termination_current); 721 + bq2415x_exec_command(bq, BQ2415X_CHARGE_TERMINATION_ENABLE); 722 + } 723 + 724 + bq2415x_exec_command(bq, BQ2415X_CHARGER_ENABLE); 725 + return 0; 726 + } 727 + 728 + /**** charger mode functions ****/ 729 + 730 + /* set charger mode */ 731 + static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode) 732 + { 733 + int ret = 0; 734 + int charger = 0; 735 + int boost = 0; 736 + 737 + if (mode == BQ2415X_MODE_HOST_CHARGER || 738 + mode == BQ2415X_MODE_DEDICATED_CHARGER) 739 + charger = 1; 740 + 741 + if (mode == BQ2415X_MODE_BOOST) 742 + boost = 1; 743 + 744 + if (!charger) 745 + ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE); 746 + 747 + if (!boost) 748 + ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE); 749 + 750 + if (ret < 0) 751 + return ret; 752 + 753 + switch (mode) { 754 + case BQ2415X_MODE_NONE: 755 + dev_dbg(bq->dev, "changing mode to: N/A\n"); 756 + ret = bq2415x_set_current_limit(bq, 100); 757 + break; 758 + case BQ2415X_MODE_HOST_CHARGER: 759 + dev_dbg(bq->dev, "changing mode to: Host/HUB charger\n"); 760 + ret = bq2415x_set_current_limit(bq, 500); 761 + break; 762 + case BQ2415X_MODE_DEDICATED_CHARGER: 763 + dev_dbg(bq->dev, "changing mode to: Dedicated charger\n"); 764 + ret = bq2415x_set_current_limit(bq, 1800); 765 + break; 766 + case BQ2415X_MODE_BOOST: /* Boost mode */ 767 + dev_dbg(bq->dev, "changing mode to: Boost\n"); 768 + ret = bq2415x_set_current_limit(bq, 100); 769 + break; 770 + } 771 + 772 + if (ret < 0) 773 + return ret; 774 + 775 + if (charger) 776 + ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_ENABLE); 777 + else if (boost) 778 + ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_ENABLE); 779 + 780 + if (ret < 0) 781 + return ret; 782 + 783 + bq2415x_set_default_value(bq, weak_battery_voltage); 784 + bq2415x_set_default_value(bq, battery_regulation_voltage); 785 + 786 + bq->mode = mode; 787 + sysfs_notify(&bq->charger.dev->kobj, NULL, "mode"); 788 + 789 + return 0; 790 + 791 + } 792 + 793 + /* hook function called by other driver which set reported mode */ 794 + static void bq2415x_hook_function(enum bq2415x_mode mode, void *data) 795 + { 796 + struct bq2415x_device *bq = data; 797 + 798 + if (!bq) 799 + return; 800 + 801 + dev_dbg(bq->dev, "hook function was called\n"); 802 + bq->reported_mode = mode; 803 + 804 + /* if automode is not enabled do not tell about reported_mode */ 805 + if (bq->automode < 1) 806 + return; 807 + 808 + sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); 809 + bq2415x_set_mode(bq, bq->reported_mode); 810 + 811 + } 812 + 813 + /**** timer functions ****/ 814 + 815 + /* enable/disable auto resetting chip timer */ 816 + static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state) 817 + { 818 + mutex_lock(&bq2415x_timer_mutex); 819 + 820 + if (bq->autotimer == state) { 821 + mutex_unlock(&bq2415x_timer_mutex); 822 + return; 823 + } 824 + 825 + bq->autotimer = state; 826 + 827 + if (state) { 828 + schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); 829 + bq2415x_exec_command(bq, BQ2415X_TIMER_RESET); 830 + bq->timer_error = NULL; 831 + } else { 832 + cancel_delayed_work_sync(&bq->work); 833 + } 834 + 835 + mutex_unlock(&bq2415x_timer_mutex); 836 + } 837 + 838 + /* called by bq2415x_timer_work on timer error */ 839 + static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg) 840 + { 841 + bq->timer_error = msg; 842 + sysfs_notify(&bq->charger.dev->kobj, NULL, "timer"); 843 + dev_err(bq->dev, "%s\n", msg); 844 + if (bq->automode > 0) 845 + bq->automode = 0; 846 + bq2415x_set_mode(bq, BQ2415X_MODE_NONE); 847 + bq2415x_set_autotimer(bq, 0); 848 + } 849 + 850 + /* delayed work function for auto resetting chip timer */ 851 + static void bq2415x_timer_work(struct work_struct *work) 852 + { 853 + struct bq2415x_device *bq = container_of(work, struct bq2415x_device, 854 + work.work); 855 + int ret; 856 + int error; 857 + int boost; 858 + 859 + if (!bq->autotimer) 860 + return; 861 + 862 + ret = bq2415x_exec_command(bq, BQ2415X_TIMER_RESET); 863 + if (ret < 0) { 864 + bq2415x_timer_error(bq, "Resetting timer failed"); 865 + return; 866 + } 867 + 868 + boost = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_STATUS); 869 + if (boost < 0) { 870 + bq2415x_timer_error(bq, "Unknown error"); 871 + return; 872 + } 873 + 874 + error = bq2415x_exec_command(bq, BQ2415X_FAULT_STATUS); 875 + if (error < 0) { 876 + bq2415x_timer_error(bq, "Unknown error"); 877 + return; 878 + } 879 + 880 + if (boost) { 881 + switch (error) { 882 + /* Non fatal errors, chip is OK */ 883 + case 0: /* No error */ 884 + break; 885 + case 6: /* Timer expired */ 886 + dev_err(bq->dev, "Timer expired\n"); 887 + break; 888 + case 3: /* Battery voltage too low */ 889 + dev_err(bq->dev, "Battery voltage to low\n"); 890 + break; 891 + 892 + /* Fatal errors, disable and reset chip */ 893 + case 1: /* Overvoltage protection (chip fried) */ 894 + bq2415x_timer_error(bq, 895 + "Overvoltage protection (chip fried)"); 896 + return; 897 + case 2: /* Overload */ 898 + bq2415x_timer_error(bq, "Overload"); 899 + return; 900 + case 4: /* Battery overvoltage protection */ 901 + bq2415x_timer_error(bq, 902 + "Battery overvoltage protection"); 903 + return; 904 + case 5: /* Thermal shutdown (too hot) */ 905 + bq2415x_timer_error(bq, 906 + "Thermal shutdown (too hot)"); 907 + return; 908 + case 7: /* N/A */ 909 + bq2415x_timer_error(bq, "Unknown error"); 910 + return; 911 + } 912 + } else { 913 + switch (error) { 914 + /* Non fatal errors, chip is OK */ 915 + case 0: /* No error */ 916 + break; 917 + case 2: /* Sleep mode */ 918 + dev_err(bq->dev, "Sleep mode\n"); 919 + break; 920 + case 3: /* Poor input source */ 921 + dev_err(bq->dev, "Poor input source\n"); 922 + break; 923 + case 6: /* Timer expired */ 924 + dev_err(bq->dev, "Timer expired\n"); 925 + break; 926 + case 7: /* No battery */ 927 + dev_err(bq->dev, "No battery\n"); 928 + break; 929 + 930 + /* Fatal errors, disable and reset chip */ 931 + case 1: /* Overvoltage protection (chip fried) */ 932 + bq2415x_timer_error(bq, 933 + "Overvoltage protection (chip fried)"); 934 + return; 935 + case 4: /* Battery overvoltage protection */ 936 + bq2415x_timer_error(bq, 937 + "Battery overvoltage protection"); 938 + return; 939 + case 5: /* Thermal shutdown (too hot) */ 940 + bq2415x_timer_error(bq, 941 + "Thermal shutdown (too hot)"); 942 + return; 943 + } 944 + } 945 + 946 + schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); 947 + } 948 + 949 + /**** power supply interface code ****/ 950 + 951 + static enum power_supply_property bq2415x_power_supply_props[] = { 952 + /* TODO: maybe add more power supply properties */ 953 + POWER_SUPPLY_PROP_STATUS, 954 + POWER_SUPPLY_PROP_MODEL_NAME, 955 + }; 956 + 957 + static int bq2415x_power_supply_get_property(struct power_supply *psy, 958 + enum power_supply_property psp, 959 + union power_supply_propval *val) 960 + { 961 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 962 + charger); 963 + int ret; 964 + 965 + switch (psp) { 966 + case POWER_SUPPLY_PROP_STATUS: 967 + ret = bq2415x_exec_command(bq, BQ2415X_CHARGE_STATUS); 968 + if (ret < 0) 969 + return ret; 970 + else if (ret == 0) /* Ready */ 971 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 972 + else if (ret == 1) /* Charge in progress */ 973 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 974 + else if (ret == 2) /* Charge done */ 975 + val->intval = POWER_SUPPLY_STATUS_FULL; 976 + else 977 + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 978 + break; 979 + case POWER_SUPPLY_PROP_MODEL_NAME: 980 + val->strval = bq->model; 981 + break; 982 + default: 983 + return -EINVAL; 984 + } 985 + return 0; 986 + } 987 + 988 + static int bq2415x_power_supply_init(struct bq2415x_device *bq) 989 + { 990 + int ret; 991 + int chip; 992 + char revstr[8]; 993 + 994 + bq->charger.name = bq->name; 995 + bq->charger.type = POWER_SUPPLY_TYPE_USB; 996 + bq->charger.properties = bq2415x_power_supply_props; 997 + bq->charger.num_properties = ARRAY_SIZE(bq2415x_power_supply_props); 998 + bq->charger.get_property = bq2415x_power_supply_get_property; 999 + 1000 + ret = bq2415x_detect_chip(bq); 1001 + if (ret < 0) 1002 + chip = BQUNKNOWN; 1003 + else 1004 + chip = ret; 1005 + 1006 + ret = bq2415x_detect_revision(bq); 1007 + if (ret < 0) 1008 + strcpy(revstr, "unknown"); 1009 + else 1010 + sprintf(revstr, "1.%d", ret); 1011 + 1012 + bq->model = kasprintf(GFP_KERNEL, 1013 + "chip %s, revision %s, vender code %.3d", 1014 + bq2415x_chip_name[chip], revstr, 1015 + bq2415x_get_vender_code(bq)); 1016 + if (!bq->model) { 1017 + dev_err(bq->dev, "failed to allocate model name\n"); 1018 + return -ENOMEM; 1019 + } 1020 + 1021 + ret = power_supply_register(bq->dev, &bq->charger); 1022 + if (ret) { 1023 + kfree(bq->model); 1024 + return ret; 1025 + } 1026 + 1027 + return 0; 1028 + } 1029 + 1030 + static void bq2415x_power_supply_exit(struct bq2415x_device *bq) 1031 + { 1032 + bq->autotimer = 0; 1033 + if (bq->automode > 0) 1034 + bq->automode = 0; 1035 + cancel_delayed_work_sync(&bq->work); 1036 + power_supply_unregister(&bq->charger); 1037 + kfree(bq->model); 1038 + } 1039 + 1040 + /**** additional sysfs entries for power supply interface ****/ 1041 + 1042 + /* show *_status entries */ 1043 + static ssize_t bq2415x_sysfs_show_status(struct device *dev, 1044 + struct device_attribute *attr, 1045 + char *buf) 1046 + { 1047 + struct power_supply *psy = dev_get_drvdata(dev); 1048 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1049 + charger); 1050 + enum bq2415x_command command; 1051 + int ret; 1052 + 1053 + if (strcmp(attr->attr.name, "otg_status") == 0) 1054 + command = BQ2415X_OTG_STATUS; 1055 + else if (strcmp(attr->attr.name, "charge_status") == 0) 1056 + command = BQ2415X_CHARGE_STATUS; 1057 + else if (strcmp(attr->attr.name, "boost_status") == 0) 1058 + command = BQ2415X_BOOST_STATUS; 1059 + else if (strcmp(attr->attr.name, "fault_status") == 0) 1060 + command = BQ2415X_FAULT_STATUS; 1061 + else 1062 + return -EINVAL; 1063 + 1064 + ret = bq2415x_exec_command(bq, command); 1065 + if (ret < 0) 1066 + return ret; 1067 + return sprintf(buf, "%d\n", ret); 1068 + } 1069 + 1070 + /* 1071 + * set timer entry: 1072 + * auto - enable auto mode 1073 + * off - disable auto mode 1074 + * (other values) - reset chip timer 1075 + */ 1076 + static ssize_t bq2415x_sysfs_set_timer(struct device *dev, 1077 + struct device_attribute *attr, 1078 + const char *buf, 1079 + size_t count) 1080 + { 1081 + struct power_supply *psy = dev_get_drvdata(dev); 1082 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1083 + charger); 1084 + int ret = 0; 1085 + 1086 + if (strncmp(buf, "auto", 4) == 0) 1087 + bq2415x_set_autotimer(bq, 1); 1088 + else if (strncmp(buf, "off", 3) == 0) 1089 + bq2415x_set_autotimer(bq, 0); 1090 + else 1091 + ret = bq2415x_exec_command(bq, BQ2415X_TIMER_RESET); 1092 + 1093 + if (ret < 0) 1094 + return ret; 1095 + return count; 1096 + } 1097 + 1098 + /* show timer entry (auto or off) */ 1099 + static ssize_t bq2415x_sysfs_show_timer(struct device *dev, 1100 + struct device_attribute *attr, 1101 + char *buf) 1102 + { 1103 + struct power_supply *psy = dev_get_drvdata(dev); 1104 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1105 + charger); 1106 + 1107 + if (bq->timer_error) 1108 + return sprintf(buf, "%s\n", bq->timer_error); 1109 + 1110 + if (bq->autotimer) 1111 + return sprintf(buf, "auto\n"); 1112 + return sprintf(buf, "off\n"); 1113 + } 1114 + 1115 + /* 1116 + * set mode entry: 1117 + * auto - if automode is supported, enable it and set mode to reported 1118 + * none - disable charger and boost mode 1119 + * host - charging mode for host/hub chargers (current limit 500mA) 1120 + * dedicated - charging mode for dedicated chargers (unlimited current limit) 1121 + * boost - disable charger and enable boost mode 1122 + */ 1123 + static ssize_t bq2415x_sysfs_set_mode(struct device *dev, 1124 + struct device_attribute *attr, 1125 + const char *buf, 1126 + size_t count) 1127 + { 1128 + struct power_supply *psy = dev_get_drvdata(dev); 1129 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1130 + charger); 1131 + enum bq2415x_mode mode; 1132 + int ret = 0; 1133 + 1134 + if (strncmp(buf, "auto", 4) == 0) { 1135 + if (bq->automode < 0) 1136 + return -ENOSYS; 1137 + bq->automode = 1; 1138 + mode = bq->reported_mode; 1139 + } else if (strncmp(buf, "none", 4) == 0) { 1140 + if (bq->automode > 0) 1141 + bq->automode = 0; 1142 + mode = BQ2415X_MODE_NONE; 1143 + } else if (strncmp(buf, "host", 4) == 0) { 1144 + if (bq->automode > 0) 1145 + bq->automode = 0; 1146 + mode = BQ2415X_MODE_HOST_CHARGER; 1147 + } else if (strncmp(buf, "dedicated", 9) == 0) { 1148 + if (bq->automode > 0) 1149 + bq->automode = 0; 1150 + mode = BQ2415X_MODE_DEDICATED_CHARGER; 1151 + } else if (strncmp(buf, "boost", 5) == 0) { 1152 + if (bq->automode > 0) 1153 + bq->automode = 0; 1154 + mode = BQ2415X_MODE_BOOST; 1155 + } else if (strncmp(buf, "reset", 5) == 0) { 1156 + bq2415x_reset_chip(bq); 1157 + bq2415x_set_defaults(bq); 1158 + if (bq->automode <= 0) 1159 + return count; 1160 + bq->automode = 1; 1161 + mode = bq->reported_mode; 1162 + } else { 1163 + return -EINVAL; 1164 + } 1165 + 1166 + ret = bq2415x_set_mode(bq, mode); 1167 + if (ret < 0) 1168 + return ret; 1169 + return count; 1170 + } 1171 + 1172 + /* show mode entry (auto, none, host, dedicated or boost) */ 1173 + static ssize_t bq2415x_sysfs_show_mode(struct device *dev, 1174 + struct device_attribute *attr, 1175 + char *buf) 1176 + { 1177 + struct power_supply *psy = dev_get_drvdata(dev); 1178 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1179 + charger); 1180 + ssize_t ret = 0; 1181 + 1182 + if (bq->automode > 0) 1183 + ret += sprintf(buf+ret, "auto ("); 1184 + 1185 + switch (bq->mode) { 1186 + case BQ2415X_MODE_NONE: 1187 + ret += sprintf(buf+ret, "none"); 1188 + break; 1189 + case BQ2415X_MODE_HOST_CHARGER: 1190 + ret += sprintf(buf+ret, "host"); 1191 + break; 1192 + case BQ2415X_MODE_DEDICATED_CHARGER: 1193 + ret += sprintf(buf+ret, "dedicated"); 1194 + break; 1195 + case BQ2415X_MODE_BOOST: 1196 + ret += sprintf(buf+ret, "boost"); 1197 + break; 1198 + } 1199 + 1200 + if (bq->automode > 0) 1201 + ret += sprintf(buf+ret, ")"); 1202 + 1203 + ret += sprintf(buf+ret, "\n"); 1204 + return ret; 1205 + } 1206 + 1207 + /* show reported_mode entry (none, host, dedicated or boost) */ 1208 + static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev, 1209 + struct device_attribute *attr, 1210 + char *buf) 1211 + { 1212 + struct power_supply *psy = dev_get_drvdata(dev); 1213 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1214 + charger); 1215 + 1216 + if (bq->automode < 0) 1217 + return -EINVAL; 1218 + 1219 + switch (bq->reported_mode) { 1220 + case BQ2415X_MODE_NONE: 1221 + return sprintf(buf, "none\n"); 1222 + case BQ2415X_MODE_HOST_CHARGER: 1223 + return sprintf(buf, "host\n"); 1224 + case BQ2415X_MODE_DEDICATED_CHARGER: 1225 + return sprintf(buf, "dedicated\n"); 1226 + case BQ2415X_MODE_BOOST: 1227 + return sprintf(buf, "boost\n"); 1228 + } 1229 + 1230 + return -EINVAL; 1231 + } 1232 + 1233 + /* directly set raw value to chip register, format: 'register value' */ 1234 + static ssize_t bq2415x_sysfs_set_registers(struct device *dev, 1235 + struct device_attribute *attr, 1236 + const char *buf, 1237 + size_t count) 1238 + { 1239 + struct power_supply *psy = dev_get_drvdata(dev); 1240 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1241 + charger); 1242 + ssize_t ret = 0; 1243 + unsigned int reg; 1244 + unsigned int val; 1245 + 1246 + if (sscanf(buf, "%x %x", &reg, &val) != 2) 1247 + return -EINVAL; 1248 + 1249 + if (reg > 4 || val > 255) 1250 + return -EINVAL; 1251 + 1252 + ret = bq2415x_i2c_write(bq, reg, val); 1253 + if (ret < 0) 1254 + return ret; 1255 + return count; 1256 + } 1257 + 1258 + /* print value of chip register, format: 'register=value' */ 1259 + static ssize_t bq2415x_sysfs_print_reg(struct bq2415x_device *bq, 1260 + u8 reg, 1261 + char *buf) 1262 + { 1263 + int ret = bq2415x_i2c_read(bq, reg); 1264 + 1265 + if (ret < 0) 1266 + return sprintf(buf, "%#.2x=error %d\n", reg, ret); 1267 + return sprintf(buf, "%#.2x=%#.2x\n", reg, ret); 1268 + } 1269 + 1270 + /* show all raw values of chip register, format per line: 'register=value' */ 1271 + static ssize_t bq2415x_sysfs_show_registers(struct device *dev, 1272 + struct device_attribute *attr, 1273 + char *buf) 1274 + { 1275 + struct power_supply *psy = dev_get_drvdata(dev); 1276 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1277 + charger); 1278 + ssize_t ret = 0; 1279 + 1280 + ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_STATUS, buf+ret); 1281 + ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_CONTROL, buf+ret); 1282 + ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_VOLTAGE, buf+ret); 1283 + ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_VENDER, buf+ret); 1284 + ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_CURRENT, buf+ret); 1285 + return ret; 1286 + } 1287 + 1288 + /* set current and voltage limit entries (in mA or mV) */ 1289 + static ssize_t bq2415x_sysfs_set_limit(struct device *dev, 1290 + struct device_attribute *attr, 1291 + const char *buf, 1292 + size_t count) 1293 + { 1294 + struct power_supply *psy = dev_get_drvdata(dev); 1295 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1296 + charger); 1297 + long val; 1298 + int ret; 1299 + 1300 + if (kstrtol(buf, 10, &val) < 0) 1301 + return -EINVAL; 1302 + 1303 + if (strcmp(attr->attr.name, "current_limit") == 0) 1304 + ret = bq2415x_set_current_limit(bq, val); 1305 + else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0) 1306 + ret = bq2415x_set_weak_battery_voltage(bq, val); 1307 + else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0) 1308 + ret = bq2415x_set_battery_regulation_voltage(bq, val); 1309 + else if (strcmp(attr->attr.name, "charge_current") == 0) 1310 + ret = bq2415x_set_charge_current(bq, val); 1311 + else if (strcmp(attr->attr.name, "termination_current") == 0) 1312 + ret = bq2415x_set_termination_current(bq, val); 1313 + else 1314 + return -EINVAL; 1315 + 1316 + if (ret < 0) 1317 + return ret; 1318 + return count; 1319 + } 1320 + 1321 + /* show current and voltage limit entries (in mA or mV) */ 1322 + static ssize_t bq2415x_sysfs_show_limit(struct device *dev, 1323 + struct device_attribute *attr, 1324 + char *buf) 1325 + { 1326 + struct power_supply *psy = dev_get_drvdata(dev); 1327 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1328 + charger); 1329 + int ret; 1330 + 1331 + if (strcmp(attr->attr.name, "current_limit") == 0) 1332 + ret = bq2415x_get_current_limit(bq); 1333 + else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0) 1334 + ret = bq2415x_get_weak_battery_voltage(bq); 1335 + else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0) 1336 + ret = bq2415x_get_battery_regulation_voltage(bq); 1337 + else if (strcmp(attr->attr.name, "charge_current") == 0) 1338 + ret = bq2415x_get_charge_current(bq); 1339 + else if (strcmp(attr->attr.name, "termination_current") == 0) 1340 + ret = bq2415x_get_termination_current(bq); 1341 + else 1342 + return -EINVAL; 1343 + 1344 + if (ret < 0) 1345 + return ret; 1346 + return sprintf(buf, "%d\n", ret); 1347 + } 1348 + 1349 + /* set *_enable entries */ 1350 + static ssize_t bq2415x_sysfs_set_enable(struct device *dev, 1351 + struct device_attribute *attr, 1352 + const char *buf, 1353 + size_t count) 1354 + { 1355 + struct power_supply *psy = dev_get_drvdata(dev); 1356 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1357 + charger); 1358 + enum bq2415x_command command; 1359 + long val; 1360 + int ret; 1361 + 1362 + if (kstrtol(buf, 10, &val) < 0) 1363 + return -EINVAL; 1364 + 1365 + if (strcmp(attr->attr.name, "charge_termination_enable") == 0) 1366 + command = val ? BQ2415X_CHARGE_TERMINATION_ENABLE : 1367 + BQ2415X_CHARGE_TERMINATION_DISABLE; 1368 + else if (strcmp(attr->attr.name, "high_impedance_enable") == 0) 1369 + command = val ? BQ2415X_HIGH_IMPEDANCE_ENABLE : 1370 + BQ2415X_HIGH_IMPEDANCE_DISABLE; 1371 + else if (strcmp(attr->attr.name, "otg_pin_enable") == 0) 1372 + command = val ? BQ2415X_OTG_PIN_ENABLE : 1373 + BQ2415X_OTG_PIN_DISABLE; 1374 + else if (strcmp(attr->attr.name, "stat_pin_enable") == 0) 1375 + command = val ? BQ2415X_STAT_PIN_ENABLE : 1376 + BQ2415X_STAT_PIN_DISABLE; 1377 + else 1378 + return -EINVAL; 1379 + 1380 + ret = bq2415x_exec_command(bq, command); 1381 + if (ret < 0) 1382 + return ret; 1383 + return count; 1384 + } 1385 + 1386 + /* show *_enable entries */ 1387 + static ssize_t bq2415x_sysfs_show_enable(struct device *dev, 1388 + struct device_attribute *attr, 1389 + char *buf) 1390 + { 1391 + struct power_supply *psy = dev_get_drvdata(dev); 1392 + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, 1393 + charger); 1394 + enum bq2415x_command command; 1395 + int ret; 1396 + 1397 + if (strcmp(attr->attr.name, "charge_termination_enable") == 0) 1398 + command = BQ2415X_CHARGE_TERMINATION_STATUS; 1399 + else if (strcmp(attr->attr.name, "high_impedance_enable") == 0) 1400 + command = BQ2415X_HIGH_IMPEDANCE_STATUS; 1401 + else if (strcmp(attr->attr.name, "otg_pin_enable") == 0) 1402 + command = BQ2415X_OTG_PIN_STATUS; 1403 + else if (strcmp(attr->attr.name, "stat_pin_enable") == 0) 1404 + command = BQ2415X_STAT_PIN_STATUS; 1405 + else 1406 + return -EINVAL; 1407 + 1408 + ret = bq2415x_exec_command(bq, command); 1409 + if (ret < 0) 1410 + return ret; 1411 + return sprintf(buf, "%d\n", ret); 1412 + } 1413 + 1414 + static DEVICE_ATTR(current_limit, S_IWUSR | S_IRUGO, 1415 + bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit); 1416 + static DEVICE_ATTR(weak_battery_voltage, S_IWUSR | S_IRUGO, 1417 + bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit); 1418 + static DEVICE_ATTR(battery_regulation_voltage, S_IWUSR | S_IRUGO, 1419 + bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit); 1420 + static DEVICE_ATTR(charge_current, S_IWUSR | S_IRUGO, 1421 + bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit); 1422 + static DEVICE_ATTR(termination_current, S_IWUSR | S_IRUGO, 1423 + bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit); 1424 + 1425 + static DEVICE_ATTR(charge_termination_enable, S_IWUSR | S_IRUGO, 1426 + bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable); 1427 + static DEVICE_ATTR(high_impedance_enable, S_IWUSR | S_IRUGO, 1428 + bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable); 1429 + static DEVICE_ATTR(otg_pin_enable, S_IWUSR | S_IRUGO, 1430 + bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable); 1431 + static DEVICE_ATTR(stat_pin_enable, S_IWUSR | S_IRUGO, 1432 + bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable); 1433 + 1434 + static DEVICE_ATTR(reported_mode, S_IRUGO, 1435 + bq2415x_sysfs_show_reported_mode, NULL); 1436 + static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, 1437 + bq2415x_sysfs_show_mode, bq2415x_sysfs_set_mode); 1438 + static DEVICE_ATTR(timer, S_IWUSR | S_IRUGO, 1439 + bq2415x_sysfs_show_timer, bq2415x_sysfs_set_timer); 1440 + 1441 + static DEVICE_ATTR(registers, S_IWUSR | S_IRUGO, 1442 + bq2415x_sysfs_show_registers, bq2415x_sysfs_set_registers); 1443 + 1444 + static DEVICE_ATTR(otg_status, S_IRUGO, bq2415x_sysfs_show_status, NULL); 1445 + static DEVICE_ATTR(charge_status, S_IRUGO, bq2415x_sysfs_show_status, NULL); 1446 + static DEVICE_ATTR(boost_status, S_IRUGO, bq2415x_sysfs_show_status, NULL); 1447 + static DEVICE_ATTR(fault_status, S_IRUGO, bq2415x_sysfs_show_status, NULL); 1448 + 1449 + static struct attribute *bq2415x_sysfs_attributes[] = { 1450 + /* 1451 + * TODO: some (appropriate) of these attrs should be switched to 1452 + * use power supply class props. 1453 + */ 1454 + &dev_attr_current_limit.attr, 1455 + &dev_attr_weak_battery_voltage.attr, 1456 + &dev_attr_battery_regulation_voltage.attr, 1457 + &dev_attr_charge_current.attr, 1458 + &dev_attr_termination_current.attr, 1459 + 1460 + &dev_attr_charge_termination_enable.attr, 1461 + &dev_attr_high_impedance_enable.attr, 1462 + &dev_attr_otg_pin_enable.attr, 1463 + &dev_attr_stat_pin_enable.attr, 1464 + 1465 + &dev_attr_reported_mode.attr, 1466 + &dev_attr_mode.attr, 1467 + &dev_attr_timer.attr, 1468 + 1469 + &dev_attr_registers.attr, 1470 + 1471 + &dev_attr_otg_status.attr, 1472 + &dev_attr_charge_status.attr, 1473 + &dev_attr_boost_status.attr, 1474 + &dev_attr_fault_status.attr, 1475 + NULL, 1476 + }; 1477 + 1478 + static const struct attribute_group bq2415x_sysfs_attr_group = { 1479 + .attrs = bq2415x_sysfs_attributes, 1480 + }; 1481 + 1482 + static int bq2415x_sysfs_init(struct bq2415x_device *bq) 1483 + { 1484 + return sysfs_create_group(&bq->charger.dev->kobj, 1485 + &bq2415x_sysfs_attr_group); 1486 + } 1487 + 1488 + static void bq2415x_sysfs_exit(struct bq2415x_device *bq) 1489 + { 1490 + sysfs_remove_group(&bq->charger.dev->kobj, &bq2415x_sysfs_attr_group); 1491 + } 1492 + 1493 + /* main bq2415x probe function */ 1494 + static int bq2415x_probe(struct i2c_client *client, 1495 + const struct i2c_device_id *id) 1496 + { 1497 + int ret; 1498 + int num; 1499 + char *name; 1500 + struct bq2415x_device *bq; 1501 + 1502 + if (!client->dev.platform_data) { 1503 + dev_err(&client->dev, "platform data not set\n"); 1504 + return -ENODEV; 1505 + } 1506 + 1507 + /* Get new ID for the new device */ 1508 + ret = idr_pre_get(&bq2415x_id, GFP_KERNEL); 1509 + if (ret == 0) 1510 + return -ENOMEM; 1511 + 1512 + mutex_lock(&bq2415x_id_mutex); 1513 + ret = idr_get_new(&bq2415x_id, client, &num); 1514 + mutex_unlock(&bq2415x_id_mutex); 1515 + 1516 + if (ret < 0) 1517 + return ret; 1518 + 1519 + name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num); 1520 + if (!name) { 1521 + dev_err(&client->dev, "failed to allocate device name\n"); 1522 + ret = -ENOMEM; 1523 + goto error_1; 1524 + } 1525 + 1526 + bq = kzalloc(sizeof(*bq), GFP_KERNEL); 1527 + if (!bq) { 1528 + dev_err(&client->dev, "failed to allocate device data\n"); 1529 + ret = -ENOMEM; 1530 + goto error_2; 1531 + } 1532 + 1533 + i2c_set_clientdata(client, bq); 1534 + 1535 + bq->id = num; 1536 + bq->dev = &client->dev; 1537 + bq->chip = id->driver_data; 1538 + bq->name = name; 1539 + bq->mode = BQ2415X_MODE_NONE; 1540 + bq->reported_mode = BQ2415X_MODE_NONE; 1541 + bq->autotimer = 0; 1542 + bq->automode = 0; 1543 + 1544 + memcpy(&bq->init_data, client->dev.platform_data, 1545 + sizeof(bq->init_data)); 1546 + 1547 + bq2415x_reset_chip(bq); 1548 + 1549 + ret = bq2415x_power_supply_init(bq); 1550 + if (ret) { 1551 + dev_err(bq->dev, "failed to register power supply: %d\n", ret); 1552 + goto error_3; 1553 + } 1554 + 1555 + ret = bq2415x_sysfs_init(bq); 1556 + if (ret) { 1557 + dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret); 1558 + goto error_4; 1559 + } 1560 + 1561 + ret = bq2415x_set_defaults(bq); 1562 + if (ret) { 1563 + dev_err(bq->dev, "failed to set default values: %d\n", ret); 1564 + goto error_5; 1565 + } 1566 + 1567 + if (bq->init_data.set_mode_hook) { 1568 + if (bq->init_data.set_mode_hook( 1569 + bq2415x_hook_function, bq)) { 1570 + bq->automode = 1; 1571 + bq2415x_set_mode(bq, bq->reported_mode); 1572 + dev_info(bq->dev, "automode enabled\n"); 1573 + } else { 1574 + bq->automode = -1; 1575 + dev_info(bq->dev, "automode failed\n"); 1576 + } 1577 + } else { 1578 + bq->automode = -1; 1579 + dev_info(bq->dev, "automode not supported\n"); 1580 + } 1581 + 1582 + INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work); 1583 + bq2415x_set_autotimer(bq, 1); 1584 + 1585 + dev_info(bq->dev, "driver registered\n"); 1586 + return 0; 1587 + 1588 + error_5: 1589 + bq2415x_sysfs_exit(bq); 1590 + error_4: 1591 + bq2415x_power_supply_exit(bq); 1592 + error_3: 1593 + kfree(bq); 1594 + error_2: 1595 + kfree(name); 1596 + error_1: 1597 + mutex_lock(&bq2415x_id_mutex); 1598 + idr_remove(&bq2415x_id, num); 1599 + mutex_unlock(&bq2415x_id_mutex); 1600 + 1601 + return ret; 1602 + } 1603 + 1604 + /* main bq2415x remove function */ 1605 + 1606 + static int bq2415x_remove(struct i2c_client *client) 1607 + { 1608 + struct bq2415x_device *bq = i2c_get_clientdata(client); 1609 + 1610 + if (bq->init_data.set_mode_hook) 1611 + bq->init_data.set_mode_hook(NULL, NULL); 1612 + 1613 + bq2415x_sysfs_exit(bq); 1614 + bq2415x_power_supply_exit(bq); 1615 + 1616 + bq2415x_reset_chip(bq); 1617 + 1618 + mutex_lock(&bq2415x_id_mutex); 1619 + idr_remove(&bq2415x_id, bq->id); 1620 + mutex_unlock(&bq2415x_id_mutex); 1621 + 1622 + dev_info(bq->dev, "driver unregistered\n"); 1623 + 1624 + kfree(bq->name); 1625 + kfree(bq); 1626 + 1627 + return 0; 1628 + } 1629 + 1630 + static const struct i2c_device_id bq2415x_i2c_id_table[] = { 1631 + { "bq2415x", BQUNKNOWN }, 1632 + { "bq24150", BQ24150 }, 1633 + { "bq24150a", BQ24150A }, 1634 + { "bq24151", BQ24151 }, 1635 + { "bq24151a", BQ24151A }, 1636 + { "bq24152", BQ24152 }, 1637 + { "bq24153", BQ24153 }, 1638 + { "bq24153a", BQ24153A }, 1639 + { "bq24155", BQ24155 }, 1640 + { "bq24156", BQ24156 }, 1641 + { "bq24156a", BQ24156A }, 1642 + { "bq24158", BQ24158 }, 1643 + {}, 1644 + }; 1645 + MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table); 1646 + 1647 + static struct i2c_driver bq2415x_driver = { 1648 + .driver = { 1649 + .name = "bq2415x-charger", 1650 + }, 1651 + .probe = bq2415x_probe, 1652 + .remove = bq2415x_remove, 1653 + .id_table = bq2415x_i2c_id_table, 1654 + }; 1655 + 1656 + static int __init bq2415x_init(void) 1657 + { 1658 + return i2c_add_driver(&bq2415x_driver); 1659 + } 1660 + module_init(bq2415x_init); 1661 + 1662 + static void __exit bq2415x_exit(void) 1663 + { 1664 + i2c_del_driver(&bq2415x_driver); 1665 + } 1666 + module_exit(bq2415x_exit); 1667 + 1668 + MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); 1669 + MODULE_DESCRIPTION("bq2415x charger driver"); 1670 + MODULE_LICENSE("GPL");
+8
drivers/power/bq27x00_battery.c
··· 230 230 */ 231 231 static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di) 232 232 { 233 + int flags; 234 + bool is_bq27500 = di->chip == BQ27500; 235 + bool is_higher = bq27xxx_is_chip_version_higher(di); 236 + 237 + flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); 238 + if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI)) 239 + return -ENODATA; 240 + 233 241 return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC); 234 242 } 235 243
+2 -2
drivers/power/ds2782_battery.c
··· 80 80 { 81 81 int ret; 82 82 83 - ret = swab16(i2c_smbus_read_word_data(info->client, reg_msb)); 83 + ret = i2c_smbus_read_word_data(info->client, reg_msb); 84 84 if (ret < 0) { 85 85 dev_err(&info->client->dev, "register read failed\n"); 86 86 return ret; 87 87 } 88 88 89 - *val = ret; 89 + *val = swab16(ret); 90 90 return 0; 91 91 } 92 92
+3 -2
drivers/power/generic-adc-battery.c
··· 279 279 } 280 280 281 281 memcpy(psy->properties, gab_props, sizeof(gab_props)); 282 - properties = psy->properties + sizeof(gab_props); 282 + properties = (enum power_supply_property *) 283 + ((char *)psy->properties + sizeof(gab_props)); 283 284 284 285 /* 285 286 * getting channel from iio and copying the battery properties ··· 328 327 ret = request_any_context_irq(irq, gab_charged, 329 328 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 330 329 "battery charged", adc_bat); 331 - if (ret) 330 + if (ret < 0) 332 331 goto err_gpio; 333 332 } 334 333
+9 -36
drivers/power/jz4740-battery.c
··· 33 33 struct jz_battery_platform_data *pdata; 34 34 struct platform_device *pdev; 35 35 36 - struct resource *mem; 37 36 void __iomem *base; 38 37 39 38 int irq; ··· 243 244 struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data; 244 245 struct jz_battery *jz_battery; 245 246 struct power_supply *battery; 247 + struct resource *mem; 246 248 247 249 if (!pdata) { 248 250 dev_err(&pdev->dev, "No platform_data supplied\n"); 249 251 return -ENXIO; 250 252 } 251 253 252 - jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL); 254 + jz_battery = devm_kzalloc(&pdev->dev, sizeof(*jz_battery), GFP_KERNEL); 253 255 if (!jz_battery) { 254 256 dev_err(&pdev->dev, "Failed to allocate driver structure\n"); 255 257 return -ENOMEM; ··· 260 260 261 261 jz_battery->irq = platform_get_irq(pdev, 0); 262 262 if (jz_battery->irq < 0) { 263 - ret = jz_battery->irq; 264 263 dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); 265 - goto err_free; 264 + return jz_battery->irq; 266 265 } 267 266 268 - jz_battery->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 269 - if (!jz_battery->mem) { 270 - ret = -ENOENT; 271 - dev_err(&pdev->dev, "Failed to get platform mmio resource\n"); 272 - goto err_free; 273 - } 267 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 274 268 275 - jz_battery->mem = request_mem_region(jz_battery->mem->start, 276 - resource_size(jz_battery->mem), pdev->name); 277 - if (!jz_battery->mem) { 278 - ret = -EBUSY; 279 - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); 280 - goto err_free; 281 - } 282 - 283 - jz_battery->base = ioremap_nocache(jz_battery->mem->start, 284 - resource_size(jz_battery->mem)); 285 - if (!jz_battery->base) { 286 - ret = -EBUSY; 287 - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); 288 - goto err_release_mem_region; 289 - } 269 + jz_battery->base = devm_request_and_ioremap(&pdev->dev, mem); 270 + if (!jz_battery->base) 271 + return -EBUSY; 290 272 291 273 battery = &jz_battery->battery; 292 274 battery->name = pdata->info.name; ··· 291 309 jz_battery); 292 310 if (ret) { 293 311 dev_err(&pdev->dev, "Failed to request irq %d\n", ret); 294 - goto err_iounmap; 312 + goto err; 295 313 } 296 314 disable_irq(jz_battery->irq); 297 315 ··· 348 366 gpio_free(jz_battery->pdata->gpio_charge); 349 367 err_free_irq: 350 368 free_irq(jz_battery->irq, jz_battery); 351 - err_iounmap: 369 + err: 352 370 platform_set_drvdata(pdev, NULL); 353 - iounmap(jz_battery->base); 354 - err_release_mem_region: 355 - release_mem_region(jz_battery->mem->start, resource_size(jz_battery->mem)); 356 - err_free: 357 - kfree(jz_battery); 358 371 return ret; 359 372 } 360 373 ··· 368 391 power_supply_unregister(&jz_battery->battery); 369 392 370 393 free_irq(jz_battery->irq, jz_battery); 371 - 372 - iounmap(jz_battery->base); 373 - release_mem_region(jz_battery->mem->start, resource_size(jz_battery->mem)); 374 - kfree(jz_battery); 375 394 376 395 return 0; 377 396 }
+16 -59
drivers/power/lp8788-charger.c
··· 235 235 return 0; 236 236 } 237 237 238 - static int lp8788_get_vbatt_adc(struct lp8788_charger *pchg, 239 - unsigned int *result) 238 + static int lp8788_get_vbatt_adc(struct lp8788_charger *pchg, int *result) 240 239 { 241 240 struct iio_channel *channel = pchg->chan[LP8788_VBATT]; 242 - int scaleint; 243 - int scalepart; 244 - int ret; 245 241 246 242 if (!channel) 247 243 return -EINVAL; 248 244 249 - ret = iio_read_channel_scale(channel, &scaleint, &scalepart); 250 - if (ret != IIO_VAL_INT_PLUS_MICRO) 251 - return -EINVAL; 252 - 253 - /* unit: mV */ 254 - *result = (scaleint + scalepart * 1000000) / 1000; 255 - 256 - return 0; 245 + return iio_read_channel_processed(channel, result); 257 246 } 258 247 259 248 static int lp8788_get_battery_voltage(struct lp8788_charger *pchg, ··· 257 268 struct lp8788 *lp = pchg->lp; 258 269 struct lp8788_charger_platform_data *pdata = pchg->pdata; 259 270 unsigned int max_vbatt; 260 - unsigned int vbatt; 271 + int vbatt; 261 272 enum lp8788_charging_state state; 262 273 u8 data; 263 274 int ret; ··· 293 304 union power_supply_propval *val) 294 305 { 295 306 struct iio_channel *channel = pchg->chan[LP8788_BATT_TEMP]; 296 - int scaleint; 297 - int scalepart; 307 + int result; 298 308 int ret; 299 309 300 310 if (!channel) 301 311 return -EINVAL; 302 312 303 - ret = iio_read_channel_scale(channel, &scaleint, &scalepart); 304 - if (ret != IIO_VAL_INT_PLUS_MICRO) 313 + ret = iio_read_channel_processed(channel, &result); 314 + if (ret < 0) 305 315 return -EINVAL; 306 316 307 317 /* unit: 0.1 'C */ 308 - val->intval = (scaleint + scalepart * 1000000) / 100; 318 + val->intval = result * 10; 309 319 310 320 return 0; 311 321 } ··· 580 592 } 581 593 } 582 594 583 - static void lp8788_setup_adc_channel(struct lp8788_charger *pchg) 595 + static void lp8788_setup_adc_channel(const char *consumer_name, 596 + struct lp8788_charger *pchg) 584 597 { 585 598 struct lp8788_charger_platform_data *pdata = pchg->pdata; 586 - struct device *dev = pchg->lp->dev; 587 599 struct iio_channel *chan; 588 - enum lp8788_adc_id id; 589 - const char *chan_name[LPADC_MAX] = { 590 - [LPADC_VBATT_5P5] = "vbatt-5p5", 591 - [LPADC_VBATT_6P0] = "vbatt-6p0", 592 - [LPADC_VBATT_5P0] = "vbatt-5p0", 593 - [LPADC_ADC1] = "adc1", 594 - [LPADC_ADC2] = "adc2", 595 - [LPADC_ADC3] = "adc3", 596 - [LPADC_ADC4] = "adc4", 597 - }; 598 600 599 601 if (!pdata) 600 602 return; 601 603 602 - id = pdata->vbatt_adc; 603 - switch (id) { 604 - case LPADC_VBATT_5P5: 605 - case LPADC_VBATT_6P0: 606 - case LPADC_VBATT_5P0: 607 - chan = iio_channel_get(NULL, chan_name[id]); 608 - pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan; 609 - break; 610 - default: 611 - dev_err(dev, "invalid ADC id for VBATT: %d\n", id); 612 - pchg->chan[LP8788_VBATT] = NULL; 613 - break; 614 - } 604 + /* ADC channel for battery voltage */ 605 + chan = iio_channel_get(consumer_name, pdata->adc_vbatt); 606 + pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan; 615 607 616 - id = pdata->batt_temp_adc; 617 - switch (id) { 618 - case LPADC_ADC1: 619 - case LPADC_ADC2: 620 - case LPADC_ADC3: 621 - case LPADC_ADC4: 622 - chan = iio_channel_get(NULL, chan_name[id]); 623 - pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan; 624 - break; 625 - default: 626 - dev_err(dev, "invalid ADC id for BATT_TEMP : %d\n", id); 627 - pchg->chan[LP8788_BATT_TEMP] = NULL; 628 - break; 629 - } 608 + /* ADC channel for battery temperature */ 609 + chan = iio_channel_get(consumer_name, pdata->adc_batt_temp); 610 + pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan; 630 611 } 631 612 632 613 static void lp8788_release_adc_channel(struct lp8788_charger *pchg) ··· 704 747 if (ret) 705 748 return ret; 706 749 707 - lp8788_setup_adc_channel(pchg); 750 + lp8788_setup_adc_channel(pdev->name, pchg); 708 751 709 752 ret = lp8788_psy_register(pdev, pchg); 710 753 if (ret)
+2 -1
drivers/power/max17042_battery.c
··· 572 572 __func__); 573 573 return -EIO; 574 574 } 575 - max17042_verify_model_lock(chip); 575 + 576 + ret = max17042_verify_model_lock(chip); 576 577 if (ret) { 577 578 dev_err(&chip->client->dev, "%s lock verify failed\n", 578 579 __func__);
+50 -1
drivers/power/max8925_power.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/err.h> 14 14 #include <linux/slab.h> 15 + #include <linux/of.h> 15 16 #include <linux/i2c.h> 16 17 #include <linux/interrupt.h> 17 18 #include <linux/platform_device.h> ··· 427 426 return 0; 428 427 } 429 428 429 + #ifdef CONFIG_OF 430 + static struct max8925_power_pdata * 431 + max8925_power_dt_init(struct platform_device *pdev) 432 + { 433 + struct device_node *nproot = pdev->dev.parent->of_node; 434 + struct device_node *np; 435 + int batt_detect; 436 + int topoff_threshold; 437 + int fast_charge; 438 + int no_temp_support; 439 + int no_insert_detect; 440 + struct max8925_power_pdata *pdata; 441 + 442 + if (!nproot) 443 + return pdev->dev.platform_data; 444 + 445 + np = of_find_node_by_name(nproot, "charger"); 446 + if (!np) { 447 + dev_err(&pdev->dev, "failed to find charger node\n"); 448 + return NULL; 449 + } 450 + 451 + pdata = devm_kzalloc(&pdev->dev, 452 + sizeof(struct max8925_power_pdata), 453 + GFP_KERNEL); 454 + 455 + of_property_read_u32(np, "topoff-threshold", &topoff_threshold); 456 + of_property_read_u32(np, "batt-detect", &batt_detect); 457 + of_property_read_u32(np, "fast-charge", &fast_charge); 458 + of_property_read_u32(np, "no-insert-detect", &no_insert_detect); 459 + of_property_read_u32(np, "no-temp-support", &no_temp_support); 460 + 461 + pdata->batt_detect = batt_detect; 462 + pdata->fast_charge = fast_charge; 463 + pdata->topoff_threshold = topoff_threshold; 464 + pdata->no_insert_detect = no_insert_detect; 465 + pdata->no_temp_support = no_temp_support; 466 + 467 + return pdata; 468 + } 469 + #else 470 + static struct max8925_power_pdata * 471 + max8925_power_dt_init(struct platform_device *pdev) 472 + { 473 + return pdev->dev.platform_data; 474 + } 475 + #endif 476 + 430 477 static int max8925_power_probe(struct platform_device *pdev) 431 478 { 432 479 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); ··· 482 433 struct max8925_power_info *info; 483 434 int ret; 484 435 485 - pdata = pdev->dev.platform_data; 436 + pdata = max8925_power_dt_init(pdev); 486 437 if (!pdata) { 487 438 dev_err(&pdev->dev, "platform data isn't assigned to " 488 439 "power supply\n");
+96
drivers/power/power_supply_core.c
··· 216 216 return; 217 217 thermal_zone_device_unregister(psy->tzd); 218 218 } 219 + 220 + /* thermal cooling device callbacks */ 221 + static int ps_get_max_charge_cntl_limit(struct thermal_cooling_device *tcd, 222 + unsigned long *state) 223 + { 224 + struct power_supply *psy; 225 + union power_supply_propval val; 226 + int ret; 227 + 228 + psy = tcd->devdata; 229 + ret = psy->get_property(psy, 230 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val); 231 + if (!ret) 232 + *state = val.intval; 233 + 234 + return ret; 235 + } 236 + 237 + static int ps_get_cur_chrage_cntl_limit(struct thermal_cooling_device *tcd, 238 + unsigned long *state) 239 + { 240 + struct power_supply *psy; 241 + union power_supply_propval val; 242 + int ret; 243 + 244 + psy = tcd->devdata; 245 + ret = psy->get_property(psy, 246 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); 247 + if (!ret) 248 + *state = val.intval; 249 + 250 + return ret; 251 + } 252 + 253 + static int ps_set_cur_charge_cntl_limit(struct thermal_cooling_device *tcd, 254 + unsigned long state) 255 + { 256 + struct power_supply *psy; 257 + union power_supply_propval val; 258 + int ret; 259 + 260 + psy = tcd->devdata; 261 + val.intval = state; 262 + ret = psy->set_property(psy, 263 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); 264 + 265 + return ret; 266 + } 267 + 268 + static struct thermal_cooling_device_ops psy_tcd_ops = { 269 + .get_max_state = ps_get_max_charge_cntl_limit, 270 + .get_cur_state = ps_get_cur_chrage_cntl_limit, 271 + .set_cur_state = ps_set_cur_charge_cntl_limit, 272 + }; 273 + 274 + static int psy_register_cooler(struct power_supply *psy) 275 + { 276 + int i; 277 + 278 + /* Register for cooling device if psy can control charging */ 279 + for (i = 0; i < psy->num_properties; i++) { 280 + if (psy->properties[i] == 281 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) { 282 + psy->tcd = thermal_cooling_device_register( 283 + (char *)psy->name, 284 + psy, &psy_tcd_ops); 285 + if (IS_ERR(psy->tcd)) 286 + return PTR_ERR(psy->tcd); 287 + break; 288 + } 289 + } 290 + return 0; 291 + } 292 + 293 + static void psy_unregister_cooler(struct power_supply *psy) 294 + { 295 + if (IS_ERR_OR_NULL(psy->tcd)) 296 + return; 297 + thermal_cooling_device_unregister(psy->tcd); 298 + } 219 299 #else 220 300 static int psy_register_thermal(struct power_supply *psy) 221 301 { ··· 303 223 } 304 224 305 225 static void psy_unregister_thermal(struct power_supply *psy) 226 + { 227 + } 228 + 229 + static int psy_register_cooler(struct power_supply *psy) 230 + { 231 + return 0; 232 + } 233 + 234 + static void psy_unregister_cooler(struct power_supply *psy) 306 235 { 307 236 } 308 237 #endif ··· 348 259 if (rc) 349 260 goto register_thermal_failed; 350 261 262 + rc = psy_register_cooler(psy); 263 + if (rc) 264 + goto register_cooler_failed; 265 + 351 266 rc = power_supply_create_triggers(psy); 352 267 if (rc) 353 268 goto create_triggers_failed; ··· 361 268 goto success; 362 269 363 270 create_triggers_failed: 271 + psy_unregister_cooler(psy); 272 + register_cooler_failed: 364 273 psy_unregister_thermal(psy); 365 274 register_thermal_failed: 366 275 device_del(dev); ··· 379 284 cancel_work_sync(&psy->changed_work); 380 285 sysfs_remove_link(&psy->dev->kobj, "powers"); 381 286 power_supply_remove_triggers(psy); 287 + psy_unregister_cooler(psy); 382 288 psy_unregister_thermal(psy); 383 289 device_unregister(psy->dev); 384 290 }
+2
drivers/power/power_supply_sysfs.c
··· 164 164 POWER_SUPPLY_ATTR(constant_charge_current_max), 165 165 POWER_SUPPLY_ATTR(constant_charge_voltage), 166 166 POWER_SUPPLY_ATTR(constant_charge_voltage_max), 167 + POWER_SUPPLY_ATTR(charge_control_limit), 168 + POWER_SUPPLY_ATTR(charge_control_limit_max), 167 169 POWER_SUPPLY_ATTR(energy_full_design), 168 170 POWER_SUPPLY_ATTR(energy_empty_design), 169 171 POWER_SUPPLY_ATTR(energy_full),
+251
drivers/power/rx51_battery.c
··· 1 + /* 2 + * Nokia RX-51 battery driver 3 + * 4 + * Copyright (C) 2012 Pali Rohár <pali.rohar@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/param.h> 23 + #include <linux/platform_device.h> 24 + #include <linux/power_supply.h> 25 + #include <linux/slab.h> 26 + #include <linux/i2c/twl4030-madc.h> 27 + 28 + struct rx51_device_info { 29 + struct device *dev; 30 + struct power_supply bat; 31 + }; 32 + 33 + /* 34 + * Read ADCIN channel value, code copied from maemo kernel 35 + */ 36 + static int rx51_battery_read_adc(int channel) 37 + { 38 + struct twl4030_madc_request req; 39 + 40 + req.channels = 1 << channel; 41 + req.do_avg = 1; 42 + req.method = TWL4030_MADC_SW1; 43 + req.func_cb = NULL; 44 + req.type = TWL4030_MADC_WAIT; 45 + 46 + if (twl4030_madc_conversion(&req) <= 0) 47 + return -ENODATA; 48 + 49 + return req.rbuf[channel]; 50 + } 51 + 52 + /* 53 + * Read ADCIN channel 12 (voltage) and convert RAW value to micro voltage 54 + * This conversion formula was extracted from maemo program bsi-read 55 + */ 56 + static int rx51_battery_read_voltage(struct rx51_device_info *di) 57 + { 58 + int voltage = rx51_battery_read_adc(12); 59 + 60 + if (voltage < 0) 61 + return voltage; 62 + 63 + return 1000 * (10000 * voltage / 1705); 64 + } 65 + 66 + /* 67 + * Temperature look-up tables 68 + * TEMP = (1/(t1 + 1/298) - 273.15) 69 + * Where t1 = (1/B) * ln((RAW_ADC_U * 2.5)/(R * I * 255)) 70 + * Formula is based on experimental data, RX-51 CAL data, maemo program bme 71 + * and formula from da9052 driver with values R = 100, B = 3380, I = 0.00671 72 + */ 73 + 74 + /* 75 + * Table1 (temperature for first 25 RAW values) 76 + * Usage: TEMP = rx51_temp_table1[RAW] 77 + * RAW is between 1 and 24 78 + * TEMP is between 201 C and 55 C 79 + */ 80 + static u8 rx51_temp_table1[] = { 81 + 255, 201, 159, 138, 124, 114, 106, 99, 94, 89, 85, 82, 78, 75, 82 + 73, 70, 68, 66, 64, 62, 61, 59, 57, 56, 55 83 + }; 84 + 85 + /* 86 + * Table2 (lowest RAW value for temperature) 87 + * Usage: RAW = rx51_temp_table2[TEMP-rx51_temp_table2_first] 88 + * TEMP is between 53 C and -32 C 89 + * RAW is between 25 and 993 90 + */ 91 + #define rx51_temp_table2_first 53 92 + static u16 rx51_temp_table2[] = { 93 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 94 + 40, 41, 43, 44, 46, 48, 49, 51, 53, 55, 57, 59, 61, 64, 95 + 66, 69, 71, 74, 77, 80, 83, 86, 90, 94, 97, 101, 106, 110, 96 + 115, 119, 125, 130, 136, 141, 148, 154, 161, 168, 176, 184, 202, 211, 97 + 221, 231, 242, 254, 266, 279, 293, 308, 323, 340, 357, 375, 395, 415, 98 + 437, 460, 485, 511, 539, 568, 600, 633, 669, 706, 747, 790, 836, 885, 99 + 937, 993, 1024 100 + }; 101 + 102 + /* 103 + * Read ADCIN channel 0 (battery temp) and convert value to tenths of Celsius 104 + * Use Temperature look-up tables for conversation 105 + */ 106 + static int rx51_battery_read_temperature(struct rx51_device_info *di) 107 + { 108 + int min = 0; 109 + int max = ARRAY_SIZE(rx51_temp_table2) - 1; 110 + int raw = rx51_battery_read_adc(0); 111 + 112 + /* Zero and negative values are undefined */ 113 + if (raw <= 0) 114 + return INT_MAX; 115 + 116 + /* ADC channels are 10 bit, higher value are undefined */ 117 + if (raw >= (1 << 10)) 118 + return INT_MIN; 119 + 120 + /* First check for temperature in first direct table */ 121 + if (raw < ARRAY_SIZE(rx51_temp_table1)) 122 + return rx51_temp_table1[raw] * 100; 123 + 124 + /* Binary search RAW value in second inverse table */ 125 + while (max - min > 1) { 126 + int mid = (max + min) / 2; 127 + if (rx51_temp_table2[mid] <= raw) 128 + min = mid; 129 + else if (rx51_temp_table2[mid] > raw) 130 + max = mid; 131 + if (rx51_temp_table2[mid] == raw) 132 + break; 133 + } 134 + 135 + return (rx51_temp_table2_first - min) * 100; 136 + } 137 + 138 + /* 139 + * Read ADCIN channel 4 (BSI) and convert RAW value to micro Ah 140 + * This conversion formula was extracted from maemo program bsi-read 141 + */ 142 + static int rx51_battery_read_capacity(struct rx51_device_info *di) 143 + { 144 + int capacity = rx51_battery_read_adc(4); 145 + 146 + if (capacity < 0) 147 + return capacity; 148 + 149 + return 1280 * (1200 * capacity)/(1024 - capacity); 150 + } 151 + 152 + /* 153 + * Return power_supply property 154 + */ 155 + static int rx51_battery_get_property(struct power_supply *psy, 156 + enum power_supply_property psp, 157 + union power_supply_propval *val) 158 + { 159 + struct rx51_device_info *di = container_of((psy), 160 + struct rx51_device_info, bat); 161 + 162 + switch (psp) { 163 + case POWER_SUPPLY_PROP_TECHNOLOGY: 164 + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 165 + break; 166 + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 167 + val->intval = 4200000; 168 + break; 169 + case POWER_SUPPLY_PROP_PRESENT: 170 + val->intval = rx51_battery_read_voltage(di) ? 1 : 0; 171 + break; 172 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 173 + val->intval = rx51_battery_read_voltage(di); 174 + break; 175 + case POWER_SUPPLY_PROP_TEMP: 176 + val->intval = rx51_battery_read_temperature(di); 177 + break; 178 + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 179 + val->intval = rx51_battery_read_capacity(di); 180 + break; 181 + default: 182 + return -EINVAL; 183 + } 184 + 185 + if (val->intval == INT_MAX || val->intval == INT_MIN) 186 + return -EINVAL; 187 + 188 + return 0; 189 + } 190 + 191 + static enum power_supply_property rx51_battery_props[] = { 192 + POWER_SUPPLY_PROP_TECHNOLOGY, 193 + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 194 + POWER_SUPPLY_PROP_PRESENT, 195 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 196 + POWER_SUPPLY_PROP_TEMP, 197 + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 198 + }; 199 + 200 + static int __devinit rx51_battery_probe(struct platform_device *pdev) 201 + { 202 + struct rx51_device_info *di; 203 + int ret; 204 + 205 + di = kzalloc(sizeof(*di), GFP_KERNEL); 206 + if (!di) 207 + return -ENOMEM; 208 + 209 + platform_set_drvdata(pdev, di); 210 + 211 + di->bat.name = dev_name(&pdev->dev); 212 + di->bat.type = POWER_SUPPLY_TYPE_BATTERY; 213 + di->bat.properties = rx51_battery_props; 214 + di->bat.num_properties = ARRAY_SIZE(rx51_battery_props); 215 + di->bat.get_property = rx51_battery_get_property; 216 + 217 + ret = power_supply_register(di->dev, &di->bat); 218 + if (ret) { 219 + platform_set_drvdata(pdev, NULL); 220 + kfree(di); 221 + return ret; 222 + } 223 + 224 + return 0; 225 + } 226 + 227 + static int __devexit rx51_battery_remove(struct platform_device *pdev) 228 + { 229 + struct rx51_device_info *di = platform_get_drvdata(pdev); 230 + 231 + power_supply_unregister(&di->bat); 232 + platform_set_drvdata(pdev, NULL); 233 + kfree(di); 234 + 235 + return 0; 236 + } 237 + 238 + static struct platform_driver rx51_battery_driver = { 239 + .probe = rx51_battery_probe, 240 + .remove = __devexit_p(rx51_battery_remove), 241 + .driver = { 242 + .name = "rx51-battery", 243 + .owner = THIS_MODULE, 244 + }, 245 + }; 246 + module_platform_driver(rx51_battery_driver); 247 + 248 + MODULE_ALIAS("platform:rx51-battery"); 249 + MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); 250 + MODULE_DESCRIPTION("Nokia RX-51 battery driver"); 251 + MODULE_LICENSE("GPL");
+6 -6
drivers/power/twl4030_charger.c
··· 114 114 115 115 static int twl4030_bci_read(u8 reg, u8 *val) 116 116 { 117 - return twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, val, reg); 117 + return twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, val, reg); 118 118 } 119 119 120 120 static int twl4030_clear_set_boot_bci(u8 clear, u8 set) 121 121 { 122 - return twl4030_clear_set(TWL4030_MODULE_PM_MASTER, clear, 122 + return twl4030_clear_set(TWL_MODULE_PM_MASTER, clear, 123 123 TWL4030_CONFIG_DONE | TWL4030_BCIAUTOWEN | set, 124 124 TWL4030_PM_MASTER_BOOT_BCI); 125 125 } ··· 152 152 int ret; 153 153 u8 hwsts; 154 154 155 - ret = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &hwsts, 155 + ret = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &hwsts, 156 156 TWL4030_PM_MASTER_STS_HW_CONDITIONS); 157 157 if (ret < 0) 158 158 return 0; ··· 199 199 return ret; 200 200 201 201 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */ 202 - ret = twl4030_clear_set(TWL4030_MODULE_MAIN_CHARGE, 0, 202 + ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0, 203 203 TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4); 204 204 } else { 205 205 ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0); ··· 238 238 if (uvolt < 2500000 || 239 239 uamp < 25) { 240 240 /* disable charging of backup battery */ 241 - ret = twl4030_clear_set(TWL4030_MODULE_PM_RECEIVER, 241 + ret = twl4030_clear_set(TWL_MODULE_PM_RECEIVER, 242 242 TWL4030_BBCHEN, 0, TWL4030_BB_CFG); 243 243 return ret; 244 244 } ··· 262 262 else 263 263 flags |= TWL4030_BBISEL_25uA; 264 264 265 - ret = twl4030_clear_set(TWL4030_MODULE_PM_RECEIVER, 265 + ret = twl4030_clear_set(TWL_MODULE_PM_RECEIVER, 266 266 TWL4030_BBSEL_MASK | TWL4030_BBISEL_MASK, 267 267 flags, 268 268 TWL4030_BB_CFG);
+9 -27
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 + enum { 278 + NTC_EXTERNAL = 0, 279 + NTC_INTERNAL, 278 280 }; 279 281 280 - struct abx500_charger_platform_data { 281 - char **supplied_to; 282 - size_t num_supplicants; 283 - bool autopower_cfg; 284 - }; 285 - 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 - }; 282 + int bmdevs_of_probe(struct device *dev, 283 + struct device_node *np, 284 + struct abx500_bm_data **battery); 303 285 304 286 int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, 305 287 u8 value);
+4 -4
include/linux/mfd/lp8788.h
··· 211 211 212 212 /* 213 213 * struct lp8788_charger_platform_data 214 - * @vbatt_adc : adc selection id for battery voltage 215 - * @batt_temp_adc : adc selection id for battery temperature 214 + * @adc_vbatt : adc channel name for battery voltage 215 + * @adc_batt_temp : adc channel name for battery temperature 216 216 * @max_vbatt_mv : used for calculating battery capacity 217 217 * @chg_params : initial charging parameters 218 218 * @num_chg_params : numbers of charging parameters 219 219 * @charger_event : the charger event can be reported to the platform side 220 220 */ 221 221 struct lp8788_charger_platform_data { 222 - enum lp8788_adc_id vbatt_adc; 223 - enum lp8788_adc_id batt_temp_adc; 222 + const char *adc_vbatt; 223 + const char *adc_batt_temp; 224 224 unsigned int max_vbatt_mv; 225 225 struct lp8788_chg_param *chg_params; 226 226 int num_chg_params;
+95
include/linux/power/bq2415x_charger.h
··· 1 + /* 2 + * bq2415x charger driver 3 + * 4 + * Copyright (C) 2011-2012 Pali Rohár <pali.rohar@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + #ifndef BQ2415X_CHARGER_H 22 + #define BQ2415X_CHARGER_H 23 + 24 + /* 25 + * This is platform data for bq2415x chip. It contains default board 26 + * voltages and currents which can be also later configured via sysfs. If 27 + * value is -1 then default chip value (specified in datasheet) will be 28 + * used. 29 + * 30 + * Value resistor_sense is needed for for configuring charge and 31 + * termination current. It it is less or equal to zero, configuring charge 32 + * and termination current will not be possible. 33 + * 34 + * Function set_mode_hook is needed for automode (setting correct current 35 + * limit when charger is connected/disconnected or setting boost mode). 36 + * When is NULL, automode function is disabled. When is not NULL, it must 37 + * have this prototype: 38 + * 39 + * int (*set_mode_hook)( 40 + * void (*hook)(enum bq2415x_mode mode, void *data), 41 + * void *data) 42 + * 43 + * hook is hook function (see below) and data is pointer to driver private 44 + * data 45 + * 46 + * bq2415x driver will call it as: 47 + * 48 + * platform_data->set_mode_hook(bq2415x_hook_function, bq2415x_device); 49 + * 50 + * Board/platform function set_mode_hook return non zero value when hook 51 + * function was successful registered. Platform code should call that hook 52 + * function (which get from pointer, with data) every time when charger 53 + * was connected/disconnected or require to enable boost mode. bq2415x 54 + * driver then will set correct current limit, enable/disable charger or 55 + * boost mode. 56 + * 57 + * Hook function has this prototype: 58 + * 59 + * void hook(enum bq2415x_mode mode, void *data); 60 + * 61 + * mode is bq2415x mode (charger or boost) 62 + * data is pointer to driver private data (which get from 63 + * set_charger_type_hook) 64 + * 65 + * When bq driver is being unloaded, it call function: 66 + * 67 + * platform_data->set_mode_hook(NULL, NULL); 68 + * 69 + * (hook function and driver private data are NULL) 70 + * 71 + * After that board/platform code must not call driver hook function! It 72 + * is possible that pointer to hook function will not be valid and calling 73 + * will cause undefined result. 74 + */ 75 + 76 + /* Supported modes with maximal current limit */ 77 + enum bq2415x_mode { 78 + BQ2415X_MODE_NONE, /* unknown or no charger (100mA) */ 79 + BQ2415X_MODE_HOST_CHARGER, /* usb host/hub charger (500mA) */ 80 + BQ2415X_MODE_DEDICATED_CHARGER, /* dedicated charger (unlimited) */ 81 + BQ2415X_MODE_BOOST, /* boost mode (charging disabled) */ 82 + }; 83 + 84 + struct bq2415x_platform_data { 85 + int current_limit; /* mA */ 86 + int weak_battery_voltage; /* mV */ 87 + int battery_regulation_voltage; /* mV */ 88 + int charge_current; /* mA */ 89 + int termination_current; /* mA */ 90 + int resistor_sense; /* m ohm */ 91 + int (*set_mode_hook)(void (*hook)(enum bq2415x_mode mode, void *data), 92 + void *data); 93 + }; 94 + 95 + #endif
+3
include/linux/power_supply.h
··· 114 114 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 115 115 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 116 116 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 117 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, 118 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, 117 119 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 118 120 POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN, 119 121 POWER_SUPPLY_PROP_ENERGY_FULL, ··· 188 186 struct work_struct changed_work; 189 187 #ifdef CONFIG_THERMAL 190 188 struct thermal_zone_device *tzd; 189 + struct thermal_cooling_device *tcd; 191 190 #endif 192 191 193 192 #ifdef CONFIG_LEDS_TRIGGERS