blob: 1bc027c96fdc56b5164710e867d130ebf7666281 [file] [log] [blame]
Xiaozhe Shi73a65692012-09-18 17:51:57 -07001/* Copyright (c) 2011-2012, 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 Shib19f7032012-08-16 12:14:16 -070037/* OCV limit registers */
38#define BMS1_OCV_USE_LOW_LIMIT_THR0 0x48
39#define BMS1_OCV_USE_LOW_LIMIT_THR1 0x49
40#define BMS1_OCV_USE_HIGH_LIMIT_THR0 0x4A
41#define BMS1_OCV_USE_HIGH_LIMIT_THR1 0x4B
42#define BMS1_OCV_USE_LIMIT_CTL 0x4C
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -070043/* Delay control */
44#define BMS1_S1_DELAY_CTL 0x5A
Xiaozhe Shib19f7032012-08-16 12:14:16 -070045/* CC interrupt threshold */
46#define BMS1_CC_THR0 0x7A
47#define BMS1_CC_THR1 0x7B
48#define BMS1_CC_THR2 0x7C
49#define BMS1_CC_THR3 0x7D
50#define BMS1_CC_THR4 0x7E
51/* OCV for r registers */
52#define BMS1_OCV_FOR_R_DATA0 0x80
53#define BMS1_OCV_FOR_R_DATA1 0x81
54#define BMS1_VSENSE_FOR_R_DATA0 0x82
55#define BMS1_VSENSE_FOR_R_DATA1 0x83
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070056/* Coulomb counter data */
Xiaozhe Shib19f7032012-08-16 12:14:16 -070057#define BMS1_CC_DATA0 0x8A
58#define BMS1_CC_DATA1 0x8B
59#define BMS1_CC_DATA2 0x8C
60#define BMS1_CC_DATA3 0x8D
61#define BMS1_CC_DATA4 0x8E
62/* OCV for soc data */
63#define BMS1_OCV_FOR_SOC_DATA0 0x90
64#define BMS1_OCV_FOR_SOC_DATA1 0x91
65#define BMS1_VSENSE_PON_DATA0 0x94
66#define BMS1_VSENSE_PON_DATA1 0x95
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070067#define BMS1_VSENSE_AVG_DATA0 0x98
68#define BMS1_VSENSE_AVG_DATA1 0x99
Xiaozhe Shib19f7032012-08-16 12:14:16 -070069#define BMS1_VBAT_AVG_DATA0 0x9E
70#define BMS1_VBAT_AVG_DATA1 0x9F
71/* Extra bms registers */
72#define BMS1_BMS_DATA_REG_0 0xB0
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070073#define IAVG_STORAGE_REG 0xB1
74#define SOC_STORAGE_REG 0xB2
Xiaozhe Shib19f7032012-08-16 12:14:16 -070075#define BMS1_BMS_DATA_REG_3 0xB3
Xiaozhe Shic40b3972012-11-30 14:11:16 -080076/* IADC Channel Select */
77#define IADC1_BMS_ADC_CH_SEL_CTL 0x48
Xiaozhe Shib19f7032012-08-16 12:14:16 -070078
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070079/* Configuration for saving of shutdown soc/iavg */
80#define IGNORE_SOC_TEMP_DECIDEG 50
81#define IAVG_STEP_SIZE_MA 50
82#define IAVG_START 600
83#define SOC_ZERO 0xFF
84
Xiaozhe Shie118c692012-09-24 15:17:43 -070085#define IAVG_SAMPLES 16
86
Xiaozhe Shib19f7032012-08-16 12:14:16 -070087#define QPNP_BMS_DEV_NAME "qcom,qpnp-bms"
88
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070089struct soc_params {
90 int fcc_uah;
91 int cc_uah;
Xiaozhe Shi904f1f72012-12-04 12:47:21 -080092 int rbatt_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -070093 int iavg_ua;
94 int uuc_uah;
95 int ocv_charge_uah;
96};
97
98struct raw_soc_params {
99 uint16_t last_good_ocv_raw;
100 int64_t cc;
101 int last_good_ocv_uv;
102};
103
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700104struct qpnp_bms_chip {
105 struct device *dev;
106 struct power_supply bms_psy;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -0700107 struct power_supply *batt_psy;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700108 struct spmi_device *spmi;
109 u16 base;
Xiaozhe Shic40b3972012-11-30 14:11:16 -0800110 u16 iadc_base;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700111
112 u8 revision1;
113 u8 revision2;
114 int charger_status;
115 bool online;
116 /* platform data */
117 unsigned int r_sense_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700118 unsigned int v_cutoff_uv;
119 unsigned int max_voltage_uv;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700120 unsigned int r_conn_mohm;
121 int shutdown_soc_valid_limit;
122 int adjust_soc_low_threshold;
123 int adjust_soc_high_threshold;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700124 int chg_term_ua;
Xiaozhe Shi73a65692012-09-18 17:51:57 -0700125 enum battery_type batt_type;
126 unsigned int fcc;
127 struct single_row_lut *fcc_temp_lut;
128 struct single_row_lut *fcc_sf_lut;
129 struct pc_temp_ocv_lut *pc_temp_ocv_lut;
130 struct sf_lut *pc_sf_lut;
131 struct sf_lut *rbatt_sf_lut;
132 int default_rbatt_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700133
134 struct delayed_work calculate_soc_delayed_work;
135
136 struct mutex bms_output_lock;
137 struct mutex last_ocv_uv_mutex;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700138 struct mutex soc_invalidation_mutex;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700139
Xiaozhe Shic40b3972012-11-30 14:11:16 -0800140 bool use_external_rsense;
141
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700142 unsigned int start_percent;
143 unsigned int end_percent;
144 bool ignore_shutdown_soc;
145 int shutdown_soc_invalid;
146 int shutdown_soc;
147 int shutdown_iavg_ma;
148
149 int low_soc_calc_threshold;
150 int low_soc_calculate_soc_ms;
151 int calculate_soc_ms;
152
Xiaozhe Shie118c692012-09-24 15:17:43 -0700153 uint16_t ocv_reading_at_100;
154 int64_t cc_reading_at_100;
155 uint16_t prev_last_good_ocv_raw;
156 int last_ocv_uv;
157 int last_cc_uah;
158 unsigned long tm_sec;
159 bool first_time_calc_soc;
160 bool first_time_calc_uuc;
161 int pon_ocv_uv;
162
163 int iavg_samples_ma[IAVG_SAMPLES];
164 int iavg_index;
165 int iavg_num_samples;
166 struct timespec t_soc_queried;
167 int last_soc;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -0700168 int last_soc_est;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700169
170 int charge_time_us;
171 int catch_up_time_us;
172 struct single_row_lut *adjusted_fcc_temp_lut;
173
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700174 unsigned int vadc_v0625;
175 unsigned int vadc_v1250;
176
Xiaozhe Shi904f1f72012-12-04 12:47:21 -0800177 int ibat_max_ua;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700178 int prev_iavg_ua;
179 int prev_uuc_iavg_ma;
180 int prev_pc_unusable;
181 int ibat_at_cv_ua;
182 int soc_at_cv;
183 int prev_chg_soc;
184 int calculated_soc;
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -0800185 int prev_voltage_based_soc;
186 bool use_voltage_soc;
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700187};
188
189static struct of_device_id qpnp_bms_match_table[] = {
190 { .compatible = QPNP_BMS_DEV_NAME },
191 {}
192};
193
194static char *qpnp_bms_supplicants[] = {
195 "battery"
196};
197
198static enum power_supply_property msm_bms_power_props[] = {
199 POWER_SUPPLY_PROP_STATUS,
200 POWER_SUPPLY_PROP_ONLINE,
201 POWER_SUPPLY_PROP_CAPACITY,
202 POWER_SUPPLY_PROP_CURRENT_NOW,
Xiaozhe Shi904f1f72012-12-04 12:47:21 -0800203 POWER_SUPPLY_PROP_CURRENT_MAX,
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700204 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
205};
206
Xiaozhe Shi781b0a22012-11-05 17:18:27 -0800207
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700208static int qpnp_read_wrapper(struct qpnp_bms_chip *chip, u8 *val,
209 u16 base, int count)
210{
211 int rc;
212 struct spmi_device *spmi = chip->spmi;
213
214 rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val, count);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700215 if (rc) {
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700216 pr_err("SPMI read failed rc=%d\n", rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700217 return rc;
218 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -0700219 return 0;
220}
221
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700222static int qpnp_write_wrapper(struct qpnp_bms_chip *chip, u8 *val,
223 u16 base, int count)
224{
225 int rc;
226 struct spmi_device *spmi = chip->spmi;
227
228 rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val, count);
229 if (rc) {
230 pr_err("SPMI write failed rc=%d\n", rc);
231 return rc;
232 }
233 return 0;
234}
235
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800236static int qpnp_masked_write_base(struct qpnp_bms_chip *chip, u16 addr,
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700237 u8 mask, u8 val)
238{
239 int rc;
240 u8 reg;
241
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800242 rc = qpnp_read_wrapper(chip, &reg, addr, 1);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700243 if (rc) {
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800244 pr_err("read failed addr = %03X, rc = %d\n", addr, rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700245 return rc;
246 }
247 reg &= ~mask;
248 reg |= val & mask;
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800249 rc = qpnp_write_wrapper(chip, &reg, addr, 1);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700250 if (rc) {
251 pr_err("write failed addr = %03X, val = %02x, mask = %02x, reg = %02x, rc = %d\n",
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800252 addr, val, mask, reg, rc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700253 return rc;
254 }
255 return 0;
256}
257
Xiaozhe Shidffbe692012-12-11 15:35:46 -0800258static int qpnp_masked_write_iadc(struct qpnp_bms_chip *chip, u16 addr,
259 u8 mask, u8 val)
260{
261 return qpnp_masked_write_base(chip, chip->iadc_base + addr, mask, val);
262}
263
264static int qpnp_masked_write(struct qpnp_bms_chip *chip, u16 addr,
265 u8 mask, u8 val)
266{
267 return qpnp_masked_write_base(chip, chip->base + addr, mask, val);
268}
269
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700270#define HOLD_OREG_DATA BIT(0)
271static int lock_output_data(struct qpnp_bms_chip *chip)
272{
273 int rc;
274
275 rc = qpnp_masked_write(chip, BMS1_CC_DATA_CTL,
276 HOLD_OREG_DATA, HOLD_OREG_DATA);
277 if (rc) {
278 pr_err("couldnt lock bms output rc = %d\n", rc);
279 return rc;
280 }
281 return 0;
282}
283
284static int unlock_output_data(struct qpnp_bms_chip *chip)
285{
286 int rc;
287
288 rc = qpnp_masked_write(chip, BMS1_CC_DATA_CTL, HOLD_OREG_DATA, 0);
289 if (rc) {
290 pr_err("fail to unlock BMS_CONTROL rc = %d\n", rc);
291 return rc;
292 }
293 return 0;
294}
295
296#define V_PER_BIT_MUL_FACTOR 97656
297#define V_PER_BIT_DIV_FACTOR 1000
298#define VADC_INTRINSIC_OFFSET 0x6000
299
300static int vadc_reading_to_uv(unsigned int reading)
301{
302 if (reading <= VADC_INTRINSIC_OFFSET)
303 return 0;
304
305 return (reading - VADC_INTRINSIC_OFFSET)
306 * V_PER_BIT_MUL_FACTOR / V_PER_BIT_DIV_FACTOR;
307}
308
309#define VADC_CALIB_UV 625000
310#define VBATT_MUL_FACTOR 3
311
312static int adjust_vbatt_reading(struct qpnp_bms_chip *chip,
313 unsigned int reading_uv)
314{
315 s64 numerator, denominator;
316
317 if (reading_uv == 0)
318 return 0;
319
320 /* don't adjust if not calibrated */
321 if (chip->vadc_v0625 == 0 || chip->vadc_v1250 == 0) {
322 pr_debug("No cal yet return %d\n",
323 VBATT_MUL_FACTOR * reading_uv);
324 return VBATT_MUL_FACTOR * reading_uv;
325 }
326
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700327 numerator = ((s64)reading_uv - chip->vadc_v0625) * VADC_CALIB_UV;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700328 denominator = (s64)chip->vadc_v1250 - chip->vadc_v0625;
329 if (denominator == 0)
330 return reading_uv * VBATT_MUL_FACTOR;
331 return (VADC_CALIB_UV + div_s64(numerator, denominator))
332 * VBATT_MUL_FACTOR;
333}
334
335static inline int convert_vbatt_raw_to_uv(struct qpnp_bms_chip *chip,
336 uint16_t reading)
337{
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700338 int uv;
339
340 uv = vadc_reading_to_uv(reading);
341 pr_debug("%u raw converted into %d uv\n", reading, uv);
342 uv = adjust_vbatt_reading(chip, uv);
343 pr_debug("adjusted into %d uv\n", uv);
344 return uv;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700345}
346
347#define CC_READING_RESOLUTION_N 542535
348#define CC_READING_RESOLUTION_D 100000
349static int cc_reading_to_uv(int16_t reading)
350{
351 return div_s64(reading * CC_READING_RESOLUTION_N,
352 CC_READING_RESOLUTION_D);
353}
354
355#define QPNP_ADC_GAIN_NV 17857LL
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700356static s64 cc_adjust_for_gain(s64 uv, uint16_t gain)
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700357{
358 s64 result_uv;
359
360 pr_debug("adjusting_uv = %lld\n", uv);
Xiaozhe Shi820a47a2012-11-27 13:23:27 -0800361 if (gain == 0) {
362 pr_debug("gain is %d, not adjusting\n", gain);
363 return uv;
364 }
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700365 pr_debug("adjusting by factor: %lld/%hu = %lld%%\n",
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700366 QPNP_ADC_GAIN_NV, gain,
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700367 div_s64(QPNP_ADC_GAIN_NV * 100LL, (s64)gain));
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700368
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700369 result_uv = div_s64(uv * QPNP_ADC_GAIN_NV, (s64)gain);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700370 pr_debug("result_uv = %lld\n", result_uv);
371 return result_uv;
372}
373
374static int convert_vsense_to_uv(struct qpnp_bms_chip *chip,
375 int16_t reading)
376{
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700377 struct qpnp_iadc_calib calibration;
378
379 qpnp_iadc_get_gain_and_offset(&calibration);
380 return cc_adjust_for_gain(cc_reading_to_uv(reading),
381 calibration.gain_raw);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700382}
383
384static int read_vsense_avg(struct qpnp_bms_chip *chip, int *result_uv)
385{
386 int rc;
387 int16_t reading;
388
389 rc = qpnp_read_wrapper(chip, (u8 *)&reading,
390 chip->base + BMS1_VSENSE_AVG_DATA0, 2);
391
392 if (rc) {
393 pr_err("fail to read VSENSE_AVG rc = %d\n", rc);
394 return rc;
395 }
396
397 *result_uv = convert_vsense_to_uv(chip, reading);
398 return 0;
399}
400
401static int get_battery_current(struct qpnp_bms_chip *chip, int *result_ua)
402{
403 int vsense_uv = 0;
404
405 if (chip->r_sense_mohm == 0) {
406 pr_err("r_sense is zero\n");
407 return -EINVAL;
408 }
409
410 mutex_lock(&chip->bms_output_lock);
411 lock_output_data(chip);
412 read_vsense_avg(chip, &vsense_uv);
413 unlock_output_data(chip);
414 mutex_unlock(&chip->bms_output_lock);
415
416 pr_debug("vsense_uv=%duV\n", vsense_uv);
417 /* cast for signed division */
418 *result_ua = vsense_uv * 1000 / (int)chip->r_sense_mohm;
419 pr_debug("ibat=%duA\n", *result_ua);
420 return 0;
421}
422
423static int get_battery_voltage(int *result_uv)
424{
425 int rc;
426 struct qpnp_vadc_result adc_result;
427
428 rc = qpnp_vadc_read(VBAT_SNS, &adc_result);
429 if (rc) {
430 pr_err("error reading adc channel = %d, rc = %d\n",
431 VBAT_SNS, rc);
432 return rc;
433 }
434 pr_debug("mvolts phy = %lld meas = 0x%llx\n", adc_result.physical,
435 adc_result.measurement);
436 *result_uv = (int)adc_result.physical;
437 return 0;
438}
439
Xiaozhe Shie118c692012-09-24 15:17:43 -0700440#define CC_36_BIT_MASK 0xFFFFFFFFFLL
441
442static int read_cc_raw(struct qpnp_bms_chip *chip, int64_t *reading)
443{
444 int64_t raw_reading;
445 int rc;
446
447 rc = qpnp_read_wrapper(chip, (u8 *)&raw_reading,
448 chip->base + BMS1_CC_DATA0, 5);
449 if (rc) {
450 pr_err("Error reading cc: rc = %d\n", rc);
451 return -ENXIO;
452 }
453
454 raw_reading = raw_reading & CC_36_BIT_MASK;
455 /* convert 36 bit signed value into 64 signed value */
456 *reading = (raw_reading >> 35) == 0LL ?
457 raw_reading : ((-1LL ^ CC_36_BIT_MASK) | raw_reading);
458 pr_debug("before conversion: %llx, after conversion: %llx\n",
459 raw_reading, *reading);
460
461 return 0;
462}
463
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700464static int calib_vadc(struct qpnp_bms_chip *chip)
465{
466 int rc;
467 struct qpnp_vadc_result result;
468
469 rc = qpnp_vadc_read(REF_625MV, &result);
470 if (rc) {
471 pr_debug("vadc read failed with rc = %d\n", rc);
472 return rc;
473 }
474 chip->vadc_v0625 = result.physical;
475
476 rc = qpnp_vadc_read(REF_125V, &result);
477 if (rc) {
478 pr_debug("vadc read failed with rc = %d\n", rc);
479 return rc;
480 }
481 chip->vadc_v1250 = result.physical;
482 pr_debug("vadc calib: 0625 = %d, 1250 = %d\n",
483 chip->vadc_v0625, chip->vadc_v1250);
484 return 0;
485}
486
Xiaozhe Shie118c692012-09-24 15:17:43 -0700487static void convert_and_store_ocv(struct qpnp_bms_chip *chip,
488 struct raw_soc_params *raw)
489{
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700490 int rc;
491
492 pr_debug("prev_last_good_ocv_raw = %d, last_good_ocv_raw = %d\n",
493 chip->prev_last_good_ocv_raw,
494 raw->last_good_ocv_raw);
495 rc = calib_vadc(chip);
496 if (rc)
497 pr_err("Vadc reference voltage read failed, rc = %d\n", rc);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700498 chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
499 raw->last_good_ocv_uv = convert_vbatt_raw_to_uv(chip,
500 raw->last_good_ocv_raw);
501 chip->last_ocv_uv = raw->last_good_ocv_uv;
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700502 pr_debug("last_good_ocv_uv = %d\n", raw->last_good_ocv_uv);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700503}
504
Xiaozhe Shia045a562012-11-28 16:55:39 -0800505#define CLEAR_CC BIT(7)
506#define CLEAR_SW_CC BIT(6)
507/**
508 * reset both cc and sw-cc.
509 * note: this should only be ever called from one thread
510 * or there may be a race condition where CC is never enabled
511 * again
512 */
513static void reset_cc(struct qpnp_bms_chip *chip)
514{
515 int rc;
516
517 pr_debug("resetting cc manually\n");
518 rc = qpnp_masked_write(chip, BMS1_CC_CLEAR_CTL,
519 CLEAR_CC | CLEAR_SW_CC,
520 CLEAR_CC | CLEAR_SW_CC);
521 if (rc)
522 pr_err("cc reset failed: %d\n", rc);
523
524 /* wait for 100us for cc to reset */
525 udelay(100);
526
527 rc = qpnp_masked_write(chip, BMS1_CC_CLEAR_CTL,
528 CLEAR_CC | CLEAR_SW_CC, 0);
529 if (rc)
530 pr_err("cc reenable failed: %d\n", rc);
531}
532
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700533static int read_soc_params_raw(struct qpnp_bms_chip *chip,
534 struct raw_soc_params *raw)
535{
Xiaozhe Shie118c692012-09-24 15:17:43 -0700536 int rc;
537
538 mutex_lock(&chip->bms_output_lock);
Xiaozhe Shia045a562012-11-28 16:55:39 -0800539
540 if (chip->prev_last_good_ocv_raw == 0) {
541 /* software workaround for BMS 1.0
542 * The coulomb counter does not reset upon PON, so reset it
543 * manually upon probe. */
544 if (chip->revision1 == 0 && chip->revision2 == 0)
545 reset_cc(chip);
546 }
547
Xiaozhe Shie118c692012-09-24 15:17:43 -0700548 lock_output_data(chip);
549
550 rc = qpnp_read_wrapper(chip, (u8 *)&raw->last_good_ocv_raw,
551 chip->base + BMS1_OCV_FOR_SOC_DATA0, 2);
552 if (rc) {
553 pr_err("Error reading ocv: rc = %d\n", rc);
554 return -ENXIO;
555 }
556
557 rc = read_cc_raw(chip, &raw->cc);
558 if (rc) {
559 pr_err("Failed to read raw cc data, rc = %d\n", rc);
560 return rc;
561 }
562
563 unlock_output_data(chip);
564 mutex_unlock(&chip->bms_output_lock);
565
566 if (chip->prev_last_good_ocv_raw == 0) {
567 convert_and_store_ocv(chip, raw);
568 pr_debug("PON_OCV_UV = %d\n", chip->last_ocv_uv);
569 } else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
570 convert_and_store_ocv(chip, raw);
571 /* forget the old cc value upon ocv */
572 chip->last_cc_uah = 0;
573 } else {
574 raw->last_good_ocv_uv = chip->last_ocv_uv;
575 }
576
577 /* fake a high OCV if done charging */
578 if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
579 chip->ocv_reading_at_100 = 0;
580 chip->cc_reading_at_100 = 0;
581 } else {
582 /*
583 * force 100% ocv by selecting the highest voltage the
584 * battery could ever reach
585 */
586 raw->last_good_ocv_uv = chip->max_voltage_uv;
587 chip->last_ocv_uv = chip->max_voltage_uv;
588 }
589 pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
590 raw->last_good_ocv_raw, raw->last_good_ocv_uv);
591 pr_debug("cc_raw= 0x%llx\n", raw->cc);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -0700592 return 0;
593}
594
Xiaozhe Shie118c692012-09-24 15:17:43 -0700595static int calculate_pc(struct qpnp_bms_chip *chip, int ocv_uv,
596 int batt_temp)
597{
598 int pc;
599
600 pc = interpolate_pc(chip->pc_temp_ocv_lut,
601 batt_temp / 10, ocv_uv / 1000);
602 pr_debug("pc = %u %% for ocv = %d uv batt_temp = %d\n",
603 pc, ocv_uv, batt_temp);
604 /* Multiply the initial FCC value by the scale factor. */
605 return pc;
606}
607
608static int calculate_fcc(struct qpnp_bms_chip *chip, int batt_temp)
609{
610 int fcc_uah;
611
612 if (chip->adjusted_fcc_temp_lut == NULL) {
613 /* interpolate_fcc returns a mv value. */
614 fcc_uah = interpolate_fcc(chip->fcc_temp_lut,
615 batt_temp) * 1000;
616 pr_debug("fcc = %d uAh\n", fcc_uah);
617 return fcc_uah;
618 } else {
619 return 1000 * interpolate_fcc(chip->adjusted_fcc_temp_lut,
620 batt_temp);
621 }
622}
623
624/* calculate remaining charge at the time of ocv */
625static int calculate_ocv_charge(struct qpnp_bms_chip *chip,
626 struct raw_soc_params *raw,
627 int fcc_uah,
628 int batt_temp)
629{
630 int ocv_uv, pc;
631
632 ocv_uv = raw->last_good_ocv_uv;
633 pc = calculate_pc(chip, ocv_uv, batt_temp);
634 pr_debug("ocv_uv = %d pc = %d\n", ocv_uv, pc);
635 return (fcc_uah * pc) / 100;
636}
637
638#define CC_RESOLUTION_N 542535
639#define CC_RESOLUTION_D 100000
640
641static s64 cc_to_uv(s64 cc)
642{
643 return div_s64(cc * CC_RESOLUTION_N, CC_RESOLUTION_D);
644}
645
646#define CC_READING_TICKS 56
647#define SLEEP_CLK_HZ 32764
648#define SECONDS_PER_HOUR 3600
649
650static s64 cc_uv_to_nvh(s64 cc_uv)
651{
652 return div_s64(cc_uv * CC_READING_TICKS * 1000,
653 SLEEP_CLK_HZ * SECONDS_PER_HOUR);
654}
655
656/**
657 * calculate_cc-
658 * @chip: the bms chip pointer
659 * @cc: the cc reading from bms h/w
660 * @val: return value
661 * @coulomb_counter: adjusted coulomb counter for 100%
662 *
663 * RETURNS: in val pointer coulomb counter based charger in uAh
664 * (micro Amp hour)
665 */
666static int calculate_cc(struct qpnp_bms_chip *chip, int64_t cc)
667{
668 int64_t cc_voltage_uv, cc_nvh, cc_uah;
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700669 struct qpnp_iadc_calib calibration;
670
671 qpnp_iadc_get_gain_and_offset(&calibration);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700672 cc_voltage_uv = cc;
673 cc_voltage_uv -= chip->cc_reading_at_100;
674 pr_debug("cc = %lld. after subtracting 0x%llx cc = %lld\n",
675 cc, chip->cc_reading_at_100,
676 cc_voltage_uv);
677 cc_voltage_uv = cc_to_uv(cc_voltage_uv);
Xiaozhe Shi4e376652012-10-25 12:38:50 -0700678 cc_voltage_uv = cc_adjust_for_gain(cc_voltage_uv, calibration.gain_raw);
Xiaozhe Shie118c692012-09-24 15:17:43 -0700679 pr_debug("cc_voltage_uv = %lld uv\n", cc_voltage_uv);
680 cc_nvh = cc_uv_to_nvh(cc_voltage_uv);
681 pr_debug("cc_nvh = %lld nano_volt_hour\n", cc_nvh);
682 cc_uah = div_s64(cc_nvh, chip->r_sense_mohm);
683 /* cc_raw had 4 bits of extra precision.
684 By now it should be within 32 bit range */
685 return (int)cc_uah;
686}
687
688static int get_rbatt(struct qpnp_bms_chip *chip,
689 int soc_rbatt_mohm, int batt_temp)
690{
691 int rbatt_mohm, scalefactor;
692
693 rbatt_mohm = chip->default_rbatt_mohm;
694 pr_debug("rbatt before scaling = %d\n", rbatt_mohm);
695 if (chip->rbatt_sf_lut == NULL) {
696 pr_debug("RBATT = %d\n", rbatt_mohm);
697 return rbatt_mohm;
698 }
699 /* Convert the batt_temp to DegC from deciDegC */
700 batt_temp = batt_temp / 10;
701 scalefactor = interpolate_scalingfactor(chip->rbatt_sf_lut,
702 batt_temp, soc_rbatt_mohm);
703 pr_debug("rbatt sf = %d for batt_temp = %d, soc_rbatt = %d\n",
704 scalefactor, batt_temp, soc_rbatt_mohm);
705 rbatt_mohm = (rbatt_mohm * scalefactor) / 100;
706
707 rbatt_mohm += chip->r_conn_mohm;
708 pr_debug("adding r_conn_mohm = %d rbatt = %d\n",
709 chip->r_conn_mohm, rbatt_mohm);
710
711 pr_debug("RBATT = %d\n", rbatt_mohm);
712 return rbatt_mohm;
713}
714
715static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
716 int *iavg_ua)
717{
718 int delta_cc_uah, delta_time_s, rc;
719 struct rtc_time tm;
720 struct rtc_device *rtc;
721 unsigned long now_tm_sec = 0;
722
723 rc = 0;
724 /* if anything fails report the previous iavg_ua */
725 *iavg_ua = chip->prev_iavg_ua;
726
727 rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
728 if (rtc == NULL) {
729 pr_err("%s: unable to open rtc device (%s)\n",
730 __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
731 goto out;
732 }
733
734 rc = rtc_read_time(rtc, &tm);
735 if (rc) {
736 pr_err("Error reading rtc device (%s) : %d\n",
737 CONFIG_RTC_HCTOSYS_DEVICE, rc);
738 goto out;
739 }
740
741 rc = rtc_valid_tm(&tm);
742 if (rc) {
743 pr_err("Invalid RTC time (%s): %d\n",
744 CONFIG_RTC_HCTOSYS_DEVICE, rc);
745 goto out;
746 }
747 rtc_tm_to_time(&tm, &now_tm_sec);
748
749 if (chip->tm_sec == 0) {
750 get_battery_current(chip, iavg_ua);
751 goto out;
752 }
753
754 delta_time_s = (now_tm_sec - chip->tm_sec);
755
756 /* use the previous iavg if called within 15 seconds */
757 if (delta_time_s < 15) {
758 *iavg_ua = chip->prev_iavg_ua;
759 goto out;
760 }
761
762 delta_cc_uah = cc_uah - chip->last_cc_uah;
763
764 *iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
765
766 pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d delta_cc = %d iavg_ua = %d\n",
767 chip->tm_sec, now_tm_sec,
768 delta_time_s, delta_cc_uah, (int)*iavg_ua);
769
770out:
771 /* remember the iavg */
772 chip->prev_iavg_ua = *iavg_ua;
773
774 /* remember cc_uah */
775 chip->last_cc_uah = cc_uah;
776
777 /* remember this time */
778 chip->tm_sec = now_tm_sec;
779}
780
781static int calculate_termination_uuc(struct qpnp_bms_chip *chip,
782 struct soc_params *params,
783 int batt_temp, int uuc_iavg_ma,
784 int *ret_pc_unusable)
785{
786 int unusable_uv, pc_unusable, uuc_uah;
787 int i = 0;
788 int ocv_mv;
789 int batt_temp_degc = batt_temp / 10;
790 int rbatt_mohm;
791 int delta_uv;
792 int prev_delta_uv = 0;
793 int prev_rbatt_mohm = 0;
794 int uuc_rbatt_mohm;
795
796 for (i = 0; i <= 100; i++) {
797 ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
798 batt_temp_degc, i);
799 rbatt_mohm = get_rbatt(chip, i, batt_temp);
800 unusable_uv = (rbatt_mohm * uuc_iavg_ma)
801 + (chip->v_cutoff_uv);
802 delta_uv = ocv_mv * 1000 - unusable_uv;
803
804 pr_debug("soc = %d ocv = %d rbat = %d u_uv = %d delta_v = %d\n",
805 i, ocv_mv, rbatt_mohm, unusable_uv, delta_uv);
806
807 if (delta_uv > 0)
808 break;
809
810 prev_delta_uv = delta_uv;
811 prev_rbatt_mohm = rbatt_mohm;
812 }
813
814 uuc_rbatt_mohm = linear_interpolate(rbatt_mohm, delta_uv,
815 prev_rbatt_mohm, prev_delta_uv,
816 0);
817
818 unusable_uv = (uuc_rbatt_mohm * uuc_iavg_ma) + (chip->v_cutoff_uv);
819
820 pc_unusable = calculate_pc(chip, unusable_uv, batt_temp);
821 uuc_uah = (params->fcc_uah * pc_unusable) / 100;
822 pr_debug("For uuc_iavg_ma = %d, unusable_rbatt = %d unusable_uv = %d unusable_pc = %d uuc = %d\n",
823 uuc_iavg_ma,
824 uuc_rbatt_mohm, unusable_uv,
825 pc_unusable, uuc_uah);
826 *ret_pc_unusable = pc_unusable;
827 return uuc_uah;
828}
829
830static int adjust_uuc(struct qpnp_bms_chip *chip,
831 struct soc_params *params,
832 int new_pc_unusable,
833 int new_uuc_uah,
834 int batt_temp)
835{
836 int new_unusable_mv, new_iavg_ma;
837 int batt_temp_degc = batt_temp / 10;
838
839 if (chip->prev_pc_unusable == -EINVAL
840 || abs(chip->prev_pc_unusable - new_pc_unusable) <= 1) {
841 chip->prev_pc_unusable = new_pc_unusable;
842 return new_uuc_uah;
843 }
844
845 /* the uuc is trying to change more than 1% restrict it */
846 if (new_pc_unusable > chip->prev_pc_unusable)
847 chip->prev_pc_unusable++;
848 else
849 chip->prev_pc_unusable--;
850
851 new_uuc_uah = (params->fcc_uah * chip->prev_pc_unusable) / 100;
852
853 /* also find update the iavg_ma accordingly */
854 new_unusable_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
855 batt_temp_degc, chip->prev_pc_unusable);
856 if (new_unusable_mv < chip->v_cutoff_uv/1000)
857 new_unusable_mv = chip->v_cutoff_uv/1000;
858
859 new_iavg_ma = (new_unusable_mv * 1000 - chip->v_cutoff_uv)
Xiaozhe Shi904f1f72012-12-04 12:47:21 -0800860 / params->rbatt_mohm;
Xiaozhe Shie118c692012-09-24 15:17:43 -0700861 if (new_iavg_ma == 0)
862 new_iavg_ma = 1;
863 chip->prev_uuc_iavg_ma = new_iavg_ma;
864 pr_debug("Restricting UUC to %d (%d%%) unusable_mv = %d iavg_ma = %d\n",
865 new_uuc_uah, chip->prev_pc_unusable,
866 new_unusable_mv, new_iavg_ma);
867
868 return new_uuc_uah;
869}
870
871#define CHARGING_IAVG_MA 250
872#define MIN_SECONDS_FOR_VALID_SAMPLE 20
873static int calculate_unusable_charge_uah(struct qpnp_bms_chip *chip,
874 struct soc_params *params,
875 int batt_temp)
876{
877 int uuc_uah_iavg;
878 int i;
879 int uuc_iavg_ma = params->iavg_ua / 1000;
880 int pc_unusable;
881
882 /*
883 * if called first time, fill all the samples with
884 * the shutdown_iavg_ma
885 */
886 if (chip->first_time_calc_uuc && chip->shutdown_iavg_ma != 0) {
887 pr_debug("Using shutdown_iavg_ma = %d in all samples\n",
888 chip->shutdown_iavg_ma);
889 for (i = 0; i < IAVG_SAMPLES; i++)
890 chip->iavg_samples_ma[i] = chip->shutdown_iavg_ma;
891
892 chip->iavg_index = 0;
893 chip->iavg_num_samples = IAVG_SAMPLES;
894 }
895
896 /*
897 * if charging use a nominal avg current to keep
898 * a reasonable UUC while charging
899 */
900 if (uuc_iavg_ma < 0)
901 uuc_iavg_ma = CHARGING_IAVG_MA;
902 chip->iavg_samples_ma[chip->iavg_index] = uuc_iavg_ma;
903 chip->iavg_index = (chip->iavg_index + 1) % IAVG_SAMPLES;
904 chip->iavg_num_samples++;
905 if (chip->iavg_num_samples >= IAVG_SAMPLES)
906 chip->iavg_num_samples = IAVG_SAMPLES;
907
908 /* now that this sample is added calcualte the average */
909 uuc_iavg_ma = 0;
910 if (chip->iavg_num_samples != 0) {
911 for (i = 0; i < chip->iavg_num_samples; i++) {
912 pr_debug("iavg_samples_ma[%d] = %d\n", i,
913 chip->iavg_samples_ma[i]);
914 uuc_iavg_ma += chip->iavg_samples_ma[i];
915 }
916
917 uuc_iavg_ma = DIV_ROUND_CLOSEST(uuc_iavg_ma,
918 chip->iavg_num_samples);
919 }
920
921 uuc_uah_iavg = calculate_termination_uuc(chip, params, uuc_iavg_ma,
922 batt_temp, &pc_unusable);
923 pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
924 uuc_iavg_ma, uuc_uah_iavg);
925
926 chip->prev_uuc_iavg_ma = uuc_iavg_ma;
927 /* restrict the uuc such that it can increase only by one percent */
928 uuc_uah_iavg = adjust_uuc(chip, params, pc_unusable,
929 uuc_uah_iavg, batt_temp);
930
931 chip->first_time_calc_uuc = 0;
932 return uuc_uah_iavg;
933}
934
935static void find_ocv_for_soc(struct qpnp_bms_chip *chip,
936 struct soc_params *params,
937 int batt_temp,
938 int shutdown_soc,
939 int *ret_ocv_uv)
940{
941 s64 ocv_charge_uah;
942 int pc, new_pc;
943 int batt_temp_degc = batt_temp / 10;
944 int ocv_uv;
945
946 ocv_charge_uah = (s64)shutdown_soc
947 * (params->fcc_uah - params->uuc_uah);
948 ocv_charge_uah = div_s64(ocv_charge_uah, 100)
949 + params->cc_uah + params->uuc_uah;
950 pc = DIV_ROUND_CLOSEST((int)ocv_charge_uah * 100, params->fcc_uah);
951 pc = clamp(pc, 0, 100);
952
953 ocv_uv = interpolate_ocv(chip->pc_temp_ocv_lut, batt_temp_degc, pc);
954
955 pr_debug("s_soc = %d, fcc = %d uuc = %d rc = %d, pc = %d, ocv mv = %d\n",
956 shutdown_soc, params->fcc_uah,
957 params->uuc_uah, (int)ocv_charge_uah,
958 pc, ocv_uv);
959 new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv_uv);
960 pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv_uv);
961
962 while (abs(new_pc - pc) > 1) {
963 int delta_mv = 5;
964
965 if (new_pc > pc)
966 delta_mv = -1 * delta_mv;
967
968 ocv_uv = ocv_uv + delta_mv;
969 new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
970 batt_temp_degc, ocv_uv);
971 pr_debug("test revlookup pc = %d for ocv = %d\n",
972 new_pc, ocv_uv);
973 }
974
975 *ret_ocv_uv = ocv_uv * 1000;
976 params->ocv_charge_uah = (int)ocv_charge_uah;
977}
978
979static void calculate_soc_params(struct qpnp_bms_chip *chip,
980 struct raw_soc_params *raw,
981 struct soc_params *params,
982 int batt_temp)
983{
984 int soc_rbatt;
985
986 params->fcc_uah = calculate_fcc(chip, batt_temp);
987 pr_debug("FCC = %uuAh batt_temp = %d\n", params->fcc_uah, batt_temp);
988
989 /* calculate remainging charge */
990 params->ocv_charge_uah = calculate_ocv_charge(
991 chip, raw,
992 params->fcc_uah,
993 batt_temp);
994 pr_debug("ocv_charge_uah = %uuAh\n", params->ocv_charge_uah);
995
996 /* calculate cc micro_volt_hour */
997 params->cc_uah = calculate_cc(chip, raw->cc);
998 pr_debug("cc_uah = %duAh raw->cc = %llx cc = %lld after subtracting %llx\n",
999 params->cc_uah, raw->cc,
1000 (int64_t)raw->cc - chip->cc_reading_at_100,
1001 chip->cc_reading_at_100);
1002
1003 soc_rbatt = ((params->ocv_charge_uah - params->cc_uah) * 100)
1004 / params->fcc_uah;
1005 if (soc_rbatt < 0)
1006 soc_rbatt = 0;
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001007 params->rbatt_mohm = get_rbatt(chip, soc_rbatt, batt_temp);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001008
1009 calculate_iavg(chip, params->cc_uah, &params->iavg_ua);
1010
1011 params->uuc_uah = calculate_unusable_charge_uah(chip, params,
1012 batt_temp);
1013 pr_debug("UUC = %uuAh\n", params->uuc_uah);
1014}
1015
1016static bool is_shutdown_soc_within_limits(struct qpnp_bms_chip *chip, int soc)
1017{
1018 if (chip->shutdown_soc_invalid) {
1019 pr_debug("NOT forcing shutdown soc = %d\n", chip->shutdown_soc);
1020 return 0;
1021 }
1022
1023 if (abs(chip->shutdown_soc - soc) > chip->shutdown_soc_valid_limit) {
1024 pr_debug("rejecting shutdown soc = %d, soc = %d limit = %d\n",
1025 chip->shutdown_soc, soc,
1026 chip->shutdown_soc_valid_limit);
1027 chip->shutdown_soc_invalid = 1;
1028 return 0;
1029 }
1030
1031 return 1;
1032}
1033
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001034#define BMS_OVERRIDE_MODE_EN_BIT BIT(7)
1035#define EN_VBAT_BIT BIT(0)
1036#define OVERRIDE_MODE_DELAY_MS 20
1037static int override_mode_batt_v_and_i(
1038 struct qpnp_bms_chip *chip, int *ibat_ua, int *vbat_uv)
1039{
1040 int16_t vsense_raw, vbat_raw;
1041 int vsense_uv, rc;
1042 u8 delay;
1043
1044 mutex_lock(&chip->bms_output_lock);
1045
1046 delay = 0x00;
1047 rc = qpnp_write_wrapper(chip, &delay,
1048 chip->base + BMS1_S1_DELAY_CTL, 1);
1049 if (rc)
1050 pr_err("unable to write into BMS1_S1_DELAY, rc: %d\n", rc);
1051
1052 rc = qpnp_masked_write(chip, BMS1_MODE_CTL,
1053 BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT,
1054 BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT);
1055 if (rc)
1056 pr_err("unable to write into BMS1_MODE_CTL, rc: %d\n", rc);
1057
1058 msleep(OVERRIDE_MODE_DELAY_MS);
1059
1060 lock_output_data(chip);
1061 qpnp_read_wrapper(chip, (u8 *)&vsense_raw,
1062 chip->base + BMS1_VSENSE_AVG_DATA0, 2);
1063 qpnp_read_wrapper(chip, (u8 *)&vbat_raw,
1064 chip->base + BMS1_VBAT_AVG_DATA0, 2);
1065 unlock_output_data(chip);
1066
1067 rc = qpnp_masked_write(chip, BMS1_MODE_CTL,
1068 BMS_OVERRIDE_MODE_EN_BIT | EN_VBAT_BIT, 0);
1069
1070 delay = 0x0B;
1071 rc = qpnp_write_wrapper(chip, &delay,
1072 chip->base + BMS1_S1_DELAY_CTL, 1);
1073 if (rc)
1074 pr_err("unable to write into BMS1_S1_DELAY, rc: %d\n", rc);
1075
1076 mutex_unlock(&chip->bms_output_lock);
1077
1078 *vbat_uv = convert_vbatt_raw_to_uv(chip, vbat_raw);
1079 vsense_uv = convert_vsense_to_uv(chip, vsense_raw);
1080 *ibat_ua = vsense_uv * 1000 / (int)chip->r_sense_mohm;
1081
1082 pr_debug("vsense_raw = 0x%x vbat_raw = 0x%x ibat_ua = %d vbat_uv = %d\n",
1083 (uint16_t)vsense_raw, (uint16_t)vbat_raw,
1084 *ibat_ua, *vbat_uv);
1085 return 0;
1086}
1087
Xiaozhe Shiba3bdd32012-11-29 14:50:53 -08001088static bool is_batfet_open(struct qpnp_bms_chip *chip)
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001089{
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001090 union power_supply_propval ret = {0,};
1091
1092 if (chip->batt_psy == NULL)
1093 chip->batt_psy = power_supply_get_by_name("battery");
1094 if (chip->batt_psy) {
1095 /* if battery has been registered, use the status property */
1096 chip->batt_psy->get_property(chip->batt_psy,
1097 POWER_SUPPLY_PROP_STATUS, &ret);
Xiaozhe Shiba3bdd32012-11-29 14:50:53 -08001098 return ret.intval == POWER_SUPPLY_STATUS_FULL;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001099 }
1100
Xiaozhe Shiba3bdd32012-11-29 14:50:53 -08001101 /* Default to true if the battery power supply is not registered. */
1102 pr_debug("battery power supply is not registered\n");
1103 return true;
1104}
1105
1106static int get_simultaneous_batt_v_and_i(struct qpnp_bms_chip *chip,
1107 int *ibat_ua, int *vbat_uv)
1108{
1109 int rc;
1110
1111 if (is_batfet_open(chip)) {
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001112 pr_debug("batfet is open using separate vbat and ibat meas\n");
1113 rc = get_battery_voltage(vbat_uv);
1114 if (rc < 0) {
1115 pr_err("adc vbat failed err = %d\n", rc);
1116 return rc;
1117 }
1118 rc = get_battery_current(chip, ibat_ua);
1119 if (rc < 0) {
1120 pr_err("bms ibat failed err = %d\n", rc);
1121 return rc;
1122 }
1123 } else {
1124 return override_mode_batt_v_and_i(chip, ibat_ua, vbat_uv);
1125 }
1126
1127 return 0;
1128}
1129
1130static int bound_soc(int soc)
1131{
1132 soc = max(0, soc);
1133 soc = min(100, soc);
1134 return soc;
1135}
1136
1137static int charging_adjustments(struct qpnp_bms_chip *chip,
1138 struct soc_params *params, int soc,
1139 int vbat_uv, int ibat_ua, int batt_temp)
1140{
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001141 int chg_soc;
1142
1143 if (chip->soc_at_cv == -EINVAL) {
1144 /* In constant current charging return the calc soc */
1145 if (vbat_uv <= chip->max_voltage_uv)
1146 pr_debug("CC CHG SOC %d\n", soc);
1147
1148 /* Note the CC to CV point */
1149 if (vbat_uv >= chip->max_voltage_uv) {
1150 chip->soc_at_cv = soc;
1151 chip->prev_chg_soc = soc;
1152 chip->ibat_at_cv_ua = ibat_ua;
1153 pr_debug("CC_TO_CV ibat_ua = %d CHG SOC %d\n",
1154 ibat_ua, soc);
1155 }
1156 return soc;
1157 }
1158
1159 /*
1160 * battery is in CV phase - begin liner inerpolation of soc based on
1161 * battery charge current
1162 */
1163
1164 /*
1165 * if voltage lessened (possibly because of a system load)
1166 * keep reporting the prev chg soc
1167 */
1168 if (vbat_uv <= chip->max_voltage_uv) {
1169 pr_debug("vbat %d < max = %d CC CHG SOC %d\n",
1170 vbat_uv, chip->max_voltage_uv, chip->prev_chg_soc);
1171 return chip->prev_chg_soc;
1172 }
1173
1174 chg_soc = linear_interpolate(chip->soc_at_cv, chip->ibat_at_cv_ua,
1175 100, -100000,
1176 ibat_ua);
Xiaozhe Shi78d0c532012-12-10 13:02:14 -08001177 chg_soc = bound_soc(chg_soc);
Xiaozhe Shi41bc1f12012-09-26 16:55:22 -07001178
1179 /* always report a higher soc */
1180 if (chg_soc > chip->prev_chg_soc) {
1181 int new_ocv_uv;
1182
1183 chip->prev_chg_soc = chg_soc;
1184
1185 find_ocv_for_soc(chip, params, batt_temp, chg_soc, &new_ocv_uv);
1186 chip->last_ocv_uv = new_ocv_uv;
1187 pr_debug("CC CHG ADJ OCV = %d CHG SOC %d\n",
1188 new_ocv_uv,
1189 chip->prev_chg_soc);
1190 }
1191
1192 pr_debug("Reporting CHG SOC %d\n", chip->prev_chg_soc);
1193 return chip->prev_chg_soc;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001194}
1195
Xiaozhe Shie118c692012-09-24 15:17:43 -07001196static int adjust_soc(struct qpnp_bms_chip *chip, struct soc_params *params,
1197 int soc, int batt_temp)
1198{
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001199 int ibat_ua = 0, vbat_uv = 0;
1200 int ocv_est_uv = 0, soc_est = 0, pc_est = 0, pc = 0;
1201 int delta_ocv_uv = 0;
1202 int n = 0;
1203 int rc_new_uah = 0;
1204 int pc_new = 0;
1205 int soc_new = 0;
1206 int slope = 0;
1207 int rc = 0;
1208 int delta_ocv_uv_limit = 0;
1209
1210 rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
1211 if (rc < 0) {
1212 pr_err("simultaneous vbat ibat failed err = %d\n", rc);
1213 goto out;
1214 }
1215
1216 delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
1217
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001218 ocv_est_uv = vbat_uv + (ibat_ua * params->rbatt_mohm)/1000;
1219
1220 chip->ibat_max_ua = (ocv_est_uv - chip->v_cutoff_uv) * 1000
1221 / (params->rbatt_mohm);
1222
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001223 pc_est = calculate_pc(chip, ocv_est_uv, batt_temp);
1224 soc_est = div_s64((s64)params->fcc_uah * pc_est - params->uuc_uah*100,
1225 (s64)params->fcc_uah - params->uuc_uah);
1226 soc_est = bound_soc(soc_est);
1227
Xiaozhe Shiba3bdd32012-11-29 14:50:53 -08001228 if (ibat_ua < 0 && !is_batfet_open(chip)) {
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001229 soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
1230 batt_temp);
1231 goto out;
1232 }
1233
1234 /*
1235 * do not adjust
1236 * if soc is same as what bms calculated
1237 * if soc_est is between 45 and 25, this is the flat portion of the
1238 * curve where soc_est is not so accurate. We generally don't want to
1239 * adjust when soc_est is inaccurate except for the cases when soc is
1240 * way far off (higher than 50 or lesser than 20).
1241 * Also don't adjust soc if it is above 90 becuase it might be pulled
1242 * low and cause a bad user experience
1243 */
1244 if (soc_est == soc
1245 || (is_between(45, chip->adjust_soc_low_threshold, soc_est)
1246 && is_between(50, chip->adjust_soc_low_threshold - 5, soc))
1247 || soc >= 90)
1248 goto out;
1249
1250 if (chip->last_soc_est == -EINVAL)
1251 chip->last_soc_est = soc;
1252
1253 n = min(200, max(1 , soc + soc_est + chip->last_soc_est));
1254 chip->last_soc_est = soc_est;
1255
1256 pc = calculate_pc(chip, chip->last_ocv_uv, batt_temp);
1257 if (pc > 0) {
1258 pc_new = calculate_pc(chip,
1259 chip->last_ocv_uv - (++slope * 1000),
1260 batt_temp);
1261 while (pc_new == pc) {
1262 /* start taking 10mV steps */
1263 slope = slope + 10;
1264 pc_new = calculate_pc(chip,
1265 chip->last_ocv_uv - (slope * 1000),
1266 batt_temp);
1267 }
1268 } else {
1269 /*
1270 * pc is already at the lowest point,
1271 * assume 1 millivolt translates to 1% pc
1272 */
1273 pc = 1;
1274 pc_new = 0;
1275 slope = 1;
1276 }
1277
1278 delta_ocv_uv = div_s64((soc - soc_est) * (s64)slope * 1000,
1279 n * (pc - pc_new));
1280
1281 if (abs(delta_ocv_uv) > delta_ocv_uv_limit) {
1282 pr_debug("limiting delta ocv %d limit = %d\n", delta_ocv_uv,
1283 delta_ocv_uv_limit);
1284
1285 if (delta_ocv_uv > 0)
1286 delta_ocv_uv = delta_ocv_uv_limit;
1287 else
1288 delta_ocv_uv = -1 * delta_ocv_uv_limit;
1289 pr_debug("new delta ocv = %d\n", delta_ocv_uv);
1290 }
1291
1292 chip->last_ocv_uv -= delta_ocv_uv;
1293
1294 if (chip->last_ocv_uv >= chip->max_voltage_uv)
1295 chip->last_ocv_uv = chip->max_voltage_uv;
1296
1297 /* calculate the soc based on this new ocv */
1298 pc_new = calculate_pc(chip, chip->last_ocv_uv, batt_temp);
1299 rc_new_uah = (params->fcc_uah * pc_new) / 100;
1300 soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100
1301 / (params->fcc_uah - params->uuc_uah);
1302 soc_new = bound_soc(soc_new);
1303
1304 /*
1305 * if soc_new is ZERO force it higher so that phone doesnt report soc=0
1306 * soc = 0 should happen only when soc_est == 0
1307 */
1308 if (soc_new == 0 && soc_est != 0)
1309 soc_new = 1;
1310
1311 soc = soc_new;
1312
1313out:
1314 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",
1315 ibat_ua, vbat_uv, ocv_est_uv, pc_est,
1316 soc_est, n, delta_ocv_uv, chip->last_ocv_uv,
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001317 pc_new, soc_new, params->rbatt_mohm, slope);
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07001318
Xiaozhe Shie118c692012-09-24 15:17:43 -07001319 return soc;
1320}
1321
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001322static int clamp_soc_based_on_voltage(struct qpnp_bms_chip *chip, int soc)
1323{
1324 int rc, vbat_uv;
1325 struct qpnp_vadc_result result;
1326
1327 rc = qpnp_vadc_read(VBAT_SNS, &result);
1328 if (rc) {
1329 pr_err("error reading vbat_sns adc channel = %d, rc = %d\n",
1330 VBAT_SNS, rc);
1331 return rc;
1332 }
1333
1334 vbat_uv = (int)result.physical;
1335 if (soc == 0 && vbat_uv > chip->v_cutoff_uv) {
1336 pr_debug("clamping soc to 1, vbat (%d) > cutoff (%d)\n",
1337 vbat_uv, chip->v_cutoff_uv);
1338 return 1;
1339 } else if (soc > 0 && vbat_uv < chip->v_cutoff_uv) {
1340 pr_debug("forcing soc to 0, vbat (%d) < cutoff (%d)\n",
1341 vbat_uv, chip->v_cutoff_uv);
1342 return 0;
1343 } else {
1344 pr_debug("not clamping, using soc = %d, vbat = %d and cutoff = %d\n",
1345 soc, vbat_uv, chip->v_cutoff_uv);
1346 return soc;
1347 }
1348}
1349
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001350static int calculate_state_of_charge(struct qpnp_bms_chip *chip,
1351 struct raw_soc_params *raw,
1352 int batt_temp)
1353{
Xiaozhe Shie118c692012-09-24 15:17:43 -07001354 int soc, new_ocv_uv;
1355 int shutdown_soc, new_calculated_soc, remaining_usable_charge_uah;
1356 struct soc_params params;
1357
1358 calculate_soc_params(chip, raw, &params, batt_temp);
1359 /* calculate remaining usable charge */
1360 remaining_usable_charge_uah = params.ocv_charge_uah
1361 - params.cc_uah
1362 - params.uuc_uah;
1363
1364 pr_debug("RUC = %duAh\n", remaining_usable_charge_uah);
1365 if (params.fcc_uah - params.uuc_uah <= 0) {
Xiaozhe Shicb386a22012-11-29 12:11:42 -08001366 pr_debug("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
Xiaozhe Shie118c692012-09-24 15:17:43 -07001367 params.fcc_uah,
1368 params.uuc_uah);
1369 soc = 0;
1370 } else {
1371 soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
1372 (params.fcc_uah
1373 - params.uuc_uah));
1374 }
1375
1376 if (chip->first_time_calc_soc && soc < 0) {
1377 /*
1378 * first time calcualtion and the pon ocv is too low resulting
1379 * in a bad soc. Adjust ocv to get 0 soc
1380 */
1381 pr_debug("soc is %d, adjusting pon ocv to make it 0\n", soc);
1382 find_ocv_for_soc(chip, &params, batt_temp, 0, &new_ocv_uv);
1383 chip->last_ocv_uv = new_ocv_uv;
1384
1385 remaining_usable_charge_uah = params.ocv_charge_uah
1386 - params.cc_uah
1387 - params.uuc_uah;
1388
1389 soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
1390 (params.fcc_uah
1391 - params.uuc_uah));
1392 pr_debug("DONE for O soc is %d, pon ocv adjusted to %duV\n",
1393 soc, chip->last_ocv_uv);
1394 }
1395
1396 if (soc > 100)
1397 soc = 100;
1398
1399 if (soc < 0) {
Xiaozhe Shicb386a22012-11-29 12:11:42 -08001400 pr_debug("bad rem_usb_chg = %d rem_chg %d, cc_uah %d, unusb_chg %d\n",
Xiaozhe Shie118c692012-09-24 15:17:43 -07001401 remaining_usable_charge_uah,
1402 params.ocv_charge_uah,
1403 params.cc_uah, params.uuc_uah);
1404
Xiaozhe Shicb386a22012-11-29 12:11:42 -08001405 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 -07001406 chip->last_ocv_uv, batt_temp,
1407 params.fcc_uah, soc);
1408 soc = 0;
1409 }
1410
1411 mutex_lock(&chip->soc_invalidation_mutex);
1412 shutdown_soc = chip->shutdown_soc;
1413
1414 if (chip->first_time_calc_soc && soc != shutdown_soc
1415 && is_shutdown_soc_within_limits(chip, soc)) {
1416 /*
1417 * soc for the first time - use shutdown soc
1418 * to adjust pon ocv since it is a small percent away from
1419 * the real soc
1420 */
1421 pr_debug("soc = %d before forcing shutdown_soc = %d\n",
1422 soc, shutdown_soc);
1423 find_ocv_for_soc(chip, &params, batt_temp,
1424 shutdown_soc, &new_ocv_uv);
1425 chip->pon_ocv_uv = chip->last_ocv_uv;
1426 chip->last_ocv_uv = new_ocv_uv;
1427
1428 remaining_usable_charge_uah = params.ocv_charge_uah
1429 - params.cc_uah
1430 - params.uuc_uah;
1431
1432 soc = DIV_ROUND_CLOSEST((remaining_usable_charge_uah * 100),
1433 (params.fcc_uah
1434 - params.uuc_uah));
1435
1436 pr_debug("DONE for shutdown_soc = %d soc is %d, adjusted ocv to %duV\n",
1437 shutdown_soc, soc, chip->last_ocv_uv);
1438 }
1439 mutex_unlock(&chip->soc_invalidation_mutex);
1440
1441 pr_debug("SOC before adjustment = %d\n", soc);
1442 new_calculated_soc = adjust_soc(chip, &params, soc, batt_temp);
1443
Xiaozhe Shi2542c602012-11-28 10:08:07 -08001444 /* clamp soc due to BMS HW inaccuracies in pm8941v2.0 */
1445 if (chip->revision1 == 0 && chip->revision2 == 0)
1446 new_calculated_soc = clamp_soc_based_on_voltage(chip,
1447 new_calculated_soc);
1448
Xiaozhe Shie118c692012-09-24 15:17:43 -07001449 if (new_calculated_soc != chip->calculated_soc
1450 && chip->bms_psy.name != NULL) {
1451 power_supply_changed(&chip->bms_psy);
1452 pr_debug("power supply changed\n");
1453 }
1454
1455 chip->calculated_soc = new_calculated_soc;
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001456 pr_debug("CC based calculated SOC = %d\n", chip->calculated_soc);
Xiaozhe Shie118c692012-09-24 15:17:43 -07001457 chip->first_time_calc_soc = 0;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001458 return chip->calculated_soc;
1459}
1460
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001461static int read_vbat(struct qpnp_bms_chip *chip)
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001462{
1463 int rc;
1464 struct qpnp_vadc_result result;
1465
1466 rc = qpnp_vadc_read(VBAT_SNS, &result);
1467 if (rc) {
1468 pr_err("error reading vadc VBAT_SNS = %d, rc = %d\n",
1469 VBAT_SNS, rc);
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001470 return rc;
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001471 }
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001472 pr_debug("read %duv from vadc\n", (int)result.physical);
1473 return (int)result.physical;
1474}
1475
1476static int calculate_soc_from_voltage(struct qpnp_bms_chip *chip)
1477{
1478 int voltage_range_uv, voltage_remaining_uv, voltage_based_soc;
1479 int vbat_uv;
1480
1481 vbat_uv = read_vbat(chip);
1482
1483 voltage_range_uv = chip->max_voltage_uv - chip->v_cutoff_uv;
1484 voltage_remaining_uv = vbat_uv - chip->v_cutoff_uv;
1485 voltage_based_soc = voltage_remaining_uv * 100 / voltage_range_uv;
1486
1487 voltage_based_soc = clamp(voltage_based_soc, 0, 100);
1488
1489 if (chip->prev_voltage_based_soc != voltage_based_soc
1490 && chip->bms_psy.name != NULL) {
1491 power_supply_changed(&chip->bms_psy);
1492 pr_debug("power supply changed\n");
1493 }
1494 chip->prev_voltage_based_soc = voltage_based_soc;
1495
1496 pr_debug("vbat used = %duv\n", vbat_uv);
1497 pr_debug("Calculated voltage based soc = %d\n", voltage_based_soc);
1498 return voltage_based_soc;
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001499}
1500
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001501static void calculate_soc_work(struct work_struct *work)
1502{
1503 struct qpnp_bms_chip *chip = container_of(work,
1504 struct qpnp_bms_chip,
1505 calculate_soc_delayed_work.work);
1506 int batt_temp, rc, soc;
1507 struct qpnp_vadc_result result;
1508 struct raw_soc_params raw;
1509
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001510 if (chip->use_voltage_soc) {
1511 soc = calculate_soc_from_voltage(chip);
1512 } else {
1513 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &result);
1514 if (rc) {
1515 pr_err("error reading vadc LR_MUX1_BATT_THERM = %d, rc = %d\n",
1516 LR_MUX1_BATT_THERM, rc);
1517 return;
1518 }
1519 pr_debug("batt_temp phy = %lld meas = 0x%llx\n",
1520 result.physical,
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001521 result.measurement);
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001522 batt_temp = (int)result.physical;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001523
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001524 mutex_lock(&chip->last_ocv_uv_mutex);
1525 read_soc_params_raw(chip, &raw);
1526 soc = calculate_state_of_charge(chip, &raw, batt_temp);
1527 mutex_unlock(&chip->last_ocv_uv_mutex);
1528 }
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001529
1530 if (soc < chip->low_soc_calc_threshold)
1531 schedule_delayed_work(&chip->calculate_soc_delayed_work,
1532 round_jiffies_relative(msecs_to_jiffies
1533 (chip->low_soc_calculate_soc_ms)));
1534 else
1535 schedule_delayed_work(&chip->calculate_soc_delayed_work,
1536 round_jiffies_relative(msecs_to_jiffies
1537 (chip->calculate_soc_ms)));
1538}
1539
Xiaozhe Shie118c692012-09-24 15:17:43 -07001540static void backup_soc_and_iavg(struct qpnp_bms_chip *chip, int batt_temp,
1541 int soc)
1542{
1543 u8 temp;
1544 int rc;
1545 int iavg_ma = chip->prev_uuc_iavg_ma;
1546
1547 if (iavg_ma > IAVG_START)
1548 temp = (iavg_ma - IAVG_START) / IAVG_STEP_SIZE_MA;
1549 else
1550 temp = 0;
1551
1552 rc = qpnp_write_wrapper(chip, &temp,
1553 chip->base + IAVG_STORAGE_REG, 1);
1554
1555 if (soc == 0)
1556 temp = SOC_ZERO;
1557 else
1558 temp = soc;
1559
1560 /* don't store soc if temperature is below 5degC */
1561 if (batt_temp > IGNORE_SOC_TEMP_DECIDEG)
1562 rc = qpnp_write_wrapper(chip, &temp,
1563 chip->base + SOC_STORAGE_REG, 1);
1564}
1565
1566#define SOC_CATCHUP_SEC_MAX 600
1567#define SOC_CATCHUP_SEC_PER_PERCENT 60
1568#define MAX_CATCHUP_SOC (SOC_CATCHUP_SEC_MAX/SOC_CATCHUP_SEC_PER_PERCENT)
1569static int scale_soc_while_chg(struct qpnp_bms_chip *chip,
1570 int delta_time_us, int new_soc, int prev_soc)
1571{
1572 int chg_time_sec;
1573 int catch_up_sec;
1574 int scaled_soc;
1575 int numerator;
1576
1577 /*
1578 * The device must be charging for reporting a higher soc, if
1579 * not ignore this soc and continue reporting the prev_soc.
1580 * Also don't report a high value immediately slowly scale the
1581 * value from prev_soc to the new soc based on a charge time
1582 * weighted average
1583 */
1584
1585 /* if not charging, return last soc */
1586 if (chip->start_percent == -EINVAL)
1587 return prev_soc;
1588
1589 chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
1590 catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
1591 pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
1592
1593 /*
1594 * if charging for more than catch_up time, simply return
1595 * new soc
1596 */
1597 if (chg_time_sec > catch_up_sec)
1598 return new_soc;
1599
1600 numerator = (catch_up_sec - chg_time_sec) * prev_soc
1601 + chg_time_sec * new_soc;
1602 scaled_soc = numerator / catch_up_sec;
1603
1604 pr_debug("cts = %d new_soc = %d prev_soc = %d scaled_soc = %d\n",
1605 chg_time_sec, new_soc, prev_soc, scaled_soc);
1606
1607 return scaled_soc;
1608}
1609
1610/*
1611 * bms_fake_battery is set in setups where a battery emulator is used instead
1612 * of a real battery. This makes the bms driver report a different/fake value
1613 * regardless of the calculated state of charge.
1614 */
1615static int bms_fake_battery = -EINVAL;
1616module_param(bms_fake_battery, int, 0644);
1617
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001618static int report_voltage_based_soc(struct qpnp_bms_chip *chip)
1619{
1620 pr_debug("Reported voltage based soc = %d\n",
1621 chip->prev_voltage_based_soc);
1622 return chip->prev_voltage_based_soc;
1623}
1624
1625static int report_cc_based_soc(struct qpnp_bms_chip *chip)
Xiaozhe Shie118c692012-09-24 15:17:43 -07001626{
1627 int soc;
1628 int delta_time_us;
1629 struct timespec now;
1630 struct qpnp_vadc_result result;
1631 int batt_temp;
1632 int rc;
1633
Xiaozhe Shie118c692012-09-24 15:17:43 -07001634 soc = chip->calculated_soc;
1635
1636 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &result);
1637
1638 if (rc) {
1639 pr_err("error reading adc channel = %d, rc = %d\n",
1640 LR_MUX1_BATT_THERM, rc);
1641 return rc;
1642 }
1643 pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
1644 result.measurement);
1645 batt_temp = (int)result.physical;
1646
1647 do_posix_clock_monotonic_gettime(&now);
1648 if (chip->t_soc_queried.tv_sec != 0) {
1649 delta_time_us
1650 = (now.tv_sec - chip->t_soc_queried.tv_sec) * USEC_PER_SEC
1651 + (now.tv_nsec - chip->t_soc_queried.tv_nsec) / 1000;
1652 } else {
1653 /* calculation for the first time */
1654 delta_time_us = 0;
1655 }
1656
1657 /*
1658 * account for charge time - limit it to SOC_CATCHUP_SEC to
1659 * avoid overflows when charging continues for extended periods
1660 */
1661 if (chip->start_percent != -EINVAL) {
1662 if (chip->charge_time_us == 0) {
1663 /*
1664 * calculating soc for the first time
1665 * after start of chg. Initialize catchup time
1666 */
1667 if (abs(soc - chip->last_soc) < MAX_CATCHUP_SOC)
1668 chip->catch_up_time_us =
1669 (soc - chip->last_soc)
1670 * SOC_CATCHUP_SEC_PER_PERCENT
1671 * USEC_PER_SEC;
1672 else
1673 chip->catch_up_time_us =
1674 SOC_CATCHUP_SEC_MAX * USEC_PER_SEC;
1675
1676 if (chip->catch_up_time_us < 0)
1677 chip->catch_up_time_us = 0;
1678 }
1679
1680 /* add charge time */
1681 if (chip->charge_time_us < SOC_CATCHUP_SEC_MAX * USEC_PER_SEC)
1682 chip->charge_time_us += delta_time_us;
1683
1684 /* end catchup if calculated soc and last soc are same */
1685 if (chip->last_soc == soc)
1686 chip->catch_up_time_us = 0;
1687 }
1688
1689 /* last_soc < soc ... scale and catch up */
Xiaozhe Shia81851f2012-11-01 16:36:58 -07001690 if (chip->last_soc != -EINVAL && chip->last_soc < soc
1691 && soc != 100 && chip->catch_up_time_us != 0)
Xiaozhe Shie118c692012-09-24 15:17:43 -07001692 soc = scale_soc_while_chg(chip, delta_time_us,
1693 soc, chip->last_soc);
1694
1695 pr_debug("last_soc = %d, calculated_soc = %d, soc = %d\n",
1696 chip->last_soc, chip->calculated_soc, soc);
1697 chip->last_soc = soc;
1698 backup_soc_and_iavg(chip, batt_temp, chip->last_soc);
1699 pr_debug("Reported SOC = %d\n", chip->last_soc);
1700 chip->t_soc_queried = now;
1701
1702 return chip->last_soc;
1703}
1704
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001705static int report_state_of_charge(struct qpnp_bms_chip *chip)
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001706{
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001707 if (bms_fake_battery != -EINVAL) {
1708 pr_debug("Returning Fake SOC = %d%%\n", bms_fake_battery);
1709 return bms_fake_battery;
1710 } else if (chip->use_voltage_soc)
1711 return report_voltage_based_soc(chip);
1712 else
1713 return report_cc_based_soc(chip);
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001714}
1715
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001716/* Returns capacity as a SoC percentage between 0 and 100 */
1717static int get_prop_bms_capacity(struct qpnp_bms_chip *chip)
1718{
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001719 return report_state_of_charge(chip);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001720}
1721
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001722/* Returns estimated max current that the battery can supply in uA */
1723static int get_prop_bms_current_max(struct qpnp_bms_chip *chip)
1724{
1725 return chip->ibat_max_ua;
1726}
1727
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001728/* Returns instantaneous current in uA */
1729static int get_prop_bms_current_now(struct qpnp_bms_chip *chip)
1730{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001731 int rc, result_ua;
1732
1733 rc = get_battery_current(chip, &result_ua);
1734 if (rc) {
1735 pr_err("failed to get current: %d\n", rc);
1736 return rc;
1737 }
1738 return result_ua;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001739}
1740
1741/* Returns full charge design in uAh */
1742static int get_prop_bms_charge_full_design(struct qpnp_bms_chip *chip)
1743{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001744 return chip->fcc;
1745}
1746
1747static bool get_prop_bms_online(struct qpnp_bms_chip *chip)
1748{
1749 return chip->online;
1750}
1751
1752static int get_prop_bms_status(struct qpnp_bms_chip *chip)
1753{
1754 return chip->charger_status;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001755}
1756
1757static void set_prop_bms_online(struct qpnp_bms_chip *chip, bool online)
1758{
1759 chip->online = online;
1760}
1761
1762static void set_prop_bms_status(struct qpnp_bms_chip *chip, int status)
1763{
1764 chip->charger_status = status;
1765}
1766
1767static void qpnp_bms_external_power_changed(struct power_supply *psy)
1768{
1769}
1770
1771static int qpnp_bms_power_get_property(struct power_supply *psy,
1772 enum power_supply_property psp,
1773 union power_supply_propval *val)
1774{
1775 struct qpnp_bms_chip *chip = container_of(psy, struct qpnp_bms_chip,
1776 bms_psy);
1777
1778 switch (psp) {
1779 case POWER_SUPPLY_PROP_CAPACITY:
1780 val->intval = get_prop_bms_capacity(chip);
1781 break;
1782 case POWER_SUPPLY_PROP_CURRENT_NOW:
1783 val->intval = get_prop_bms_current_now(chip);
1784 break;
Xiaozhe Shi904f1f72012-12-04 12:47:21 -08001785 case POWER_SUPPLY_PROP_CURRENT_MAX:
1786 val->intval = get_prop_bms_current_max(chip);
1787 break;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001788 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1789 val->intval = get_prop_bms_charge_full_design(chip);
1790 break;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001791 case POWER_SUPPLY_PROP_STATUS:
1792 val->intval = get_prop_bms_status(chip);
1793 break;
1794 case POWER_SUPPLY_PROP_ONLINE:
1795 val->intval = get_prop_bms_online(chip);
1796 break;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001797 default:
1798 return -EINVAL;
1799 }
1800 return 0;
1801}
1802
1803static int qpnp_bms_power_set_property(struct power_supply *psy,
1804 enum power_supply_property psp,
1805 const union power_supply_propval *val)
1806{
1807 struct qpnp_bms_chip *chip = container_of(psy, struct qpnp_bms_chip,
1808 bms_psy);
1809
1810 switch (psp) {
1811 case POWER_SUPPLY_PROP_ONLINE:
1812 set_prop_bms_online(chip, val->intval);
1813 break;
1814 case POWER_SUPPLY_PROP_STATUS:
1815 set_prop_bms_status(chip, (bool)val->intval);
1816 break;
1817 default:
1818 return -EINVAL;
1819 }
1820 return 0;
1821}
1822
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001823static void read_shutdown_soc_and_iavg(struct qpnp_bms_chip *chip)
1824{
1825 int rc;
1826 u8 temp;
1827
1828 if (chip->ignore_shutdown_soc) {
1829 chip->shutdown_soc_invalid = 1;
1830 chip->shutdown_soc = 0;
1831 chip->shutdown_iavg_ma = 0;
1832 } else {
1833 rc = qpnp_read_wrapper(chip, &temp,
1834 chip->base + IAVG_STORAGE_REG, 1);
1835 if (rc) {
1836 pr_err("failed to read addr = %d %d assuming %d\n",
1837 chip->base + IAVG_STORAGE_REG, rc,
1838 IAVG_START);
1839 chip->shutdown_iavg_ma = IAVG_START;
1840 } else {
1841 if (temp == 0) {
1842 chip->shutdown_iavg_ma = IAVG_START;
1843 } else {
1844 chip->shutdown_iavg_ma = IAVG_START
1845 + IAVG_STEP_SIZE_MA * (temp + 1);
1846 }
1847 }
1848
1849 rc = qpnp_read_wrapper(chip, &temp,
1850 chip->base + SOC_STORAGE_REG, 1);
1851 if (rc) {
1852 pr_err("failed to read addr = %d %d\n",
1853 chip->base + SOC_STORAGE_REG, rc);
1854 } else {
1855 chip->shutdown_soc = temp;
1856
1857 if (chip->shutdown_soc == 0) {
1858 pr_debug("No shutdown soc available\n");
1859 chip->shutdown_soc_invalid = 1;
1860 chip->shutdown_iavg_ma = 0;
1861 } else if (chip->shutdown_soc == SOC_ZERO) {
1862 chip->shutdown_soc = 0;
1863 }
1864 }
1865 }
1866
1867 pr_debug("shutdown_soc = %d shutdown_iavg = %d shutdown_soc_invalid = %d\n",
1868 chip->shutdown_soc,
1869 chip->shutdown_iavg_ma,
1870 chip->shutdown_soc_invalid);
1871}
1872
Xiaozhe Shi73a65692012-09-18 17:51:57 -07001873#define PALLADIUM_ID_MIN 0x7F40
1874#define PALLADIUM_ID_MAX 0x7F5A
1875#define DESAY_5200_ID_MIN 0x7F7F
1876#define DESAY_5200_ID_MAX 0x802F
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001877static int32_t read_battery_id(struct qpnp_bms_chip *chip)
Xiaozhe Shi73a65692012-09-18 17:51:57 -07001878{
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001879 int rc;
1880 struct qpnp_vadc_result result;
1881
1882 rc = qpnp_vadc_read(LR_MUX2_BAT_ID, &result);
1883 if (rc) {
1884 pr_err("error reading batt id channel = %d, rc = %d\n",
1885 LR_MUX2_BAT_ID, rc);
1886 return rc;
1887 }
1888 pr_debug("batt_id phy = %lld meas = 0x%llx\n", result.physical,
1889 result.measurement);
1890 pr_debug("raw_code = 0x%x\n", result.adc_code);
1891 return result.adc_code;
Xiaozhe Shi73a65692012-09-18 17:51:57 -07001892}
1893
1894static int set_battery_data(struct qpnp_bms_chip *chip)
1895{
1896 int64_t battery_id;
1897
1898 if (chip->batt_type == BATT_DESAY)
1899 goto desay;
1900 else if (chip->batt_type == BATT_PALLADIUM)
1901 goto palladium;
1902
1903 battery_id = read_battery_id(chip);
1904 if (battery_id < 0) {
1905 pr_err("cannot read battery id err = %lld\n", battery_id);
1906 return battery_id;
1907 }
1908
1909 if (is_between(PALLADIUM_ID_MIN, PALLADIUM_ID_MAX, battery_id)) {
1910 goto palladium;
1911 } else if (is_between(DESAY_5200_ID_MIN, DESAY_5200_ID_MAX,
1912 battery_id)) {
1913 goto desay;
1914 } else {
1915 pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
1916 battery_id);
1917 goto palladium;
1918 }
1919
1920palladium:
1921 chip->fcc = palladium_1500_data.fcc;
1922 chip->fcc_temp_lut = palladium_1500_data.fcc_temp_lut;
1923 chip->fcc_sf_lut = palladium_1500_data.fcc_sf_lut;
1924 chip->pc_temp_ocv_lut = palladium_1500_data.pc_temp_ocv_lut;
1925 chip->pc_sf_lut = palladium_1500_data.pc_sf_lut;
1926 chip->rbatt_sf_lut = palladium_1500_data.rbatt_sf_lut;
1927 chip->default_rbatt_mohm
1928 = palladium_1500_data.default_rbatt_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001929 goto check_lut;
Xiaozhe Shi73a65692012-09-18 17:51:57 -07001930desay:
1931 chip->fcc = desay_5200_data.fcc;
1932 chip->fcc_temp_lut = desay_5200_data.fcc_temp_lut;
1933 chip->pc_temp_ocv_lut = desay_5200_data.pc_temp_ocv_lut;
1934 chip->pc_sf_lut = desay_5200_data.pc_sf_lut;
1935 chip->rbatt_sf_lut = desay_5200_data.rbatt_sf_lut;
1936 chip->default_rbatt_mohm = desay_5200_data.default_rbatt_mohm;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001937 goto check_lut;
1938check_lut:
1939 if (chip->pc_temp_ocv_lut == NULL) {
1940 pr_err("temp ocv lut table is NULL\n");
1941 return -EINVAL;
1942 }
Xiaozhe Shi73a65692012-09-18 17:51:57 -07001943 return 0;
1944}
1945
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001946#define SPMI_PROP_READ(chip_prop, qpnp_spmi_property, retval) \
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001947do { \
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001948 retval = of_property_read_u32(chip->spmi->dev.of_node, \
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001949 "qcom,bms-" qpnp_spmi_property, \
1950 &chip->chip_prop); \
1951 if (retval) { \
1952 pr_err("Error reading " #qpnp_spmi_property \
1953 " property %d\n", rc); \
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001954 return -EINVAL; \
Xiaozhe Shib19f7032012-08-16 12:14:16 -07001955 } \
1956} while (0)
1957
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001958static inline int bms_read_properties(struct qpnp_bms_chip *chip)
1959{
1960 int rc;
1961
1962 SPMI_PROP_READ(r_sense_mohm, "r-sense-mohm", rc);
1963 SPMI_PROP_READ(v_cutoff_uv, "v-cutoff-uv", rc);
1964 SPMI_PROP_READ(max_voltage_uv, "max-voltage-uv", rc);
1965 SPMI_PROP_READ(r_conn_mohm, "r-conn-mohm", rc);
1966 SPMI_PROP_READ(chg_term_ua, "chg-term-ua", rc);
1967 SPMI_PROP_READ(shutdown_soc_valid_limit,
1968 "shutdown-soc-valid-limit", rc);
1969 SPMI_PROP_READ(adjust_soc_high_threshold,
1970 "adjust-soc-high-threshold", rc);
1971 SPMI_PROP_READ(adjust_soc_low_threshold,
1972 "adjust-soc-low-threshold", rc);
1973 SPMI_PROP_READ(batt_type, "batt-type", rc);
1974 SPMI_PROP_READ(low_soc_calc_threshold,
1975 "low-soc-calculate-soc-threshold", rc);
1976 SPMI_PROP_READ(low_soc_calculate_soc_ms,
1977 "low-soc-calculate-soc-ms", rc);
1978 SPMI_PROP_READ(calculate_soc_ms, "calculate-soc-ms", rc);
Xiaozhe Shidffbe692012-12-11 15:35:46 -08001979 chip->use_external_rsense = of_property_read_bool(
1980 chip->spmi->dev.of_node,
1981 "qcom,bms-use-external-rsense");
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001982 chip->ignore_shutdown_soc = of_property_read_bool(
1983 chip->spmi->dev.of_node,
1984 "qcom,bms-ignore-shutdown-soc");
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08001985 chip->use_voltage_soc = of_property_read_bool(chip->spmi->dev.of_node,
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08001986 "qcom,bms-use-voltage-soc");
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07001987
1988 if (chip->adjust_soc_low_threshold >= 45)
1989 chip->adjust_soc_low_threshold = 45;
1990
1991 pr_debug("dts data: r_sense_mohm:%d, v_cutoff_uv:%d, max_v:%d\n",
1992 chip->r_sense_mohm, chip->v_cutoff_uv,
1993 chip->max_voltage_uv);
1994 pr_debug("r_conn:%d, shutdown_soc: %d, adjust_soc_low:%d\n",
1995 chip->r_conn_mohm, chip->shutdown_soc_valid_limit,
1996 chip->adjust_soc_low_threshold);
1997 pr_debug("adjust_soc_high:%d, chg_term_ua:%d, batt_type:%d\n",
1998 chip->adjust_soc_high_threshold, chip->chg_term_ua,
1999 chip->batt_type);
Xiaozhe Shi781b0a22012-11-05 17:18:27 -08002000 pr_debug("ignore_shutdown_soc:%d, use_voltage_soc:%d\n",
Xiaozhe Shi79d6c1d2012-11-26 13:19:50 -08002001 chip->ignore_shutdown_soc, chip->use_voltage_soc);
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002002 pr_debug("use external rsense: %d\n", chip->use_external_rsense);
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002003 return 0;
2004}
2005
2006static inline void bms_initialize_constants(struct qpnp_bms_chip *chip)
2007{
2008 chip->start_percent = -EINVAL;
2009 chip->end_percent = -EINVAL;
2010 chip->prev_pc_unusable = -EINVAL;
2011 chip->soc_at_cv = -EINVAL;
2012 chip->calculated_soc = -EINVAL;
Xiaozhe Shie118c692012-09-24 15:17:43 -07002013 chip->last_soc = -EINVAL;
Xiaozhe Shi7edde5d2012-09-26 11:23:09 -07002014 chip->last_soc_est = -EINVAL;
Xiaozhe Shie118c692012-09-24 15:17:43 -07002015 chip->first_time_calc_soc = 1;
2016 chip->first_time_calc_uuc = 1;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002017}
2018
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002019#define REG_OFFSET_PERP_TYPE 0x04
2020#define REG_OFFSET_PERP_SUBTYPE 0x05
2021#define BMS_BMS_TYPE 0xD
2022#define BMS_BMS_SUBTYPE 0x1
2023#define BMS_IADC_TYPE 0x8
2024#define BMS_IADC_SUBTYPE 0x3
2025
2026static int register_spmi(struct qpnp_bms_chip *chip, struct spmi_device *spmi)
2027{
2028 struct spmi_resource *spmi_resource;
2029 struct resource *resource;
2030 int rc;
2031 u8 type, subtype;
2032
2033 chip->dev = &(spmi->dev);
2034 chip->spmi = spmi;
2035
2036 spmi_for_each_container_dev(spmi_resource, spmi) {
2037 if (!spmi_resource) {
2038 pr_err("qpnp_bms: spmi resource absent\n");
2039 return -ENXIO;
2040 }
2041
2042 resource = spmi_get_resource(spmi, spmi_resource,
2043 IORESOURCE_MEM, 0);
2044 if (!(resource && resource->start)) {
2045 pr_err("node %s IO resource absent!\n",
2046 spmi->dev.of_node->full_name);
2047 return -ENXIO;
2048 }
2049
2050 rc = qpnp_read_wrapper(chip, &type,
2051 resource->start + REG_OFFSET_PERP_TYPE, 1);
2052 if (rc) {
2053 pr_err("Peripheral type read failed rc=%d\n", rc);
2054 return rc;
2055 }
2056 rc = qpnp_read_wrapper(chip, &subtype,
2057 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2058 if (rc) {
2059 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2060 return rc;
2061 }
2062
2063 if (type == BMS_BMS_TYPE && subtype == BMS_BMS_SUBTYPE) {
2064 chip->base = resource->start;
2065 } else if (type == BMS_IADC_TYPE
2066 && subtype == BMS_IADC_SUBTYPE) {
2067 chip->iadc_base = resource->start;
2068 } else {
2069 pr_err("Invalid peripheral start=0x%x type=0x%x, subtype=0x%x\n",
2070 resource->start, type, subtype);
2071 }
2072 }
2073
2074 if (chip->base == 0) {
2075 dev_err(&spmi->dev, "BMS peripheral was not registered\n");
2076 return -EINVAL;
2077 }
2078 if (chip->iadc_base == 0) {
2079 dev_err(&spmi->dev, "BMS_IADC peripheral was not registered\n");
2080 return -EINVAL;
2081 }
2082
2083 return 0;
2084}
2085
2086#define ADC_CH_SEL_MASK 0x7
2087static int read_iadc_channel_select(struct qpnp_bms_chip *chip)
2088{
2089 u8 iadc_channel_select;
2090 int rc;
2091
2092 rc = qpnp_read_wrapper(chip, &iadc_channel_select,
2093 chip->iadc_base + IADC1_BMS_ADC_CH_SEL_CTL, 1);
2094 if (rc) {
2095 pr_err("Error reading bms_iadc channel register %d\n", rc);
2096 return rc;
2097 }
2098
2099 iadc_channel_select &= ADC_CH_SEL_MASK;
2100 if (iadc_channel_select == INTERNAL_RSENSE) {
2101 pr_debug("Internal rsense used\n");
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002102 if (chip->use_external_rsense) {
2103 pr_debug("Changing rsense to external\n");
2104 rc = qpnp_masked_write_iadc(chip,
2105 IADC1_BMS_ADC_CH_SEL_CTL,
2106 ADC_CH_SEL_MASK,
2107 EXTERNAL_RSENSE);
2108 if (rc) {
2109 pr_err("Unable to set IADC1_BMS channel %x to %x: %d\n",
2110 IADC1_BMS_ADC_CH_SEL_CTL,
2111 EXTERNAL_RSENSE, rc);
2112 return rc;
2113 }
2114 reset_cc(chip);
2115 }
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002116 } else if (iadc_channel_select == EXTERNAL_RSENSE) {
2117 pr_debug("External rsense used\n");
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002118 if (!chip->use_external_rsense) {
2119 pr_debug("Changing rsense to internal\n");
2120 rc = qpnp_masked_write_iadc(chip,
2121 IADC1_BMS_ADC_CH_SEL_CTL,
2122 ADC_CH_SEL_MASK,
2123 INTERNAL_RSENSE);
2124 if (rc) {
2125 pr_err("Unable to set IADC1_BMS channel %x to %x: %d\n",
2126 IADC1_BMS_ADC_CH_SEL_CTL,
2127 INTERNAL_RSENSE, rc);
2128 return rc;
2129 }
2130 reset_cc(chip);
2131 }
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002132 } else {
2133 pr_err("IADC1_BMS_IADC configured incorrectly. Selected channel = %d\n",
2134 iadc_channel_select);
2135 return -EINVAL;
2136 }
2137 return 0;
2138}
2139
2140static int __devinit qpnp_bms_probe(struct spmi_device *spmi)
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002141{
2142 struct qpnp_bms_chip *chip;
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002143 int rc, vbatt;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002144
2145 chip = kzalloc(sizeof *chip, GFP_KERNEL);
2146
2147 if (chip == NULL) {
2148 pr_err("kzalloc() failed.\n");
2149 return -ENOMEM;
2150 }
2151
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002152 rc = qpnp_vadc_is_ready();
2153 if (rc) {
2154 pr_info("vadc not ready: %d, deferring probe\n", rc);
2155 goto error_read;
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002156 }
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002157
2158 rc = qpnp_iadc_is_ready();
2159 if (rc) {
2160 pr_info("iadc not ready: %d, deferring probe\n", rc);
2161 goto error_read;
2162 }
2163
2164 rc = register_spmi(chip, spmi);
2165 if (rc) {
2166 pr_err("error registering spmi resource %d\n", rc);
2167 goto error_resource;
2168 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002169
2170 rc = qpnp_read_wrapper(chip, &chip->revision1,
2171 chip->base + BMS1_REVISION1, 1);
2172 if (rc) {
2173 pr_err("error reading version register %d\n", rc);
2174 goto error_read;
2175 }
2176
2177 rc = qpnp_read_wrapper(chip, &chip->revision2,
2178 chip->base + BMS1_REVISION2, 1);
2179 if (rc) {
2180 pr_err("Error reading version register %d\n", rc);
2181 goto error_read;
2182 }
Xiaozhe Shia045a562012-11-28 16:55:39 -08002183 pr_debug("BMS version: %hhu.%hhu\n", chip->revision2, chip->revision1);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002184
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002185 rc = bms_read_properties(chip);
2186 if (rc) {
2187 pr_err("Unable to read all bms properties, rc = %d\n", rc);
2188 goto error_read;
2189 }
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002190
Xiaozhe Shidffbe692012-12-11 15:35:46 -08002191 rc = read_iadc_channel_select(chip);
2192 if (rc) {
2193 pr_err("Unable to get iadc selected channel = %d\n", rc);
2194 goto error_read;
2195 }
2196
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002197 rc = set_battery_data(chip);
2198 if (rc) {
2199 pr_err("Bad battery data %d\n", rc);
2200 goto error_read;
2201 }
2202
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002203 bms_initialize_constants(chip);
2204
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002205 mutex_init(&chip->bms_output_lock);
2206 mutex_init(&chip->last_ocv_uv_mutex);
2207 mutex_init(&chip->soc_invalidation_mutex);
2208
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002209 INIT_DELAYED_WORK(&chip->calculate_soc_delayed_work,
2210 calculate_soc_work);
2211
2212 read_shutdown_soc_and_iavg(chip);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002213
2214 dev_set_drvdata(&spmi->dev, chip);
2215 device_init_wakeup(&spmi->dev, 1);
2216
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002217 calculate_soc_work(&(chip->calculate_soc_delayed_work.work));
2218
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002219 /* setup & register the battery power supply */
2220 chip->bms_psy.name = "bms";
2221 chip->bms_psy.type = POWER_SUPPLY_TYPE_BMS;
2222 chip->bms_psy.properties = msm_bms_power_props;
2223 chip->bms_psy.num_properties = ARRAY_SIZE(msm_bms_power_props);
2224 chip->bms_psy.get_property = qpnp_bms_power_get_property;
2225 chip->bms_psy.set_property = qpnp_bms_power_set_property;
2226 chip->bms_psy.external_power_changed =
2227 qpnp_bms_external_power_changed;
2228 chip->bms_psy.supplied_to = qpnp_bms_supplicants;
2229 chip->bms_psy.num_supplicants = ARRAY_SIZE(qpnp_bms_supplicants);
2230
2231 rc = power_supply_register(chip->dev, &chip->bms_psy);
2232
2233 if (rc < 0) {
2234 pr_err("power_supply_register bms failed rc = %d\n", rc);
2235 goto unregister_dc;
2236 }
2237
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002238 vbatt = 0;
2239 get_battery_voltage(&vbatt);
2240
Xiaozhe Shi8cf085e2012-11-26 11:36:36 -08002241 pr_debug("OK battery_capacity_at_boot=%d vbatt = %d\n",
Xiaozhe Shicd7e5302012-10-17 12:29:53 -07002242 get_prop_bms_capacity(chip),
2243 vbatt);
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002244 pr_info("probe success\n");
2245 return 0;
2246
2247unregister_dc:
2248 power_supply_unregister(&chip->bms_psy);
2249 dev_set_drvdata(&spmi->dev, NULL);
Xiaozhe Shic40b3972012-11-30 14:11:16 -08002250error_resource:
Xiaozhe Shib19f7032012-08-16 12:14:16 -07002251error_read:
2252 kfree(chip);
2253 return rc;
2254}
2255
2256static int __devexit
2257qpnp_bms_remove(struct spmi_device *spmi)
2258{
2259 struct qpnp_bms_chip *chip = dev_get_drvdata(&spmi->dev);
2260
2261 dev_set_drvdata(&spmi->dev, NULL);
2262 kfree(chip);
2263 return 0;
2264}
2265
2266static struct spmi_driver qpnp_bms_driver = {
2267 .probe = qpnp_bms_probe,
2268 .remove = __devexit_p(qpnp_bms_remove),
2269 .driver = {
2270 .name = QPNP_BMS_DEV_NAME,
2271 .owner = THIS_MODULE,
2272 .of_match_table = qpnp_bms_match_table,
2273 },
2274};
2275
2276static int __init qpnp_bms_init(void)
2277{
2278 pr_info("QPNP BMS INIT\n");
2279 return spmi_driver_register(&qpnp_bms_driver);
2280}
2281
2282static void __exit qpnp_bms_exit(void)
2283{
2284 pr_info("QPNP BMS EXIT\n");
2285 return spmi_driver_unregister(&qpnp_bms_driver);
2286}
2287
2288module_init(qpnp_bms_init);
2289module_exit(qpnp_bms_exit);
2290
2291MODULE_DESCRIPTION("QPNP BMS Driver");
2292MODULE_LICENSE("GPL v2");
2293MODULE_ALIAS("platform:" QPNP_BMS_DEV_NAME);