blob: d4239ea621083a65e3b8155ea1f7bb4595a331ce [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2 *
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 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/platform_device.h>
17#include <linux/errno.h>
18#include <linux/mfd/pmic8058.h>
19#include <linux/interrupt.h>
20#include <linux/delay.h>
21#include <linux/bitops.h>
22#include <linux/workqueue.h>
23#include <linux/msm-charger.h>
24#include <linux/debugfs.h>
25#include <linux/slab.h>
26#include <linux/msm_adc.h>
27#include <linux/notifier.h>
28#include <linux/pmic8058-batt-alarm.h>
29
30#include <mach/msm_xo.h>
31#include <mach/msm_hsusb.h>
32
33/* Config Regs and their bits*/
34#define PM8058_CHG_TEST 0x75
35#define IGNORE_LL 2
36#define PM8058_CHG_TEST_2 0xEA
37#define PM8058_CHG_TEST_3 0xEB
38#define PM8058_OVP_TEST_REG 0xF6
39#define FORCE_OVP_OFF 3
40
41#define PM8058_CHG_CNTRL 0x1E
42#define CHG_TRICKLE_EN 7
43#define CHG_USB_SUSPEND 6
44#define CHG_IMON_CAL 5
45#define CHG_IMON_GAIN 4
46#define CHG_CHARGE_BAT 3
47#define CHG_VBUS_FROM_BOOST_OVRD 2
48#define CHG_CHARGE_DIS 1
49#define CHG_VCP_EN 0
50
51#define PM8058_CHG_CNTRL_2 0xD8
52#define ATC_DIS 7 /* coincell backed */
53#define CHARGE_AUTO_DIS 6
54#define DUMB_CHG_OVRD 5 /* coincell backed */
55#define ENUM_DONE 4
56#define CHG_TEMP_MODE 3
57#define CHG_BATT_TEMP_DIS 1 /* coincell backed */
58#define CHG_FAILED_CLEAR 0
59
60#define PM8058_CHG_VMAX_SEL 0x21
61#define PM8058_CHG_VBAT_DET 0xD9
62#define PM8058_CHG_IMAX 0x1F
63#define PM8058_CHG_TRICKLE 0xDB
64#define PM8058_CHG_ITERM 0xDC
65#define PM8058_CHG_TTRKL_MAX 0xE1
66#define PM8058_CHG_TCHG_MAX 0xE4
67#define PM8058_CHG_TEMP_THRESH 0xE2
68#define PM8058_CHG_TEMP_REG 0xE3
69#define PM8058_CHG_PULSE 0x22
70
71/* IRQ STATUS and CLEAR */
72#define PM8058_CHG_STATUS_CLEAR_IRQ_1 0x31
73#define PM8058_CHG_STATUS_CLEAR_IRQ_3 0x33
74#define PM8058_CHG_STATUS_CLEAR_IRQ_10 0xB3
75#define PM8058_CHG_STATUS_CLEAR_IRQ_11 0xB4
76
77/* IRQ MASKS */
78#define PM8058_CHG_MASK_IRQ_1 0x38
79
80#define PM8058_CHG_MASK_IRQ_3 0x3A
81#define PM8058_CHG_MASK_IRQ_10 0xBA
82#define PM8058_CHG_MASK_IRQ_11 0xBB
83
84/* IRQ Real time status regs */
85#define PM8058_CHG_STATUS_RT_1 0x3F
86#define STATUS_RTCHGVAL 7
87#define STATUS_RTCHGINVAL 6
88#define STATUS_RTBATT_REPLACE 5
89#define STATUS_RTVBATDET_LOW 4
90#define STATUS_RTCHGILIM 3
91#define STATUS_RTPCTDONE 1
92#define STATUS_RTVCP 0
93#define PM8058_CHG_STATUS_RT_3 0x41
94#define PM8058_CHG_STATUS_RT_10 0xC1
95#define PM8058_CHG_STATUS_RT_11 0xC2
96
97/* VTRIM */
98#define PM8058_CHG_VTRIM 0x1D
99#define PM8058_CHG_VBATDET_TRIM 0x1E
100#define PM8058_CHG_ITRIM 0x1F
101#define PM8058_CHG_TTRIM 0x20
102
103#define AUTO_CHARGING_VMAXSEL 4200
104#define AUTO_CHARGING_FAST_TIME_MAX_MINUTES 512
105#define AUTO_CHARGING_TRICKLE_TIME_MINUTES 30
106#define AUTO_CHARGING_VEOC_ITERM 100
107#define AUTO_CHARGING_IEOC_ITERM 160
108#define AUTO_CHARGING_RESUME_MV 4100
109
110#define AUTO_CHARGING_VBATDET 4150
111#define AUTO_CHARGING_VBATDET_DEBOUNCE_TIME_MS 3000
112#define AUTO_CHARGING_VEOC_VBATDET 4100
113#define AUTO_CHARGING_VEOC_TCHG 16
114#define AUTO_CHARGING_VEOC_TCHG_FINAL_CYCLE 32
115#define AUTO_CHARGING_VEOC_BEGIN_TIME_MS 5400000
116
117#define AUTO_CHARGING_VEOC_VBAT_LOW_CHECK_TIME_MS 60000
118#define AUTO_CHARGING_RESUME_CHARGE_DETECTION_COUNTER 5
119
120#define AUTO_CHARGING_DONE_CHECK_TIME_MS 1000
121
122#define PM8058_CHG_I_STEP_MA 50
123#define PM8058_CHG_I_MIN_MA 50
124#define PM8058_CHG_T_TCHG_SHIFT 2
125#define PM8058_CHG_I_TERM_STEP_MA 10
126#define PM8058_CHG_V_STEP_MV 25
127#define PM8058_CHG_V_MIN_MV 2400
128/*
129 * enum pmic_chg_interrupts: pmic interrupts
130 * @CHGVAL_IRQ: charger V between 3.3 and 7.9
131 * @CHGINVAL_IRQ: charger V outside 3.3 and 7.9
132 * @VBATDET_LOW_IRQ: VBAT < VBATDET
133 * @VCP_IRQ: VDD went below VBAT: BAT_FET is turned on
134 * @CHGILIM_IRQ: mA consumed>IMAXSEL: chgloop draws less mA
135 * @ATC_DONE_IRQ: Auto Trickle done
136 * @ATCFAIL_IRQ: Auto Trickle fail
137 * @AUTO_CHGDONE_IRQ: Auto chg done
138 * @AUTO_CHGFAIL_IRQ: time exceeded w/o reaching term current
139 * @CHGSTATE_IRQ: something happend causing a state change
140 * @FASTCHG_IRQ: trkl charging completed: moving to fastchg
141 * @CHG_END_IRQ: mA has dropped to termination current
142 * @BATTTEMP_IRQ: batt temp is out of range
143 * @CHGHOT_IRQ: the pass device is too hot
144 * @CHGTLIMIT_IRQ: unused
145 * @CHG_GONE_IRQ: charger was removed
146 * @VCPMAJOR_IRQ: vcp major
147 * @VBATDET_IRQ: VBAT >= VBATDET
148 * @BATFET_IRQ: BATFET closed
149 * @BATT_REPLACE_IRQ:
150 * @BATTCONNECT_IRQ:
151 */
152enum pmic_chg_interrupts {
153 CHGVAL_IRQ,
154 CHGINVAL_IRQ,
155 VBATDET_LOW_IRQ,
156 VCP_IRQ,
157 CHGILIM_IRQ,
158 ATC_DONE_IRQ,
159 ATCFAIL_IRQ,
160 AUTO_CHGDONE_IRQ,
161 AUTO_CHGFAIL_IRQ,
162 CHGSTATE_IRQ,
163 FASTCHG_IRQ,
164 CHG_END_IRQ,
165 BATTTEMP_IRQ,
166 CHGHOT_IRQ,
167 CHGTLIMIT_IRQ,
168 CHG_GONE_IRQ,
169 VCPMAJOR_IRQ,
170 VBATDET_IRQ,
171 BATFET_IRQ,
172 BATT_REPLACE_IRQ,
173 BATTCONNECT_IRQ,
174 PMIC_CHG_MAX_INTS
175};
176
177struct pm8058_charger {
178 struct pmic_charger_pdata *pdata;
179 struct pm8058_chip *pm_chip;
180 struct device *dev;
181
182 int pmic_chg_irq[PMIC_CHG_MAX_INTS];
183 DECLARE_BITMAP(enabled_irqs, PMIC_CHG_MAX_INTS);
184
185 struct delayed_work chg_done_check_work;
186 struct delayed_work check_vbat_low_work;
187 struct delayed_work veoc_begin_work;
188 struct delayed_work charging_check_work;
189 int waiting_for_topoff;
190 int waiting_for_veoc;
191 int vbatdet;
192 struct msm_hardware_charger hw_chg;
193 int current_charger_current;
194 int disabled;
195
196 struct msm_xo_voter *voter;
197 struct dentry *dent;
198
199 int inited;
200 int present;
201};
202
203static struct pm8058_charger pm8058_chg;
204static struct msm_hardware_charger usb_hw_chg;
205
206
207static int msm_battery_gauge_alarm_notify(struct notifier_block *nb,
208 unsigned long status, void *unused);
209
210static struct notifier_block alarm_notifier = {
211 .notifier_call = msm_battery_gauge_alarm_notify,
212};
213
214static int resume_mv = AUTO_CHARGING_RESUME_MV;
215static DEFINE_MUTEX(batt_alarm_lock);
216static int resume_mv_set(const char *val, struct kernel_param *kp);
217module_param_call(resume_mv, resume_mv_set, param_get_int,
218 &resume_mv, S_IRUGO | S_IWUSR);
219
220static int resume_mv_set(const char *val, struct kernel_param *kp)
221{
222 int rc;
223
224 mutex_lock(&batt_alarm_lock);
225
226 rc = param_set_int(val, kp);
227 if (rc)
228 goto out;
229
230 rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
231
232out:
233 mutex_unlock(&batt_alarm_lock);
234 return rc;
235}
236
237static void pm8058_chg_enable_irq(int interrupt)
238{
239 if (!__test_and_set_bit(interrupt, pm8058_chg.enabled_irqs)) {
240 dev_dbg(pm8058_chg.dev, "%s %d\n", __func__,
241 pm8058_chg.pmic_chg_irq[interrupt]);
242 enable_irq(pm8058_chg.pmic_chg_irq[interrupt]);
243 }
244}
245
246static void pm8058_chg_disable_irq(int interrupt)
247{
248 if (__test_and_clear_bit(interrupt, pm8058_chg.enabled_irqs)) {
249 dev_dbg(pm8058_chg.dev, "%s %d\n", __func__,
250 pm8058_chg.pmic_chg_irq[interrupt]);
251 disable_irq_nosync(pm8058_chg.pmic_chg_irq[interrupt]);
252 }
253}
254
255static int pm_chg_get_rt_status(int irq)
256{
257 int count = 3;
258 int ret;
259
260 while ((ret =
261 pm8058_irq_get_rt_status(pm8058_chg.pm_chip, irq)) == -EAGAIN
262 && count--) {
263 dev_info(pm8058_chg.dev, "%s trycount=%d\n", __func__, count);
264 cpu_relax();
265 }
266 if (ret == -EAGAIN)
267 return 0;
268 else
269 return ret;
270}
271
272static int is_chg_plugged_in(void)
273{
274 return pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
275}
276
277#ifdef DEBUG
278static void __dump_chg_regs(void)
279{
280 u8 temp;
281 int temp2;
282
283 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
284 dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL = 0x%x\n", temp);
285 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
286 dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL_2 = 0x%x\n", temp);
287 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
288 dev_dbg(pm8058_chg.dev, "PM8058_CHG_VMAX_SEL = 0x%x\n", temp);
289 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
290 dev_dbg(pm8058_chg.dev, "PM8058_CHG_VBAT_DET = 0x%x\n", temp);
291 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
292 dev_dbg(pm8058_chg.dev, "PM8058_CHG_IMAX = 0x%x\n", temp);
293 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TRICKLE, &temp, 1);
294 dev_dbg(pm8058_chg.dev, "PM8058_CHG_TRICKLE = 0x%x\n", temp);
295 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
296 dev_dbg(pm8058_chg.dev, "PM8058_CHG_ITERM = 0x%x\n", temp);
297 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
298 dev_dbg(pm8058_chg.dev, "PM8058_CHG_TTRKL_MAX = 0x%x\n", temp);
299 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
300 dev_dbg(pm8058_chg.dev, "PM8058_CHG_TCHG_MAX = 0x%x\n", temp);
301 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_THRESH, &temp, 1);
302 dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_THRESH = 0x%x\n", temp);
303 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_REG, &temp, 1);
304 dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_REG = 0x%x\n", temp);
305 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_PULSE, &temp, 1);
306 dev_dbg(pm8058_chg.dev, "PM8058_CHG_PULSE = 0x%x\n", temp);
307
308 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_1,
309 &temp, 1);
310 dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_1 = 0x%x\n", temp);
311 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_3,
312 &temp, 1);
313 dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_3 = 0x%x\n", temp);
314 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_10,
315 &temp, 1);
316 dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_10 = 0x%x\n",
317 temp);
318 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_11,
319 &temp, 1);
320 dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_11 = 0x%x\n",
321 temp);
322
323 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_1, &temp, 1);
324 dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_1 = 0x%x\n", temp);
325 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_3, &temp, 1);
326 dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_3 = 0x%x\n", temp);
327 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_10, &temp, 1);
328 dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_10 = 0x%x\n", temp);
329 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_11, &temp, 1);
330 dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_11 = 0x%x\n", temp);
331
332 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
333 dev_dbg(pm8058_chg.dev, "CHGVAL_IRQ = %d\n", temp2);
334
335 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ]);
336 dev_dbg(pm8058_chg.dev, "CHGINVAL_IRQ = %d\n", temp2);
337
338 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_LOW_IRQ]);
339 dev_dbg(pm8058_chg.dev, "VBATDET_LOW_IRQ= %d\n", temp2);
340
341 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VCP_IRQ]);
342 dev_dbg(pm8058_chg.dev, "VCP_IRQ= %d\n", temp2);
343
344 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGILIM_IRQ]);
345 dev_dbg(pm8058_chg.dev, "CHGILIM_IRQ= %d\n", temp2);
346
347 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[ATC_DONE_IRQ]);
348 dev_dbg(pm8058_chg.dev, "ATC_DONE_IRQ= %d\n", temp2);
349
350 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[ATCFAIL_IRQ]);
351 dev_dbg(pm8058_chg.dev, "ATCFAIL_IRQ= %d\n", temp2);
352
353 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ]);
354 dev_dbg(pm8058_chg.dev, "AUTO_CHGDONE_IRQ= %d\n", temp2);
355
356 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ]);
357 dev_dbg(pm8058_chg.dev, "AUTO_CHGFAIL_IRQ= %d\n", temp2);
358
359 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ]);
360 dev_dbg(pm8058_chg.dev, "CHGSTATE_IRQ= %d\n", temp2);
361
362 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[FASTCHG_IRQ]);
363 dev_dbg(pm8058_chg.dev, "FASTCHG_IRQ= %d\n", temp2);
364
365 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHG_END_IRQ]);
366 dev_dbg(pm8058_chg.dev, "CHG_END_IRQ= %d\n", temp2);
367
368 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ]);
369 dev_dbg(pm8058_chg.dev, "BATTTEMP_IRQ= %d\n", temp2);
370
371 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGHOT_IRQ]);
372 dev_dbg(pm8058_chg.dev, "CHGHOT_IRQ= %d\n", temp2);
373
374 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGTLIMIT_IRQ]);
375 dev_dbg(pm8058_chg.dev, "CHGTLIMIT_IRQ= %d\n", temp2);
376
377 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHG_GONE_IRQ]);
378 dev_dbg(pm8058_chg.dev, "CHG_GONE_IRQ= %d\n", temp2);
379
380 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VCPMAJOR_IRQ]);
381 dev_dbg(pm8058_chg.dev, "VCPMAJOR_IRQ= %d\n", temp2);
382
383 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_IRQ]);
384 dev_dbg(pm8058_chg.dev, "VBATDET_IRQ= %d\n", temp2);
385
386 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATFET_IRQ]);
387 dev_dbg(pm8058_chg.dev, "BATFET_IRQ= %d\n", temp2);
388
389 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ]);
390 dev_dbg(pm8058_chg.dev, "BATT_REPLACE_IRQ= %d\n", temp2);
391
392 temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ]);
393 dev_dbg(pm8058_chg.dev, "BATTCONNECT_IRQ= %d\n", temp2);
394}
395#else
396static inline void __dump_chg_regs(void)
397{
398}
399#endif
400
401/* SSBI register access helper functions */
402static int pm_chg_suspend(int value)
403{
404 u8 temp;
405 int ret;
406
407 ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
408 if (ret)
409 return ret;
410 if (value)
411 temp |= BIT(CHG_USB_SUSPEND);
412 else
413 temp &= ~BIT(CHG_USB_SUSPEND);
414
415 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
416}
417
418static int pm_chg_auto_disable(int value)
419{
420 u8 temp;
421 int ret;
422
423 ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
424 if (ret)
425 return ret;
426 if (value)
427 temp |= BIT(CHARGE_AUTO_DIS);
428 else
429 temp &= ~BIT(CHARGE_AUTO_DIS);
430
431 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
432}
433
434static int pm_chg_batt_temp_disable(int value)
435{
436 u8 temp;
437 int ret;
438
439 ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
440 if (ret)
441 return ret;
442 if (value)
443 temp |= BIT(CHG_BATT_TEMP_DIS);
444 else
445 temp &= ~BIT(CHG_BATT_TEMP_DIS);
446
447 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
448}
449
450static int pm_chg_vbatdet_set(int voltage)
451{
452 u8 temp;
453 int diff;
454
455 diff = (voltage - PM8058_CHG_V_MIN_MV);
456 if (diff < 0) {
457 dev_warn(pm8058_chg.dev, "%s bad mV=%d asked to set\n",
458 __func__, voltage);
459 return -EINVAL;
460 }
461
462 temp = diff / PM8058_CHG_V_STEP_MV;
463 dev_dbg(pm8058_chg.dev, "%s voltage=%d setting %02x\n", __func__,
464 voltage, temp);
465 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
466}
467
468static int pm_chg_imaxsel_set(int chg_current)
469{
470 u8 temp;
471 int diff;
472
473 diff = chg_current - PM8058_CHG_I_MIN_MA;
474 if (diff < 0) {
475 dev_warn(pm8058_chg.dev, "%s bad mA=%d asked to set\n",
476 __func__, chg_current);
477 return -EINVAL;
478 }
479 temp = diff / PM8058_CHG_I_STEP_MA;
480 /* make sure we arent writing more than 5 bits of data */
481 if (temp > 31) {
482 dev_warn(pm8058_chg.dev, "%s max mA=1500 requested mA=%d\n",
483 __func__, chg_current);
484 temp = 31;
485 }
486 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
487}
488
489#define PM8058_CHG_VMAX_MIN 3300
490#define PM8058_CHG_VMAX_MAX 5500
491static int pm_chg_vmaxsel_set(int voltage)
492{
493 u8 temp;
494
495 if (voltage < PM8058_CHG_VMAX_MIN || voltage > PM8058_CHG_VMAX_MAX) {
496 dev_warn(pm8058_chg.dev, "%s bad mV=%d asked to set\n",
497 __func__, voltage);
498 return -EINVAL;
499 }
500 temp = (voltage - PM8058_CHG_V_MIN_MV) / PM8058_CHG_V_STEP_MV;
501 dev_dbg(pm8058_chg.dev, "%s mV=%d setting %02x\n", __func__, voltage,
502 temp);
503 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
504}
505
506static int pm_chg_failed_clear(int value)
507{
508 u8 temp;
509 int ret;
510
511 ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
512 if (ret)
513 return ret;
514 if (value)
515 temp |= BIT(CHG_FAILED_CLEAR);
516 else
517 temp &= ~BIT(CHG_FAILED_CLEAR);
518 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
519}
520
521static int pm_chg_iterm_set(int chg_current)
522{
523 u8 temp;
524
525 temp = (chg_current / PM8058_CHG_I_TERM_STEP_MA) - 1;
526 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
527}
528
529static int pm_chg_tchg_set(int minutes)
530{
531 u8 temp;
532
533 temp = (minutes >> PM8058_CHG_T_TCHG_SHIFT) - 1;
534 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
535}
536
537static int pm_chg_ttrkl_set(int minutes)
538{
539 u8 temp;
540
541 temp = minutes - 1;
542 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
543}
544
545static int pm_chg_enum_done_enable(int value)
546{
547 u8 temp;
548 int ret;
549
550 ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
551 if (ret)
552 return ret;
553 if (value)
554 temp |= BIT(ENUM_DONE);
555 else
556 temp &= ~BIT(ENUM_DONE);
557
558 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
559}
560
561static uint32_t get_fsm_state(void)
562{
563 u8 temp;
564
565 temp = 0x00;
566 pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
567 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
568 return (uint32_t)temp;
569}
570
571static int get_fsm_status(void *data, u64 * val)
572{
573 *val = get_fsm_state();
574 return 0;
575}
576
Abhijeet Dharmapurikar0758e1e2011-07-14 18:11:41 -0700577static int pm_chg_disable(int value)
578{
579 u8 temp;
580 int ret;
581
582 ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
583 if (ret)
584 return ret;
585 if (value)
586 temp |= BIT(CHG_CHARGE_DIS);
587 else
588 temp &= ~BIT(CHG_CHARGE_DIS);
589
590 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
591}
592
593static void pm8058_start_system_current(struct msm_hardware_charger *hw_chg,
594 int max_current)
595{
596 int ret = 0;
597
598 if (pm8058_chg.disabled)
599 return;
600
601 ret = pm_chg_imaxsel_set(max_current);
602 ret |= pm_chg_enum_done_enable(1);
603 ret |= pm_chg_disable(0);
604 if (ret)
605 pr_err("%s: failed to turn on system power err=%d",
606 __func__, ret);
607}
608
609static void pm8058_stop_system_current(struct msm_hardware_charger *hw_chg)
610{
611 int ret = 0;
612
613 ret = pm_chg_enum_done_enable(0);
614 ret |= pm_chg_disable(1);
615 if (ret)
616 pr_err("%s: failed to turn off system power err=%d",
617 __func__, ret);
618}
619
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700620static int __pm8058_start_charging(int chg_current, int termination_current,
621 int time)
622{
623 int ret = 0;
624
625 if (pm8058_chg.disabled)
626 goto out;
627
628 dev_info(pm8058_chg.dev, "%s %dmA %dmin\n",
629 __func__, chg_current, time);
630
631 ret = pm_chg_auto_disable(1);
632 if (ret)
633 goto out;
634
635 ret = pm_chg_suspend(0);
636 if (ret)
637 goto out;
638
639 ret = pm_chg_imaxsel_set(chg_current);
640 if (ret)
641 goto out;
642
643 ret = pm_chg_failed_clear(1);
644 if (ret)
645 goto out;
646
647 ret = pm_chg_iterm_set(termination_current);
648 if (ret)
649 goto out;
650
651 ret = pm_chg_tchg_set(time);
652 if (ret)
653 goto out;
654
655 ret = pm_chg_ttrkl_set(AUTO_CHARGING_TRICKLE_TIME_MINUTES);
656 if (ret)
657 goto out;
658
659 ret = pm_chg_batt_temp_disable(0);
660 if (ret)
661 goto out;
662
663 if (pm8058_chg.voter == NULL)
664 pm8058_chg.voter = msm_xo_get(MSM_XO_TCXO_D1, "pm8058_charger");
665 msm_xo_mode_vote(pm8058_chg.voter, MSM_XO_MODE_ON);
666
667 ret = pm_chg_enum_done_enable(1);
668 if (ret)
669 goto out;
670
671 wmb();
672
673 ret = pm_chg_auto_disable(0);
674 if (ret)
675 goto out;
676
677 /* wait for the enable to update interrupt status*/
678 msleep(20);
679
680 pm8058_chg_enable_irq(AUTO_CHGFAIL_IRQ);
681 pm8058_chg_enable_irq(CHGHOT_IRQ);
682 pm8058_chg_enable_irq(AUTO_CHGDONE_IRQ);
683 pm8058_chg_enable_irq(CHG_END_IRQ);
684 pm8058_chg_enable_irq(CHGSTATE_IRQ);
685
686out:
687 return ret;
688}
689
690static void chg_done_cleanup(void)
691{
692 dev_info(pm8058_chg.dev, "%s notify pm8058 charging completion"
693 "\n", __func__);
694
695 pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
696 cancel_delayed_work_sync(&pm8058_chg.veoc_begin_work);
697 cancel_delayed_work_sync(&pm8058_chg.check_vbat_low_work);
698
699 pm8058_chg_disable_irq(CHG_END_IRQ);
700
701 pm8058_chg_disable_irq(VBATDET_LOW_IRQ);
702 pm8058_chg_disable_irq(VBATDET_IRQ);
703 pm8058_chg.waiting_for_veoc = 0;
704 pm8058_chg.waiting_for_topoff = 0;
705
706 pm_chg_auto_disable(1);
707
708 msm_charger_notify_event(&usb_hw_chg, CHG_DONE_EVENT);
709}
710
711static void chg_done_check_work(struct work_struct *work)
712{
713 chg_done_cleanup();
714}
715
716static void charging_check_work(struct work_struct *work)
717{
718 uint32_t fsm_state = get_fsm_state();
719 int rc;
720
721 switch (fsm_state) {
722 /* We're charging, so disarm alarm */
723 case 2:
724 case 7:
725 case 8:
726 rc = pm8058_batt_alarm_state_set(0, 0);
727 if (rc)
728 dev_err(pm8058_chg.dev,
729 "%s: unable to set alarm state\n", __func__);
730 break;
731 default:
732 /* Still not charging, so update driver state */
733 chg_done_cleanup();
734 break;
735 };
736}
737
738static int pm8058_start_charging(struct msm_hardware_charger *hw_chg,
739 int chg_voltage, int chg_current)
740{
741 int vbat_higher_than_vbatdet;
742 int ret = 0;
743
744 cancel_delayed_work_sync(&pm8058_chg.charging_check_work);
745
746 /*
747 * adjust the max current for PC USB connection - set the higher limit
748 * to 450 and make sure we never cross it
749 */
750 if (chg_current == 500)
751 chg_current = 450;
752 pm8058_chg.current_charger_current = chg_current;
753 pm8058_chg_enable_irq(FASTCHG_IRQ);
754
755 ret = pm_chg_vmaxsel_set(chg_voltage);
756 if (ret)
757 goto out;
758
759 /* set vbat to CC to CV threshold */
760 ret = pm_chg_vbatdet_set(AUTO_CHARGING_VBATDET);
761 if (ret)
762 goto out;
763
764 pm8058_chg.vbatdet = AUTO_CHARGING_VBATDET;
765 /*
766 * get the state of vbat and if it is higher than
767 * AUTO_CHARGING_VBATDET we start the veoc start timer
768 * else wait for the voltage to go to AUTO_CHARGING_VBATDET
769 * and then start the 90 min timer
770 */
771 vbat_higher_than_vbatdet =
772 pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_IRQ]);
773 if (vbat_higher_than_vbatdet) {
774 /*
775 * we are in constant voltage phase of charging
776 * IEOC should happen withing 90 mins of this instant
777 * else we enable VEOC
778 */
779 dev_info(pm8058_chg.dev, "%s begin veoc timer\n", __func__);
780 schedule_delayed_work(&pm8058_chg.veoc_begin_work,
781 round_jiffies_relative(msecs_to_jiffies
782 (AUTO_CHARGING_VEOC_BEGIN_TIME_MS)));
783 } else
784 pm8058_chg_enable_irq(VBATDET_IRQ);
785
786 ret = __pm8058_start_charging(chg_current, AUTO_CHARGING_IEOC_ITERM,
787 AUTO_CHARGING_FAST_TIME_MAX_MINUTES);
788 pm8058_chg.current_charger_current = chg_current;
789
790 /*
791 * We want to check the FSM state to verify we're charging. We must
792 * wait before doing this to allow the VBATDET to settle. The worst
793 * case for this is two seconds. The batt alarm does not have this
794 * delay.
795 */
796 schedule_delayed_work(&pm8058_chg.charging_check_work,
797 round_jiffies_relative(msecs_to_jiffies
798 (AUTO_CHARGING_VBATDET_DEBOUNCE_TIME_MS)));
799
800out:
801 return ret;
802}
803
804static void veoc_begin_work(struct work_struct *work)
805{
806 /* we have been doing CV for 90mins with no signs of IEOC
807 * start checking for VEOC in addition with 16min charges*/
808 dev_info(pm8058_chg.dev, "%s begin veoc detection\n", __func__);
809 pm8058_chg.waiting_for_veoc = 1;
810 /*
811 * disable VBATDET irq we dont need it unless we are at the end of
812 * charge cycle
813 */
814 pm8058_chg_disable_irq(VBATDET_IRQ);
815 __pm8058_start_charging(pm8058_chg.current_charger_current,
816 AUTO_CHARGING_VEOC_ITERM,
817 AUTO_CHARGING_VEOC_TCHG);
818}
819
820static void vbat_low_work(struct work_struct *work)
821{
822 /*
823 * It has been one minute and the battery still holds voltage
824 * start the final topoff - charging is almost done
825 */
826 dev_info(pm8058_chg.dev, "%s vbatt maintains for a minute"
827 "starting topoff\n", __func__);
828 pm8058_chg.waiting_for_veoc = 0;
829 pm8058_chg.waiting_for_topoff = 1;
830 pm8058_chg_disable_irq(VBATDET_LOW_IRQ);
831 pm8058_chg_disable_irq(VBATDET_IRQ);
832 __pm8058_start_charging(pm8058_chg.current_charger_current,
833 AUTO_CHARGING_VEOC_ITERM,
834 AUTO_CHARGING_VEOC_TCHG_FINAL_CYCLE);
835}
836
837
838static irqreturn_t pm8058_chg_chgval_handler(int irq, void *dev_id)
839{
840 u8 old, temp;
841 int ret;
842
843 if (is_chg_plugged_in()) { /* this debounces it */
844 if (!pm8058_chg.present) {
845 msm_charger_notify_event(&usb_hw_chg,
846 CHG_INSERTED_EVENT);
847 pm8058_chg.present = 1;
848 }
849 } else {
850 if (pm8058_chg.present) {
851 ret = pm8058_read(pm8058_chg.pm_chip,
852 PM8058_OVP_TEST_REG,
853 &old, 1);
854 temp = old | BIT(FORCE_OVP_OFF);
855 ret = pm8058_write(pm8058_chg.pm_chip,
856 PM8058_OVP_TEST_REG,
857 &temp, 1);
858 temp = 0xFC;
859 ret = pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST,
860 &temp, 1);
861 /* 10 ms sleep is for the VCHG to discharge */
862 msleep(10);
863 temp = 0xF0;
864 ret = pm8058_write(pm8058_chg.pm_chip,
865 PM8058_CHG_TEST,
866 &temp, 1);
867 ret = pm8058_write(pm8058_chg.pm_chip,
868 PM8058_OVP_TEST_REG,
869 &old, 1);
870
871 pm_chg_enum_done_enable(0);
872 pm_chg_auto_disable(1);
873 msm_charger_notify_event(&usb_hw_chg,
874 CHG_REMOVED_EVENT);
875 pm8058_chg.present = 0;
876 }
877 }
878
879 return IRQ_HANDLED;
880}
881
882static irqreturn_t pm8058_chg_chginval_handler(int irq, void *dev_id)
883{
884 u8 old, temp;
885 int ret;
886
887 if (pm8058_chg.present) {
888 pm8058_chg_disable_irq(CHGINVAL_IRQ);
889
890 pm_chg_enum_done_enable(0);
891 pm_chg_auto_disable(1);
892 ret = pm8058_read(pm8058_chg.pm_chip,
893 PM8058_OVP_TEST_REG, &old, 1);
894 temp = old | BIT(FORCE_OVP_OFF);
895 ret = pm8058_write(pm8058_chg.pm_chip,
896 PM8058_OVP_TEST_REG, &temp, 1);
897 temp = 0xFC;
898 ret = pm8058_write(pm8058_chg.pm_chip,
899 PM8058_CHG_TEST, &temp, 1);
900 /* 10 ms sleep is for the VCHG to discharge */
901 msleep(10);
902 temp = 0xF0;
903 ret = pm8058_write(pm8058_chg.pm_chip,
904 PM8058_CHG_TEST, &temp, 1);
905 ret = pm8058_write(pm8058_chg.pm_chip,
906 PM8058_OVP_TEST_REG, &old, 1);
907
908 if (!is_chg_plugged_in()) {
909 msm_charger_notify_event(&usb_hw_chg,
910 CHG_REMOVED_EVENT);
911 pm8058_chg.present = 0;
912 } else {
913 /* was a fake */
914 pm8058_chg_enable_irq(CHGINVAL_IRQ);
915 }
916 }
917
918 return IRQ_HANDLED;
919}
920
921static irqreturn_t pm8058_chg_auto_chgdone_handler(int irq, void *dev_id)
922{
923 dev_info(pm8058_chg.dev, "%s waiting a sec to confirm\n",
924 __func__);
Abhijeet Dharmapurikar2dae2392011-07-14 18:31:28 -0700925 pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700926 pm8058_chg_disable_irq(VBATDET_IRQ);
927 if (!delayed_work_pending(&pm8058_chg.chg_done_check_work)) {
928 schedule_delayed_work(&pm8058_chg.chg_done_check_work,
929 round_jiffies_relative(msecs_to_jiffies
930 (AUTO_CHARGING_DONE_CHECK_TIME_MS)));
931 }
932 return IRQ_HANDLED;
933}
934
935/* can only happen with the pmic charger when it has been charing
936 * for either 16 mins wating for VEOC or 32 mins for topoff
937 * without a IEOC indication */
938static irqreturn_t pm8058_chg_auto_chgfail_handler(int irq, void *dev_id)
939{
940 pm8058_chg_disable_irq(AUTO_CHGFAIL_IRQ);
941
942 if (pm8058_chg.waiting_for_topoff == 1) {
943 dev_info(pm8058_chg.dev, "%s topoff done, charging done\n",
944 __func__);
945 pm8058_chg.waiting_for_topoff = 0;
946 /* notify we are done charging */
947 msm_charger_notify_event(&usb_hw_chg, CHG_DONE_EVENT);
948 } else {
949 /* start one minute timer and monitor VBATDET_LOW */
950 dev_info(pm8058_chg.dev, "%s monitoring vbat_low for a"
951 "minute\n", __func__);
952 schedule_delayed_work(&pm8058_chg.check_vbat_low_work,
953 round_jiffies_relative(msecs_to_jiffies
954 (AUTO_CHARGING_VEOC_VBAT_LOW_CHECK_TIME_MS)));
955
956 /* note we are waiting on veoc */
957 pm8058_chg.waiting_for_veoc = 1;
958
959 pm_chg_vbatdet_set(AUTO_CHARGING_VEOC_VBATDET);
960 pm8058_chg.vbatdet = AUTO_CHARGING_VEOC_VBATDET;
961 pm8058_chg_enable_irq(VBATDET_LOW_IRQ);
962 }
963 return IRQ_HANDLED;
964}
965
966static irqreturn_t pm8058_chg_chgstate_handler(int irq, void *dev_id)
967{
968 u8 temp;
969
970 temp = 0x00;
971 if (!pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1)) {
972 pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
973 dev_dbg(pm8058_chg.dev, "%s state=%d\n", __func__, temp);
974 }
975 return IRQ_HANDLED;
976}
977
978static irqreturn_t pm8058_chg_fastchg_handler(int irq, void *dev_id)
979{
980 pm8058_chg_disable_irq(FASTCHG_IRQ);
981
982 /* we have begun the fast charging state */
983 dev_info(pm8058_chg.dev, "%s begin fast charging"
984 , __func__);
985 msm_charger_notify_event(&usb_hw_chg, CHG_BATT_BEGIN_FAST_CHARGING);
986 return IRQ_HANDLED;
987}
988
989static irqreturn_t pm8058_chg_batttemp_handler(int irq, void *dev_id)
990{
991 int ret;
992
993 /* we could get temperature
994 * interrupt when the battery is plugged out
995 */
996 ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ]);
997 if (ret) {
998 msm_charger_notify_event(&usb_hw_chg, CHG_BATT_REMOVED);
999 } else {
1000 /* read status to determine we are inrange or outofrange */
1001 ret =
1002 pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ]);
1003 if (ret)
1004 msm_charger_notify_event(&usb_hw_chg,
1005 CHG_BATT_TEMP_OUTOFRANGE);
1006 else
1007 msm_charger_notify_event(&usb_hw_chg,
1008 CHG_BATT_TEMP_INRANGE);
1009 }
1010
1011 return IRQ_HANDLED;
1012}
1013
1014static irqreturn_t pm8058_chg_vbatdet_handler(int irq, void *dev_id)
1015{
1016 int ret;
1017
1018 /* settling time */
1019 msleep(20);
1020 ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_IRQ]);
1021
1022 if (ret) {
1023 if (pm8058_chg.vbatdet == AUTO_CHARGING_VBATDET
1024 && !delayed_work_pending(&pm8058_chg.veoc_begin_work)) {
1025 /*
1026 * we are in constant voltage phase of charging
1027 * IEOC should happen withing 90 mins of this instant
1028 * else we enable VEOC
1029 */
1030 dev_info(pm8058_chg.dev, "%s entered constant voltage"
1031 "begin veoc timer\n", __func__);
1032 schedule_delayed_work(&pm8058_chg.veoc_begin_work,
1033 round_jiffies_relative
1034 (msecs_to_jiffies
1035 (AUTO_CHARGING_VEOC_BEGIN_TIME_MS)));
1036 }
1037 } else {
1038 if (pm8058_chg.vbatdet == AUTO_CHARGING_VEOC_VBATDET) {
1039 cancel_delayed_work_sync(
1040 &pm8058_chg.check_vbat_low_work);
1041
1042 if (pm8058_chg.waiting_for_topoff
1043 || pm8058_chg.waiting_for_veoc) {
1044 /*
1045 * the battery dropped its voltage below 4100
1046 * around a minute charge the battery for 16
1047 * mins and check vbat again for a minute
1048 */
1049 dev_info(pm8058_chg.dev, "%s batt dropped vlt"
1050 "within a minute\n", __func__);
1051 pm8058_chg.waiting_for_topoff = 0;
1052 pm8058_chg.waiting_for_veoc = 1;
1053 pm8058_chg_disable_irq(VBATDET_IRQ);
1054 __pm8058_start_charging(pm8058_chg.
1055 current_charger_current,
1056 AUTO_CHARGING_VEOC_ITERM,
1057 AUTO_CHARGING_VEOC_TCHG);
1058 }
1059 }
1060 }
1061 return IRQ_HANDLED;
1062}
1063
1064static irqreturn_t pm8058_chg_batt_replace_handler(int irq, void *dev_id)
1065{
1066 int ret;
1067
1068 pm8058_chg_disable_irq(BATT_REPLACE_IRQ);
1069 ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ]);
1070 if (ret) {
1071 msm_charger_notify_event(&usb_hw_chg, CHG_BATT_INSERTED);
1072 /*
1073 * battery is present enable batt removal
1074 * and batt temperatture interrupt
1075 */
1076 pm8058_chg_enable_irq(BATTCONNECT_IRQ);
1077 }
1078 return IRQ_HANDLED;
1079}
1080
1081static irqreturn_t pm8058_chg_battconnect_handler(int irq, void *dev_id)
1082{
1083 int ret;
1084
1085 ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ]);
1086 if (ret) {
1087 msm_charger_notify_event(&usb_hw_chg, CHG_BATT_REMOVED);
1088 } else {
1089 msm_charger_notify_event(&usb_hw_chg, CHG_BATT_INSERTED);
1090 pm8058_chg_enable_irq(BATTTEMP_IRQ);
1091 }
1092
1093 return IRQ_HANDLED;
1094}
1095
1096static int get_rt_status(void *data, u64 * val)
1097{
1098 int i = (int)data;
1099 int ret;
1100
1101 ret = pm_chg_get_rt_status(i);
1102 *val = ret;
1103 return 0;
1104}
1105
1106DEFINE_SIMPLE_ATTRIBUTE(rt_fops, get_rt_status, NULL, "%llu\n");
1107DEFINE_SIMPLE_ATTRIBUTE(fsm_fops, get_fsm_status, NULL, "%llu\n");
1108
1109static void free_irqs(void)
1110{
1111 int i;
1112
1113 for (i = 0; i < PMIC_CHG_MAX_INTS; i++)
1114 if (pm8058_chg.pmic_chg_irq[i]) {
1115 free_irq(pm8058_chg.pmic_chg_irq[i], NULL);
1116 pm8058_chg.pmic_chg_irq[i] = 0;
1117 }
1118}
1119
1120static int __devinit request_irqs(struct platform_device *pdev)
1121{
1122 struct resource *res;
1123 int ret;
1124
1125 ret = 0;
1126 bitmap_fill(pm8058_chg.enabled_irqs, PMIC_CHG_MAX_INTS);
1127
1128 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "CHGVAL");
1129 if (res == NULL) {
1130 dev_err(pm8058_chg.dev,
1131 "%s:couldnt find resource CHGVAL\n", __func__);
1132 goto err_out;
1133 } else {
1134 ret = request_threaded_irq(res->start, NULL,
1135 pm8058_chg_chgval_handler,
1136 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1137 res->name, NULL);
1138 if (ret < 0) {
1139 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1140 __func__, res->start, ret);
1141 goto err_out;
1142 } else {
1143 pm8058_chg.pmic_chg_irq[CHGVAL_IRQ] = res->start;
1144 pm8058_chg_disable_irq(CHGVAL_IRQ);
1145 enable_irq_wake(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
1146 }
1147 }
1148
1149 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "CHGINVAL");
1150 if (res == NULL) {
1151 dev_err(pm8058_chg.dev,
1152 "%s:couldnt find resource CHGINVAL\n", __func__);
1153 goto err_out;
1154 } else {
1155 ret = request_threaded_irq(res->start, NULL,
1156 pm8058_chg_chginval_handler,
1157 IRQF_TRIGGER_RISING, res->name, NULL);
1158 if (ret < 0) {
1159 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1160 __func__, res->start, ret);
1161 goto err_out;
1162 } else {
1163 pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ] = res->start;
1164 pm8058_chg_disable_irq(CHGINVAL_IRQ);
1165 }
1166 }
1167
1168 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1169 "AUTO_CHGDONE");
1170 if (res == NULL) {
1171 dev_err(pm8058_chg.dev,
1172 "%s:couldnt find resource AUTO_CHGDONE\n", __func__);
1173 goto err_out;
1174 } else {
1175 ret = request_threaded_irq(res->start, NULL,
1176 pm8058_chg_auto_chgdone_handler,
Abhijeet Dharmapurikar2dae2392011-07-14 18:31:28 -07001177 IRQF_TRIGGER_RISING,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001178 res->name, NULL);
1179 if (ret < 0) {
1180 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1181 __func__, res->start, ret);
1182 goto err_out;
1183 } else {
1184 pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ] = res->start;
1185 pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
1186 }
1187 }
1188
1189 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1190 "AUTO_CHGFAIL");
1191 if (res == NULL) {
1192 dev_err(pm8058_chg.dev,
1193 "%s:couldnt find resource AUTO_CHGFAIL\n", __func__);
1194 goto err_out;
1195 } else {
1196 ret = request_threaded_irq(res->start, NULL,
1197 pm8058_chg_auto_chgfail_handler,
1198 IRQF_TRIGGER_RISING, res->name, NULL);
1199 if (ret < 0) {
1200 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1201 __func__, res->start, ret);
1202 goto err_out;
1203 } else {
1204 pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ] = res->start;
1205 pm8058_chg_disable_irq(AUTO_CHGFAIL_IRQ);
1206 }
1207 }
1208
1209 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "CHGSTATE");
1210 if (res == NULL) {
1211 dev_err(pm8058_chg.dev,
1212 "%s:couldnt find resource CHGSTATE\n", __func__);
1213 goto err_out;
1214 } else {
1215 ret = request_threaded_irq(res->start, NULL,
1216 pm8058_chg_chgstate_handler,
1217 IRQF_TRIGGER_RISING, res->name, NULL);
1218 if (ret < 0) {
1219 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1220 __func__, res->start, ret);
1221 goto err_out;
1222 } else {
1223 pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ] = res->start;
1224 pm8058_chg_disable_irq(CHGSTATE_IRQ);
1225 }
1226 }
1227
1228 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "FASTCHG");
1229 if (res == NULL) {
1230 dev_err(pm8058_chg.dev,
1231 "%s:couldnt find resource FASTCHG\n", __func__);
1232 goto err_out;
1233 } else {
1234 ret = request_threaded_irq(res->start, NULL,
1235 pm8058_chg_fastchg_handler,
1236 IRQF_TRIGGER_RISING, res->name, NULL);
1237 if (ret < 0) {
1238 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1239 __func__, res->start, ret);
1240 goto err_out;
1241 } else {
1242 pm8058_chg.pmic_chg_irq[FASTCHG_IRQ] = res->start;
1243 pm8058_chg_disable_irq(FASTCHG_IRQ);
1244 }
1245 }
1246
1247 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "BATTTEMP");
1248 if (res == NULL) {
1249 dev_err(pm8058_chg.dev,
1250 "%s:couldnt find resource CHG_END\n", __func__);
1251 goto err_out;
1252 } else {
1253 ret = request_threaded_irq(res->start, NULL,
1254 pm8058_chg_batttemp_handler,
1255 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1256 res->name, NULL);
1257 if (ret < 0) {
1258 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1259 __func__, res->start, ret);
1260 goto err_out;
1261 } else {
1262 pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ] = res->start;
1263 pm8058_chg_disable_irq(BATTTEMP_IRQ);
1264 }
1265 }
1266
1267 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1268 "BATT_REPLACE");
1269 if (res == NULL) {
1270 dev_err(pm8058_chg.dev,
1271 "%s:couldnt find resource BATT_REPLACE\n", __func__);
1272 goto err_out;
1273 } else {
1274 ret = request_threaded_irq(res->start, NULL,
1275 pm8058_chg_batt_replace_handler,
1276 IRQF_TRIGGER_RISING, res->name, NULL);
1277 if (ret < 0) {
1278 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1279 __func__, res->start, ret);
1280 goto err_out;
1281 } else {
1282 pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ] = res->start;
1283 pm8058_chg_disable_irq(BATT_REPLACE_IRQ);
1284 }
1285 }
1286
1287 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "BATTCONNECT");
1288 if (res == NULL) {
1289 dev_err(pm8058_chg.dev,
1290 "%s:couldnt find resource BATTCONNECT\n", __func__);
1291 goto err_out;
1292 } else {
1293 ret = request_threaded_irq(res->start, NULL,
1294 pm8058_chg_battconnect_handler,
1295 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1296 res->name, NULL);
1297 if (ret < 0) {
1298 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1299 __func__, res->start, ret);
1300 goto err_out;
1301 } else {
1302 pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ] = res->start;
1303 pm8058_chg_disable_irq(BATTCONNECT_IRQ);
1304 }
1305 }
1306
1307 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "VBATDET");
1308 if (res == NULL) {
1309 dev_err(pm8058_chg.dev,
1310 "%s:couldnt find resource VBATDET\n", __func__);
1311 goto err_out;
1312 } else {
1313 ret = request_threaded_irq(res->start, NULL,
1314 pm8058_chg_vbatdet_handler,
1315 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1316 res->name, NULL);
1317 if (ret < 0) {
1318 dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
1319 __func__, res->start, ret);
1320 goto err_out;
1321 } else {
1322 pm8058_chg.pmic_chg_irq[VBATDET_IRQ] = res->start;
1323 pm8058_chg_disable_irq(VBATDET_IRQ);
1324 }
1325 }
1326
1327 return 0;
1328
1329err_out:
1330 free_irqs();
1331 return -EINVAL;
1332}
1333
1334static int pm8058_get_charge_batt(void)
1335{
1336 u8 temp;
1337 int rc;
1338
1339 rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
1340 if (rc)
1341 return rc;
1342
1343 temp &= BIT(CHG_CHARGE_BAT);
1344 if (temp)
1345 temp = 1;
1346 return temp;
1347}
1348EXPORT_SYMBOL(pm8058_get_charge_batt);
1349
1350static int pm8058_set_charge_batt(int on)
1351{
1352 u8 temp;
1353 int rc;
1354
1355 rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
1356 if (rc)
1357 return rc;
1358 if (on)
1359 temp |= BIT(CHG_CHARGE_BAT);
1360 else
1361 temp &= ~BIT(CHG_CHARGE_BAT);
1362
1363 return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
1364
1365}
1366EXPORT_SYMBOL(pm8058_set_charge_batt);
1367
1368static int get_charge_batt(void *data, u64 * val)
1369{
1370 int ret;
1371
1372 ret = pm8058_get_charge_batt();
1373 if (ret < 0)
1374 return ret;
1375
1376 *val = ret;
1377 return 0;
1378}
1379
1380static int set_charge_batt(void *data, u64 val)
1381{
1382 return pm8058_set_charge_batt(val);
1383}
1384DEFINE_SIMPLE_ATTRIBUTE(fet_fops, get_charge_batt, set_charge_batt, "%llu\n");
1385
1386static void pm8058_chg_determine_initial_state(void)
1387{
1388 if (is_chg_plugged_in()) {
1389 pm8058_chg.present = 1;
1390 msm_charger_notify_event(&usb_hw_chg, CHG_INSERTED_EVENT);
1391 dev_info(pm8058_chg.dev, "%s charger present\n", __func__);
1392 } else {
1393 pm8058_chg.present = 0;
1394 dev_info(pm8058_chg.dev, "%s charger absent\n", __func__);
1395 }
1396 pm8058_chg_enable_irq(CHGVAL_IRQ);
1397}
1398
1399static int pm8058_stop_charging(struct msm_hardware_charger *hw_chg)
1400{
1401 int ret;
1402
1403 dev_info(pm8058_chg.dev, "%s stopping charging\n", __func__);
Abhijeet Dharmapurikar2dae2392011-07-14 18:31:28 -07001404
1405 /* disable the irqs enabled while charging */
1406 pm8058_chg_disable_irq(AUTO_CHGFAIL_IRQ);
1407 pm8058_chg_disable_irq(CHGHOT_IRQ);
1408 pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
1409 pm8058_chg_disable_irq(FASTCHG_IRQ);
1410 pm8058_chg_disable_irq(CHG_END_IRQ);
1411 pm8058_chg_disable_irq(VBATDET_IRQ);
1412 pm8058_chg_disable_irq(VBATDET_LOW_IRQ);
1413
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001414 cancel_delayed_work_sync(&pm8058_chg.veoc_begin_work);
1415 cancel_delayed_work_sync(&pm8058_chg.check_vbat_low_work);
1416 cancel_delayed_work_sync(&pm8058_chg.chg_done_check_work);
1417 cancel_delayed_work_sync(&pm8058_chg.charging_check_work);
1418
1419 ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[FASTCHG_IRQ]);
1420 if (ret == 1)
1421 pm_chg_suspend(1);
1422 else
1423 dev_err(pm8058_chg.dev,
1424 "%s called when not fast-charging\n", __func__);
1425
1426 pm_chg_failed_clear(1);
1427
1428 pm8058_chg.waiting_for_veoc = 0;
1429 pm8058_chg.waiting_for_topoff = 0;
1430
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001431 if (pm8058_chg.voter)
1432 msm_xo_mode_vote(pm8058_chg.voter, MSM_XO_MODE_OFF);
1433
1434 return 0;
1435}
1436
1437static int get_status(void *data, u64 * val)
1438{
1439 *val = pm8058_chg.current_charger_current;
1440 return 0;
1441}
1442
1443static int set_status(void *data, u64 val)
1444{
1445
1446 pm8058_chg.current_charger_current = val;
1447 if (pm8058_chg.current_charger_current)
1448 pm8058_start_charging(NULL,
1449 AUTO_CHARGING_VMAXSEL,
1450 pm8058_chg.current_charger_current);
1451 else
1452 pm8058_stop_charging(NULL);
1453 return 0;
1454}
1455DEFINE_SIMPLE_ATTRIBUTE(chg_fops, get_status, set_status, "%llu\n");
1456
1457static int set_disable_status_param(const char *val, struct kernel_param *kp)
1458{
1459 int ret;
1460
1461 ret = param_set_int(val, kp);
1462 if (ret)
1463 return ret;
1464
1465 if (pm8058_chg.inited && pm8058_chg.disabled) {
1466 /*
1467 * stop_charging is called during usb suspend
1468 * act as the usb is removed by disabling auto and enum
1469 */
1470 pm_chg_enum_done_enable(0);
1471 pm_chg_auto_disable(1);
1472 pm8058_stop_charging(NULL);
1473 }
1474 return 0;
1475}
1476module_param_call(disabled, set_disable_status_param, param_get_uint,
1477 &(pm8058_chg.disabled), 0644);
1478
1479static int pm8058_charging_switched(struct msm_hardware_charger *hw_chg)
1480{
1481 u8 temp;
1482
1483 temp = 0xA3;
1484 pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
1485 temp = 0x84;
1486 pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
1487 msleep(2);
1488 temp = 0x80;
1489 pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
1490 return 0;
1491}
1492
1493static int get_reg(void *data, u64 * val)
1494{
1495 int i = (int)data;
1496 int ret;
1497 u8 temp;
1498
1499 ret = pm8058_read(pm8058_chg.pm_chip, i, &temp, 1);
1500 if (ret)
1501 return -EAGAIN;
1502 *val = temp;
1503 return 0;
1504}
1505
1506static int set_reg(void *data, u64 val)
1507{
1508 int i = (int)data;
1509 int ret;
1510 u8 temp;
1511
1512 temp = (u8) val;
1513 ret = pm8058_write(pm8058_chg.pm_chip, i, &temp, 1);
1514 mb();
1515 if (ret)
1516 return -EAGAIN;
1517 return 0;
1518}
1519
1520DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_reg, set_reg, "%llu\n");
1521
1522#ifdef CONFIG_DEBUG_FS
1523static void create_debugfs_entries(void)
1524{
1525 pm8058_chg.dent = debugfs_create_dir("pm8058_usb_chg", NULL);
1526
1527 if (IS_ERR(pm8058_chg.dent)) {
1528 pr_err("pmic charger couldnt create debugfs dir\n");
1529 return;
1530 }
1531
1532 debugfs_create_file("CHG_CNTRL", 0644, pm8058_chg.dent,
1533 (void *)PM8058_CHG_CNTRL, &reg_fops);
1534 debugfs_create_file("CHG_CNTRL_2", 0644, pm8058_chg.dent,
1535 (void *)PM8058_CHG_CNTRL_2, &reg_fops);
1536 debugfs_create_file("CHG_VMAX_SEL", 0644, pm8058_chg.dent,
1537 (void *)PM8058_CHG_VMAX_SEL, &reg_fops);
1538 debugfs_create_file("CHG_VBAT_DET", 0644, pm8058_chg.dent,
1539 (void *)PM8058_CHG_VBAT_DET, &reg_fops);
1540 debugfs_create_file("CHG_IMAX", 0644, pm8058_chg.dent,
1541 (void *)PM8058_CHG_IMAX, &reg_fops);
1542 debugfs_create_file("CHG_TRICKLE", 0644, pm8058_chg.dent,
1543 (void *)PM8058_CHG_TRICKLE, &reg_fops);
1544 debugfs_create_file("CHG_ITERM", 0644, pm8058_chg.dent,
1545 (void *)PM8058_CHG_ITERM, &reg_fops);
1546 debugfs_create_file("CHG_TTRKL_MAX", 0644, pm8058_chg.dent,
1547 (void *)PM8058_CHG_TTRKL_MAX, &reg_fops);
1548 debugfs_create_file("CHG_TCHG_MAX", 0644, pm8058_chg.dent,
1549 (void *)PM8058_CHG_TCHG_MAX, &reg_fops);
1550 debugfs_create_file("CHG_TEMP_THRESH", 0644, pm8058_chg.dent,
1551 (void *)PM8058_CHG_TEMP_THRESH, &reg_fops);
1552 debugfs_create_file("CHG_TEMP_REG", 0644, pm8058_chg.dent,
1553 (void *)PM8058_CHG_TEMP_REG, &reg_fops);
1554
1555 debugfs_create_file("FSM_STATE", 0644, pm8058_chg.dent, NULL,
1556 &fsm_fops);
1557
1558 debugfs_create_file("stop", 0644, pm8058_chg.dent, NULL,
1559 &chg_fops);
1560
1561 if (pm8058_chg.pmic_chg_irq[CHGVAL_IRQ])
1562 debugfs_create_file("CHGVAL", 0444, pm8058_chg.dent,
1563 (void *)pm8058_chg.pmic_chg_irq[CHGVAL_IRQ],
1564 &rt_fops);
1565
1566 if (pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ])
1567 debugfs_create_file("CHGINVAL", 0444, pm8058_chg.dent, (void *)
1568 pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ],
1569 &rt_fops);
1570 if (pm8058_chg.pmic_chg_irq[CHGILIM_IRQ])
1571 debugfs_create_file("CHGILIM", 0444, pm8058_chg.dent, (void *)
1572 pm8058_chg.pmic_chg_irq[CHGILIM_IRQ],
1573 &rt_fops);
1574 if (pm8058_chg.pmic_chg_irq[VCP_IRQ])
1575 debugfs_create_file("VCP", 0444, pm8058_chg.dent,
1576 (void *)pm8058_chg.pmic_chg_irq[VCP_IRQ],
1577 &rt_fops);
1578 if (pm8058_chg.pmic_chg_irq[ATC_DONE_IRQ])
1579 debugfs_create_file("ATC_DONE", 0444, pm8058_chg.dent, (void *)
1580 pm8058_chg.pmic_chg_irq[ATC_DONE_IRQ],
1581 &rt_fops);
1582 if (pm8058_chg.pmic_chg_irq[ATCFAIL_IRQ])
1583 debugfs_create_file("ATCFAIL", 0444, pm8058_chg.dent, (void *)
1584 pm8058_chg.pmic_chg_irq[ATCFAIL_IRQ],
1585 &rt_fops);
1586 if (pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ])
1587 debugfs_create_file("AUTO_CHGDONE", 0444, pm8058_chg.dent,
1588 (void *)
1589 pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ],
1590 &rt_fops);
1591 if (pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ])
1592 debugfs_create_file("AUTO_CHGFAIL", 0444, pm8058_chg.dent,
1593 (void *)
1594 pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ],
1595 &rt_fops);
1596 if (pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ])
1597 debugfs_create_file("CHGSTATE", 0444, pm8058_chg.dent, (void *)
1598 pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ],
1599 &rt_fops);
1600 if (pm8058_chg.pmic_chg_irq[FASTCHG_IRQ])
1601 debugfs_create_file("FASTCHG", 0444, pm8058_chg.dent, (void *)
1602 pm8058_chg.pmic_chg_irq[FASTCHG_IRQ],
1603 &rt_fops);
1604 if (pm8058_chg.pmic_chg_irq[CHG_END_IRQ])
1605 debugfs_create_file("CHG_END", 0444, pm8058_chg.dent, (void *)
1606 pm8058_chg.pmic_chg_irq[CHG_END_IRQ],
1607 &rt_fops);
1608 if (pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ])
1609 debugfs_create_file("BATTTEMP", 0444, pm8058_chg.dent, (void *)
1610 pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ],
1611 &rt_fops);
1612 if (pm8058_chg.pmic_chg_irq[CHGHOT_IRQ])
1613 debugfs_create_file("CHGHOT", 0444, pm8058_chg.dent,
1614 (void *)pm8058_chg.pmic_chg_irq[CHGHOT_IRQ],
1615 &rt_fops);
1616 if (pm8058_chg.pmic_chg_irq[CHGTLIMIT_IRQ])
1617 debugfs_create_file("CHGTLIMIT", 0444, pm8058_chg.dent, (void *)
1618 pm8058_chg.pmic_chg_irq[CHGTLIMIT_IRQ],
1619 &rt_fops);
1620 if (pm8058_chg.pmic_chg_irq[CHG_GONE_IRQ])
1621 debugfs_create_file("CHG_GONE", 0444, pm8058_chg.dent, (void *)
1622 pm8058_chg.pmic_chg_irq[CHG_GONE_IRQ],
1623 &rt_fops);
1624 if (pm8058_chg.pmic_chg_irq[VCPMAJOR_IRQ])
1625 debugfs_create_file("VCPMAJOR", 0444, pm8058_chg.dent, (void *)
1626 pm8058_chg.pmic_chg_irq[VCPMAJOR_IRQ],
1627 &rt_fops);
1628 if (pm8058_chg.pmic_chg_irq[BATFET_IRQ])
1629 debugfs_create_file("BATFET", 0444, pm8058_chg.dent,
1630 (void *)pm8058_chg.pmic_chg_irq[BATFET_IRQ],
1631 &rt_fops);
1632 if (pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ])
1633 debugfs_create_file("BATT_REPLACE", 0444, pm8058_chg.dent,
1634 (void *)
1635 pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ],
1636 &rt_fops);
1637 if (pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ])
1638 debugfs_create_file("BATTCONNECT", 0444, pm8058_chg.dent,
1639 (void *)
1640 pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ],
1641 &rt_fops);
1642 if (pm8058_chg.pmic_chg_irq[VBATDET_IRQ])
1643 debugfs_create_file("VBATDET", 0444, pm8058_chg.dent, (void *)
1644 pm8058_chg.pmic_chg_irq[VBATDET_IRQ],
1645 &rt_fops);
1646 if (pm8058_chg.pmic_chg_irq[VBATDET_LOW_IRQ])
1647 debugfs_create_file("VBATDET_LOW", 0444, pm8058_chg.dent,
1648 (void *)
1649 pm8058_chg.pmic_chg_irq[VBATDET_LOW_IRQ],
1650 &rt_fops);
1651 debugfs_create_file("CHARGE_BATT", 0444, pm8058_chg.dent,
1652 NULL,
1653 &fet_fops);
1654}
1655#else
1656static inline void create_debugfs_entries(void)
1657{
1658}
1659#endif
1660
1661static void remove_debugfs_entries(void)
1662{
1663 debugfs_remove_recursive(pm8058_chg.dent);
1664}
1665
1666static struct msm_hardware_charger usb_hw_chg = {
Abhijeet Dharmapurikar0758e1e2011-07-14 18:11:41 -07001667 .type = CHG_TYPE_USB,
1668 .rating = 1,
1669 .name = "pm8058-usb",
1670 .start_charging = pm8058_start_charging,
1671 .stop_charging = pm8058_stop_charging,
1672 .charging_switched = pm8058_charging_switched,
1673 .start_system_current = pm8058_start_system_current,
1674 .stop_system_current = pm8058_stop_system_current,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001675};
1676
1677static int batt_read_adc(int channel, int *mv_reading)
1678{
1679 int ret;
1680 void *h;
1681 struct adc_chan_result adc_chan_result;
1682 struct completion conv_complete_evt;
1683
1684 pr_debug("%s: called for %d\n", __func__, channel);
1685 ret = adc_channel_open(channel, &h);
1686 if (ret) {
1687 pr_err("%s: couldnt open channel %d ret=%d\n",
1688 __func__, channel, ret);
1689 goto out;
1690 }
1691 init_completion(&conv_complete_evt);
1692 ret = adc_channel_request_conv(h, &conv_complete_evt);
1693 if (ret) {
1694 pr_err("%s: couldnt request conv channel %d ret=%d\n",
1695 __func__, channel, ret);
1696 goto out;
1697 }
1698 wait_for_completion(&conv_complete_evt);
1699 ret = adc_channel_read_result(h, &adc_chan_result);
1700 if (ret) {
1701 pr_err("%s: couldnt read result channel %d ret=%d\n",
1702 __func__, channel, ret);
1703 goto out;
1704 }
1705 ret = adc_channel_close(h);
1706 if (ret) {
1707 pr_err("%s: couldnt close channel %d ret=%d\n",
1708 __func__, channel, ret);
1709 }
1710 if (mv_reading)
1711 *mv_reading = adc_chan_result.measurement;
1712
1713 pr_debug("%s: done for %d\n", __func__, channel);
1714 return adc_chan_result.physical;
1715out:
1716 pr_debug("%s: done for %d\n", __func__, channel);
1717 return -EINVAL;
1718
1719}
1720
1721#define BATT_THERM_OPEN_MV 2000
1722static int pm8058_is_battery_present(void)
1723{
1724 int mv_reading;
1725
1726 mv_reading = 0;
1727 batt_read_adc(CHANNEL_ADC_BATT_THERM, &mv_reading);
1728 pr_debug("%s: therm_raw is %d\n", __func__, mv_reading);
1729 if (mv_reading > 0 && mv_reading < BATT_THERM_OPEN_MV)
1730 return 1;
1731
1732 return 0;
1733}
1734
1735static int pm8058_get_battery_temperature(void)
1736{
1737 return batt_read_adc(CHANNEL_ADC_BATT_THERM, NULL);
1738}
1739
1740#define BATT_THERM_OPERATIONAL_MAX_CELCIUS 40
1741#define BATT_THERM_OPERATIONAL_MIN_CELCIUS 0
1742static int pm8058_is_battery_temp_within_range(void)
1743{
1744 int therm_celcius;
1745
1746 therm_celcius = pm8058_get_battery_temperature();
1747 pr_debug("%s: therm_celcius is %d\n", __func__, therm_celcius);
1748 if (therm_celcius > 0
1749 && therm_celcius > BATT_THERM_OPERATIONAL_MIN_CELCIUS
1750 && therm_celcius < BATT_THERM_OPERATIONAL_MAX_CELCIUS)
1751 return 1;
1752
1753 return 0;
1754}
1755
1756#define BATT_ID_MAX_MV 800
1757#define BATT_ID_MIN_MV 600
1758static int pm8058_is_battery_id_valid(void)
1759{
1760 int batt_id_mv;
1761
1762 batt_id_mv = batt_read_adc(CHANNEL_ADC_BATT_ID, NULL);
1763 pr_debug("%s: batt_id_mv is %d\n", __func__, batt_id_mv);
1764
1765 /*
1766 * The readings are not in range
1767 * assume battery is present for now
1768 */
1769 return 1;
1770
1771 if (batt_id_mv > 0
1772 && batt_id_mv > BATT_ID_MIN_MV
1773 && batt_id_mv < BATT_ID_MAX_MV)
1774 return 1;
1775
1776 return 0;
1777}
1778
1779/* returns voltage in mV */
1780static int pm8058_get_battery_mvolts(void)
1781{
1782 int vbatt_mv;
1783
1784 vbatt_mv = batt_read_adc(CHANNEL_ADC_VBATT, NULL);
1785 pr_debug("%s: vbatt_mv is %d\n", __func__, vbatt_mv);
1786 if (vbatt_mv > 0)
1787 return vbatt_mv;
1788 /*
1789 * return 0 to tell the upper layers
1790 * we couldnt read the battery voltage
1791 */
1792 return 0;
1793}
1794
1795static int msm_battery_gauge_alarm_notify(struct notifier_block *nb,
1796 unsigned long status, void *unused)
1797{
1798 int rc;
1799
1800 pr_info("%s: status: %lu\n", __func__, status);
1801
1802 switch (status) {
1803 case 0:
1804 dev_err(pm8058_chg.dev,
1805 "%s: spurious interrupt\n", __func__);
1806 break;
1807 /* expected case - trip of low threshold */
1808 case 1:
1809 rc = pm8058_batt_alarm_state_set(0, 0);
1810 if (rc)
1811 dev_err(pm8058_chg.dev,
1812 "%s: unable to set alarm state\n", __func__);
1813 msm_charger_notify_event(NULL, CHG_BATT_NEEDS_RECHARGING);
1814 break;
1815 case 2:
1816 dev_err(pm8058_chg.dev,
1817 "%s: trip of high threshold\n", __func__);
1818 break;
1819 default:
1820 dev_err(pm8058_chg.dev,
1821 "%s: error received\n", __func__);
1822 };
1823
1824 return 0;
1825}
1826
1827static int pm8058_monitor_for_recharging(void)
1828{
1829 /* enable low comparator */
1830 return pm8058_batt_alarm_state_set(1, 0);
1831}
1832
1833static struct msm_battery_gauge pm8058_batt_gauge = {
1834 .get_battery_mvolts = pm8058_get_battery_mvolts,
1835 .get_battery_temperature = pm8058_get_battery_temperature,
1836 .is_battery_present = pm8058_is_battery_present,
1837 .is_battery_temp_within_range = pm8058_is_battery_temp_within_range,
1838 .is_battery_id_valid = pm8058_is_battery_id_valid,
1839 .monitor_for_recharging = pm8058_monitor_for_recharging,
1840};
1841
1842static int pm8058_usb_voltage_lower_limit(void)
1843{
1844 u8 temp, old;
1845 int ret = 0;
1846
1847 temp = 0x10;
1848 ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
1849 ret |= pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST, &old, 1);
1850 old = old & ~BIT(IGNORE_LL);
1851 temp = 0x90 | (0xF & old);
1852 ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
1853
1854 return ret;
1855}
1856
1857static int __devinit pm8058_charger_probe(struct platform_device *pdev)
1858{
1859 struct pm8058_chip *pm_chip;
1860 int rc = 0;
1861
1862 pm_chip = dev_get_drvdata(pdev->dev.parent);
1863 if (pm_chip == NULL) {
1864 pr_err("%s:no parent data passed in.\n", __func__);
1865 return -EFAULT;
1866 }
1867
1868 pm8058_chg.pm_chip = pm_chip;
1869 pm8058_chg.pdata = pdev->dev.platform_data;
1870 pm8058_chg.dev = &pdev->dev;
1871
1872 rc = request_irqs(pdev);
1873 if (rc) {
1874 pr_err("%s: couldnt register interrupts\n", __func__);
1875 goto out;
1876 }
1877
1878 rc = pm8058_usb_voltage_lower_limit();
1879 if (rc) {
1880 pr_err("%s: couldnt set ignore lower limit bit to 0\n",
1881 __func__);
1882 goto free_irq;
1883 }
1884
1885 rc = msm_charger_register(&usb_hw_chg);
1886 if (rc) {
1887 pr_err("%s: msm_charger_register failed ret=%d\n",
1888 __func__, rc);
1889 goto free_irq;
1890 }
1891
1892 pm_chg_batt_temp_disable(0);
1893 msm_battery_gauge_register(&pm8058_batt_gauge);
1894 __dump_chg_regs();
1895
1896 create_debugfs_entries();
1897 INIT_DELAYED_WORK(&pm8058_chg.veoc_begin_work, veoc_begin_work);
1898 INIT_DELAYED_WORK(&pm8058_chg.check_vbat_low_work, vbat_low_work);
1899 INIT_DELAYED_WORK(&pm8058_chg.chg_done_check_work, chg_done_check_work);
1900 INIT_DELAYED_WORK(&pm8058_chg.charging_check_work, charging_check_work);
1901
1902 /* determine what state the charger is in */
1903 pm8058_chg_determine_initial_state();
1904
1905 pm8058_chg_enable_irq(BATTTEMP_IRQ);
1906 pm8058_chg_enable_irq(BATTCONNECT_IRQ);
1907
1908 rc = pm8058_batt_alarm_state_set(0, 0);
1909 if (rc) {
1910 pr_err("%s: unable to set batt alarm state\n", __func__);
1911 goto free_irq;
1912 }
1913
1914 /*
1915 * The batt-alarm driver requires sane values for both min / max,
1916 * regardless of whether they're both activated.
1917 */
1918 rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
1919 if (rc) {
1920 pr_err("%s: unable to set batt alarm threshold\n", __func__);
1921 goto free_irq;
1922 }
1923
1924 rc = pm8058_batt_alarm_hold_time_set(PM8058_BATT_ALARM_HOLD_TIME_16_MS);
1925 if (rc) {
1926 pr_err("%s: unable to set batt alarm hold time\n", __func__);
1927 goto free_irq;
1928 }
1929
1930 /* PWM enabled at 2Hz */
1931 rc = pm8058_batt_alarm_pwm_rate_set(1, 7, 4);
1932 if (rc) {
1933 pr_err("%s: unable to set batt alarm pwm rate\n", __func__);
1934 goto free_irq;
1935 }
1936
1937 rc = pm8058_batt_alarm_register_notifier(&alarm_notifier);
1938 if (rc) {
1939 pr_err("%s: unable to register alarm notifier\n", __func__);
1940 goto free_irq;
1941 }
1942
1943 pm8058_chg.inited = 1;
1944
1945 return 0;
1946
1947free_irq:
1948 free_irqs();
1949out:
1950 return rc;
1951}
1952
1953static int __devexit pm8058_charger_remove(struct platform_device *pdev)
1954{
1955 struct pm8058_charger_chip *chip = platform_get_drvdata(pdev);
1956 int rc;
1957
1958 msm_charger_notify_event(&usb_hw_chg, CHG_REMOVED_EVENT);
1959 msm_charger_unregister(&usb_hw_chg);
1960 cancel_delayed_work_sync(&pm8058_chg.veoc_begin_work);
1961 cancel_delayed_work_sync(&pm8058_chg.check_vbat_low_work);
1962 cancel_delayed_work_sync(&pm8058_chg.charging_check_work);
1963 free_irqs();
1964 remove_debugfs_entries();
1965 kfree(chip);
1966
1967 rc = pm8058_batt_alarm_state_set(0, 0);
1968 if (rc)
1969 pr_err("%s: unable to set batt alarm state\n", __func__);
1970
1971 rc |= pm8058_batt_alarm_unregister_notifier(&alarm_notifier);
1972 if (rc)
1973 pr_err("%s: unable to register alarm notifier\n", __func__);
1974 return rc;
1975}
1976
1977static struct platform_driver pm8058_charger_driver = {
1978 .probe = pm8058_charger_probe,
1979 .remove = __devexit_p(pm8058_charger_remove),
1980 .driver = {
1981 .name = "pm8058-charger",
1982 .owner = THIS_MODULE,
1983 },
1984};
1985
1986static int __init pm8058_charger_init(void)
1987{
1988 return platform_driver_register(&pm8058_charger_driver);
1989}
1990
1991static void __exit pm8058_charger_exit(void)
1992{
1993 platform_driver_unregister(&pm8058_charger_driver);
1994}
1995
1996late_initcall(pm8058_charger_init);
1997module_exit(pm8058_charger_exit);
1998
1999MODULE_LICENSE("GPL v2");
2000MODULE_DESCRIPTION("PMIC8058 BATTERY driver");
2001MODULE_VERSION("1.0");
2002MODULE_ALIAS("platform:pm8058_charger");