blob: cb5be3d39b8fdf7e579c5c4c6bf6031e0627be2e [file] [log] [blame]
Xiaozhe Shi28f5dd52013-01-04 12:19:58 -08001/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Xiaozhe Shi73a65692012-09-18 17:51:57 -070013#define pr_fmt(fmt) "BMS: %s: " fmt, __func__
Xiaozhe Shib19f7032012-08-16 12:14:16 -070014
15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/err.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/power_supply.h>
23#include <linux/spmi.h>
Xiaozhe Shie118c692012-09-24 15:17:43 -070024#include <linux/rtc.h>
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -070025#include <linux/delay.h>
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070026#include <linux/qpnp/qpnp-adc.h>
Xiaozhe Shi73a65692012-09-18 17:51:57 -070027#include <linux/mfd/pm8xxx/batterydata-lib.h>
Xiaozhe Shib19f7032012-08-16 12:14:16 -070028
Xiaozhe Shib19f7032012-08-16 12:14:16 -070029/* BMS Register Offsets */
30#define BMS1_REVISION1 0x0
31#define BMS1_REVISION2 0x1
32#define BMS1_STATUS1 0x8
33#define BMS1_MODE_CTL 0X40
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070034/* Coulomb counter clear registers */
Xiaozhe Shib19f7032012-08-16 12:14:16 -070035#define BMS1_CC_DATA_CTL 0x42
Xiaozhe Shia045a562012-11-28 16:55:39 -080036#define BMS1_CC_CLEAR_CTL 0x43
Xiaozhe Shi20640b52013-01-03 11:49:30 -080037/* BMS Tolerances */
38#define BMS1_TOL_CTL 0X44
Xiaozhe Shib19f7032012-08-16 12:14:16 -070039/* OCV limit registers */
40#define BMS1_OCV_USE_LOW_LIMIT_THR0 0x48
41#define BMS1_OCV_USE_LOW_LIMIT_THR1 0x49
42#define BMS1_OCV_USE_HIGH_LIMIT_THR0 0x4A
43#define BMS1_OCV_USE_HIGH_LIMIT_THR1 0x4B
44#define BMS1_OCV_USE_LIMIT_CTL 0x4C
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -070045/* Delay control */
46#define BMS1_S1_DELAY_CTL 0x5A
Xiaozhe Shib19f7032012-08-16 12:14:16 -070047/* CC interrupt threshold */
48#define BMS1_CC_THR0 0x7A
49#define BMS1_CC_THR1 0x7B
50#define BMS1_CC_THR2 0x7C
51#define BMS1_CC_THR3 0x7D
52#define BMS1_CC_THR4 0x7E
53/* OCV for r registers */
54#define BMS1_OCV_FOR_R_DATA0 0x80
55#define BMS1_OCV_FOR_R_DATA1 0x81
56#define BMS1_VSENSE_FOR_R_DATA0 0x82
57#define BMS1_VSENSE_FOR_R_DATA1 0x83
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070058/* Coulomb counter data */
Xiaozhe Shib19f7032012-08-16 12:14:16 -070059#define BMS1_CC_DATA0 0x8A
60#define BMS1_CC_DATA1 0x8B
61#define BMS1_CC_DATA2 0x8C
62#define BMS1_CC_DATA3 0x8D
63#define BMS1_CC_DATA4 0x8E
64/* OCV for soc data */
65#define BMS1_OCV_FOR_SOC_DATA0 0x90
66#define BMS1_OCV_FOR_SOC_DATA1 0x91
67#define BMS1_VSENSE_PON_DATA0 0x94
68#define BMS1_VSENSE_PON_DATA1 0x95
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070069#define BMS1_VSENSE_AVG_DATA0 0x98
70#define BMS1_VSENSE_AVG_DATA1 0x99
Xiaozhe Shib19f7032012-08-16 12:14:16 -070071#define BMS1_VBAT_AVG_DATA0 0x9E
72#define BMS1_VBAT_AVG_DATA1 0x9F
73/* Extra bms registers */
74#define BMS1_BMS_DATA_REG_0 0xB0
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070075#define IAVG_STORAGE_REG 0xB1
76#define SOC_STORAGE_REG 0xB2
Xiaozhe Shib19f7032012-08-16 12:14:16 -070077#define BMS1_BMS_DATA_REG_3 0xB3
Xiaozhe Shic40b3972012-11-30 14:11:16 -080078/* IADC Channel Select */
79#define IADC1_BMS_ADC_CH_SEL_CTL 0x48
Xiaozhe Shib19f7032012-08-16 12:14:16 -070080
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070081/* Configuration for saving of shutdown soc/iavg */
82#define IGNORE_SOC_TEMP_DECIDEG 50
83#define IAVG_STEP_SIZE_MA 50
84#define IAVG_START 600
Xiaozhe Shif5f966d2013-02-19 14:23:11 -080085#define IAVG_INVALID 0xFF
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070086#define SOC_ZERO 0xFF
87
Xiaozhe Shie118c692012-09-24 15:17:43 -070088#define IAVG_SAMPLES 16
89
Xiaozhe Shib19f7032012-08-16 12:14:16 -070090#define QPNP_BMS_DEV_NAME "qcom,qpnp-bms"
91
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070092struct soc_params {
93 int fcc_uah;
94 int cc_uah;
Xiaozhe Shi904f1f72012-12-04 12:47:21 -080095 int rbatt_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070096 int iavg_ua;
97 int uuc_uah;
98 int ocv_charge_uah;
Xiaozhe Shif36d2862013-01-04 10:17:35 -080099 int delta_time_s;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700100};
101
102struct raw_soc_params {
103 uint16_t last_good_ocv_raw;
104 int64_t cc;
105 int last_good_ocv_uv;
106};
107
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700108struct qpnp_bms_chip {
109 struct device *dev;
110 struct power_supply bms_psy;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -0700111 struct power_supply *batt_psy;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700112 struct spmi_device *spmi;
113 u16 base;
Xiaozhe Shic40b3972012-11-30 14:11:16 -0800114 u16 iadc_base;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700115
116 u8 revision1;
117 u8 revision2;
Xiaozhe Shid5d21412013-02-06 17:14:41 -0800118 int battery_present;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -0800119 bool new_battery;
120 bool last_soc_invalid;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700121 /* platform data */
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -0800122 int r_sense_uohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700123 unsigned int v_cutoff_uv;
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -0800124 int max_voltage_uv;
125 int r_conn_mohm;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700126 int shutdown_soc_valid_limit;
127 int adjust_soc_low_threshold;
128 int adjust_soc_high_threshold;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700129 int chg_term_ua;
Xiaozhe Shi73a65692012-09-18 17:51:57 -0700130 enum battery_type batt_type;
131 unsigned int fcc;
132 struct single_row_lut *fcc_temp_lut;
133 struct single_row_lut *fcc_sf_lut;
134 struct pc_temp_ocv_lut *pc_temp_ocv_lut;
135 struct sf_lut *pc_sf_lut;
136 struct sf_lut *rbatt_sf_lut;
137 int default_rbatt_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700138
139 struct delayed_work calculate_soc_delayed_work;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -0800140 struct work_struct recalc_work;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700141
142 struct mutex bms_output_lock;
143 struct mutex last_ocv_uv_mutex;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700144 struct mutex soc_invalidation_mutex;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700145
Xiaozhe Shic40b3972012-11-30 14:11:16 -0800146 bool use_external_rsense;
Xiaozhe Shibdf14742012-12-05 12:41:48 -0800147 bool use_ocv_thresholds;
Xiaozhe Shic40b3972012-11-30 14:11:16 -0800148
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700149 bool ignore_shutdown_soc;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -0800150 bool shutdown_soc_invalid;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700151 int shutdown_soc;
152 int shutdown_iavg_ma;
153
Xiaozhe Shi4be85782013-02-22 17:33:40 -0800154 struct wake_lock low_voltage_wake_lock;
155 bool low_voltage_wake_lock_held;
156 int low_voltage_threshold;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700157 int low_soc_calc_threshold;
158 int low_soc_calculate_soc_ms;
159 int calculate_soc_ms;
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -0800160 struct wake_lock soc_wake_lock;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700161
Xiaozhe Shie118c692012-09-24 15:17:43 -0700162 uint16_t ocv_reading_at_100;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700163 uint16_t prev_last_good_ocv_raw;
164 int last_ocv_uv;
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800165 int last_ocv_temp;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700166 int last_cc_uah;
167 unsigned long tm_sec;
168 bool first_time_calc_soc;
169 bool first_time_calc_uuc;
170 int pon_ocv_uv;
171
172 int iavg_samples_ma[IAVG_SAMPLES];
173 int iavg_index;
174 int iavg_num_samples;
175 struct timespec t_soc_queried;
176 int last_soc;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -0700177 int last_soc_est;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700178
179 int charge_time_us;
180 int catch_up_time_us;
181 struct single_row_lut *adjusted_fcc_temp_lut;
182
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700183 unsigned int vadc_v0625;
184 unsigned int vadc_v1250;
185
Xiaozhe Shi904f1f72012-12-04 12:47:21 -0800186 int ibat_max_ua;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700187 int prev_iavg_ua;
188 int prev_uuc_iavg_ma;
189 int prev_pc_unusable;
190 int ibat_at_cv_ua;
191 int soc_at_cv;
192 int prev_chg_soc;
193 int calculated_soc;
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -0800194 int prev_voltage_based_soc;
195 bool use_voltage_soc;
Xiaozhe Shibdf14742012-12-05 12:41:48 -0800196
197 int ocv_high_threshold_uv;
198 int ocv_low_threshold_uv;
Xiaozhe Shicdeee312012-12-18 15:10:18 -0800199 unsigned long last_recalc_time;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700200};
201
202static struct of_device_id qpnp_bms_match_table[] = {
203 { .compatible = QPNP_BMS_DEV_NAME },
204 {}
205};
206
207static char *qpnp_bms_supplicants[] = {
208 "battery"
209};
210
211static enum power_supply_property msm_bms_power_props[] = {
Xiaozhe Shid5d21412013-02-06 17:14:41 -0800212 POWER_SUPPLY_PROP_PRESENT,
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700213 POWER_SUPPLY_PROP_CAPACITY,
214 POWER_SUPPLY_PROP_CURRENT_NOW,
Xiaozhe Shi904f1f72012-12-04 12:47:21 -0800215 POWER_SUPPLY_PROP_CURRENT_MAX,
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700216 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
217};
218
Xiaozhe Shi20640b52013-01-03 11:49:30 -0800219static bool bms_reset;
Xiaozhe Shi781b0a22012-11-05 17:18:27 -0800220
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700221static int qpnp_read_wrapper(struct qpnp_bms_chip *chip, u8 *val,
222 u16 base, int count)
223{
224 int rc;
225 struct spmi_device *spmi = chip->spmi;
226
227 rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val, count);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700228 if (rc) {
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700229 pr_err("SPMI read failed rc=%d\n", rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700230 return rc;
231 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700232 return 0;
233}
234
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700235static int qpnp_write_wrapper(struct qpnp_bms_chip *chip, u8 *val,
236 u16 base, int count)
237{
238 int rc;
239 struct spmi_device *spmi = chip->spmi;
240
241 rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val, count);
242 if (rc) {
243 pr_err("SPMI write failed rc=%d\n", rc);
244 return rc;
245 }
246 return 0;
247}
248
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800249static int qpnp_masked_write_base(struct qpnp_bms_chip *chip, u16 addr,
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700250 u8 mask, u8 val)
251{
252 int rc;
253 u8 reg;
254
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800255 rc = qpnp_read_wrapper(chip, &reg, addr, 1);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700256 if (rc) {
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800257 pr_err("read failed addr = %03X, rc = %d\n", addr, rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700258 return rc;
259 }
260 reg &= ~mask;
261 reg |= val & mask;
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800262 rc = qpnp_write_wrapper(chip, &reg, addr, 1);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700263 if (rc) {
264 pr_err("write failed addr = %03X, val = %02x, mask = %02x, reg = %02x, rc = %d\n",
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800265 addr, val, mask, reg, rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700266 return rc;
267 }
268 return 0;
269}
270
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800271static int qpnp_masked_write_iadc(struct qpnp_bms_chip *chip, u16 addr,
272 u8 mask, u8 val)
273{
274 return qpnp_masked_write_base(chip, chip->iadc_base + addr, mask, val);
275}
276
277static int qpnp_masked_write(struct qpnp_bms_chip *chip, u16 addr,
278 u8 mask, u8 val)
279{
280 return qpnp_masked_write_base(chip, chip->base + addr, mask, val);
281}
282
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700283#define HOLD_OREG_DATA BIT(0)
284static int lock_output_data(struct qpnp_bms_chip *chip)
285{
286 int rc;
287
288 rc = qpnp_masked_write(chip, BMS1_CC_DATA_CTL,
289 HOLD_OREG_DATA, HOLD_OREG_DATA);
290 if (rc) {
291 pr_err("couldnt lock bms output rc = %d\n", rc);
292 return rc;
293 }
294 return 0;
295}
296
297static int unlock_output_data(struct qpnp_bms_chip *chip)
298{
299 int rc;
300
301 rc = qpnp_masked_write(chip, BMS1_CC_DATA_CTL, HOLD_OREG_DATA, 0);
302 if (rc) {
303 pr_err("fail to unlock BMS_CONTROL rc = %d\n", rc);
304 return rc;
305 }
306 return 0;
307}
308
309#define V_PER_BIT_MUL_FACTOR 97656
310#define V_PER_BIT_DIV_FACTOR 1000
311#define VADC_INTRINSIC_OFFSET 0x6000
312
Xiaozhe Shibdf14742012-12-05 12:41:48 -0800313static int vadc_reading_to_uv(int reading)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700314{
315 if (reading <= VADC_INTRINSIC_OFFSET)
316 return 0;
317
318 return (reading - VADC_INTRINSIC_OFFSET)
319 * V_PER_BIT_MUL_FACTOR / V_PER_BIT_DIV_FACTOR;
320}
321
322#define VADC_CALIB_UV 625000
323#define VBATT_MUL_FACTOR 3
324
Xiaozhe Shibdf14742012-12-05 12:41:48 -0800325static int adjust_vbatt_reading(struct qpnp_bms_chip *chip, int reading_uv)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700326{
327 s64 numerator, denominator;
328
329 if (reading_uv == 0)
330 return 0;
331
332 /* don't adjust if not calibrated */
333 if (chip->vadc_v0625 == 0 || chip->vadc_v1250 == 0) {
334 pr_debug("No cal yet return %d\n",
335 VBATT_MUL_FACTOR * reading_uv);
336 return VBATT_MUL_FACTOR * reading_uv;
337 }
338
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700339 numerator = ((s64)reading_uv - chip->vadc_v0625) * VADC_CALIB_UV;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700340 denominator = (s64)chip->vadc_v1250 - chip->vadc_v0625;
341 if (denominator == 0)
342 return reading_uv * VBATT_MUL_FACTOR;
343 return (VADC_CALIB_UV + div_s64(numerator, denominator))
344 * VBATT_MUL_FACTOR;
345}
346
Xiaozhe Shibdf14742012-12-05 12:41:48 -0800347static int convert_vbatt_uv_to_raw(struct qpnp_bms_chip *chip,
348 int unadjusted_vbatt)
349{
350 int scaled_vbatt = unadjusted_vbatt / VBATT_MUL_FACTOR;
351
352 if (scaled_vbatt <= 0)
353 return VADC_INTRINSIC_OFFSET;
354 return ((scaled_vbatt * V_PER_BIT_DIV_FACTOR) / V_PER_BIT_MUL_FACTOR)
355 + VADC_INTRINSIC_OFFSET;
356}
357
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700358static inline int convert_vbatt_raw_to_uv(struct qpnp_bms_chip *chip,
359 uint16_t reading)
360{
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700361 int uv;
362
363 uv = vadc_reading_to_uv(reading);
364 pr_debug("%u raw converted into %d uv\n", reading, uv);
365 uv = adjust_vbatt_reading(chip, uv);
366 pr_debug("adjusted into %d uv\n", uv);
367 return uv;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700368}
369
370#define CC_READING_RESOLUTION_N 542535
371#define CC_READING_RESOLUTION_D 100000
372static int cc_reading_to_uv(int16_t reading)
373{
374 return div_s64(reading * CC_READING_RESOLUTION_N,
375 CC_READING_RESOLUTION_D);
376}
377
Xiaozhe Shi0c484932013-02-05 16:14:10 -0800378#define QPNP_ADC_GAIN_IDEAL 3291LL
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700379static s64 cc_adjust_for_gain(s64 uv, uint16_t gain)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700380{
381 s64 result_uv;
382
383 pr_debug("adjusting_uv = %lld\n", uv);
Xiaozhe Shi820a47a2012-11-27 13:23:27 -0800384 if (gain == 0) {
385 pr_debug("gain is %d, not adjusting\n", gain);
386 return uv;
387 }
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700388 pr_debug("adjusting by factor: %lld/%hu = %lld%%\n",
Xiaozhe Shi0c484932013-02-05 16:14:10 -0800389 QPNP_ADC_GAIN_IDEAL, gain,
390 div_s64(QPNP_ADC_GAIN_IDEAL * 100LL, (s64)gain));
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700391
Xiaozhe Shi0c484932013-02-05 16:14:10 -0800392 result_uv = div_s64(uv * QPNP_ADC_GAIN_IDEAL, (s64)gain);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700393 pr_debug("result_uv = %lld\n", result_uv);
394 return result_uv;
395}
396
397static int convert_vsense_to_uv(struct qpnp_bms_chip *chip,
398 int16_t reading)
399{
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700400 struct qpnp_iadc_calib calibration;
401
402 qpnp_iadc_get_gain_and_offset(&calibration);
403 return cc_adjust_for_gain(cc_reading_to_uv(reading),
Xiaozhe Shi0c484932013-02-05 16:14:10 -0800404 calibration.gain_raw - calibration.offset_raw);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700405}
406
407static int read_vsense_avg(struct qpnp_bms_chip *chip, int *result_uv)
408{
409 int rc;
410 int16_t reading;
411
412 rc = qpnp_read_wrapper(chip, (u8 *)&reading,
413 chip->base + BMS1_VSENSE_AVG_DATA0, 2);
414
415 if (rc) {
416 pr_err("fail to read VSENSE_AVG rc = %d\n", rc);
417 return rc;
418 }
419
420 *result_uv = convert_vsense_to_uv(chip, reading);
421 return 0;
422}
423
424static int get_battery_current(struct qpnp_bms_chip *chip, int *result_ua)
425{
426 int vsense_uv = 0;
427
Xiaozhe Shid0a79542012-11-06 10:00:38 -0800428 if (chip->r_sense_uohm == 0) {
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700429 pr_err("r_sense is zero\n");
430 return -EINVAL;
431 }
432
433 mutex_lock(&chip->bms_output_lock);
434 lock_output_data(chip);
435 read_vsense_avg(chip, &vsense_uv);
436 unlock_output_data(chip);
437 mutex_unlock(&chip->bms_output_lock);
438
439 pr_debug("vsense_uv=%duV\n", vsense_uv);
440 /* cast for signed division */
Xiaozhe Shid0a79542012-11-06 10:00:38 -0800441 *result_ua = div_s64((vsense_uv * 1000000LL), (int)chip->r_sense_uohm);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700442 pr_debug("ibat=%duA\n", *result_ua);
443 return 0;
444}
445
446static int get_battery_voltage(int *result_uv)
447{
448 int rc;
449 struct qpnp_vadc_result adc_result;
450
451 rc = qpnp_vadc_read(VBAT_SNS, &adc_result);
452 if (rc) {
453 pr_err("error reading adc channel = %d, rc = %d\n",
454 VBAT_SNS, rc);
455 return rc;
456 }
457 pr_debug("mvolts phy = %lld meas = 0x%llx\n", adc_result.physical,
458 adc_result.measurement);
459 *result_uv = (int)adc_result.physical;
460 return 0;
461}
462
Xiaozhe Shie118c692012-09-24 15:17:43 -0700463#define CC_36_BIT_MASK 0xFFFFFFFFFLL
464
465static int read_cc_raw(struct qpnp_bms_chip *chip, int64_t *reading)
466{
467 int64_t raw_reading;
468 int rc;
469
470 rc = qpnp_read_wrapper(chip, (u8 *)&raw_reading,
471 chip->base + BMS1_CC_DATA0, 5);
472 if (rc) {
473 pr_err("Error reading cc: rc = %d\n", rc);
474 return -ENXIO;
475 }
476
477 raw_reading = raw_reading & CC_36_BIT_MASK;
478 /* convert 36 bit signed value into 64 signed value */
479 *reading = (raw_reading >> 35) == 0LL ?
480 raw_reading : ((-1LL ^ CC_36_BIT_MASK) | raw_reading);
481 pr_debug("before conversion: %llx, after conversion: %llx\n",
482 raw_reading, *reading);
483
484 return 0;
485}
486
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700487static int calib_vadc(struct qpnp_bms_chip *chip)
488{
Xiaozhe Shif62c0152013-03-28 17:57:19 -0700489 int rc, raw_0625, raw_1250;
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700490 struct qpnp_vadc_result result;
491
492 rc = qpnp_vadc_read(REF_625MV, &result);
493 if (rc) {
494 pr_debug("vadc read failed with rc = %d\n", rc);
495 return rc;
496 }
Xiaozhe Shif62c0152013-03-28 17:57:19 -0700497 raw_0625 = result.adc_code;
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700498
499 rc = qpnp_vadc_read(REF_125V, &result);
500 if (rc) {
501 pr_debug("vadc read failed with rc = %d\n", rc);
502 return rc;
503 }
Xiaozhe Shif62c0152013-03-28 17:57:19 -0700504 raw_1250 = result.adc_code;
505 chip->vadc_v0625 = vadc_reading_to_uv(raw_0625);
506 chip->vadc_v1250 = vadc_reading_to_uv(raw_1250);
507 pr_debug("vadc calib: 0625 = %d raw (%d uv), 1250 = %d raw (%d uv)\n",
508 raw_0625, chip->vadc_v0625,
509 raw_1250, chip->vadc_v1250);
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700510 return 0;
511}
512
Xiaozhe Shie118c692012-09-24 15:17:43 -0700513static void convert_and_store_ocv(struct qpnp_bms_chip *chip,
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800514 struct raw_soc_params *raw,
515 int batt_temp)
Xiaozhe Shie118c692012-09-24 15:17:43 -0700516{
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700517 int rc;
518
519 pr_debug("prev_last_good_ocv_raw = %d, last_good_ocv_raw = %d\n",
520 chip->prev_last_good_ocv_raw,
521 raw->last_good_ocv_raw);
522 rc = calib_vadc(chip);
523 if (rc)
524 pr_err("Vadc reference voltage read failed, rc = %d\n", rc);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700525 chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
526 raw->last_good_ocv_uv = convert_vbatt_raw_to_uv(chip,
527 raw->last_good_ocv_raw);
528 chip->last_ocv_uv = raw->last_good_ocv_uv;
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800529 chip->last_ocv_temp = batt_temp;
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700530 pr_debug("last_good_ocv_uv = %d\n", raw->last_good_ocv_uv);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700531}
532
Xiaozhe Shia045a562012-11-28 16:55:39 -0800533#define CLEAR_CC BIT(7)
534#define CLEAR_SW_CC BIT(6)
535/**
536 * reset both cc and sw-cc.
537 * note: this should only be ever called from one thread
538 * or there may be a race condition where CC is never enabled
539 * again
540 */
541static void reset_cc(struct qpnp_bms_chip *chip)
542{
543 int rc;
544
545 pr_debug("resetting cc manually\n");
546 rc = qpnp_masked_write(chip, BMS1_CC_CLEAR_CTL,
547 CLEAR_CC | CLEAR_SW_CC,
548 CLEAR_CC | CLEAR_SW_CC);
549 if (rc)
550 pr_err("cc reset failed: %d\n", rc);
551
552 /* wait for 100us for cc to reset */
553 udelay(100);
554
555 rc = qpnp_masked_write(chip, BMS1_CC_CLEAR_CTL,
556 CLEAR_CC | CLEAR_SW_CC, 0);
557 if (rc)
558 pr_err("cc reenable failed: %d\n", rc);
559}
560
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -0800561static bool is_battery_charging(struct qpnp_bms_chip *chip)
562{
563 union power_supply_propval ret = {0,};
564
565 if (chip->batt_psy == NULL)
566 chip->batt_psy = power_supply_get_by_name("battery");
567 if (chip->batt_psy) {
568 /* if battery has been registered, use the status property */
569 chip->batt_psy->get_property(chip->batt_psy,
570 POWER_SUPPLY_PROP_STATUS, &ret);
571 return ret.intval == POWER_SUPPLY_STATUS_CHARGING;
572 }
573
574 /* Default to false if the battery power supply is not registered. */
575 pr_debug("battery power supply is not registered\n");
576 return false;
577}
578
579static bool is_batfet_open(struct qpnp_bms_chip *chip)
580{
581 union power_supply_propval ret = {0,};
582
583 if (chip->batt_psy == NULL)
584 chip->batt_psy = power_supply_get_by_name("battery");
585 if (chip->batt_psy) {
586 /* if battery has been registered, use the status property */
587 chip->batt_psy->get_property(chip->batt_psy,
588 POWER_SUPPLY_PROP_STATUS, &ret);
589 return ret.intval == POWER_SUPPLY_STATUS_FULL;
590 }
591
592 /* Default to true if the battery power supply is not registered. */
593 pr_debug("battery power supply is not registered\n");
594 return true;
595}
596
597static int get_simultaneous_batt_v_and_i(struct qpnp_bms_chip *chip,
598 int *ibat_ua, int *vbat_uv)
599{
600 struct qpnp_iadc_result i_result;
601 struct qpnp_vadc_result v_result;
602 enum qpnp_iadc_channels iadc_channel;
603 int rc;
604
605 iadc_channel = chip->use_external_rsense ?
606 EXTERNAL_RSENSE : INTERNAL_RSENSE;
607 rc = qpnp_iadc_vadc_sync_read(iadc_channel, &i_result,
608 VBAT_SNS, &v_result);
609 if (rc) {
610 pr_err("vadc read failed with rc: %d\n", rc);
611 return rc;
612 }
613 /*
614 * reverse the current read by the iadc, since the bms uses
615 * flipped battery current polarity.
616 */
617 *ibat_ua = -1 * (int)i_result.result_ua;
618 *vbat_uv = (int)v_result.physical;
619
620 return 0;
621}
622
623static int estimate_ocv(struct qpnp_bms_chip *chip)
624{
625 int ibat_ua, vbat_uv, ocv_est_uv;
626 int rc;
627 int rbatt_mohm = chip->default_rbatt_mohm + chip->r_conn_mohm;
628
629 rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
630 if (rc) {
631 pr_err("simultaneous failed rc = %d\n", rc);
632 return rc;
633 }
634
635 ocv_est_uv = vbat_uv + (ibat_ua * rbatt_mohm) / 1000;
636 pr_debug("estimated pon ocv = %d\n", ocv_est_uv);
637 return ocv_est_uv;
638}
639
640static void reset_for_new_battery(struct qpnp_bms_chip *chip, int batt_temp)
641{
642 chip->last_ocv_uv = estimate_ocv(chip);
643 chip->last_soc = -EINVAL;
644 chip->soc_at_cv = -EINVAL;
645 chip->shutdown_soc_invalid = true;
646 chip->shutdown_soc = 0;
647 chip->shutdown_iavg_ma = 0;
648 chip->prev_pc_unusable = -EINVAL;
649 reset_cc(chip);
650 chip->last_cc_uah = INT_MIN;
651 chip->last_ocv_temp = batt_temp;
652 chip->last_soc_invalid = true;
653}
654
Abhijeet Dharmapurikar15f30fb2012-12-27 17:20:29 -0800655#define OCV_RAW_UNINITIALIZED 0xFFFF
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700656static int read_soc_params_raw(struct qpnp_bms_chip *chip,
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800657 struct raw_soc_params *raw,
658 int batt_temp)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700659{
Xiaozhe Shie118c692012-09-24 15:17:43 -0700660 int rc;
661
662 mutex_lock(&chip->bms_output_lock);
Xiaozhe Shia045a562012-11-28 16:55:39 -0800663
Abhijeet Dharmapurikar15f30fb2012-12-27 17:20:29 -0800664 if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
Xiaozhe Shia045a562012-11-28 16:55:39 -0800665 /* software workaround for BMS 1.0
666 * The coulomb counter does not reset upon PON, so reset it
667 * manually upon probe. */
668 if (chip->revision1 == 0 && chip->revision2 == 0)
669 reset_cc(chip);
670 }
671
Xiaozhe Shie118c692012-09-24 15:17:43 -0700672 lock_output_data(chip);
673
674 rc = qpnp_read_wrapper(chip, (u8 *)&raw->last_good_ocv_raw,
675 chip->base + BMS1_OCV_FOR_SOC_DATA0, 2);
676 if (rc) {
677 pr_err("Error reading ocv: rc = %d\n", rc);
678 return -ENXIO;
679 }
680
681 rc = read_cc_raw(chip, &raw->cc);
682 if (rc) {
683 pr_err("Failed to read raw cc data, rc = %d\n", rc);
684 return rc;
685 }
686
687 unlock_output_data(chip);
688 mutex_unlock(&chip->bms_output_lock);
689
Abhijeet Dharmapurikar15f30fb2012-12-27 17:20:29 -0800690 if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800691 convert_and_store_ocv(chip, raw, batt_temp);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700692 pr_debug("PON_OCV_UV = %d\n", chip->last_ocv_uv);
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -0800693 } else if (chip->new_battery) {
694 /* if a new battery was inserted, estimate the ocv */
695 reset_for_new_battery(chip, batt_temp);
696 raw->cc = 0;
697 raw->last_good_ocv_uv = chip->last_ocv_uv;
698 chip->new_battery = false;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700699 } else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800700 convert_and_store_ocv(chip, raw, batt_temp);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700701 /* forget the old cc value upon ocv */
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800702 chip->last_cc_uah = INT_MIN;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700703 } else {
704 raw->last_good_ocv_uv = chip->last_ocv_uv;
705 }
706
707 /* fake a high OCV if done charging */
708 if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
Abhijeet Dharmapurikar15f30fb2012-12-27 17:20:29 -0800709 chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700710 } else {
711 /*
712 * force 100% ocv by selecting the highest voltage the
713 * battery could ever reach
714 */
715 raw->last_good_ocv_uv = chip->max_voltage_uv;
716 chip->last_ocv_uv = chip->max_voltage_uv;
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800717 chip->last_ocv_temp = batt_temp;
Xiaozhe Shi1c63a892013-02-13 15:49:40 -0800718 reset_cc(chip);
719 raw->cc = 0;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700720 }
721 pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
722 raw->last_good_ocv_raw, raw->last_good_ocv_uv);
723 pr_debug("cc_raw= 0x%llx\n", raw->cc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700724 return 0;
725}
726
Xiaozhe Shie118c692012-09-24 15:17:43 -0700727static int calculate_pc(struct qpnp_bms_chip *chip, int ocv_uv,
728 int batt_temp)
729{
730 int pc;
731
732 pc = interpolate_pc(chip->pc_temp_ocv_lut,
733 batt_temp / 10, ocv_uv / 1000);
734 pr_debug("pc = %u %% for ocv = %d uv batt_temp = %d\n",
735 pc, ocv_uv, batt_temp);
736 /* Multiply the initial FCC value by the scale factor. */
737 return pc;
738}
739
740static int calculate_fcc(struct qpnp_bms_chip *chip, int batt_temp)
741{
742 int fcc_uah;
743
744 if (chip->adjusted_fcc_temp_lut == NULL) {
745 /* interpolate_fcc returns a mv value. */
746 fcc_uah = interpolate_fcc(chip->fcc_temp_lut,
747 batt_temp) * 1000;
748 pr_debug("fcc = %d uAh\n", fcc_uah);
749 return fcc_uah;
750 } else {
751 return 1000 * interpolate_fcc(chip->adjusted_fcc_temp_lut,
752 batt_temp);
753 }
754}
755
756/* calculate remaining charge at the time of ocv */
757static int calculate_ocv_charge(struct qpnp_bms_chip *chip,
758 struct raw_soc_params *raw,
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800759 int fcc_uah)
Xiaozhe Shie118c692012-09-24 15:17:43 -0700760{
761 int ocv_uv, pc;
762
763 ocv_uv = raw->last_good_ocv_uv;
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -0800764 pc = calculate_pc(chip, ocv_uv, chip->last_ocv_temp);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700765 pr_debug("ocv_uv = %d pc = %d\n", ocv_uv, pc);
766 return (fcc_uah * pc) / 100;
767}
768
769#define CC_RESOLUTION_N 542535
770#define CC_RESOLUTION_D 100000
771
772static s64 cc_to_uv(s64 cc)
773{
774 return div_s64(cc * CC_RESOLUTION_N, CC_RESOLUTION_D);
775}
776
777#define CC_READING_TICKS 56
778#define SLEEP_CLK_HZ 32764
779#define SECONDS_PER_HOUR 3600
780
Xiaozhe Shia9b597d2013-02-12 11:00:39 -0800781static s64 cc_uv_to_pvh(s64 cc_uv)
Xiaozhe Shie118c692012-09-24 15:17:43 -0700782{
Xiaozhe Shia9b597d2013-02-12 11:00:39 -0800783 /* Note that it is necessary need to multiply by 1000000 to convert
784 * from uvh to pvh here.
785 * However, the maximum Coulomb Counter value is 2^35, which can cause
786 * an over flow.
787 * Multiply by 100000 first to perserve as much precision as possible
788 * then multiply by 10 after doing the division in order to avoid
789 * overflow on the maximum Coulomb Counter value.
790 */
791 return div_s64(cc_uv * CC_READING_TICKS * 100000,
792 SLEEP_CLK_HZ * SECONDS_PER_HOUR) * 10;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700793}
794
795/**
796 * calculate_cc-
797 * @chip: the bms chip pointer
798 * @cc: the cc reading from bms h/w
799 * @val: return value
800 * @coulomb_counter: adjusted coulomb counter for 100%
801 *
802 * RETURNS: in val pointer coulomb counter based charger in uAh
803 * (micro Amp hour)
804 */
805static int calculate_cc(struct qpnp_bms_chip *chip, int64_t cc)
806{
Xiaozhe Shia9b597d2013-02-12 11:00:39 -0800807 int64_t cc_voltage_uv, cc_pvh, cc_uah;
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700808 struct qpnp_iadc_calib calibration;
809
810 qpnp_iadc_get_gain_and_offset(&calibration);
Xiaozhe Shi1c63a892013-02-13 15:49:40 -0800811 pr_debug("cc = %lld\n", cc);
812 cc_voltage_uv = cc_to_uv(cc);
Xiaozhe Shi0c484932013-02-05 16:14:10 -0800813 cc_voltage_uv = cc_adjust_for_gain(cc_voltage_uv,
814 calibration.gain_raw
815 - calibration.offset_raw);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700816 pr_debug("cc_voltage_uv = %lld uv\n", cc_voltage_uv);
Xiaozhe Shia9b597d2013-02-12 11:00:39 -0800817 cc_pvh = cc_uv_to_pvh(cc_voltage_uv);
818 pr_debug("cc_pvh = %lld pvh\n", cc_pvh);
819 cc_uah = div_s64(cc_pvh, chip->r_sense_uohm);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700820 /* cc_raw had 4 bits of extra precision.
821 By now it should be within 32 bit range */
822 return (int)cc_uah;
823}
824
825static int get_rbatt(struct qpnp_bms_chip *chip,
826 int soc_rbatt_mohm, int batt_temp)
827{
828 int rbatt_mohm, scalefactor;
829
830 rbatt_mohm = chip->default_rbatt_mohm;
831 pr_debug("rbatt before scaling = %d\n", rbatt_mohm);
832 if (chip->rbatt_sf_lut == NULL) {
833 pr_debug("RBATT = %d\n", rbatt_mohm);
834 return rbatt_mohm;
835 }
836 /* Convert the batt_temp to DegC from deciDegC */
837 batt_temp = batt_temp / 10;
838 scalefactor = interpolate_scalingfactor(chip->rbatt_sf_lut,
839 batt_temp, soc_rbatt_mohm);
840 pr_debug("rbatt sf = %d for batt_temp = %d, soc_rbatt = %d\n",
841 scalefactor, batt_temp, soc_rbatt_mohm);
842 rbatt_mohm = (rbatt_mohm * scalefactor) / 100;
843
844 rbatt_mohm += chip->r_conn_mohm;
845 pr_debug("adding r_conn_mohm = %d rbatt = %d\n",
846 chip->r_conn_mohm, rbatt_mohm);
847
848 pr_debug("RBATT = %d\n", rbatt_mohm);
849 return rbatt_mohm;
850}
851
852static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800853 int *iavg_ua, int delta_time_s)
Xiaozhe Shie118c692012-09-24 15:17:43 -0700854{
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800855 int delta_cc_uah = 0;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700856
Xiaozhe Shie118c692012-09-24 15:17:43 -0700857 /* if anything fails report the previous iavg_ua */
858 *iavg_ua = chip->prev_iavg_ua;
859
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800860 if (chip->last_cc_uah == INT_MIN) {
Xiaozhe Shie118c692012-09-24 15:17:43 -0700861 get_battery_current(chip, iavg_ua);
862 goto out;
863 }
864
Xiaozhe Shie118c692012-09-24 15:17:43 -0700865 /* use the previous iavg if called within 15 seconds */
866 if (delta_time_s < 15) {
867 *iavg_ua = chip->prev_iavg_ua;
868 goto out;
869 }
870
871 delta_cc_uah = cc_uah - chip->last_cc_uah;
872
873 *iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
874
Xiaozhe Shie118c692012-09-24 15:17:43 -0700875out:
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800876 pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700877 /* remember the iavg */
878 chip->prev_iavg_ua = *iavg_ua;
879
880 /* remember cc_uah */
881 chip->last_cc_uah = cc_uah;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700882}
883
884static int calculate_termination_uuc(struct qpnp_bms_chip *chip,
885 struct soc_params *params,
886 int batt_temp, int uuc_iavg_ma,
887 int *ret_pc_unusable)
888{
889 int unusable_uv, pc_unusable, uuc_uah;
890 int i = 0;
891 int ocv_mv;
892 int batt_temp_degc = batt_temp / 10;
893 int rbatt_mohm;
894 int delta_uv;
895 int prev_delta_uv = 0;
896 int prev_rbatt_mohm = 0;
897 int uuc_rbatt_mohm;
898
899 for (i = 0; i <= 100; i++) {
900 ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
901 batt_temp_degc, i);
902 rbatt_mohm = get_rbatt(chip, i, batt_temp);
903 unusable_uv = (rbatt_mohm * uuc_iavg_ma)
904 + (chip->v_cutoff_uv);
905 delta_uv = ocv_mv * 1000 - unusable_uv;
906
907 pr_debug("soc = %d ocv = %d rbat = %d u_uv = %d delta_v = %d\n",
908 i, ocv_mv, rbatt_mohm, unusable_uv, delta_uv);
909
910 if (delta_uv > 0)
911 break;
912
913 prev_delta_uv = delta_uv;
914 prev_rbatt_mohm = rbatt_mohm;
915 }
916
917 uuc_rbatt_mohm = linear_interpolate(rbatt_mohm, delta_uv,
918 prev_rbatt_mohm, prev_delta_uv,
919 0);
920
921 unusable_uv = (uuc_rbatt_mohm * uuc_iavg_ma) + (chip->v_cutoff_uv);
922
923 pc_unusable = calculate_pc(chip, unusable_uv, batt_temp);
924 uuc_uah = (params->fcc_uah * pc_unusable) / 100;
925 pr_debug("For uuc_iavg_ma = %d, unusable_rbatt = %d unusable_uv = %d unusable_pc = %d uuc = %d\n",
926 uuc_iavg_ma,
927 uuc_rbatt_mohm, unusable_uv,
928 pc_unusable, uuc_uah);
929 *ret_pc_unusable = pc_unusable;
930 return uuc_uah;
931}
932
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800933#define TIME_PER_PERCENT_UUC 60
Xiaozhe Shie118c692012-09-24 15:17:43 -0700934static int adjust_uuc(struct qpnp_bms_chip *chip,
935 struct soc_params *params,
936 int new_pc_unusable,
937 int new_uuc_uah,
938 int batt_temp)
939{
940 int new_unusable_mv, new_iavg_ma;
941 int batt_temp_degc = batt_temp / 10;
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800942 int max_percent_change;
943
944 max_percent_change = max(params->delta_time_s
945 / TIME_PER_PERCENT_UUC, 1);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700946
947 if (chip->prev_pc_unusable == -EINVAL
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800948 || abs(chip->prev_pc_unusable - new_pc_unusable)
949 <= max_percent_change) {
Xiaozhe Shie118c692012-09-24 15:17:43 -0700950 chip->prev_pc_unusable = new_pc_unusable;
951 return new_uuc_uah;
952 }
953
954 /* the uuc is trying to change more than 1% restrict it */
955 if (new_pc_unusable > chip->prev_pc_unusable)
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800956 chip->prev_pc_unusable += max_percent_change;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700957 else
Xiaozhe Shif36d2862013-01-04 10:17:35 -0800958 chip->prev_pc_unusable -= max_percent_change;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700959
960 new_uuc_uah = (params->fcc_uah * chip->prev_pc_unusable) / 100;
961
962 /* also find update the iavg_ma accordingly */
963 new_unusable_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
964 batt_temp_degc, chip->prev_pc_unusable);
965 if (new_unusable_mv < chip->v_cutoff_uv/1000)
966 new_unusable_mv = chip->v_cutoff_uv/1000;
967
968 new_iavg_ma = (new_unusable_mv * 1000 - chip->v_cutoff_uv)
Xiaozhe Shi904f1f72012-12-04 12:47:21 -0800969 / params->rbatt_mohm;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700970 if (new_iavg_ma == 0)
971 new_iavg_ma = 1;
972 chip->prev_uuc_iavg_ma = new_iavg_ma;
973 pr_debug("Restricting UUC to %d (%d%%) unusable_mv = %d iavg_ma = %d\n",
974 new_uuc_uah, chip->prev_pc_unusable,
975 new_unusable_mv, new_iavg_ma);
976
977 return new_uuc_uah;
978}
979
Abhijeet Dharmapurikarbdf8ba82012-12-20 18:33:56 -0800980#define MIN_IAVG_MA 250
Xiaozhe Shie118c692012-09-24 15:17:43 -0700981#define MIN_SECONDS_FOR_VALID_SAMPLE 20
982static int calculate_unusable_charge_uah(struct qpnp_bms_chip *chip,
983 struct soc_params *params,
984 int batt_temp)
985{
986 int uuc_uah_iavg;
987 int i;
988 int uuc_iavg_ma = params->iavg_ua / 1000;
989 int pc_unusable;
990
991 /*
992 * if called first time, fill all the samples with
993 * the shutdown_iavg_ma
994 */
995 if (chip->first_time_calc_uuc && chip->shutdown_iavg_ma != 0) {
996 pr_debug("Using shutdown_iavg_ma = %d in all samples\n",
997 chip->shutdown_iavg_ma);
998 for (i = 0; i < IAVG_SAMPLES; i++)
999 chip->iavg_samples_ma[i] = chip->shutdown_iavg_ma;
1000
1001 chip->iavg_index = 0;
1002 chip->iavg_num_samples = IAVG_SAMPLES;
1003 }
1004
1005 /*
1006 * if charging use a nominal avg current to keep
1007 * a reasonable UUC while charging
1008 */
Abhijeet Dharmapurikarbdf8ba82012-12-20 18:33:56 -08001009 if (uuc_iavg_ma < MIN_IAVG_MA)
1010 uuc_iavg_ma = MIN_IAVG_MA;
Xiaozhe Shie118c692012-09-24 15:17:43 -07001011 chip->iavg_samples_ma[chip->iavg_index] = uuc_iavg_ma;
1012 chip->iavg_index = (chip->iavg_index + 1) % IAVG_SAMPLES;
1013 chip->iavg_num_samples++;
1014 if (chip->iavg_num_samples >= IAVG_SAMPLES)
1015 chip->iavg_num_samples = IAVG_SAMPLES;
1016
1017 /* now that this sample is added calcualte the average */
1018 uuc_iavg_ma = 0;
1019 if (chip->iavg_num_samples != 0) {
1020 for (i = 0; i < chip->iavg_num_samples; i++) {
1021 pr_debug("iavg_samples_ma[%d] = %d\n", i,
1022 chip->iavg_samples_ma[i]);
1023 uuc_iavg_ma += chip->iavg_samples_ma[i];
1024 }
1025
1026 uuc_iavg_ma = DIV_ROUND_CLOSEST(uuc_iavg_ma,
1027 chip->iavg_num_samples);
1028 }
1029
Xiaozhe Shi20640b52013-01-03 11:49:30 -08001030 /*
1031 * if we're in bms reset mode, force uuc to be 3% of fcc
1032 */
1033 if (bms_reset)
1034 return (params->fcc_uah * 3) / 100;
1035
Xiaozhe Shi75e5efe2013-02-07 09:51:43 -08001036 uuc_uah_iavg = calculate_termination_uuc(chip, params, batt_temp,
1037 uuc_iavg_ma, &pc_unusable);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001038 pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
1039 uuc_iavg_ma, uuc_uah_iavg);
1040
1041 chip->prev_uuc_iavg_ma = uuc_iavg_ma;
1042 /* restrict the uuc such that it can increase only by one percent */
1043 uuc_uah_iavg = adjust_uuc(chip, params, pc_unusable,
1044 uuc_uah_iavg, batt_temp);
1045
1046 chip->first_time_calc_uuc = 0;
1047 return uuc_uah_iavg;
1048}
1049
1050static void find_ocv_for_soc(struct qpnp_bms_chip *chip,
1051 struct soc_params *params,
1052 int batt_temp,
1053 int shutdown_soc,
1054 int *ret_ocv_uv)
1055{
1056 s64 ocv_charge_uah;
1057 int pc, new_pc;
1058 int batt_temp_degc = batt_temp / 10;
1059 int ocv_uv;
1060
1061 ocv_charge_uah = (s64)shutdown_soc
1062 * (params->fcc_uah - params->uuc_uah);
1063 ocv_charge_uah = div_s64(ocv_charge_uah, 100)
1064 + params->cc_uah + params->uuc_uah;
1065 pc = DIV_ROUND_CLOSEST((int)ocv_charge_uah * 100, params->fcc_uah);
1066 pc = clamp(pc, 0, 100);
1067
1068 ocv_uv = interpolate_ocv(chip->pc_temp_ocv_lut, batt_temp_degc, pc);
1069
1070 pr_debug("s_soc = %d, fcc = %d uuc = %d rc = %d, pc = %d, ocv mv = %d\n",
1071 shutdown_soc, params->fcc_uah,
1072 params->uuc_uah, (int)ocv_charge_uah,
1073 pc, ocv_uv);
1074 new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv_uv);
1075 pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv_uv);
1076
1077 while (abs(new_pc - pc) > 1) {
1078 int delta_mv = 5;
1079
1080 if (new_pc > pc)
1081 delta_mv = -1 * delta_mv;
1082
1083 ocv_uv = ocv_uv + delta_mv;
1084 new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
1085 batt_temp_degc, ocv_uv);
1086 pr_debug("test revlookup pc = %d for ocv = %d\n",
1087 new_pc, ocv_uv);
1088 }
1089
1090 *ret_ocv_uv = ocv_uv * 1000;
1091 params->ocv_charge_uah = (int)ocv_charge_uah;
1092}
1093
Xiaozhe Shif36d2862013-01-04 10:17:35 -08001094static int get_current_time(unsigned long *now_tm_sec)
1095{
1096 struct rtc_time tm;
1097 struct rtc_device *rtc;
1098 int rc;
1099
1100 rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
1101 if (rtc == NULL) {
1102 pr_err("%s: unable to open rtc device (%s)\n",
1103 __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
1104 rc = -EINVAL;
1105 goto close_time;
1106 }
1107
1108 rc = rtc_read_time(rtc, &tm);
1109 if (rc) {
1110 pr_err("Error reading rtc device (%s) : %d\n",
1111 CONFIG_RTC_HCTOSYS_DEVICE, rc);
1112 goto close_time;
1113 }
1114
1115 rc = rtc_valid_tm(&tm);
1116 if (rc) {
1117 pr_err("Invalid RTC time (%s): %d\n",
1118 CONFIG_RTC_HCTOSYS_DEVICE, rc);
1119 goto close_time;
1120 }
1121 rtc_tm_to_time(&tm, now_tm_sec);
1122
1123close_time:
1124 rtc_class_close(rtc);
1125 return rc;
1126}
1127
1128static int calculate_delta_time(struct qpnp_bms_chip *chip, int *delta_time_s)
1129{
1130 unsigned long now_tm_sec = 0;
1131
1132 /* default to delta time = 0 if anything fails */
1133 *delta_time_s = 0;
1134
1135 get_current_time(&now_tm_sec);
1136
1137 *delta_time_s = (now_tm_sec - chip->tm_sec);
1138 pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d\n",
1139 chip->tm_sec, now_tm_sec, *delta_time_s);
1140
1141 /* remember this time */
1142 chip->tm_sec = now_tm_sec;
1143 return 0;
1144}
1145
Xiaozhe Shie118c692012-09-24 15:17:43 -07001146static void calculate_soc_params(struct qpnp_bms_chip *chip,
1147 struct raw_soc_params *raw,
1148 struct soc_params *params,
1149 int batt_temp)
1150{
1151 int soc_rbatt;
1152
Xiaozhe Shif36d2862013-01-04 10:17:35 -08001153 calculate_delta_time(chip, &params->delta_time_s);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001154 params->fcc_uah = calculate_fcc(chip, batt_temp);
1155 pr_debug("FCC = %uuAh batt_temp = %d\n", params->fcc_uah, batt_temp);
1156
1157 /* calculate remainging charge */
1158 params->ocv_charge_uah = calculate_ocv_charge(
1159 chip, raw,
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -08001160 params->fcc_uah);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001161 pr_debug("ocv_charge_uah = %uuAh\n", params->ocv_charge_uah);
1162
1163 /* calculate cc micro_volt_hour */
1164 params->cc_uah = calculate_cc(chip, raw->cc);
Xiaozhe Shi1c63a892013-02-13 15:49:40 -08001165 pr_debug("cc_uah = %duAh raw->cc = %llx\n", params->cc_uah, raw->cc);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001166
1167 soc_rbatt = ((params->ocv_charge_uah - params->cc_uah) * 100)
1168 / params->fcc_uah;
1169 if (soc_rbatt < 0)
1170 soc_rbatt = 0;
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001171 params->rbatt_mohm = get_rbatt(chip, soc_rbatt, batt_temp);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001172
Xiaozhe Shif36d2862013-01-04 10:17:35 -08001173 calculate_iavg(chip, params->cc_uah, &params->iavg_ua,
1174 params->delta_time_s);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001175
1176 params->uuc_uah = calculate_unusable_charge_uah(chip, params,
1177 batt_temp);
1178 pr_debug("UUC = %uuAh\n", params->uuc_uah);
1179}
1180
1181static bool is_shutdown_soc_within_limits(struct qpnp_bms_chip *chip, int soc)
1182{
1183 if (chip->shutdown_soc_invalid) {
1184 pr_debug("NOT forcing shutdown soc = %d\n", chip->shutdown_soc);
1185 return 0;
1186 }
1187
1188 if (abs(chip->shutdown_soc - soc) > chip->shutdown_soc_valid_limit) {
1189 pr_debug("rejecting shutdown soc = %d, soc = %d limit = %d\n",
1190 chip->shutdown_soc, soc,
1191 chip->shutdown_soc_valid_limit);
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001192 chip->shutdown_soc_invalid = true;
Xiaozhe Shie118c692012-09-24 15:17:43 -07001193 return 0;
1194 }
1195
1196 return 1;
1197}
1198
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001199static int bound_soc(int soc)
1200{
1201 soc = max(0, soc);
1202 soc = min(100, soc);
1203 return soc;
1204}
1205
Xiaozhe Shi20640b52013-01-03 11:49:30 -08001206#define IBAT_TOL_MASK 0x0F
1207#define OCV_TOL_MASK 0xF0
1208#define IBAT_TOL_DEFAULT 0x03
1209#define IBAT_TOL_NOCHG 0x0F
1210#define OCV_TOL_DEFAULT 0x20
1211#define OCV_TOL_NO_OCV 0x00
1212static int stop_ocv_updates(struct qpnp_bms_chip *chip)
1213{
1214 pr_debug("stopping ocv updates\n");
1215 return qpnp_masked_write(chip, BMS1_TOL_CTL,
1216 OCV_TOL_MASK, OCV_TOL_NO_OCV);
1217}
1218
1219static int reset_bms_for_test(struct qpnp_bms_chip *chip)
1220{
Xiaozhe Shi95da77f2013-02-20 13:40:06 -08001221 int ibat_ua = 0, vbat_uv = 0, rc;
Xiaozhe Shi20640b52013-01-03 11:49:30 -08001222 int ocv_est_uv;
1223
1224 if (!chip) {
1225 pr_err("BMS driver has not been initialized yet!\n");
1226 return -EINVAL;
1227 }
1228
1229 rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
1230
1231 ocv_est_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
1232 pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
1233 chip->last_ocv_uv = ocv_est_uv;
1234 chip->last_soc = -EINVAL;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001235 chip->last_soc_invalid = true;
Xiaozhe Shi20640b52013-01-03 11:49:30 -08001236 reset_cc(chip);
1237 chip->last_cc_uah = INT_MIN;
1238 stop_ocv_updates(chip);
1239
1240 pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
1241 chip->last_ocv_uv, vbat_uv, ibat_ua);
1242
1243 return rc;
1244}
1245
1246static int bms_reset_set(const char *val, const struct kernel_param *kp)
1247{
1248 int rc;
1249
1250 rc = param_set_bool(val, kp);
1251 if (rc) {
1252 pr_err("Unable to set bms_reset: %d\n", rc);
1253 return rc;
1254 }
1255
1256 if (*(bool *)kp->arg) {
1257 struct power_supply *bms_psy = power_supply_get_by_name("bms");
1258 struct qpnp_bms_chip *chip = container_of(bms_psy,
1259 struct qpnp_bms_chip, bms_psy);
1260
1261 rc = reset_bms_for_test(chip);
1262 if (rc) {
1263 pr_err("Unable to modify bms_reset: %d\n", rc);
1264 return rc;
1265 }
1266 }
1267 return 0;
1268}
1269
1270static struct kernel_param_ops bms_reset_ops = {
1271 .set = bms_reset_set,
1272 .get = param_get_bool,
1273};
1274
1275module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
1276
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001277static int charging_adjustments(struct qpnp_bms_chip *chip,
1278 struct soc_params *params, int soc,
1279 int vbat_uv, int ibat_ua, int batt_temp)
1280{
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001281 int chg_soc;
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -08001282 int batt_terminal_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001283
1284 if (chip->soc_at_cv == -EINVAL) {
1285 /* In constant current charging return the calc soc */
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -08001286 if (batt_terminal_uv <= chip->max_voltage_uv)
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001287 pr_debug("CC CHG SOC %d\n", soc);
1288
1289 /* Note the CC to CV point */
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -08001290 if (batt_terminal_uv >= chip->max_voltage_uv) {
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001291 chip->soc_at_cv = soc;
1292 chip->prev_chg_soc = soc;
1293 chip->ibat_at_cv_ua = ibat_ua;
1294 pr_debug("CC_TO_CV ibat_ua = %d CHG SOC %d\n",
1295 ibat_ua, soc);
1296 }
1297 return soc;
1298 }
1299
1300 /*
1301 * battery is in CV phase - begin liner inerpolation of soc based on
1302 * battery charge current
1303 */
1304
1305 /*
1306 * if voltage lessened (possibly because of a system load)
1307 * keep reporting the prev chg soc
1308 */
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -08001309 if (batt_terminal_uv <= chip->max_voltage_uv - 10000) {
1310 pr_debug("batt_terminal_uv %d < (max = %d - 10000); CC CHG SOC %d\n",
1311 batt_terminal_uv,
1312 chip->max_voltage_uv, chip->prev_chg_soc);
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001313 return chip->prev_chg_soc;
1314 }
1315
1316 chg_soc = linear_interpolate(chip->soc_at_cv, chip->ibat_at_cv_ua,
Abhijeet Dharmapurikareef88662012-11-08 17:26:29 -08001317 100, -1 * chip->chg_term_ua,
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001318 ibat_ua);
Xiaozhe Shi78d0c532012-12-10 13:02:14 -08001319 chg_soc = bound_soc(chg_soc);
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001320
1321 /* always report a higher soc */
1322 if (chg_soc > chip->prev_chg_soc) {
1323 int new_ocv_uv;
1324
1325 chip->prev_chg_soc = chg_soc;
1326
1327 find_ocv_for_soc(chip, params, batt_temp, chg_soc, &new_ocv_uv);
1328 chip->last_ocv_uv = new_ocv_uv;
1329 pr_debug("CC CHG ADJ OCV = %d CHG SOC %d\n",
1330 new_ocv_uv,
1331 chip->prev_chg_soc);
1332 }
1333
1334 pr_debug("Reporting CHG SOC %d\n", chip->prev_chg_soc);
1335 return chip->prev_chg_soc;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001336}
1337
Xiaozhe Shi4be85782013-02-22 17:33:40 -08001338static void very_low_voltage_check(struct qpnp_bms_chip *chip, int vbat_uv)
1339{
1340 /*
1341 * if battery is very low (v_cutoff voltage + 20mv) hold
1342 * a wakelock untill soc = 0%
1343 */
1344 if (vbat_uv <= chip->low_voltage_threshold
1345 && !chip->low_voltage_wake_lock_held) {
1346 pr_debug("voltage = %d low holding wakelock\n", vbat_uv);
1347 wake_lock(&chip->low_voltage_wake_lock);
1348 chip->low_voltage_wake_lock_held = 1;
1349 } else if (vbat_uv > chip->low_voltage_threshold
1350 && chip->low_voltage_wake_lock_held) {
1351 pr_debug("voltage = %d releasing wakelock\n", vbat_uv);
1352 chip->low_voltage_wake_lock_held = 0;
1353 wake_unlock(&chip->low_voltage_wake_lock);
1354 }
1355}
1356
Xiaozhe Shie118c692012-09-24 15:17:43 -07001357static int adjust_soc(struct qpnp_bms_chip *chip, struct soc_params *params,
1358 int soc, int batt_temp)
1359{
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001360 int ibat_ua = 0, vbat_uv = 0;
1361 int ocv_est_uv = 0, soc_est = 0, pc_est = 0, pc = 0;
1362 int delta_ocv_uv = 0;
1363 int n = 0;
1364 int rc_new_uah = 0;
1365 int pc_new = 0;
1366 int soc_new = 0;
1367 int slope = 0;
1368 int rc = 0;
1369 int delta_ocv_uv_limit = 0;
1370
1371 rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
1372 if (rc < 0) {
1373 pr_err("simultaneous vbat ibat failed err = %d\n", rc);
1374 goto out;
1375 }
1376
Xiaozhe Shi4be85782013-02-22 17:33:40 -08001377 very_low_voltage_check(chip, vbat_uv);
1378
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001379 delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
1380
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001381 ocv_est_uv = vbat_uv + (ibat_ua * params->rbatt_mohm)/1000;
1382
1383 chip->ibat_max_ua = (ocv_est_uv - chip->v_cutoff_uv) * 1000
1384 / (params->rbatt_mohm);
1385
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001386 pc_est = calculate_pc(chip, ocv_est_uv, batt_temp);
1387 soc_est = div_s64((s64)params->fcc_uah * pc_est - params->uuc_uah*100,
1388 (s64)params->fcc_uah - params->uuc_uah);
1389 soc_est = bound_soc(soc_est);
1390
Xiaozhe Shi20640b52013-01-03 11:49:30 -08001391 /* never adjust during bms reset mode */
1392 if (bms_reset) {
1393 pr_debug("bms reset mode, SOC adjustment skipped\n");
1394 goto out;
1395 }
1396
Xiaozhe Shiba3bdd32012-11-29 14:50:53 -08001397 if (ibat_ua < 0 && !is_batfet_open(chip)) {
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001398 soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
1399 batt_temp);
1400 goto out;
1401 }
1402
1403 /*
1404 * do not adjust
1405 * if soc is same as what bms calculated
1406 * if soc_est is between 45 and 25, this is the flat portion of the
1407 * curve where soc_est is not so accurate. We generally don't want to
1408 * adjust when soc_est is inaccurate except for the cases when soc is
1409 * way far off (higher than 50 or lesser than 20).
1410 * Also don't adjust soc if it is above 90 becuase it might be pulled
1411 * low and cause a bad user experience
1412 */
1413 if (soc_est == soc
1414 || (is_between(45, chip->adjust_soc_low_threshold, soc_est)
1415 && is_between(50, chip->adjust_soc_low_threshold - 5, soc))
1416 || soc >= 90)
1417 goto out;
1418
1419 if (chip->last_soc_est == -EINVAL)
1420 chip->last_soc_est = soc;
1421
1422 n = min(200, max(1 , soc + soc_est + chip->last_soc_est));
1423 chip->last_soc_est = soc_est;
1424
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -08001425 pc = calculate_pc(chip, chip->last_ocv_uv, chip->last_ocv_temp);
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001426 if (pc > 0) {
1427 pc_new = calculate_pc(chip,
1428 chip->last_ocv_uv - (++slope * 1000),
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -08001429 chip->last_ocv_temp);
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001430 while (pc_new == pc) {
1431 /* start taking 10mV steps */
1432 slope = slope + 10;
1433 pc_new = calculate_pc(chip,
1434 chip->last_ocv_uv - (slope * 1000),
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -08001435 chip->last_ocv_temp);
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001436 }
1437 } else {
1438 /*
1439 * pc is already at the lowest point,
1440 * assume 1 millivolt translates to 1% pc
1441 */
1442 pc = 1;
1443 pc_new = 0;
1444 slope = 1;
1445 }
1446
1447 delta_ocv_uv = div_s64((soc - soc_est) * (s64)slope * 1000,
1448 n * (pc - pc_new));
1449
1450 if (abs(delta_ocv_uv) > delta_ocv_uv_limit) {
1451 pr_debug("limiting delta ocv %d limit = %d\n", delta_ocv_uv,
1452 delta_ocv_uv_limit);
1453
1454 if (delta_ocv_uv > 0)
1455 delta_ocv_uv = delta_ocv_uv_limit;
1456 else
1457 delta_ocv_uv = -1 * delta_ocv_uv_limit;
1458 pr_debug("new delta ocv = %d\n", delta_ocv_uv);
1459 }
1460
1461 chip->last_ocv_uv -= delta_ocv_uv;
1462
1463 if (chip->last_ocv_uv >= chip->max_voltage_uv)
1464 chip->last_ocv_uv = chip->max_voltage_uv;
1465
1466 /* calculate the soc based on this new ocv */
Abhijeet Dharmapurikar4b97cdd2012-12-26 21:10:53 -08001467 pc_new = calculate_pc(chip, chip->last_ocv_uv, chip->last_ocv_temp);
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001468 rc_new_uah = (params->fcc_uah * pc_new) / 100;
1469 soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100
1470 / (params->fcc_uah - params->uuc_uah);
1471 soc_new = bound_soc(soc_new);
1472
1473 /*
1474 * if soc_new is ZERO force it higher so that phone doesnt report soc=0
1475 * soc = 0 should happen only when soc_est == 0
1476 */
1477 if (soc_new == 0 && soc_est != 0)
1478 soc_new = 1;
1479
1480 soc = soc_new;
1481
1482out:
1483 pr_debug("ibat_ua = %d, vbat_uv = %d, ocv_est_uv = %d, pc_est = %d, soc_est = %d, n = %d, delta_ocv_uv = %d, last_ocv_uv = %d, pc_new = %d, soc_new = %d, rbatt = %d, slope = %d\n",
1484 ibat_ua, vbat_uv, ocv_est_uv, pc_est,
1485 soc_est, n, delta_ocv_uv, chip->last_ocv_uv,
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001486 pc_new, soc_new, params->rbatt_mohm, slope);
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001487
Xiaozhe Shie118c692012-09-24 15:17:43 -07001488 return soc;
1489}
1490
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001491static int clamp_soc_based_on_voltage(struct qpnp_bms_chip *chip, int soc)
1492{
1493 int rc, vbat_uv;
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001494
Xiaozhe Shi36458962013-02-06 16:19:57 -08001495 rc = get_battery_voltage(&vbat_uv);
1496 if (rc < 0) {
1497 pr_err("adc vbat failed err = %d\n", rc);
1498 return soc;
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001499 }
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001500 if (soc == 0 && vbat_uv > chip->v_cutoff_uv) {
1501 pr_debug("clamping soc to 1, vbat (%d) > cutoff (%d)\n",
1502 vbat_uv, chip->v_cutoff_uv);
1503 return 1;
1504 } else if (soc > 0 && vbat_uv < chip->v_cutoff_uv) {
1505 pr_debug("forcing soc to 0, vbat (%d) < cutoff (%d)\n",
1506 vbat_uv, chip->v_cutoff_uv);
1507 return 0;
1508 } else {
1509 pr_debug("not clamping, using soc = %d, vbat = %d and cutoff = %d\n",
1510 soc, vbat_uv, chip->v_cutoff_uv);
1511 return soc;
1512 }
1513}
1514
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001515static int calculate_state_of_charge(struct qpnp_bms_chip *chip,
1516 struct raw_soc_params *raw,
1517 int batt_temp)
1518{
Xiaozhe Shie118c692012-09-24 15:17:43 -07001519 int soc, new_ocv_uv;
1520 int shutdown_soc, new_calculated_soc, remaining_usable_charge_uah;
1521 struct soc_params params;
1522
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001523 if (!chip->battery_present) {
Xiaozhe Shi026fa9b2013-03-22 17:00:50 -07001524 pr_debug("battery gone, reporting 100\n");
1525 new_calculated_soc = 100;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001526 goto done_calculating;
1527 }
Xiaozhe Shie118c692012-09-24 15:17:43 -07001528 calculate_soc_params(chip, raw, &params, batt_temp);
1529 /* calculate remaining usable charge */
1530 remaining_usable_charge_uah = params.ocv_charge_uah
1531 - params.cc_uah
1532 - params.uuc_uah;
1533
1534 pr_debug("RUC = %duAh\n", remaining_usable_charge_uah);
1535 if (params.fcc_uah - params.uuc_uah <= 0) {
Xiaozhe Shicb386a22012-11-29 12:11:42 -08001536 pr_debug("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
Xiaozhe Shie118c692012-09-24 15:17:43 -07001537 params.fcc_uah,
1538 params.uuc_uah);
Xiaozhe Shifd8cd482013-02-12 10:00:38 -08001539 new_calculated_soc = 0;
1540 goto done_calculating;
Xiaozhe Shie118c692012-09-24 15:17:43 -07001541 }
1542
Xiaozhe Shifd8cd482013-02-12 10:00:38 -08001543 soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
1544 (params.fcc_uah - params.uuc_uah));
1545
Xiaozhe Shie118c692012-09-24 15:17:43 -07001546 if (chip->first_time_calc_soc && soc < 0) {
1547 /*
1548 * first time calcualtion and the pon ocv is too low resulting
1549 * in a bad soc. Adjust ocv to get 0 soc
1550 */
1551 pr_debug("soc is %d, adjusting pon ocv to make it 0\n", soc);
1552 find_ocv_for_soc(chip, &params, batt_temp, 0, &new_ocv_uv);
1553 chip->last_ocv_uv = new_ocv_uv;
1554
1555 remaining_usable_charge_uah = params.ocv_charge_uah
1556 - params.cc_uah
1557 - params.uuc_uah;
1558
1559 soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
1560 (params.fcc_uah
1561 - params.uuc_uah));
1562 pr_debug("DONE for O soc is %d, pon ocv adjusted to %duV\n",
1563 soc, chip->last_ocv_uv);
1564 }
1565
1566 if (soc > 100)
1567 soc = 100;
1568
1569 if (soc < 0) {
Xiaozhe Shicb386a22012-11-29 12:11:42 -08001570 pr_debug("bad rem_usb_chg = %d rem_chg %d, cc_uah %d, unusb_chg %d\n",
Xiaozhe Shie118c692012-09-24 15:17:43 -07001571 remaining_usable_charge_uah,
1572 params.ocv_charge_uah,
1573 params.cc_uah, params.uuc_uah);
1574
Xiaozhe Shicb386a22012-11-29 12:11:42 -08001575 pr_debug("for bad rem_usb_chg last_ocv_uv = %d batt_temp = %d fcc = %d soc =%d\n",
Xiaozhe Shie118c692012-09-24 15:17:43 -07001576 chip->last_ocv_uv, batt_temp,
1577 params.fcc_uah, soc);
1578 soc = 0;
1579 }
1580
1581 mutex_lock(&chip->soc_invalidation_mutex);
1582 shutdown_soc = chip->shutdown_soc;
1583
1584 if (chip->first_time_calc_soc && soc != shutdown_soc
1585 && is_shutdown_soc_within_limits(chip, soc)) {
1586 /*
1587 * soc for the first time - use shutdown soc
1588 * to adjust pon ocv since it is a small percent away from
1589 * the real soc
1590 */
1591 pr_debug("soc = %d before forcing shutdown_soc = %d\n",
1592 soc, shutdown_soc);
1593 find_ocv_for_soc(chip, &params, batt_temp,
1594 shutdown_soc, &new_ocv_uv);
1595 chip->pon_ocv_uv = chip->last_ocv_uv;
1596 chip->last_ocv_uv = new_ocv_uv;
1597
1598 remaining_usable_charge_uah = params.ocv_charge_uah
1599 - params.cc_uah
1600 - params.uuc_uah;
1601
1602 soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
1603 (params.fcc_uah
1604 - params.uuc_uah));
1605
1606 pr_debug("DONE for shutdown_soc = %d soc is %d, adjusted ocv to %duV\n",
1607 shutdown_soc, soc, chip->last_ocv_uv);
1608 }
1609 mutex_unlock(&chip->soc_invalidation_mutex);
1610
1611 pr_debug("SOC before adjustment = %d\n", soc);
1612 new_calculated_soc = adjust_soc(chip, &params, soc, batt_temp);
1613
Xiaozhe Shi445d2492013-03-27 18:10:18 -07001614 /* always clamp soc due to BMS hw/sw immaturities */
1615 new_calculated_soc = clamp_soc_based_on_voltage(chip,
1616 new_calculated_soc);
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001617
Xiaozhe Shifd8cd482013-02-12 10:00:38 -08001618done_calculating:
Xiaozhe Shie118c692012-09-24 15:17:43 -07001619 if (new_calculated_soc != chip->calculated_soc
1620 && chip->bms_psy.name != NULL) {
1621 power_supply_changed(&chip->bms_psy);
1622 pr_debug("power supply changed\n");
1623 }
1624
1625 chip->calculated_soc = new_calculated_soc;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001626 if (chip->last_soc_invalid) {
1627 chip->last_soc_invalid = false;
1628 chip->last_soc = -EINVAL;
1629 }
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001630 pr_debug("CC based calculated SOC = %d\n", chip->calculated_soc);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001631 chip->first_time_calc_soc = 0;
Xiaozhe Shicdeee312012-12-18 15:10:18 -08001632 get_current_time(&chip->last_recalc_time);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001633 return chip->calculated_soc;
1634}
1635
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001636static int calculate_soc_from_voltage(struct qpnp_bms_chip *chip)
1637{
1638 int voltage_range_uv, voltage_remaining_uv, voltage_based_soc;
Xiaozhe Shi36458962013-02-06 16:19:57 -08001639 int rc, vbat_uv;
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001640
Xiaozhe Shi36458962013-02-06 16:19:57 -08001641 rc = get_battery_voltage(&vbat_uv);
1642 if (rc < 0) {
1643 pr_err("adc vbat failed err = %d\n", rc);
1644 return rc;
1645 }
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001646 voltage_range_uv = chip->max_voltage_uv - chip->v_cutoff_uv;
1647 voltage_remaining_uv = vbat_uv - chip->v_cutoff_uv;
1648 voltage_based_soc = voltage_remaining_uv * 100 / voltage_range_uv;
1649
1650 voltage_based_soc = clamp(voltage_based_soc, 0, 100);
1651
1652 if (chip->prev_voltage_based_soc != voltage_based_soc
1653 && chip->bms_psy.name != NULL) {
1654 power_supply_changed(&chip->bms_psy);
1655 pr_debug("power supply changed\n");
1656 }
1657 chip->prev_voltage_based_soc = voltage_based_soc;
1658
1659 pr_debug("vbat used = %duv\n", vbat_uv);
1660 pr_debug("Calculated voltage based soc = %d\n", voltage_based_soc);
1661 return voltage_based_soc;
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001662}
1663
Xiaozhe Shicdeee312012-12-18 15:10:18 -08001664static int recalculate_soc(struct qpnp_bms_chip *chip)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001665{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001666 int batt_temp, rc, soc;
1667 struct qpnp_vadc_result result;
1668 struct raw_soc_params raw;
1669
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -08001670 wake_lock(&chip->soc_wake_lock);
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001671 if (chip->use_voltage_soc) {
1672 soc = calculate_soc_from_voltage(chip);
1673 } else {
1674 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &result);
1675 if (rc) {
1676 pr_err("error reading vadc LR_MUX1_BATT_THERM = %d, rc = %d\n",
1677 LR_MUX1_BATT_THERM, rc);
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -08001678 soc = chip->calculated_soc;
1679 } else {
1680 pr_debug("batt_temp phy = %lld meas = 0x%llx\n",
1681 result.physical,
1682 result.measurement);
1683 batt_temp = (int)result.physical;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001684
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -08001685 mutex_lock(&chip->last_ocv_uv_mutex);
1686 read_soc_params_raw(chip, &raw, batt_temp);
1687 soc = calculate_state_of_charge(chip, &raw, batt_temp);
1688 mutex_unlock(&chip->last_ocv_uv_mutex);
1689 }
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001690 }
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -08001691 wake_unlock(&chip->soc_wake_lock);
Xiaozhe Shicdeee312012-12-18 15:10:18 -08001692 return soc;
1693}
1694
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001695static void recalculate_work(struct work_struct *work)
1696{
1697 struct qpnp_bms_chip *chip = container_of(work,
1698 struct qpnp_bms_chip,
1699 recalc_work);
1700
1701 recalculate_soc(chip);
1702}
1703
Xiaozhe Shicdeee312012-12-18 15:10:18 -08001704static void calculate_soc_work(struct work_struct *work)
1705{
1706 struct qpnp_bms_chip *chip = container_of(work,
1707 struct qpnp_bms_chip,
1708 calculate_soc_delayed_work.work);
1709 int soc = recalculate_soc(chip);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001710
Xiaozhe Shi4be85782013-02-22 17:33:40 -08001711 if (soc < chip->low_soc_calc_threshold
1712 || chip->low_voltage_wake_lock_held)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001713 schedule_delayed_work(&chip->calculate_soc_delayed_work,
1714 round_jiffies_relative(msecs_to_jiffies
1715 (chip->low_soc_calculate_soc_ms)));
1716 else
1717 schedule_delayed_work(&chip->calculate_soc_delayed_work,
1718 round_jiffies_relative(msecs_to_jiffies
1719 (chip->calculate_soc_ms)));
1720}
1721
Xiaozhe Shie118c692012-09-24 15:17:43 -07001722static void backup_soc_and_iavg(struct qpnp_bms_chip *chip, int batt_temp,
1723 int soc)
1724{
1725 u8 temp;
1726 int rc;
1727 int iavg_ma = chip->prev_uuc_iavg_ma;
1728
1729 if (iavg_ma > IAVG_START)
1730 temp = (iavg_ma - IAVG_START) / IAVG_STEP_SIZE_MA;
1731 else
1732 temp = 0;
1733
1734 rc = qpnp_write_wrapper(chip, &temp,
1735 chip->base + IAVG_STORAGE_REG, 1);
1736
1737 if (soc == 0)
1738 temp = SOC_ZERO;
1739 else
1740 temp = soc;
1741
1742 /* don't store soc if temperature is below 5degC */
1743 if (batt_temp > IGNORE_SOC_TEMP_DECIDEG)
1744 rc = qpnp_write_wrapper(chip, &temp,
1745 chip->base + SOC_STORAGE_REG, 1);
1746}
1747
1748#define SOC_CATCHUP_SEC_MAX 600
1749#define SOC_CATCHUP_SEC_PER_PERCENT 60
1750#define MAX_CATCHUP_SOC (SOC_CATCHUP_SEC_MAX/SOC_CATCHUP_SEC_PER_PERCENT)
1751static int scale_soc_while_chg(struct qpnp_bms_chip *chip,
1752 int delta_time_us, int new_soc, int prev_soc)
1753{
1754 int chg_time_sec;
1755 int catch_up_sec;
1756 int scaled_soc;
1757 int numerator;
1758
1759 /*
1760 * The device must be charging for reporting a higher soc, if
1761 * not ignore this soc and continue reporting the prev_soc.
1762 * Also don't report a high value immediately slowly scale the
1763 * value from prev_soc to the new soc based on a charge time
1764 * weighted average
1765 */
1766
1767 /* if not charging, return last soc */
Xiaozhe Shi28f5dd52013-01-04 12:19:58 -08001768 if (!is_battery_charging(chip))
Xiaozhe Shie118c692012-09-24 15:17:43 -07001769 return prev_soc;
1770
1771 chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
1772 catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
Xiaozhe Shi4532d2d2012-12-17 19:34:50 -08001773 if (catch_up_sec == 0)
1774 return new_soc;
Xiaozhe Shie118c692012-09-24 15:17:43 -07001775 pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
1776
1777 /*
1778 * if charging for more than catch_up time, simply return
1779 * new soc
1780 */
1781 if (chg_time_sec > catch_up_sec)
1782 return new_soc;
1783
1784 numerator = (catch_up_sec - chg_time_sec) * prev_soc
1785 + chg_time_sec * new_soc;
1786 scaled_soc = numerator / catch_up_sec;
1787
1788 pr_debug("cts = %d new_soc = %d prev_soc = %d scaled_soc = %d\n",
1789 chg_time_sec, new_soc, prev_soc, scaled_soc);
1790
1791 return scaled_soc;
1792}
1793
1794/*
1795 * bms_fake_battery is set in setups where a battery emulator is used instead
1796 * of a real battery. This makes the bms driver report a different/fake value
1797 * regardless of the calculated state of charge.
1798 */
1799static int bms_fake_battery = -EINVAL;
1800module_param(bms_fake_battery, int, 0644);
1801
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001802static int report_voltage_based_soc(struct qpnp_bms_chip *chip)
1803{
1804 pr_debug("Reported voltage based soc = %d\n",
1805 chip->prev_voltage_based_soc);
1806 return chip->prev_voltage_based_soc;
1807}
1808
1809static int report_cc_based_soc(struct qpnp_bms_chip *chip)
Xiaozhe Shie118c692012-09-24 15:17:43 -07001810{
1811 int soc;
1812 int delta_time_us;
1813 struct timespec now;
1814 struct qpnp_vadc_result result;
1815 int batt_temp;
1816 int rc;
1817
Xiaozhe Shie118c692012-09-24 15:17:43 -07001818 soc = chip->calculated_soc;
1819
1820 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &result);
1821
1822 if (rc) {
1823 pr_err("error reading adc channel = %d, rc = %d\n",
1824 LR_MUX1_BATT_THERM, rc);
1825 return rc;
1826 }
1827 pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
1828 result.measurement);
1829 batt_temp = (int)result.physical;
1830
1831 do_posix_clock_monotonic_gettime(&now);
1832 if (chip->t_soc_queried.tv_sec != 0) {
1833 delta_time_us
1834 = (now.tv_sec - chip->t_soc_queried.tv_sec) * USEC_PER_SEC
1835 + (now.tv_nsec - chip->t_soc_queried.tv_nsec) / 1000;
1836 } else {
1837 /* calculation for the first time */
1838 delta_time_us = 0;
1839 }
1840
1841 /*
1842 * account for charge time - limit it to SOC_CATCHUP_SEC to
1843 * avoid overflows when charging continues for extended periods
1844 */
Xiaozhe Shi28f5dd52013-01-04 12:19:58 -08001845 if (is_battery_charging(chip)) {
Xiaozhe Shie118c692012-09-24 15:17:43 -07001846 if (chip->charge_time_us == 0) {
1847 /*
1848 * calculating soc for the first time
1849 * after start of chg. Initialize catchup time
1850 */
1851 if (abs(soc - chip->last_soc) < MAX_CATCHUP_SOC)
1852 chip->catch_up_time_us =
1853 (soc - chip->last_soc)
1854 * SOC_CATCHUP_SEC_PER_PERCENT
1855 * USEC_PER_SEC;
1856 else
1857 chip->catch_up_time_us =
1858 SOC_CATCHUP_SEC_MAX * USEC_PER_SEC;
1859
1860 if (chip->catch_up_time_us < 0)
1861 chip->catch_up_time_us = 0;
1862 }
1863
1864 /* add charge time */
1865 if (chip->charge_time_us < SOC_CATCHUP_SEC_MAX * USEC_PER_SEC)
1866 chip->charge_time_us += delta_time_us;
1867
1868 /* end catchup if calculated soc and last soc are same */
1869 if (chip->last_soc == soc)
1870 chip->catch_up_time_us = 0;
1871 }
1872
1873 /* last_soc < soc ... scale and catch up */
Xiaozhe Shi4532d2d2012-12-17 19:34:50 -08001874 if (chip->last_soc != -EINVAL && chip->last_soc < soc && soc != 100)
Xiaozhe Shie118c692012-09-24 15:17:43 -07001875 soc = scale_soc_while_chg(chip, delta_time_us,
1876 soc, chip->last_soc);
1877
1878 pr_debug("last_soc = %d, calculated_soc = %d, soc = %d\n",
1879 chip->last_soc, chip->calculated_soc, soc);
1880 chip->last_soc = soc;
1881 backup_soc_and_iavg(chip, batt_temp, chip->last_soc);
1882 pr_debug("Reported SOC = %d\n", chip->last_soc);
1883 chip->t_soc_queried = now;
1884
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001885 return soc;
Xiaozhe Shie118c692012-09-24 15:17:43 -07001886}
1887
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001888static int report_state_of_charge(struct qpnp_bms_chip *chip)
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001889{
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001890 if (bms_fake_battery != -EINVAL) {
1891 pr_debug("Returning Fake SOC = %d%%\n", bms_fake_battery);
1892 return bms_fake_battery;
1893 } else if (chip->use_voltage_soc)
1894 return report_voltage_based_soc(chip);
1895 else
1896 return report_cc_based_soc(chip);
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001897}
1898
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001899/* Returns capacity as a SoC percentage between 0 and 100 */
1900static int get_prop_bms_capacity(struct qpnp_bms_chip *chip)
1901{
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001902 return report_state_of_charge(chip);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001903}
1904
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001905/* Returns estimated max current that the battery can supply in uA */
1906static int get_prop_bms_current_max(struct qpnp_bms_chip *chip)
1907{
1908 return chip->ibat_max_ua;
1909}
1910
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001911/* Returns instantaneous current in uA */
1912static int get_prop_bms_current_now(struct qpnp_bms_chip *chip)
1913{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001914 int rc, result_ua;
1915
1916 rc = get_battery_current(chip, &result_ua);
1917 if (rc) {
1918 pr_err("failed to get current: %d\n", rc);
1919 return rc;
1920 }
1921 return result_ua;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001922}
1923
1924/* Returns full charge design in uAh */
1925static int get_prop_bms_charge_full_design(struct qpnp_bms_chip *chip)
1926{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001927 return chip->fcc;
1928}
1929
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001930static int get_prop_bms_present(struct qpnp_bms_chip *chip)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001931{
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001932 return chip->battery_present;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001933}
1934
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001935static void set_prop_bms_present(struct qpnp_bms_chip *chip, int present)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001936{
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001937 if (chip->battery_present != present) {
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001938 chip->battery_present = present;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08001939 if (present)
1940 chip->new_battery = true;
1941 /* a new battery was inserted or removed, so force a soc
1942 * recalculation to update the SoC */
1943 schedule_work(&chip->recalc_work);
1944 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001945}
1946
1947static void qpnp_bms_external_power_changed(struct power_supply *psy)
1948{
1949}
1950
1951static int qpnp_bms_power_get_property(struct power_supply *psy,
1952 enum power_supply_property psp,
1953 union power_supply_propval *val)
1954{
1955 struct qpnp_bms_chip *chip = container_of(psy, struct qpnp_bms_chip,
1956 bms_psy);
1957
1958 switch (psp) {
1959 case POWER_SUPPLY_PROP_CAPACITY:
1960 val->intval = get_prop_bms_capacity(chip);
1961 break;
1962 case POWER_SUPPLY_PROP_CURRENT_NOW:
1963 val->intval = get_prop_bms_current_now(chip);
1964 break;
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001965 case POWER_SUPPLY_PROP_CURRENT_MAX:
1966 val->intval = get_prop_bms_current_max(chip);
1967 break;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001968 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1969 val->intval = get_prop_bms_charge_full_design(chip);
1970 break;
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001971 case POWER_SUPPLY_PROP_PRESENT:
1972 val->intval = get_prop_bms_present(chip);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001973 break;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001974 default:
1975 return -EINVAL;
1976 }
1977 return 0;
1978}
1979
1980static int qpnp_bms_power_set_property(struct power_supply *psy,
1981 enum power_supply_property psp,
1982 const union power_supply_propval *val)
1983{
1984 struct qpnp_bms_chip *chip = container_of(psy, struct qpnp_bms_chip,
1985 bms_psy);
1986
1987 switch (psp) {
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001988 case POWER_SUPPLY_PROP_PRESENT:
1989 set_prop_bms_present(chip, val->intval);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001990 break;
1991 default:
1992 return -EINVAL;
1993 }
1994 return 0;
1995}
1996
Xiaozhe Shibdf14742012-12-05 12:41:48 -08001997#define OCV_USE_LIMIT_EN BIT(7)
1998static int set_ocv_voltage_thresholds(struct qpnp_bms_chip *chip,
1999 int low_voltage_threshold,
2000 int high_voltage_threshold)
2001{
2002 uint16_t low_voltage_raw, high_voltage_raw;
2003 int rc;
2004
2005 low_voltage_raw = convert_vbatt_uv_to_raw(chip,
2006 low_voltage_threshold);
2007 high_voltage_raw = convert_vbatt_uv_to_raw(chip,
2008 high_voltage_threshold);
2009 rc = qpnp_write_wrapper(chip, (u8 *)&low_voltage_raw,
2010 chip->base + BMS1_OCV_USE_LOW_LIMIT_THR0, 2);
2011 if (rc) {
2012 pr_err("Failed to set ocv low voltage threshold: %d\n", rc);
2013 return rc;
2014 }
2015 rc = qpnp_write_wrapper(chip, (u8 *)&high_voltage_raw,
2016 chip->base + BMS1_OCV_USE_HIGH_LIMIT_THR0, 2);
2017 if (rc) {
2018 pr_err("Failed to set ocv high voltage threshold: %d\n", rc);
2019 return rc;
2020 }
2021 rc = qpnp_masked_write(chip, BMS1_OCV_USE_LIMIT_CTL,
2022 OCV_USE_LIMIT_EN, OCV_USE_LIMIT_EN);
2023 if (rc) {
2024 pr_err("Failed to enabled ocv voltage thresholds: %d\n", rc);
2025 return rc;
2026 }
2027 pr_debug("ocv low threshold set to %d uv or 0x%x raw\n",
2028 low_voltage_threshold, low_voltage_raw);
2029 pr_debug("ocv high threshold set to %d uv or 0x%x raw\n",
2030 high_voltage_threshold, high_voltage_raw);
2031 return 0;
2032}
2033
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002034static void read_shutdown_soc_and_iavg(struct qpnp_bms_chip *chip)
2035{
2036 int rc;
2037 u8 temp;
2038
2039 if (chip->ignore_shutdown_soc) {
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08002040 chip->shutdown_soc_invalid = true;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002041 chip->shutdown_soc = 0;
2042 chip->shutdown_iavg_ma = 0;
2043 } else {
2044 rc = qpnp_read_wrapper(chip, &temp,
2045 chip->base + IAVG_STORAGE_REG, 1);
2046 if (rc) {
2047 pr_err("failed to read addr = %d %d assuming %d\n",
2048 chip->base + IAVG_STORAGE_REG, rc,
2049 IAVG_START);
2050 chip->shutdown_iavg_ma = IAVG_START;
Xiaozhe Shif5f966d2013-02-19 14:23:11 -08002051 } else if (temp == IAVG_INVALID) {
2052 pr_err("invalid iavg read from BMS1_DATA_REG_1, using %d\n",
2053 IAVG_START);
2054 chip->shutdown_iavg_ma = IAVG_START;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002055 } else {
2056 if (temp == 0) {
2057 chip->shutdown_iavg_ma = IAVG_START;
2058 } else {
2059 chip->shutdown_iavg_ma = IAVG_START
2060 + IAVG_STEP_SIZE_MA * (temp + 1);
2061 }
2062 }
2063
2064 rc = qpnp_read_wrapper(chip, &temp,
2065 chip->base + SOC_STORAGE_REG, 1);
2066 if (rc) {
2067 pr_err("failed to read addr = %d %d\n",
2068 chip->base + SOC_STORAGE_REG, rc);
2069 } else {
2070 chip->shutdown_soc = temp;
2071
2072 if (chip->shutdown_soc == 0) {
2073 pr_debug("No shutdown soc available\n");
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08002074 chip->shutdown_soc_invalid = true;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002075 chip->shutdown_iavg_ma = 0;
2076 } else if (chip->shutdown_soc == SOC_ZERO) {
2077 chip->shutdown_soc = 0;
2078 }
2079 }
2080 }
2081
2082 pr_debug("shutdown_soc = %d shutdown_iavg = %d shutdown_soc_invalid = %d\n",
2083 chip->shutdown_soc,
2084 chip->shutdown_iavg_ma,
2085 chip->shutdown_soc_invalid);
2086}
2087
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002088#define PALLADIUM_ID_MIN 0x7F40
2089#define PALLADIUM_ID_MAX 0x7F5A
2090#define DESAY_5200_ID_MIN 0x7F7F
2091#define DESAY_5200_ID_MAX 0x802F
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002092static int32_t read_battery_id(struct qpnp_bms_chip *chip)
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002093{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002094 int rc;
2095 struct qpnp_vadc_result result;
2096
2097 rc = qpnp_vadc_read(LR_MUX2_BAT_ID, &result);
2098 if (rc) {
2099 pr_err("error reading batt id channel = %d, rc = %d\n",
2100 LR_MUX2_BAT_ID, rc);
2101 return rc;
2102 }
2103 pr_debug("batt_id phy = %lld meas = 0x%llx\n", result.physical,
2104 result.measurement);
2105 pr_debug("raw_code = 0x%x\n", result.adc_code);
2106 return result.adc_code;
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002107}
2108
2109static int set_battery_data(struct qpnp_bms_chip *chip)
2110{
2111 int64_t battery_id;
Xiaozhe Shi77a5b052012-12-14 16:37:45 -08002112 struct bms_battery_data *batt_data;
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002113
Xiaozhe Shi77a5b052012-12-14 16:37:45 -08002114 if (chip->batt_type == BATT_DESAY) {
2115 batt_data = &desay_5200_data;
2116 } else if (chip->batt_type == BATT_PALLADIUM) {
2117 batt_data = &palladium_1500_data;
2118 } else if (chip->batt_type == BATT_OEM) {
2119 batt_data = &oem_batt_data;
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002120 } else {
Xiaozhe Shi77a5b052012-12-14 16:37:45 -08002121 battery_id = read_battery_id(chip);
2122 if (battery_id < 0) {
2123 pr_err("cannot read battery id err = %lld\n",
2124 battery_id);
2125 return battery_id;
2126 }
2127
2128 if (is_between(PALLADIUM_ID_MIN, PALLADIUM_ID_MAX,
2129 battery_id)) {
2130 batt_data = &palladium_1500_data;
2131 } else if (is_between(DESAY_5200_ID_MIN, DESAY_5200_ID_MAX,
2132 battery_id)) {
2133 batt_data = &desay_5200_data;
2134 } else {
2135 pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
2136 battery_id);
2137 batt_data = &palladium_1500_data;
2138 }
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002139 }
2140
Xiaozhe Shi77a5b052012-12-14 16:37:45 -08002141 chip->fcc = batt_data->fcc;
2142 chip->fcc_temp_lut = batt_data->fcc_temp_lut;
2143 chip->fcc_sf_lut = batt_data->fcc_sf_lut;
2144 chip->pc_temp_ocv_lut = batt_data->pc_temp_ocv_lut;
2145 chip->pc_sf_lut = batt_data->pc_sf_lut;
2146 chip->rbatt_sf_lut = batt_data->rbatt_sf_lut;
2147 chip->default_rbatt_mohm = batt_data->default_rbatt_mohm;
2148
2149 if (chip->pc_temp_ocv_lut == NULL) {
2150 pr_err("temp ocv lut table is NULL\n");
2151 return -EINVAL;
2152 }
2153 return 0;
Xiaozhe Shi73a65692012-09-18 17:51:57 -07002154}
2155
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002156#define SPMI_PROP_READ(chip_prop, qpnp_spmi_property, retval) \
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002157do { \
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002158 retval = of_property_read_u32(chip->spmi->dev.of_node, \
Xiaozhe Shi9bd24622013-01-23 15:54:54 -08002159 "qcom," qpnp_spmi_property, \
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002160 &chip->chip_prop); \
2161 if (retval) { \
2162 pr_err("Error reading " #qpnp_spmi_property \
2163 " property %d\n", rc); \
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002164 return -EINVAL; \
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002165 } \
2166} while (0)
2167
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002168static inline int bms_read_properties(struct qpnp_bms_chip *chip)
2169{
2170 int rc;
2171
Xiaozhe Shid0a79542012-11-06 10:00:38 -08002172 SPMI_PROP_READ(r_sense_uohm, "r-sense-uohm", rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002173 SPMI_PROP_READ(v_cutoff_uv, "v-cutoff-uv", rc);
2174 SPMI_PROP_READ(max_voltage_uv, "max-voltage-uv", rc);
2175 SPMI_PROP_READ(r_conn_mohm, "r-conn-mohm", rc);
2176 SPMI_PROP_READ(chg_term_ua, "chg-term-ua", rc);
2177 SPMI_PROP_READ(shutdown_soc_valid_limit,
2178 "shutdown-soc-valid-limit", rc);
2179 SPMI_PROP_READ(adjust_soc_high_threshold,
2180 "adjust-soc-high-threshold", rc);
2181 SPMI_PROP_READ(adjust_soc_low_threshold,
2182 "adjust-soc-low-threshold", rc);
2183 SPMI_PROP_READ(batt_type, "batt-type", rc);
2184 SPMI_PROP_READ(low_soc_calc_threshold,
2185 "low-soc-calculate-soc-threshold", rc);
2186 SPMI_PROP_READ(low_soc_calculate_soc_ms,
2187 "low-soc-calculate-soc-ms", rc);
2188 SPMI_PROP_READ(calculate_soc_ms, "calculate-soc-ms", rc);
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002189 chip->use_external_rsense = of_property_read_bool(
2190 chip->spmi->dev.of_node,
Xiaozhe Shi9bd24622013-01-23 15:54:54 -08002191 "qcom,use-external-rsense");
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002192 chip->ignore_shutdown_soc = of_property_read_bool(
2193 chip->spmi->dev.of_node,
Xiaozhe Shi9bd24622013-01-23 15:54:54 -08002194 "qcom,ignore-shutdown-soc");
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08002195 chip->use_voltage_soc = of_property_read_bool(chip->spmi->dev.of_node,
Xiaozhe Shi9bd24622013-01-23 15:54:54 -08002196 "qcom,use-voltage-soc");
Xiaozhe Shibdf14742012-12-05 12:41:48 -08002197 chip->use_ocv_thresholds = of_property_read_bool(
2198 chip->spmi->dev.of_node,
Xiaozhe Shi9bd24622013-01-23 15:54:54 -08002199 "qcom,use-ocv-thresholds");
Xiaozhe Shibdf14742012-12-05 12:41:48 -08002200 SPMI_PROP_READ(ocv_high_threshold_uv,
2201 "ocv-voltage-high-threshold-uv", rc);
2202 SPMI_PROP_READ(ocv_low_threshold_uv,
2203 "ocv-voltage-low-threshold-uv", rc);
Xiaozhe Shi4be85782013-02-22 17:33:40 -08002204 SPMI_PROP_READ(low_voltage_threshold, "low-voltage-threshold", rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002205
2206 if (chip->adjust_soc_low_threshold >= 45)
2207 chip->adjust_soc_low_threshold = 45;
2208
Xiaozhe Shid0a79542012-11-06 10:00:38 -08002209 pr_debug("dts data: r_sense_uohm:%d, v_cutoff_uv:%d, max_v:%d\n",
2210 chip->r_sense_uohm, chip->v_cutoff_uv,
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002211 chip->max_voltage_uv);
2212 pr_debug("r_conn:%d, shutdown_soc: %d, adjust_soc_low:%d\n",
2213 chip->r_conn_mohm, chip->shutdown_soc_valid_limit,
2214 chip->adjust_soc_low_threshold);
2215 pr_debug("adjust_soc_high:%d, chg_term_ua:%d, batt_type:%d\n",
2216 chip->adjust_soc_high_threshold, chip->chg_term_ua,
2217 chip->batt_type);
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08002218 pr_debug("ignore_shutdown_soc:%d, use_voltage_soc:%d\n",
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08002219 chip->ignore_shutdown_soc, chip->use_voltage_soc);
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002220 pr_debug("use external rsense: %d\n", chip->use_external_rsense);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002221 return 0;
2222}
2223
2224static inline void bms_initialize_constants(struct qpnp_bms_chip *chip)
2225{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002226 chip->prev_pc_unusable = -EINVAL;
2227 chip->soc_at_cv = -EINVAL;
2228 chip->calculated_soc = -EINVAL;
Xiaozhe Shie118c692012-09-24 15:17:43 -07002229 chip->last_soc = -EINVAL;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07002230 chip->last_soc_est = -EINVAL;
Xiaozhe Shif36d2862013-01-04 10:17:35 -08002231 chip->last_cc_uah = INT_MIN;
Abhijeet Dharmapurikar15f30fb2012-12-27 17:20:29 -08002232 chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
2233 chip->prev_last_good_ocv_raw = OCV_RAW_UNINITIALIZED;
Xiaozhe Shie118c692012-09-24 15:17:43 -07002234 chip->first_time_calc_soc = 1;
2235 chip->first_time_calc_uuc = 1;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002236}
2237
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002238#define REG_OFFSET_PERP_TYPE 0x04
2239#define REG_OFFSET_PERP_SUBTYPE 0x05
2240#define BMS_BMS_TYPE 0xD
Xiaozhe Shief6274c2013-03-06 15:23:52 -08002241#define BMS_BMS1_SUBTYPE 0x1
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002242#define BMS_IADC_TYPE 0x8
Xiaozhe Shief6274c2013-03-06 15:23:52 -08002243#define BMS_IADC1_SUBTYPE 0x3
2244#define BMS_IADC2_SUBTYPE 0x5
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002245
2246static int register_spmi(struct qpnp_bms_chip *chip, struct spmi_device *spmi)
2247{
2248 struct spmi_resource *spmi_resource;
2249 struct resource *resource;
2250 int rc;
2251 u8 type, subtype;
2252
2253 chip->dev = &(spmi->dev);
2254 chip->spmi = spmi;
2255
2256 spmi_for_each_container_dev(spmi_resource, spmi) {
2257 if (!spmi_resource) {
2258 pr_err("qpnp_bms: spmi resource absent\n");
2259 return -ENXIO;
2260 }
2261
2262 resource = spmi_get_resource(spmi, spmi_resource,
2263 IORESOURCE_MEM, 0);
2264 if (!(resource && resource->start)) {
2265 pr_err("node %s IO resource absent!\n",
2266 spmi->dev.of_node->full_name);
2267 return -ENXIO;
2268 }
2269
2270 rc = qpnp_read_wrapper(chip, &type,
2271 resource->start + REG_OFFSET_PERP_TYPE, 1);
2272 if (rc) {
2273 pr_err("Peripheral type read failed rc=%d\n", rc);
2274 return rc;
2275 }
2276 rc = qpnp_read_wrapper(chip, &subtype,
2277 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2278 if (rc) {
2279 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2280 return rc;
2281 }
2282
Xiaozhe Shief6274c2013-03-06 15:23:52 -08002283 if (type == BMS_BMS_TYPE && subtype == BMS_BMS1_SUBTYPE) {
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002284 chip->base = resource->start;
2285 } else if (type == BMS_IADC_TYPE
Xiaozhe Shief6274c2013-03-06 15:23:52 -08002286 && (subtype == BMS_IADC1_SUBTYPE
2287 || subtype == BMS_IADC2_SUBTYPE)) {
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002288 chip->iadc_base = resource->start;
2289 } else {
2290 pr_err("Invalid peripheral start=0x%x type=0x%x, subtype=0x%x\n",
2291 resource->start, type, subtype);
2292 }
2293 }
2294
2295 if (chip->base == 0) {
2296 dev_err(&spmi->dev, "BMS peripheral was not registered\n");
2297 return -EINVAL;
2298 }
2299 if (chip->iadc_base == 0) {
2300 dev_err(&spmi->dev, "BMS_IADC peripheral was not registered\n");
2301 return -EINVAL;
2302 }
2303
2304 return 0;
2305}
2306
2307#define ADC_CH_SEL_MASK 0x7
2308static int read_iadc_channel_select(struct qpnp_bms_chip *chip)
2309{
2310 u8 iadc_channel_select;
Xiaozhe Shi767fdb62013-01-10 15:09:08 -08002311 int32_t rds_rsense_nohm;
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002312 int rc;
2313
2314 rc = qpnp_read_wrapper(chip, &iadc_channel_select,
2315 chip->iadc_base + IADC1_BMS_ADC_CH_SEL_CTL, 1);
2316 if (rc) {
2317 pr_err("Error reading bms_iadc channel register %d\n", rc);
2318 return rc;
2319 }
2320
2321 iadc_channel_select &= ADC_CH_SEL_MASK;
Xiaozhe Shi767fdb62013-01-10 15:09:08 -08002322 if (iadc_channel_select != EXTERNAL_RSENSE
2323 && iadc_channel_select != INTERNAL_RSENSE) {
2324 pr_err("IADC1_BMS_IADC configured incorrectly. Selected channel = %d\n",
2325 iadc_channel_select);
2326 return -EINVAL;
2327 }
2328
2329 if (chip->use_external_rsense) {
2330 pr_debug("External rsense selected\n");
2331 if (iadc_channel_select == INTERNAL_RSENSE) {
2332 pr_debug("Internal rsense detected; Changing rsense to external\n");
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002333 rc = qpnp_masked_write_iadc(chip,
2334 IADC1_BMS_ADC_CH_SEL_CTL,
2335 ADC_CH_SEL_MASK,
2336 EXTERNAL_RSENSE);
2337 if (rc) {
2338 pr_err("Unable to set IADC1_BMS channel %x to %x: %d\n",
2339 IADC1_BMS_ADC_CH_SEL_CTL,
2340 EXTERNAL_RSENSE, rc);
2341 return rc;
2342 }
2343 reset_cc(chip);
2344 }
Xiaozhe Shi767fdb62013-01-10 15:09:08 -08002345 } else {
2346 pr_debug("Internal rsense selected\n");
2347 if (iadc_channel_select == EXTERNAL_RSENSE) {
2348 pr_debug("External rsense detected; Changing rsense to internal\n");
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002349 rc = qpnp_masked_write_iadc(chip,
2350 IADC1_BMS_ADC_CH_SEL_CTL,
2351 ADC_CH_SEL_MASK,
2352 INTERNAL_RSENSE);
2353 if (rc) {
2354 pr_err("Unable to set IADC1_BMS channel %x to %x: %d\n",
2355 IADC1_BMS_ADC_CH_SEL_CTL,
2356 INTERNAL_RSENSE, rc);
2357 return rc;
2358 }
2359 reset_cc(chip);
2360 }
Xiaozhe Shi767fdb62013-01-10 15:09:08 -08002361
2362 rc = qpnp_iadc_get_rsense(&rds_rsense_nohm);
2363 if (rc) {
2364 pr_err("Unable to read RDS resistance value from IADC; rc = %d\n",
2365 rc);
2366 return rc;
2367 }
Xiaozhe Shid0a79542012-11-06 10:00:38 -08002368 chip->r_sense_uohm = rds_rsense_nohm/1000;
2369 pr_debug("rds_rsense = %d nOhm, saved as %d uOhm\n",
2370 rds_rsense_nohm, chip->r_sense_uohm);
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002371 }
2372 return 0;
2373}
2374
2375static int __devinit qpnp_bms_probe(struct spmi_device *spmi)
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002376{
2377 struct qpnp_bms_chip *chip;
Xiaozhe Shid5d21412013-02-06 17:14:41 -08002378 union power_supply_propval retval = {0,};
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002379 int rc, vbatt;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002380
2381 chip = kzalloc(sizeof *chip, GFP_KERNEL);
2382
2383 if (chip == NULL) {
2384 pr_err("kzalloc() failed.\n");
2385 return -ENOMEM;
2386 }
2387
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002388 rc = qpnp_vadc_is_ready();
2389 if (rc) {
2390 pr_info("vadc not ready: %d, deferring probe\n", rc);
2391 goto error_read;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002392 }
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002393
2394 rc = qpnp_iadc_is_ready();
2395 if (rc) {
2396 pr_info("iadc not ready: %d, deferring probe\n", rc);
2397 goto error_read;
2398 }
2399
2400 rc = register_spmi(chip, spmi);
2401 if (rc) {
2402 pr_err("error registering spmi resource %d\n", rc);
2403 goto error_resource;
2404 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002405
2406 rc = qpnp_read_wrapper(chip, &chip->revision1,
2407 chip->base + BMS1_REVISION1, 1);
2408 if (rc) {
2409 pr_err("error reading version register %d\n", rc);
2410 goto error_read;
2411 }
2412
2413 rc = qpnp_read_wrapper(chip, &chip->revision2,
2414 chip->base + BMS1_REVISION2, 1);
2415 if (rc) {
2416 pr_err("Error reading version register %d\n", rc);
2417 goto error_read;
2418 }
Xiaozhe Shia045a562012-11-28 16:55:39 -08002419 pr_debug("BMS version: %hhu.%hhu\n", chip->revision2, chip->revision1);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002420
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002421 rc = bms_read_properties(chip);
2422 if (rc) {
2423 pr_err("Unable to read all bms properties, rc = %d\n", rc);
2424 goto error_read;
2425 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002426
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002427 rc = read_iadc_channel_select(chip);
2428 if (rc) {
2429 pr_err("Unable to get iadc selected channel = %d\n", rc);
2430 goto error_read;
2431 }
2432
Xiaozhe Shibdf14742012-12-05 12:41:48 -08002433 if (chip->use_ocv_thresholds) {
2434 rc = set_ocv_voltage_thresholds(chip,
2435 chip->ocv_low_threshold_uv,
2436 chip->ocv_high_threshold_uv);
2437 if (rc) {
2438 pr_err("Could not set ocv voltage thresholds: %d\n",
2439 rc);
2440 goto error_read;
2441 }
2442 }
2443
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002444 rc = set_battery_data(chip);
2445 if (rc) {
2446 pr_err("Bad battery data %d\n", rc);
2447 goto error_read;
2448 }
2449
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002450 bms_initialize_constants(chip);
2451
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002452 mutex_init(&chip->bms_output_lock);
2453 mutex_init(&chip->last_ocv_uv_mutex);
2454 mutex_init(&chip->soc_invalidation_mutex);
2455
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -08002456 wake_lock_init(&chip->soc_wake_lock, WAKE_LOCK_SUSPEND,
2457 "qpnp_soc_lock");
Xiaozhe Shi4be85782013-02-22 17:33:40 -08002458 wake_lock_init(&chip->low_voltage_wake_lock, WAKE_LOCK_SUSPEND,
2459 "qpnp_low_voltage_lock");
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002460 INIT_DELAYED_WORK(&chip->calculate_soc_delayed_work,
2461 calculate_soc_work);
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08002462 INIT_WORK(&chip->recalc_work, recalculate_work);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002463
2464 read_shutdown_soc_and_iavg(chip);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002465
2466 dev_set_drvdata(&spmi->dev, chip);
2467 device_init_wakeup(&spmi->dev, 1);
2468
Xiaozhe Shid5d21412013-02-06 17:14:41 -08002469 if (!chip->batt_psy)
2470 chip->batt_psy = power_supply_get_by_name("battery");
2471 if (chip->batt_psy) {
2472 chip->batt_psy->get_property(chip->batt_psy,
2473 POWER_SUPPLY_PROP_PRESENT, &retval);
2474 chip->battery_present = retval.intval;
Xiaozhe Shi5cf7a672013-02-06 17:18:05 -08002475 pr_debug("present = %d\n", chip->battery_present);
2476 } else {
2477 chip->battery_present = 1;
Xiaozhe Shid5d21412013-02-06 17:14:41 -08002478 }
2479
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002480 calculate_soc_work(&(chip->calculate_soc_delayed_work.work));
2481
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002482 /* setup & register the battery power supply */
2483 chip->bms_psy.name = "bms";
2484 chip->bms_psy.type = POWER_SUPPLY_TYPE_BMS;
2485 chip->bms_psy.properties = msm_bms_power_props;
2486 chip->bms_psy.num_properties = ARRAY_SIZE(msm_bms_power_props);
2487 chip->bms_psy.get_property = qpnp_bms_power_get_property;
2488 chip->bms_psy.set_property = qpnp_bms_power_set_property;
2489 chip->bms_psy.external_power_changed =
2490 qpnp_bms_external_power_changed;
2491 chip->bms_psy.supplied_to = qpnp_bms_supplicants;
2492 chip->bms_psy.num_supplicants = ARRAY_SIZE(qpnp_bms_supplicants);
2493
2494 rc = power_supply_register(chip->dev, &chip->bms_psy);
2495
2496 if (rc < 0) {
2497 pr_err("power_supply_register bms failed rc = %d\n", rc);
2498 goto unregister_dc;
2499 }
2500
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002501 vbatt = 0;
Xiaozhe Shi36458962013-02-06 16:19:57 -08002502 rc = get_battery_voltage(&vbatt);
2503 if (rc) {
2504 pr_err("error reading vbat_sns adc channel = %d, rc = %d\n",
2505 VBAT_SNS, rc);
2506 goto unregister_dc;
2507 }
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002508
Xiaozhe Shid0a79542012-11-06 10:00:38 -08002509 pr_info("probe success: soc =%d vbatt = %d ocv = %d r_sense_uohm = %u\n",
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002510 get_prop_bms_capacity(chip),
Xiaozhe Shid0a79542012-11-06 10:00:38 -08002511 vbatt, chip->last_ocv_uv, chip->r_sense_uohm);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002512 return 0;
2513
2514unregister_dc:
Abhijeet Dharmapurikar713b60a2012-12-26 21:30:05 -08002515 wake_lock_destroy(&chip->soc_wake_lock);
Xiaozhe Shi4be85782013-02-22 17:33:40 -08002516 wake_lock_destroy(&chip->low_voltage_wake_lock);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002517 power_supply_unregister(&chip->bms_psy);
2518 dev_set_drvdata(&spmi->dev, NULL);
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002519error_resource:
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002520error_read:
2521 kfree(chip);
2522 return rc;
2523}
2524
2525static int __devexit
2526qpnp_bms_remove(struct spmi_device *spmi)
2527{
2528 struct qpnp_bms_chip *chip = dev_get_drvdata(&spmi->dev);
2529
2530 dev_set_drvdata(&spmi->dev, NULL);
2531 kfree(chip);
2532 return 0;
2533}
2534
Xiaozhe Shicdeee312012-12-18 15:10:18 -08002535static int bms_resume(struct device *dev)
2536{
2537 int rc;
2538 unsigned long soc_calc_period;
2539 unsigned long time_since_last_recalc;
2540 unsigned long tm_now_sec;
2541 struct qpnp_bms_chip *chip = dev_get_drvdata(dev);
2542
2543 rc = get_current_time(&tm_now_sec);
2544 if (rc) {
2545 pr_err("Could not read current time: %d\n", rc);
2546 } else if (tm_now_sec > chip->last_recalc_time) {
2547 time_since_last_recalc = tm_now_sec - chip->last_recalc_time;
2548 pr_debug("Time since last recalc: %lu\n",
2549 time_since_last_recalc);
2550 if (chip->calculated_soc < chip->low_soc_calc_threshold)
2551 soc_calc_period = chip->low_soc_calculate_soc_ms;
2552 else
2553 soc_calc_period = chip->calculate_soc_ms;
2554
2555 if (time_since_last_recalc >= soc_calc_period) {
2556 chip->last_recalc_time = tm_now_sec;
2557 recalculate_soc(chip);
2558 }
2559 }
2560 return 0;
2561}
2562
2563static const struct dev_pm_ops qpnp_bms_pm_ops = {
2564 .resume = bms_resume,
2565};
2566
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002567static struct spmi_driver qpnp_bms_driver = {
2568 .probe = qpnp_bms_probe,
2569 .remove = __devexit_p(qpnp_bms_remove),
2570 .driver = {
2571 .name = QPNP_BMS_DEV_NAME,
2572 .owner = THIS_MODULE,
2573 .of_match_table = qpnp_bms_match_table,
Xiaozhe Shicdeee312012-12-18 15:10:18 -08002574 .pm = &qpnp_bms_pm_ops,
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002575 },
2576};
2577
2578static int __init qpnp_bms_init(void)
2579{
2580 pr_info("QPNP BMS INIT\n");
2581 return spmi_driver_register(&qpnp_bms_driver);
2582}
2583
2584static void __exit qpnp_bms_exit(void)
2585{
2586 pr_info("QPNP BMS EXIT\n");
2587 return spmi_driver_unregister(&qpnp_bms_driver);
2588}
2589
2590module_init(qpnp_bms_init);
2591module_exit(qpnp_bms_exit);
2592
2593MODULE_DESCRIPTION("QPNP BMS Driver");
2594MODULE_LICENSE("GPL v2");
2595MODULE_ALIAS("platform:" QPNP_BMS_DEV_NAME);