blob: 993b2cbf81b7ff4a7b3d9494816ed8f86c3aab2e [file] [log] [blame]
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
David Keitel80668952012-07-27 14:25:49 -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 */
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/module.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include <linux/spmi.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/radix-tree.h>
22#include <linux/interrupt.h>
David Keiteld681cda2012-10-02 15:44:21 -070023#include <linux/delay.h>
David Keitel80668952012-07-27 14:25:49 -070024#include <linux/qpnp/qpnp-adc.h>
25#include <linux/power_supply.h>
26#include <linux/bitops.h>
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -070027#include <linux/ratelimit.h>
David Keitel80668952012-07-27 14:25:49 -070028
29/* Interrupt offsets */
30#define INT_RT_STS(base) (base + 0x10)
31#define INT_SET_TYPE(base) (base + 0x11)
32#define INT_POLARITY_HIGH(base) (base + 0x12)
33#define INT_POLARITY_LOW(base) (base + 0x13)
34#define INT_LATCHED_CLR(base) (base + 0x14)
35#define INT_EN_SET(base) (base + 0x15)
36#define INT_EN_CLR(base) (base + 0x16)
37#define INT_LATCHED_STS(base) (base + 0x18)
38#define INT_PENDING_STS(base) (base + 0x19)
39#define INT_MID_SEL(base) (base + 0x1A)
40#define INT_PRIORITY(base) (base + 0x1B)
41
42/* Peripheral register offsets */
43#define CHGR_CHG_OPTION 0x08
44#define CHGR_ATC_STATUS 0x0A
45#define CHGR_VBAT_STATUS 0x0B
46#define CHGR_IBAT_BMS 0x0C
47#define CHGR_IBAT_STS 0x0D
48#define CHGR_VDD_MAX 0x40
49#define CHGR_VDD_SAFE 0x41
50#define CHGR_VDD_MAX_STEP 0x42
51#define CHGR_IBAT_MAX 0x44
52#define CHGR_IBAT_SAFE 0x45
53#define CHGR_VIN_MIN 0x47
54#define CHGR_VIN_MIN_STEP 0x48
55#define CHGR_CHG_CTRL 0x49
56#define CHGR_CHG_FAILED 0x4A
57#define CHGR_ATC_CTRL 0x4B
58#define CHGR_ATC_FAILED 0x4C
59#define CHGR_VBAT_TRKL 0x50
60#define CHGR_VBAT_WEAK 0x52
61#define CHGR_IBAT_ATC_A 0x54
62#define CHGR_IBAT_ATC_B 0x55
63#define CHGR_IBAT_TERM_CHGR 0x5B
64#define CHGR_IBAT_TERM_BMS 0x5C
65#define CHGR_VBAT_DET 0x5D
66#define CHGR_TTRKL_MAX 0x5F
67#define CHGR_TTRKL_MAX_EN 0x60
68#define CHGR_TCHG_MAX 0x61
69#define CHGR_CHG_WDOG_TIME 0x62
70#define CHGR_CHG_WDOG_DLY 0x63
71#define CHGR_CHG_WDOG_PET 0x64
72#define CHGR_CHG_WDOG_EN 0x65
David Keitel9201df32013-01-10 18:38:34 -080073#define CHGR_IR_DROP_COMPEN 0x67
David Keitel22ed2232013-01-28 11:04:07 -080074#define CHGR_I_MAX_REG 0x44
David Keiteld681cda2012-10-02 15:44:21 -070075#define CHGR_USB_USB_SUSP 0x47
David Keitel6f865cd2012-11-30 15:04:32 -080076#define CHGR_USB_USB_OTG_CTL 0x48
David Keitel80668952012-07-27 14:25:49 -070077#define CHGR_USB_ENUM_T_STOP 0x4E
78#define CHGR_CHG_TEMP_THRESH 0x66
79#define CHGR_BAT_IF_PRES_STATUS 0x08
David Keiteld681cda2012-10-02 15:44:21 -070080#define CHGR_STATUS 0x09
David Keitel80668952012-07-27 14:25:49 -070081#define CHGR_BAT_IF_VCP 0x42
82#define CHGR_BAT_IF_BATFET_CTRL1 0x90
83#define CHGR_MISC_BOOT_DONE 0x42
David Keiteld681cda2012-10-02 15:44:21 -070084#define CHGR_BUCK_COMPARATOR_OVRIDE_3 0xED
David Keitel9201df32013-01-10 18:38:34 -080085#define CHGR_BUCK_BCK_VBAT_REG_MODE 0x74
Sridhar Parasuramae183bd2012-12-21 09:28:46 -080086#define MISC_REVISION2 0x01
David Keitel5c3a7702012-12-20 11:13:21 -080087#define USB_OVP_CTL 0x42
David Keitel344c6972013-04-09 19:28:21 -070088#define USB_CHG_GONE_REV_BST 0xED
89#define BUCK_VCHG_OV 0x77
90#define BUCK_TEST_SMBC_MODES 0xE6
David Keiteld681cda2012-10-02 15:44:21 -070091#define SEC_ACCESS 0xD0
David Keitel85ae4342013-04-16 11:46:00 -070092#define BAT_IF_VREF_BAT_THM_CTRL 0x4A
David Keitel80668952012-07-27 14:25:49 -070093
David Keitel80668952012-07-27 14:25:49 -070094#define REG_OFFSET_PERP_SUBTYPE 0x05
David Keitelf2170cc2013-02-20 17:49:03 -080095/* SMBB peripheral subtype values */
David Keitel80668952012-07-27 14:25:49 -070096#define SMBB_CHGR_SUBTYPE 0x01
97#define SMBB_BUCK_SUBTYPE 0x02
98#define SMBB_BAT_IF_SUBTYPE 0x03
99#define SMBB_USB_CHGPTH_SUBTYPE 0x04
100#define SMBB_DC_CHGPTH_SUBTYPE 0x05
101#define SMBB_BOOST_SUBTYPE 0x06
102#define SMBB_MISC_SUBTYPE 0x07
103
David Keitelf2170cc2013-02-20 17:49:03 -0800104/* SMBB peripheral subtype values */
105#define SMBBP_CHGR_SUBTYPE 0x31
106#define SMBBP_BUCK_SUBTYPE 0x32
107#define SMBBP_BAT_IF_SUBTYPE 0x33
108#define SMBBP_USB_CHGPTH_SUBTYPE 0x34
109#define SMBBP_BOOST_SUBTYPE 0x36
110#define SMBBP_MISC_SUBTYPE 0x37
111
David Keitel46c9f7b2013-04-02 19:54:12 -0700112/* SMBCL peripheral subtype values */
113#define SMBCL_CHGR_SUBTYPE 0x41
114#define SMBCL_BUCK_SUBTYPE 0x42
115#define SMBCL_BAT_IF_SUBTYPE 0x43
116#define SMBCL_USB_CHGPTH_SUBTYPE 0x44
117#define SMBCL_MISC_SUBTYPE 0x47
118
David Keitel80668952012-07-27 14:25:49 -0700119#define QPNP_CHARGER_DEV_NAME "qcom,qpnp-charger"
120
David Keitelb80eda82012-10-15 10:49:11 -0700121/* Status bits and masks */
122#define CHGR_BOOT_DONE BIT(7)
123#define CHGR_CHG_EN BIT(7)
124#define CHGR_ON_BAT_FORCE_BIT BIT(0)
David Keitel5c3a7702012-12-20 11:13:21 -0800125#define USB_VALID_DEB_20MS 0x03
David Keitel9201df32013-01-10 18:38:34 -0800126#define BUCK_VBAT_REG_NODE_SEL_BIT BIT(0)
David Keitel85ae4342013-04-16 11:46:00 -0700127#define VREF_BATT_THERM_FORCE_ON 0xC0
128#define VREF_BAT_THM_ENABLED_FSM 0x80
David Keitelb80eda82012-10-15 10:49:11 -0700129
David Keitel80668952012-07-27 14:25:49 -0700130/* Interrupt definitions */
131/* smbb_chg_interrupts */
132#define CHG_DONE_IRQ BIT(7)
133#define CHG_FAILED_IRQ BIT(6)
134#define FAST_CHG_ON_IRQ BIT(5)
135#define TRKL_CHG_ON_IRQ BIT(4)
136#define STATE_CHANGE_ON_IR BIT(3)
137#define CHGWDDOG_IRQ BIT(2)
138#define VBAT_DET_HI_IRQ BIT(1)
139#define VBAT_DET_LOW_IRQ BIT(0)
140
141/* smbb_buck_interrupts */
142#define VDD_LOOP_IRQ BIT(6)
143#define IBAT_LOOP_IRQ BIT(5)
144#define ICHG_LOOP_IRQ BIT(4)
145#define VCHG_LOOP_IRQ BIT(3)
146#define OVERTEMP_IRQ BIT(2)
147#define VREF_OV_IRQ BIT(1)
148#define VBAT_OV_IRQ BIT(0)
149
150/* smbb_bat_if_interrupts */
151#define PSI_IRQ BIT(4)
152#define VCP_ON_IRQ BIT(3)
153#define BAT_FET_ON_IRQ BIT(2)
154#define BAT_TEMP_OK_IRQ BIT(1)
155#define BATT_PRES_IRQ BIT(0)
156
157/* smbb_usb_interrupts */
158#define CHG_GONE_IRQ BIT(2)
159#define USBIN_VALID_IRQ BIT(1)
160#define COARSE_DET_USB_IRQ BIT(0)
161
162/* smbb_dc_interrupts */
163#define DCIN_VALID_IRQ BIT(1)
164#define COARSE_DET_DC_IRQ BIT(0)
165
166/* smbb_boost_interrupts */
167#define LIMIT_ERROR_IRQ BIT(1)
168#define BOOST_PWR_OK_IRQ BIT(0)
169
170/* smbb_misc_interrupts */
171#define TFTWDOG_IRQ BIT(0)
172
David Keitelfe51cb92013-04-02 19:42:58 -0700173/* SMBB types */
174#define SMBB BIT(1)
175#define SMBBP BIT(2)
176#define SMBCL BIT(3)
177
David Keiteld681cda2012-10-02 15:44:21 -0700178/* Workaround flags */
179#define CHG_FLAGS_VCP_WA BIT(0)
180
David Keitel80668952012-07-27 14:25:49 -0700181/**
182 * struct qpnp_chg_chip - device information
183 * @dev: device pointer to access the parent
184 * @spmi: spmi pointer to access spmi information
185 * @chgr_base: charger peripheral base address
186 * @buck_base: buck peripheral base address
187 * @bat_if_base: battery interface peripheral base address
188 * @usb_chgpth_base: USB charge path peripheral base address
189 * @dc_chgpth_base: DC charge path peripheral base address
190 * @boost_base: boost peripheral base address
191 * @misc_base: misc peripheral base address
192 * @freq_base: freq peripheral base address
David Keitel454ee842013-03-08 16:19:11 -0800193 * @bat_is_cool: indicates that battery is cool
194 * @bat_is_warm: indicates that battery is warm
David Keitel80668952012-07-27 14:25:49 -0700195 * @chg_done: indicates that charging is completed
196 * @usb_present: present status of usb
197 * @dc_present: present status of dc
David Keitel42ae0aa2013-03-08 16:20:10 -0800198 * @batt_present: present status of battery
David Keitel3dd5e0f2012-12-12 18:12:36 -0800199 * @use_default_batt_values: flag to report default battery properties
David Keitel80668952012-07-27 14:25:49 -0700200 * @max_voltage_mv: the max volts the batt should be charged up to
David Keitel5d44fa52012-12-03 16:37:31 -0800201 * @min_voltage_mv: min battery voltage before turning the FET on
David Keitel454ee842013-03-08 16:19:11 -0800202 * @max_bat_chg_current: maximum battery charge current in mA
203 * @warm_bat_chg_ma: warm battery maximum charge current in mA
204 * @cool_bat_chg_ma: cool battery maximum charge current in mA
205 * @warm_bat_mv: warm temperature battery target voltage
206 * @cool_bat_mv: cool temperature battery target voltage
207 * @resume_delta_mv: voltage delta at which battery resumes charging
David Keitel80668952012-07-27 14:25:49 -0700208 * @term_current: the charging based term current
David Keitel5d44fa52012-12-03 16:37:31 -0800209 * @safe_current: battery safety current setting
David Keitel22ed2232013-01-28 11:04:07 -0800210 * @maxinput_usb_ma: Maximum Input current USB
211 * @maxinput_dc_ma: Maximum Input current DC
David Keitel0c1a4532013-03-21 16:39:06 -0700212 * @warm_bat_decidegc Warm battery temperature in degree Celsius
213 * @cool_bat_decidegc Cool battery temperature in degree Celsius
David Keitel80668952012-07-27 14:25:49 -0700214 * @revision: PMIC revision
David Keitelfe51cb92013-04-02 19:42:58 -0700215 * @type: SMBB type
216 * @tchg_mins maximum allowed software initiated charge time
David Keitelbe208252013-01-31 14:49:25 -0800217 * @thermal_levels amount of thermal mitigation levels
218 * @thermal_mitigation thermal mitigation level values
219 * @therm_lvl_sel thermal mitigation level selection
David Keitel80668952012-07-27 14:25:49 -0700220 * @dc_psy power supply to export information to userspace
221 * @usb_psy power supply to export information to userspace
222 * @bms_psy power supply to export information to userspace
223 * @batt_psy: power supply to export information to userspace
David Keiteld681cda2012-10-02 15:44:21 -0700224 * @flags: flags to activate specific workarounds
225 * throughout the driver
David Keitel80668952012-07-27 14:25:49 -0700226 *
227 */
228struct qpnp_chg_chip {
229 struct device *dev;
230 struct spmi_device *spmi;
231 u16 chgr_base;
232 u16 buck_base;
233 u16 bat_if_base;
234 u16 usb_chgpth_base;
235 u16 dc_chgpth_base;
236 u16 boost_base;
237 u16 misc_base;
238 u16 freq_base;
239 unsigned int usbin_valid_irq;
David Keitel7450dcd2013-01-29 18:41:41 -0800240 unsigned int dcin_valid_irq;
David Keitel344c6972013-04-09 19:28:21 -0700241 unsigned int chg_gone_irq;
David Keitel42ae0aa2013-03-08 16:20:10 -0800242 unsigned int chg_fastchg_irq;
243 unsigned int chg_trklchg_irq;
David Keitel80668952012-07-27 14:25:49 -0700244 unsigned int chg_failed_irq;
David Keitel454ee842013-03-08 16:19:11 -0800245 unsigned int batt_pres_irq;
246 bool bat_is_cool;
247 bool bat_is_warm;
David Keitel80668952012-07-27 14:25:49 -0700248 bool chg_done;
249 bool usb_present;
250 bool dc_present;
David Keitel42ae0aa2013-03-08 16:20:10 -0800251 bool batt_present;
David Keitel03ee6b52012-10-22 12:25:19 -0700252 bool charging_disabled;
David Keitel3dd5e0f2012-12-12 18:12:36 -0800253 bool use_default_batt_values;
David Keitel80668952012-07-27 14:25:49 -0700254 unsigned int max_bat_chg_current;
David Keitel454ee842013-03-08 16:19:11 -0800255 unsigned int warm_bat_chg_ma;
256 unsigned int cool_bat_chg_ma;
David Keitel80668952012-07-27 14:25:49 -0700257 unsigned int safe_voltage_mv;
258 unsigned int max_voltage_mv;
259 unsigned int min_voltage_mv;
David Keitel454ee842013-03-08 16:19:11 -0800260 unsigned int warm_bat_mv;
261 unsigned int cool_bat_mv;
262 unsigned int resume_delta_mv;
David Keitel80668952012-07-27 14:25:49 -0700263 unsigned int term_current;
David Keitel22ed2232013-01-28 11:04:07 -0800264 unsigned int maxinput_usb_ma;
265 unsigned int maxinput_dc_ma;
David Keitel0c1a4532013-03-21 16:39:06 -0700266 unsigned int warm_bat_decidegc;
267 unsigned int cool_bat_decidegc;
David Keitel5d44fa52012-12-03 16:37:31 -0800268 unsigned int safe_current;
David Keitel80668952012-07-27 14:25:49 -0700269 unsigned int revision;
David Keitelfe51cb92013-04-02 19:42:58 -0700270 unsigned int type;
271 unsigned int tchg_mins;
David Keitelbe208252013-01-31 14:49:25 -0800272 unsigned int thermal_levels;
273 unsigned int therm_lvl_sel;
274 unsigned int *thermal_mitigation;
David Keitel80668952012-07-27 14:25:49 -0700275 struct power_supply dc_psy;
276 struct power_supply *usb_psy;
277 struct power_supply *bms_psy;
278 struct power_supply batt_psy;
David Keiteld681cda2012-10-02 15:44:21 -0700279 uint32_t flags;
David Keitel454ee842013-03-08 16:19:11 -0800280 struct qpnp_adc_tm_btm_param adc_param;
David Keitel79f4c932013-04-03 16:08:39 -0700281 struct work_struct adc_measure_work;
David Keitel344c6972013-04-09 19:28:21 -0700282 struct delayed_work arb_stop_work;
David Keitel80668952012-07-27 14:25:49 -0700283};
284
David Keitel80668952012-07-27 14:25:49 -0700285static struct of_device_id qpnp_charger_match_table[] = {
286 { .compatible = QPNP_CHARGER_DEV_NAME, },
287 {}
288};
289
290static int
291qpnp_chg_read(struct qpnp_chg_chip *chip, u8 *val,
292 u16 base, int count)
293{
294 int rc;
295 struct spmi_device *spmi = chip->spmi;
296
297 rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val,
298 count);
299 if (rc) {
300 pr_err("SPMI read failed base=0x%02x sid=0x%02x rc=%d\n", base,
301 spmi->sid, rc);
302 return rc;
303 }
304 return 0;
305}
306
307static int
308qpnp_chg_write(struct qpnp_chg_chip *chip, u8 *val,
309 u16 base, int count)
310{
311 int rc;
312 struct spmi_device *spmi = chip->spmi;
313
314 rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val,
315 count);
316 if (rc) {
317 pr_err("write failed base=0x%02x sid=0x%02x rc=%d\n",
318 base, spmi->sid, rc);
319 return rc;
320 }
321
322 return 0;
323}
324
325static int
326qpnp_chg_masked_write(struct qpnp_chg_chip *chip, u16 base,
327 u8 mask, u8 val, int count)
328{
329 int rc;
330 u8 reg;
331
332 rc = qpnp_chg_read(chip, &reg, base, count);
333 if (rc) {
334 pr_err("spmi read failed: addr=%03X, rc=%d\n", base, rc);
335 return rc;
336 }
337 pr_debug("addr = 0x%x read 0x%x\n", base, reg);
338
339 reg &= ~mask;
340 reg |= val & mask;
341
342 pr_debug("Writing 0x%x\n", reg);
343
344 rc = qpnp_chg_write(chip, &reg, base, count);
345 if (rc) {
346 pr_err("spmi write failed: addr=%03X, rc=%d\n", base, rc);
347 return rc;
348 }
349
350 return 0;
351}
352
David Keitel6f865cd2012-11-30 15:04:32 -0800353#define USB_OTG_EN_BIT BIT(0)
354static int
355qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
356{
357 u8 usb_otg_en;
358 int rc;
359
360 rc = qpnp_chg_read(chip, &usb_otg_en,
361 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
362 1);
363
364 if (rc) {
365 pr_err("spmi read failed: addr=%03X, rc=%d\n",
366 chip->usb_chgpth_base + CHGR_STATUS, rc);
367 return rc;
368 }
369 pr_debug("usb otg en 0x%x\n", usb_otg_en);
370
371 return (usb_otg_en & USB_OTG_EN_BIT) ? 1 : 0;
372}
373
David Keitel42ae0aa2013-03-08 16:20:10 -0800374static int
375qpnp_chg_is_batt_present(struct qpnp_chg_chip *chip)
376{
377 u8 batt_pres_rt_sts;
378 int rc;
379
380 rc = qpnp_chg_read(chip, &batt_pres_rt_sts,
381 INT_RT_STS(chip->bat_if_base), 1);
382 if (rc) {
383 pr_err("spmi read failed: addr=%03X, rc=%d\n",
384 INT_RT_STS(chip->bat_if_base), rc);
385 return rc;
386 }
387
388 return (batt_pres_rt_sts & BATT_PRES_IRQ) ? 1 : 0;
389}
390
David Keiteld681cda2012-10-02 15:44:21 -0700391#define USB_VALID_BIT BIT(7)
David Keitel80668952012-07-27 14:25:49 -0700392static int
393qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip)
394{
395 u8 usbin_valid_rt_sts;
396 int rc;
397
398 rc = qpnp_chg_read(chip, &usbin_valid_rt_sts,
David Keiteld681cda2012-10-02 15:44:21 -0700399 chip->usb_chgpth_base + CHGR_STATUS , 1);
David Keitel80668952012-07-27 14:25:49 -0700400
401 if (rc) {
402 pr_err("spmi read failed: addr=%03X, rc=%d\n",
David Keiteld681cda2012-10-02 15:44:21 -0700403 chip->usb_chgpth_base + CHGR_STATUS, rc);
David Keitel80668952012-07-27 14:25:49 -0700404 return rc;
405 }
406 pr_debug("chgr usb sts 0x%x\n", usbin_valid_rt_sts);
407
David Keiteld681cda2012-10-02 15:44:21 -0700408 return (usbin_valid_rt_sts & USB_VALID_BIT) ? 1 : 0;
David Keitel80668952012-07-27 14:25:49 -0700409}
410
411static int
412qpnp_chg_is_dc_chg_plugged_in(struct qpnp_chg_chip *chip)
413{
414 u8 dcin_valid_rt_sts;
415 int rc;
416
David Keitelf2170cc2013-02-20 17:49:03 -0800417 if (!chip->dc_chgpth_base)
418 return 0;
419
David Keitel80668952012-07-27 14:25:49 -0700420 rc = qpnp_chg_read(chip, &dcin_valid_rt_sts,
421 INT_RT_STS(chip->dc_chgpth_base), 1);
422 if (rc) {
423 pr_err("spmi read failed: addr=%03X, rc=%d\n",
424 INT_RT_STS(chip->dc_chgpth_base), rc);
425 return rc;
426 }
427
428 return (dcin_valid_rt_sts & DCIN_VALID_IRQ) ? 1 : 0;
429}
430
David Keitel22ed2232013-01-28 11:04:07 -0800431#define QPNP_CHG_I_MAX_MIN_100 100
432#define QPNP_CHG_I_MAX_MIN_150 150
433#define QPNP_CHG_I_MAX_MIN_MA 200
434#define QPNP_CHG_I_MAX_MAX_MA 2500
435#define QPNP_CHG_I_MAXSTEP_MA 100
436static int
437qpnp_chg_idcmax_set(struct qpnp_chg_chip *chip, int mA)
438{
439 int rc = 0;
440 u8 dc = 0;
441
442 if (mA < QPNP_CHG_I_MAX_MIN_100
443 || mA > QPNP_CHG_I_MAX_MAX_MA) {
444 pr_err("bad mA=%d asked to set\n", mA);
445 return -EINVAL;
446 }
447
448 if (mA == QPNP_CHG_I_MAX_MIN_100) {
449 dc = 0x00;
450 pr_debug("current=%d setting %02x\n", mA, dc);
451 return qpnp_chg_write(chip, &dc,
452 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
453 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
454 dc = 0x01;
455 pr_debug("current=%d setting %02x\n", mA, dc);
456 return qpnp_chg_write(chip, &dc,
457 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
458 }
459
460 dc = mA / QPNP_CHG_I_MAXSTEP_MA;
461
462 pr_debug("current=%d setting 0x%x\n", mA, dc);
463 rc = qpnp_chg_write(chip, &dc,
464 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
465
466 return rc;
467}
468
David Keitel80668952012-07-27 14:25:49 -0700469static int
470qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
471{
David Keiteld681cda2012-10-02 15:44:21 -0700472 int rc = 0;
473 u8 usb_reg = 0, temp = 8;
David Keitel80668952012-07-27 14:25:49 -0700474
David Keitel22ed2232013-01-28 11:04:07 -0800475 if (mA < QPNP_CHG_I_MAX_MIN_100
476 || mA > QPNP_CHG_I_MAX_MAX_MA) {
David Keitel80668952012-07-27 14:25:49 -0700477 pr_err("bad mA=%d asked to set\n", mA);
478 return -EINVAL;
479 }
480
David Keitel22ed2232013-01-28 11:04:07 -0800481 if (mA == QPNP_CHG_I_MAX_MIN_100) {
482 usb_reg = 0x00;
483 pr_debug("current=%d setting %02x\n", mA, usb_reg);
484 return qpnp_chg_write(chip, &usb_reg,
485 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
486 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
487 usb_reg = 0x01;
488 pr_debug("current=%d setting %02x\n", mA, usb_reg);
489 return qpnp_chg_write(chip, &usb_reg,
490 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
491 }
492
493 /* Impose input current limit */
494 if (chip->maxinput_usb_ma)
495 mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
496
497 usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
David Keitel80668952012-07-27 14:25:49 -0700498
David Keiteld681cda2012-10-02 15:44:21 -0700499 if (chip->flags & CHG_FLAGS_VCP_WA) {
500 temp = 0xA5;
501 rc = qpnp_chg_write(chip, &temp,
502 chip->buck_base + SEC_ACCESS, 1);
503 rc = qpnp_chg_masked_write(chip,
504 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
505 0x0C, 0x0C, 1);
506 }
507
David Keitel80668952012-07-27 14:25:49 -0700508 pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
David Keiteld681cda2012-10-02 15:44:21 -0700509 rc = qpnp_chg_write(chip, &usb_reg,
David Keitel22ed2232013-01-28 11:04:07 -0800510 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
David Keiteld681cda2012-10-02 15:44:21 -0700511
512 if (chip->flags & CHG_FLAGS_VCP_WA) {
513 temp = 0xA5;
514 udelay(200);
515 rc = qpnp_chg_write(chip, &temp,
516 chip->buck_base + SEC_ACCESS, 1);
517 rc = qpnp_chg_masked_write(chip,
518 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
519 0x0C, 0x00, 1);
520 }
521
522 return rc;
523}
524
525#define USB_SUSPEND_BIT BIT(0)
526static int
527qpnp_chg_usb_suspend_enable(struct qpnp_chg_chip *chip, int enable)
528{
529 return qpnp_chg_masked_write(chip,
530 chip->usb_chgpth_base + CHGR_USB_USB_SUSP,
531 USB_SUSPEND_BIT,
532 enable ? USB_SUSPEND_BIT : 0, 1);
David Keitel80668952012-07-27 14:25:49 -0700533}
534
David Keitel344c6972013-04-09 19:28:21 -0700535static int
536qpnp_chg_charge_en(struct qpnp_chg_chip *chip, int enable)
537{
538 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
539 CHGR_CHG_EN,
540 enable ? CHGR_CHG_EN : 0, 1);
541}
542
543static int
544qpnp_chg_force_run_on_batt(struct qpnp_chg_chip *chip, int disable)
545{
546 /* Don't run on battery for batteryless hardware */
547 if (chip->use_default_batt_values)
548 return 0;
David Keitel4d66ea02013-04-30 10:57:58 -0700549 /* Don't force on battery if battery is not present */
550 if (!qpnp_chg_is_batt_present(chip))
551 return 0;
David Keitel344c6972013-04-09 19:28:21 -0700552
553 /* This bit forces the charger to run off of the battery rather
554 * than a connected charger */
555 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
556 CHGR_ON_BAT_FORCE_BIT,
557 disable ? CHGR_ON_BAT_FORCE_BIT : 0, 1);
558}
559
560static void
561qpnp_arb_stop_work(struct work_struct *work)
562{
563 struct delayed_work *dwork = to_delayed_work(work);
564 struct qpnp_chg_chip *chip = container_of(dwork,
565 struct qpnp_chg_chip, arb_stop_work);
566
567 qpnp_chg_charge_en(chip, !chip->charging_disabled);
568 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
569}
570
571static void
572qpnp_bat_if_adc_measure_work(struct work_struct *work)
David Keitel79f4c932013-04-03 16:08:39 -0700573{
574 struct qpnp_chg_chip *chip = container_of(work,
575 struct qpnp_chg_chip, adc_measure_work);
576
577 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
578 pr_err("request ADC error\n");
579}
580
David Keitel344c6972013-04-09 19:28:21 -0700581#define ARB_STOP_WORK_MS 1000
582static irqreturn_t
583qpnp_chg_usb_chg_gone_irq_handler(int irq, void *_chip)
584{
585 struct qpnp_chg_chip *chip = _chip;
586
587 pr_debug("chg_gone triggered\n");
588 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
589 qpnp_chg_charge_en(chip, 0);
590 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
591 schedule_delayed_work(&chip->arb_stop_work,
592 msecs_to_jiffies(ARB_STOP_WORK_MS));
593 }
594
595 return IRQ_HANDLED;
596}
597
David Keitel80668952012-07-27 14:25:49 -0700598#define ENUM_T_STOP_BIT BIT(0)
599static irqreturn_t
600qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
601{
602 struct qpnp_chg_chip *chip = _chip;
David Keitel6f865cd2012-11-30 15:04:32 -0800603 int usb_present, host_mode;
David Keitel80668952012-07-27 14:25:49 -0700604
605 usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
David Keitel6f865cd2012-11-30 15:04:32 -0800606 host_mode = qpnp_chg_is_otg_en_set(chip);
607 pr_debug("usbin-valid triggered: %d host_mode: %d\n",
608 usb_present, host_mode);
609
610 /* In host mode notifications cmoe from USB supply */
611 if (host_mode)
612 return IRQ_HANDLED;
David Keitel80668952012-07-27 14:25:49 -0700613
614 if (chip->usb_present ^ usb_present) {
615 chip->usb_present = usb_present;
David Keitelc69f2d62013-03-17 14:52:35 -0700616 if (!usb_present)
David Keitel344c6972013-04-09 19:28:21 -0700617 qpnp_chg_usb_suspend_enable(chip, 1);
618
Sridhar Parasuramae183bd2012-12-21 09:28:46 -0800619 power_supply_set_present(chip->usb_psy,
620 chip->usb_present);
David Keitel80668952012-07-27 14:25:49 -0700621 }
622
623 return IRQ_HANDLED;
624}
625
David Keitel7450dcd2013-01-29 18:41:41 -0800626static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800627qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
628{
629 struct qpnp_chg_chip *chip = _chip;
630 int batt_present;
631
632 batt_present = qpnp_chg_is_batt_present(chip);
633 pr_debug("batt-pres triggered: %d\n", batt_present);
634
635 if (chip->batt_present ^ batt_present) {
636 chip->batt_present = batt_present;
637 power_supply_changed(&chip->batt_psy);
David Keitel0c1a4532013-03-21 16:39:06 -0700638
639 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
640 && batt_present) {
David Keitel79f4c932013-04-03 16:08:39 -0700641 schedule_work(&chip->adc_measure_work);
David Keitel0c1a4532013-03-21 16:39:06 -0700642 }
David Keitel42ae0aa2013-03-08 16:20:10 -0800643 }
644
Xiaozhe Shid5d21412013-02-06 17:14:41 -0800645 if (chip->bms_psy)
646 power_supply_set_present(chip->bms_psy, batt_present);
647
David Keitel42ae0aa2013-03-08 16:20:10 -0800648 return IRQ_HANDLED;
649}
650
651static irqreturn_t
David Keitel7450dcd2013-01-29 18:41:41 -0800652qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
653{
654 struct qpnp_chg_chip *chip = _chip;
655 int dc_present;
656
657 dc_present = qpnp_chg_is_dc_chg_plugged_in(chip);
658 pr_debug("dcin-valid triggered: %d\n", dc_present);
659
660 if (chip->dc_present ^ dc_present) {
661 chip->dc_present = dc_present;
662 power_supply_changed(&chip->dc_psy);
663 }
664
665 return IRQ_HANDLED;
666}
667
David Keitel80668952012-07-27 14:25:49 -0700668#define CHGR_CHG_FAILED_BIT BIT(7)
669static irqreturn_t
670qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
671{
672 struct qpnp_chg_chip *chip = _chip;
David Keitel4429b1f2012-10-18 10:42:50 -0700673 int rc;
David Keitel80668952012-07-27 14:25:49 -0700674
675 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -0700676 chip->chgr_base + CHGR_CHG_FAILED,
David Keitel80668952012-07-27 14:25:49 -0700677 CHGR_CHG_FAILED_BIT,
678 CHGR_CHG_FAILED_BIT, 1);
679 if (rc)
680 pr_err("Failed to write chg_fail clear bit!\n");
681
David Keitel80668952012-07-27 14:25:49 -0700682 return IRQ_HANDLED;
683}
684
685static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800686qpnp_chg_chgr_chg_trklchg_irq_handler(int irq, void *_chip)
687{
688 struct qpnp_chg_chip *chip = _chip;
689
690 pr_debug("TRKL IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800691
692 chip->chg_done = false;
David Keitel42ae0aa2013-03-08 16:20:10 -0800693 power_supply_changed(&chip->batt_psy);
694
695 return IRQ_HANDLED;
696}
697
698static irqreturn_t
699qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
700{
701 struct qpnp_chg_chip *chip = _chip;
702
703 pr_debug("FAST_CHG IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800704
705 chip->chg_done = false;
David Keitel42ae0aa2013-03-08 16:20:10 -0800706 power_supply_changed(&chip->batt_psy);
707
708 return IRQ_HANDLED;
709}
710
David Keitel03ee6b52012-10-22 12:25:19 -0700711static int
712qpnp_batt_property_is_writeable(struct power_supply *psy,
713 enum power_supply_property psp)
714{
715 switch (psp) {
716 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitelbe208252013-01-31 14:49:25 -0800717 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
David Keitel03ee6b52012-10-22 12:25:19 -0700718 return 1;
719 default:
720 break;
721 }
722
723 return 0;
724}
725
David Keitel6f865cd2012-11-30 15:04:32 -0800726static int
David Keitelbe208252013-01-31 14:49:25 -0800727qpnp_chg_buck_control(struct qpnp_chg_chip *chip, int enable)
728{
729 int rc;
730
731 if (chip->charging_disabled && enable) {
732 pr_debug("Charging disabled\n");
733 return 0;
734 }
735
736 rc = qpnp_chg_charge_en(chip, enable);
737 if (rc) {
738 pr_err("Failed to control charging %d\n", rc);
739 return rc;
740 }
741
742 rc = qpnp_chg_force_run_on_batt(chip, !enable);
743 if (rc)
744 pr_err("Failed to control charging %d\n", rc);
745
746 return rc;
747}
748
David Keitel454ee842013-03-08 16:19:11 -0800749static int
750switch_usb_to_charge_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800751{
752 int rc;
753
754 pr_debug("switch to charge mode\n");
755 if (!qpnp_chg_is_otg_en_set(chip))
756 return 0;
757
758 /* enable usb ovp fet */
759 rc = qpnp_chg_masked_write(chip,
760 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
761 USB_OTG_EN_BIT,
762 0, 1);
763 if (rc) {
764 pr_err("Failed to turn on usb ovp rc = %d\n", rc);
765 return rc;
766 }
767
768 rc = qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
769 if (rc) {
770 pr_err("Failed re-enable charging rc = %d\n", rc);
771 return rc;
772 }
773
774 return 0;
775}
776
David Keitel454ee842013-03-08 16:19:11 -0800777static int
778switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800779{
780 int rc;
781
782 pr_debug("switch to host mode\n");
783 if (qpnp_chg_is_otg_en_set(chip))
784 return 0;
785
786 rc = qpnp_chg_force_run_on_batt(chip, 1);
787 if (rc) {
788 pr_err("Failed to disable charging rc = %d\n", rc);
789 return rc;
790 }
791
792 /* force usb ovp fet off */
793 rc = qpnp_chg_masked_write(chip,
794 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
795 USB_OTG_EN_BIT,
796 USB_OTG_EN_BIT, 1);
797 if (rc) {
798 pr_err("Failed to turn off usb ovp rc = %d\n", rc);
799 return rc;
800 }
801
802 return 0;
803}
804
David Keitel80668952012-07-27 14:25:49 -0700805static enum power_supply_property pm_power_props_mains[] = {
806 POWER_SUPPLY_PROP_PRESENT,
807 POWER_SUPPLY_PROP_ONLINE,
808};
809
810static enum power_supply_property msm_batt_power_props[] = {
David Keitelb80eda82012-10-15 10:49:11 -0700811 POWER_SUPPLY_PROP_CHARGING_ENABLED,
David Keitel80668952012-07-27 14:25:49 -0700812 POWER_SUPPLY_PROP_STATUS,
813 POWER_SUPPLY_PROP_CHARGE_TYPE,
814 POWER_SUPPLY_PROP_HEALTH,
815 POWER_SUPPLY_PROP_PRESENT,
816 POWER_SUPPLY_PROP_TECHNOLOGY,
817 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
818 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
819 POWER_SUPPLY_PROP_VOLTAGE_NOW,
820 POWER_SUPPLY_PROP_CAPACITY,
David Keitelabdf2872013-03-28 18:14:42 -0700821 POWER_SUPPLY_PROP_CURRENT_MAX,
David Keitel80668952012-07-27 14:25:49 -0700822 POWER_SUPPLY_PROP_CURRENT_NOW,
823 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
824 POWER_SUPPLY_PROP_TEMP,
David Keitelbe208252013-01-31 14:49:25 -0800825 POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
David Keitel80668952012-07-27 14:25:49 -0700826};
827
828static char *pm_power_supplied_to[] = {
829 "battery",
830};
831
832#define USB_WALL_THRESHOLD_MA 500
833static int
834qpnp_power_get_property_mains(struct power_supply *psy,
835 enum power_supply_property psp,
836 union power_supply_propval *val)
837{
838 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
839 dc_psy);
840
841 switch (psp) {
842 case POWER_SUPPLY_PROP_PRESENT:
843 case POWER_SUPPLY_PROP_ONLINE:
844 val->intval = 0;
David Keitel03ee6b52012-10-22 12:25:19 -0700845 if (chip->charging_disabled)
David Keitel80668952012-07-27 14:25:49 -0700846 return 0;
847
848 val->intval = qpnp_chg_is_dc_chg_plugged_in(chip);
849 break;
850 default:
851 return -EINVAL;
852 }
853 return 0;
854}
855
856static int
857get_prop_battery_voltage_now(struct qpnp_chg_chip *chip)
858{
859 int rc = 0;
860 struct qpnp_vadc_result results;
861
David Keitelfe51cb92013-04-02 19:42:58 -0700862 if (chip->revision == 0 && chip->type == SMBB) {
863 pr_err("vbat reading not supported for 1.0 rc=%d\n", rc);
864 return 0;
865 } else {
David Keitel80668952012-07-27 14:25:49 -0700866 rc = qpnp_vadc_read(VBAT_SNS, &results);
867 if (rc) {
868 pr_err("Unable to read vbat rc=%d\n", rc);
869 return 0;
870 }
871 return results.physical;
David Keitel80668952012-07-27 14:25:49 -0700872 }
873}
874
875#define BATT_PRES_BIT BIT(7)
876static int
877get_prop_batt_present(struct qpnp_chg_chip *chip)
878{
879 u8 batt_present;
880 int rc;
881
882 rc = qpnp_chg_read(chip, &batt_present,
883 chip->bat_if_base + CHGR_BAT_IF_PRES_STATUS, 1);
884 if (rc) {
885 pr_err("Couldn't read battery status read failed rc=%d\n", rc);
886 return 0;
887 };
888 return (batt_present & BATT_PRES_BIT) ? 1 : 0;
889}
890
891#define BATT_TEMP_HOT BIT(6)
892#define BATT_TEMP_OK BIT(7)
893static int
894get_prop_batt_health(struct qpnp_chg_chip *chip)
895{
896 u8 batt_health;
897 int rc;
898
899 rc = qpnp_chg_read(chip, &batt_health,
David Keiteld681cda2012-10-02 15:44:21 -0700900 chip->bat_if_base + CHGR_STATUS, 1);
David Keitel80668952012-07-27 14:25:49 -0700901 if (rc) {
902 pr_err("Couldn't read battery health read failed rc=%d\n", rc);
903 return POWER_SUPPLY_HEALTH_UNKNOWN;
904 };
905
906 if (BATT_TEMP_OK & batt_health)
907 return POWER_SUPPLY_HEALTH_GOOD;
908 if (BATT_TEMP_HOT & batt_health)
909 return POWER_SUPPLY_HEALTH_OVERHEAT;
910 else
911 return POWER_SUPPLY_HEALTH_COLD;
912}
913
914static int
915get_prop_charge_type(struct qpnp_chg_chip *chip)
916{
917 int rc;
918 u8 chgr_sts;
919
920 if (!get_prop_batt_present(chip))
921 return POWER_SUPPLY_CHARGE_TYPE_NONE;
922
923 rc = qpnp_chg_read(chip, &chgr_sts,
924 INT_RT_STS(chip->chgr_base), 1);
925 if (rc) {
926 pr_err("failed to read interrupt sts %d\n", rc);
927 return POWER_SUPPLY_CHARGE_TYPE_NONE;
928 }
929
930 if (chgr_sts & TRKL_CHG_ON_IRQ)
931 return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
932 if (chgr_sts & FAST_CHG_ON_IRQ)
933 return POWER_SUPPLY_CHARGE_TYPE_FAST;
934
935 return POWER_SUPPLY_CHARGE_TYPE_NONE;
936}
937
938static int
939get_prop_batt_status(struct qpnp_chg_chip *chip)
940{
941 int rc;
942 u8 chgr_sts;
943
David Keitelc9ffe842013-01-25 19:37:51 -0800944 if (chip->chg_done)
945 return POWER_SUPPLY_STATUS_FULL;
946
David Keitel80668952012-07-27 14:25:49 -0700947 rc = qpnp_chg_read(chip, &chgr_sts,
948 INT_RT_STS(chip->chgr_base), 1);
949 if (rc) {
950 pr_err("failed to read interrupt sts %d\n", rc);
David Keitelc9ffe842013-01-25 19:37:51 -0800951 return POWER_SUPPLY_CHARGE_TYPE_NONE;
David Keitel80668952012-07-27 14:25:49 -0700952 }
953
David Keitel80668952012-07-27 14:25:49 -0700954 if (chgr_sts & TRKL_CHG_ON_IRQ)
955 return POWER_SUPPLY_STATUS_CHARGING;
956 if (chgr_sts & FAST_CHG_ON_IRQ)
957 return POWER_SUPPLY_STATUS_CHARGING;
958
959 return POWER_SUPPLY_STATUS_DISCHARGING;
960}
David Keitelabdf2872013-03-28 18:14:42 -0700961static int
962get_prop_current_max(struct qpnp_chg_chip *chip)
963{
964 union power_supply_propval ret = {0,};
965
966 if (chip->bms_psy) {
967 chip->bms_psy->get_property(chip->bms_psy,
968 POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
969 return ret.intval;
970 } else {
971 pr_debug("No BMS supply registered return 0\n");
972 }
973
974 return 0;
975}
David Keitel80668952012-07-27 14:25:49 -0700976
977static int
978get_prop_current_now(struct qpnp_chg_chip *chip)
979{
980 union power_supply_propval ret = {0,};
981
982 if (chip->bms_psy) {
983 chip->bms_psy->get_property(chip->bms_psy,
984 POWER_SUPPLY_PROP_CURRENT_NOW, &ret);
985 return ret.intval;
986 } else {
987 pr_debug("No BMS supply registered return 0\n");
988 }
989
990 return 0;
991}
992
993static int
994get_prop_full_design(struct qpnp_chg_chip *chip)
995{
996 union power_supply_propval ret = {0,};
997
998 if (chip->bms_psy) {
999 chip->bms_psy->get_property(chip->bms_psy,
1000 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, &ret);
1001 return ret.intval;
1002 } else {
1003 pr_debug("No BMS supply registered return 0\n");
1004 }
1005
1006 return 0;
1007}
1008
1009#define DEFAULT_CAPACITY 50
1010static int
1011get_prop_capacity(struct qpnp_chg_chip *chip)
1012{
1013 union power_supply_propval ret = {0,};
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001014 bool usb_online, dc_online;
David Keitel80668952012-07-27 14:25:49 -07001015
David Keitel3dd5e0f2012-12-12 18:12:36 -08001016 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1017 return DEFAULT_CAPACITY;
1018
David Keitel80668952012-07-27 14:25:49 -07001019 if (chip->bms_psy) {
1020 chip->bms_psy->get_property(chip->bms_psy,
1021 POWER_SUPPLY_PROP_CAPACITY, &ret);
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001022 if (ret.intval == 0) {
1023 usb_online = chip->usb_psy->get_property(chip->usb_psy,
1024 POWER_SUPPLY_PROP_ONLINE, &ret);
1025 dc_online = chip->dc_psy.get_property(&chip->dc_psy,
1026 POWER_SUPPLY_PROP_ONLINE, &ret);
1027 if (!usb_online && !dc_online)
1028 pr_warn_ratelimited("Battery 0, CHG absent\n");
1029 }
David Keitel80668952012-07-27 14:25:49 -07001030 return ret.intval;
1031 } else {
1032 pr_debug("No BMS supply registered return 50\n");
1033 }
1034
1035 /* return default capacity to avoid userspace
1036 * from shutting down unecessarily */
1037 return DEFAULT_CAPACITY;
1038}
1039
David Keitel3dd5e0f2012-12-12 18:12:36 -08001040#define DEFAULT_TEMP 250
David Keitel80668952012-07-27 14:25:49 -07001041#define MAX_TOLERABLE_BATT_TEMP_DDC 680
1042static int
1043get_prop_batt_temp(struct qpnp_chg_chip *chip)
1044{
1045 int rc = 0;
1046 struct qpnp_vadc_result results;
1047
David Keitel3dd5e0f2012-12-12 18:12:36 -08001048 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1049 return DEFAULT_TEMP;
1050
David Keitel80668952012-07-27 14:25:49 -07001051 if (chip->revision > 0) {
1052 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
1053 if (rc) {
1054 pr_debug("Unable to read batt temperature rc=%d\n", rc);
1055 return 0;
1056 }
1057 pr_debug("get_bat_temp %d %lld\n",
1058 results.adc_code, results.physical);
1059 return (int)results.physical;
1060 } else {
1061 pr_debug("batt temp not supported for PMIC 1.0 rc=%d\n", rc);
1062 }
1063
1064 /* return default temperature to avoid userspace
1065 * from shutting down unecessarily */
1066 return DEFAULT_TEMP;
1067}
1068
1069static void
1070qpnp_batt_external_power_changed(struct power_supply *psy)
1071{
1072 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1073 batt_psy);
1074 union power_supply_propval ret = {0,};
1075
1076 if (!chip->bms_psy)
1077 chip->bms_psy = power_supply_get_by_name("bms");
1078
1079 chip->usb_psy->get_property(chip->usb_psy,
David Keitel6f865cd2012-11-30 15:04:32 -08001080 POWER_SUPPLY_PROP_SCOPE, &ret);
1081 if (ret.intval) {
1082 if ((ret.intval == POWER_SUPPLY_SCOPE_SYSTEM)
1083 && !qpnp_chg_is_otg_en_set(chip)) {
1084 switch_usb_to_host_mode(chip);
1085 return;
1086 }
1087 if ((ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
1088 && qpnp_chg_is_otg_en_set(chip)) {
1089 switch_usb_to_charge_mode(chip);
1090 return;
1091 }
1092 }
1093
1094 chip->usb_psy->get_property(chip->usb_psy,
David Keitel80668952012-07-27 14:25:49 -07001095 POWER_SUPPLY_PROP_ONLINE, &ret);
1096
David Keitelc69f2d62013-03-17 14:52:35 -07001097 /* Only honour requests while USB is present */
1098 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001099 chip->usb_psy->get_property(chip->usb_psy,
1100 POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
David Keitel87473252013-03-21 14:39:45 -07001101 if (ret.intval <= 2 && !chip->use_default_batt_values &&
1102 get_prop_batt_present(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001103 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -07001104 qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
David Keitelc69f2d62013-03-17 14:52:35 -07001105 } else {
David Keiteld681cda2012-10-02 15:44:21 -07001106 qpnp_chg_usb_suspend_enable(chip, 0);
David Keitel359ab652013-03-21 17:46:00 -07001107 qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
David Keitelc69f2d62013-03-17 14:52:35 -07001108 }
David Keitel80668952012-07-27 14:25:49 -07001109 }
1110
1111 pr_debug("end of power supply changed\n");
1112 power_supply_changed(&chip->batt_psy);
1113}
1114
1115static int
1116qpnp_batt_power_get_property(struct power_supply *psy,
1117 enum power_supply_property psp,
1118 union power_supply_propval *val)
1119{
1120 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1121 batt_psy);
1122
1123 switch (psp) {
1124 case POWER_SUPPLY_PROP_STATUS:
1125 val->intval = get_prop_batt_status(chip);
1126 break;
1127 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1128 val->intval = get_prop_charge_type(chip);
1129 break;
1130 case POWER_SUPPLY_PROP_HEALTH:
1131 val->intval = get_prop_batt_health(chip);
1132 break;
1133 case POWER_SUPPLY_PROP_PRESENT:
1134 val->intval = get_prop_batt_present(chip);
1135 break;
1136 case POWER_SUPPLY_PROP_TECHNOLOGY:
1137 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
1138 break;
1139 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
1140 val->intval = chip->max_voltage_mv * 1000;
1141 break;
1142 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
1143 val->intval = chip->min_voltage_mv * 1000;
1144 break;
1145 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1146 val->intval = get_prop_battery_voltage_now(chip);
1147 break;
1148 case POWER_SUPPLY_PROP_TEMP:
1149 val->intval = get_prop_batt_temp(chip);
1150 break;
1151 case POWER_SUPPLY_PROP_CAPACITY:
1152 val->intval = get_prop_capacity(chip);
1153 break;
David Keitelabdf2872013-03-28 18:14:42 -07001154 case POWER_SUPPLY_PROP_CURRENT_MAX:
1155 val->intval = get_prop_current_max(chip);
1156 break;
David Keitel80668952012-07-27 14:25:49 -07001157 case POWER_SUPPLY_PROP_CURRENT_NOW:
1158 val->intval = get_prop_current_now(chip);
1159 break;
1160 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1161 val->intval = get_prop_full_design(chip);
1162 break;
David Keitelb80eda82012-10-15 10:49:11 -07001163 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitel03ee6b52012-10-22 12:25:19 -07001164 val->intval = !(chip->charging_disabled);
David Keitelb80eda82012-10-15 10:49:11 -07001165 break;
David Keitelbe208252013-01-31 14:49:25 -08001166 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1167 val->intval = chip->therm_lvl_sel;
David Keitelb80eda82012-10-15 10:49:11 -07001168 break;
1169 default:
1170 return -EINVAL;
1171 }
1172
David Keitelb80eda82012-10-15 10:49:11 -07001173 return 0;
David Keitel80668952012-07-27 14:25:49 -07001174}
1175
David Keitel80668952012-07-27 14:25:49 -07001176#define QPNP_CHG_VINMIN_MIN_MV 3400
1177#define QPNP_CHG_VINMIN_HIGH_MIN_MV 5600
1178#define QPNP_CHG_VINMIN_HIGH_MIN_VAL 0x2B
1179#define QPNP_CHG_VINMIN_MAX_MV 9600
1180#define QPNP_CHG_VINMIN_STEP_MV 50
1181#define QPNP_CHG_VINMIN_STEP_HIGH_MV 200
1182#define QPNP_CHG_VINMIN_MASK 0x1F
1183static int
1184qpnp_chg_vinmin_set(struct qpnp_chg_chip *chip, int voltage)
1185{
1186 u8 temp;
1187
1188 if (voltage < QPNP_CHG_VINMIN_MIN_MV
1189 || voltage > QPNP_CHG_VINMIN_MAX_MV) {
1190 pr_err("bad mV=%d asked to set\n", voltage);
1191 return -EINVAL;
1192 }
1193 if (voltage >= QPNP_CHG_VINMIN_HIGH_MIN_MV) {
1194 temp = QPNP_CHG_VINMIN_HIGH_MIN_VAL;
1195 temp += (voltage - QPNP_CHG_VINMIN_MIN_MV)
1196 / QPNP_CHG_VINMIN_STEP_HIGH_MV;
1197 } else {
1198 temp = (voltage - QPNP_CHG_VINMIN_MIN_MV)
1199 / QPNP_CHG_VINMIN_STEP_MV;
1200 }
1201
1202 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1203 return qpnp_chg_masked_write(chip,
1204 chip->chgr_base + CHGR_VIN_MIN,
1205 QPNP_CHG_VINMIN_MASK, temp, 1);
1206}
1207
David Keitel5d44fa52012-12-03 16:37:31 -08001208#define QPNP_CHG_IBATSAFE_MIN_MA 100
1209#define QPNP_CHG_IBATSAFE_MAX_MA 3250
1210#define QPNP_CHG_I_STEP_MA 50
1211#define QPNP_CHG_I_MIN_MA 100
1212#define QPNP_CHG_I_MASK 0x3F
1213static int
1214qpnp_chg_ibatsafe_set(struct qpnp_chg_chip *chip, int safe_current)
1215{
1216 u8 temp;
1217
1218 if (safe_current < QPNP_CHG_IBATSAFE_MIN_MA
1219 || safe_current > QPNP_CHG_IBATSAFE_MAX_MA) {
1220 pr_err("bad mA=%d asked to set\n", safe_current);
1221 return -EINVAL;
1222 }
1223
1224 temp = (safe_current - QPNP_CHG_IBATSAFE_MIN_MA)
1225 / QPNP_CHG_I_STEP_MA;
1226 return qpnp_chg_masked_write(chip,
1227 chip->chgr_base + CHGR_IBAT_SAFE,
1228 QPNP_CHG_I_MASK, temp, 1);
1229}
David Keitel80668952012-07-27 14:25:49 -07001230
1231#define QPNP_CHG_ITERM_MIN_MA 100
1232#define QPNP_CHG_ITERM_MAX_MA 250
1233#define QPNP_CHG_ITERM_STEP_MA 50
1234#define QPNP_CHG_ITERM_MASK 0x03
1235static int
1236qpnp_chg_ibatterm_set(struct qpnp_chg_chip *chip, int term_current)
1237{
1238 u8 temp;
1239
1240 if (term_current < QPNP_CHG_ITERM_MIN_MA
1241 || term_current > QPNP_CHG_ITERM_MAX_MA) {
1242 pr_err("bad mA=%d asked to set\n", term_current);
1243 return -EINVAL;
1244 }
1245
1246 temp = (term_current - QPNP_CHG_ITERM_MIN_MA)
1247 / QPNP_CHG_ITERM_STEP_MA;
1248 return qpnp_chg_masked_write(chip,
1249 chip->chgr_base + CHGR_IBAT_TERM_CHGR,
1250 QPNP_CHG_ITERM_MASK, temp, 1);
1251}
1252
David Keitelff5d0472013-04-04 11:36:06 -07001253#define QPNP_CHG_IBATMAX_MIN 50
David Keitel80668952012-07-27 14:25:49 -07001254#define QPNP_CHG_IBATMAX_MAX 3250
David Keitel80668952012-07-27 14:25:49 -07001255static int
1256qpnp_chg_ibatmax_set(struct qpnp_chg_chip *chip, int chg_current)
1257{
1258 u8 temp;
1259
1260 if (chg_current < QPNP_CHG_IBATMAX_MIN
1261 || chg_current > QPNP_CHG_IBATMAX_MAX) {
1262 pr_err("bad mA=%d asked to set\n", chg_current);
1263 return -EINVAL;
1264 }
David Keitelff5d0472013-04-04 11:36:06 -07001265 temp = chg_current / QPNP_CHG_I_STEP_MA;
David Keitel80668952012-07-27 14:25:49 -07001266 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_IBAT_MAX,
1267 QPNP_CHG_I_MASK, temp, 1);
1268}
1269
David Keitela4b7b592013-04-11 18:34:35 -07001270#define QPNP_CHG_TCHG_MASK 0x7F
1271#define QPNP_CHG_TCHG_MIN 4
1272#define QPNP_CHG_TCHG_MAX 512
1273#define QPNP_CHG_TCHG_STEP 4
1274static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
1275{
1276 u8 temp;
1277
1278 if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
1279 pr_err("bad max minutes =%d asked to set\n", minutes);
1280 return -EINVAL;
1281 }
1282
1283 temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
1284 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
1285 QPNP_CHG_I_MASK, temp, 1);
1286}
David Keitel5d44fa52012-12-03 16:37:31 -08001287#define QPNP_CHG_VBATDET_MIN_MV 3240
1288#define QPNP_CHG_VBATDET_MAX_MV 5780
1289#define QPNP_CHG_VBATDET_STEP_MV 20
1290static int
1291qpnp_chg_vbatdet_set(struct qpnp_chg_chip *chip, int vbatdet_mv)
1292{
1293 u8 temp;
1294
1295 if (vbatdet_mv < QPNP_CHG_VBATDET_MIN_MV
1296 || vbatdet_mv > QPNP_CHG_VBATDET_MAX_MV) {
1297 pr_err("bad mV=%d asked to set\n", vbatdet_mv);
1298 return -EINVAL;
1299 }
1300 temp = (vbatdet_mv - QPNP_CHG_VBATDET_MIN_MV)
1301 / QPNP_CHG_VBATDET_STEP_MV;
1302
1303 pr_debug("voltage=%d setting %02x\n", vbatdet_mv, temp);
1304 return qpnp_chg_write(chip, &temp,
1305 chip->chgr_base + CHGR_VBAT_DET, 1);
1306}
David Keitel80668952012-07-27 14:25:49 -07001307
1308#define QPNP_CHG_V_MIN_MV 3240
1309#define QPNP_CHG_V_MAX_MV 4500
1310#define QPNP_CHG_V_STEP_MV 10
1311static int
1312qpnp_chg_vddsafe_set(struct qpnp_chg_chip *chip, int voltage)
1313{
1314 u8 temp;
1315
1316 if (voltage < QPNP_CHG_V_MIN_MV
1317 || voltage > QPNP_CHG_V_MAX_MV) {
1318 pr_err("bad mV=%d asked to set\n", voltage);
1319 return -EINVAL;
1320 }
1321 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1322 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1323 return qpnp_chg_write(chip, &temp,
1324 chip->chgr_base + CHGR_VDD_SAFE, 1);
1325}
1326
1327#define QPNP_CHG_VDDMAX_MIN 3400
1328static int
1329qpnp_chg_vddmax_set(struct qpnp_chg_chip *chip, int voltage)
1330{
1331 u8 temp = 0;
1332
1333 if (voltage < QPNP_CHG_VDDMAX_MIN
1334 || voltage > QPNP_CHG_V_MAX_MV) {
1335 pr_err("bad mV=%d asked to set\n", voltage);
1336 return -EINVAL;
1337 }
1338
1339 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1340
1341 pr_debug("voltage=%d setting %02x\n", voltage, temp);
David Keitel454ee842013-03-08 16:19:11 -08001342 return qpnp_chg_write(chip, &temp, chip->chgr_base + CHGR_VDD_MAX, 1);
1343}
1344
1345/* JEITA compliance logic */
1346static void
1347qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
1348{
1349 if (chip->bat_is_cool)
1350 qpnp_chg_vddmax_set(chip, chip->cool_bat_mv);
1351 else if (chip->bat_is_warm)
1352 qpnp_chg_vddmax_set(chip, chip->warm_bat_mv);
1353 else
1354 qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
1355}
1356
1357static void
1358qpnp_chg_set_appropriate_vbatdet(struct qpnp_chg_chip *chip)
1359{
1360 if (chip->bat_is_cool)
1361 qpnp_chg_vbatdet_set(chip, chip->cool_bat_mv
1362 - chip->resume_delta_mv);
1363 else if (chip->bat_is_warm)
1364 qpnp_chg_vbatdet_set(chip, chip->warm_bat_mv
1365 - chip->resume_delta_mv);
1366 else
1367 qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
1368 - chip->resume_delta_mv);
David Keitel80668952012-07-27 14:25:49 -07001369}
1370
David Keitelbe208252013-01-31 14:49:25 -08001371static void
1372qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
1373{
1374 unsigned int chg_current = chip->max_bat_chg_current;
1375
David Keitel454ee842013-03-08 16:19:11 -08001376 if (chip->bat_is_cool)
1377 chg_current = min(chg_current, chip->cool_bat_chg_ma);
1378
1379 if (chip->bat_is_warm)
1380 chg_current = min(chg_current, chip->warm_bat_chg_ma);
1381
David Keitelbe208252013-01-31 14:49:25 -08001382 if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
1383 chg_current = min(chg_current,
1384 chip->thermal_mitigation[chip->therm_lvl_sel]);
1385
1386 pr_debug("setting %d mA\n", chg_current);
1387 qpnp_chg_ibatmax_set(chip, chg_current);
1388}
1389
1390static void
1391qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
1392{
1393 if (lvl_sel >= 0 && lvl_sel < chip->thermal_levels) {
1394 chip->therm_lvl_sel = lvl_sel;
1395 if (lvl_sel == (chip->thermal_levels - 1)) {
1396 /* disable charging if highest value selected */
1397 qpnp_chg_buck_control(chip, 0);
1398 } else {
1399 qpnp_chg_buck_control(chip, 1);
1400 qpnp_chg_set_appropriate_battery_current(chip);
1401 }
1402 } else {
1403 pr_err("Unsupported level selected %d\n", lvl_sel);
1404 }
1405}
1406
David Keitel0c1a4532013-03-21 16:39:06 -07001407#define HYSTERISIS_DECIDEGC 20
David Keitel454ee842013-03-08 16:19:11 -08001408static void
1409qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
1410{
1411 struct qpnp_chg_chip *chip = ctx;
1412 bool bat_warm = 0, bat_cool = 0;
David Keitel1219a802013-03-21 16:37:21 -07001413 int temp;
David Keitel454ee842013-03-08 16:19:11 -08001414
1415 if (state >= ADC_TM_STATE_NUM) {
1416 pr_err("invalid notification %d\n", state);
1417 return;
1418 }
1419
David Keitel1219a802013-03-21 16:37:21 -07001420 temp = get_prop_batt_temp(chip);
David Keitel454ee842013-03-08 16:19:11 -08001421
David Keitel1219a802013-03-21 16:37:21 -07001422 pr_debug("temp = %d state = %s\n", temp,
1423 state == ADC_TM_WARM_STATE ? "warm" : "cool");
1424
1425 if (state == ADC_TM_WARM_STATE) {
1426 if (temp > chip->warm_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07001427 /* Normal to warm */
David Keitel454ee842013-03-08 16:19:11 -08001428 bat_warm = true;
1429 bat_cool = false;
1430 chip->adc_param.low_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07001431 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07001432 chip->adc_param.state_request =
1433 ADC_TM_COOL_THR_ENABLE;
1434 } else if (temp >
1435 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07001436 /* Cool to normal */
David Keitel454ee842013-03-08 16:19:11 -08001437 bat_warm = false;
1438 bat_cool = false;
David Keitel1219a802013-03-21 16:37:21 -07001439
1440 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel0c1a4532013-03-21 16:39:06 -07001441 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07001442 chip->adc_param.state_request =
1443 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08001444 }
1445 } else {
David Keitel1219a802013-03-21 16:37:21 -07001446 if (temp < chip->cool_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07001447 /* Normal to cool */
David Keitel454ee842013-03-08 16:19:11 -08001448 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07001449 bat_cool = true;
David Keitel454ee842013-03-08 16:19:11 -08001450 chip->adc_param.high_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07001451 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07001452 chip->adc_param.state_request =
1453 ADC_TM_WARM_THR_ENABLE;
David Keitel3e37e5a2013-04-18 10:42:30 -07001454 } else if (temp <
David Keitel1219a802013-03-21 16:37:21 -07001455 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07001456 /* Warm to normal */
David Keitel454ee842013-03-08 16:19:11 -08001457 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07001458 bat_cool = false;
1459
David Keitel0c1a4532013-03-21 16:39:06 -07001460 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07001461 chip->adc_param.high_temp = chip->warm_bat_decidegc;
1462 chip->adc_param.state_request =
1463 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08001464 }
1465 }
1466
1467 if (chip->bat_is_cool ^ bat_cool || chip->bat_is_warm ^ bat_warm) {
David Keitel1219a802013-03-21 16:37:21 -07001468 chip->bat_is_cool = bat_cool;
1469 chip->bat_is_warm = bat_warm;
1470
David Keitel454ee842013-03-08 16:19:11 -08001471 /* set appropriate voltages and currents */
1472 qpnp_chg_set_appropriate_vddmax(chip);
1473 qpnp_chg_set_appropriate_battery_current(chip);
1474 qpnp_chg_set_appropriate_vbatdet(chip);
David Keitel454ee842013-03-08 16:19:11 -08001475 }
1476
David Keitel1219a802013-03-21 16:37:21 -07001477 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
1478 pr_err("request ADC error\n");
David Keitel454ee842013-03-08 16:19:11 -08001479}
1480
David Keitelbe208252013-01-31 14:49:25 -08001481static int
1482qpnp_batt_power_set_property(struct power_supply *psy,
1483 enum power_supply_property psp,
1484 const union power_supply_propval *val)
1485{
1486 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1487 batt_psy);
1488
1489 switch (psp) {
1490 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
1491 chip->charging_disabled = !(val->intval);
1492 qpnp_chg_charge_en(chip, !chip->charging_disabled);
1493 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
1494 break;
1495 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1496 qpnp_batt_system_temp_level_set(chip, val->intval);
1497 break;
1498 default:
1499 return -EINVAL;
1500 }
1501
1502 power_supply_changed(&chip->batt_psy);
1503 return 0;
1504}
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08001505
1506static void
1507qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
David Keiteld681cda2012-10-02 15:44:21 -07001508{
David Keitelfe51cb92013-04-02 19:42:58 -07001509 if (chip->revision > 0 && chip->type == SMBB)
David Keiteld681cda2012-10-02 15:44:21 -07001510 chip->flags |= CHG_FLAGS_VCP_WA;
1511}
1512
David Keitel0f35be42013-04-16 11:10:40 -07001513static int
1514qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
1515{
1516 int rc = 0;
1517 struct resource *resource;
1518 struct spmi_resource *spmi_resource;
1519 u8 subtype;
1520 struct spmi_device *spmi = chip->spmi;
1521
1522 spmi_for_each_container_dev(spmi_resource, chip->spmi) {
1523 if (!spmi_resource) {
1524 pr_err("qpnp_chg: spmi resource absent\n");
1525 return rc;
1526 }
1527
1528 resource = spmi_get_resource(spmi, spmi_resource,
1529 IORESOURCE_MEM, 0);
1530 if (!(resource && resource->start)) {
1531 pr_err("node %s IO resource absent!\n",
1532 spmi->dev.of_node->full_name);
1533 return rc;
1534 }
1535
1536 rc = qpnp_chg_read(chip, &subtype,
1537 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
1538 if (rc) {
1539 pr_err("Peripheral subtype read failed rc=%d\n", rc);
1540 return rc;
1541 }
1542
1543 switch (subtype) {
1544 case SMBB_CHGR_SUBTYPE:
1545 case SMBBP_CHGR_SUBTYPE:
1546 case SMBCL_CHGR_SUBTYPE:
1547 chip->chg_fastchg_irq = spmi_get_irq_byname(spmi,
1548 spmi_resource, "fast-chg-on");
1549 if (chip->chg_fastchg_irq < 0) {
1550 pr_err("Unable to get fast-chg-on irq\n");
1551 return rc;
1552 }
1553
1554 chip->chg_trklchg_irq = spmi_get_irq_byname(spmi,
1555 spmi_resource, "trkl-chg-on");
1556 if (chip->chg_trklchg_irq < 0) {
1557 pr_err("Unable to get trkl-chg-on irq\n");
1558 return rc;
1559 }
1560
1561 chip->chg_failed_irq = spmi_get_irq_byname(spmi,
1562 spmi_resource, "chg-failed");
1563 if (chip->chg_failed_irq < 0) {
1564 pr_err("Unable to get chg_failed irq\n");
1565 return rc;
1566 }
1567
1568 rc |= devm_request_irq(chip->dev, chip->chg_failed_irq,
1569 qpnp_chg_chgr_chg_failed_irq_handler,
David Keitelc9f19172013-04-29 11:01:26 -07001570 IRQF_TRIGGER_RISING, "chg-failed", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001571 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07001572 pr_err("Can't request %d chg-failed: %d\n",
David Keitel0f35be42013-04-16 11:10:40 -07001573 chip->chg_failed_irq, rc);
1574 return rc;
1575 }
1576
1577 rc |= devm_request_irq(chip->dev, chip->chg_fastchg_irq,
1578 qpnp_chg_chgr_chg_fastchg_irq_handler,
1579 IRQF_TRIGGER_RISING,
1580 "fast-chg-on", chip);
1581 if (rc < 0) {
1582 pr_err("Can't request %d fast-chg-on: %d\n",
1583 chip->chg_fastchg_irq, rc);
1584 return rc;
1585 }
1586
1587 rc |= devm_request_irq(chip->dev, chip->chg_trklchg_irq,
1588 qpnp_chg_chgr_chg_trklchg_irq_handler,
1589 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07001590 "trkl-chg-on", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001591 if (rc < 0) {
1592 pr_err("Can't request %d trkl-chg-on: %d\n",
1593 chip->chg_trklchg_irq, rc);
1594 return rc;
1595 }
1596 enable_irq_wake(chip->chg_fastchg_irq);
1597 enable_irq_wake(chip->chg_trklchg_irq);
1598 enable_irq_wake(chip->chg_failed_irq);
1599
1600 break;
1601 case SMBB_BAT_IF_SUBTYPE:
1602 case SMBBP_BAT_IF_SUBTYPE:
1603 case SMBCL_BAT_IF_SUBTYPE:
1604 chip->batt_pres_irq = spmi_get_irq_byname(spmi,
1605 spmi_resource, "batt-pres");
1606 if (chip->batt_pres_irq < 0) {
1607 pr_err("Unable to get batt-pres irq\n");
1608 return rc;
1609 }
1610 rc = devm_request_irq(chip->dev, chip->batt_pres_irq,
1611 qpnp_chg_bat_if_batt_pres_irq_handler,
1612 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07001613 "batt-pres", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001614 if (rc < 0) {
1615 pr_err("Can't request %d batt-pres irq: %d\n",
1616 chip->batt_pres_irq, rc);
1617 return rc;
1618 }
1619
1620 enable_irq_wake(chip->batt_pres_irq);
1621 break;
1622 case SMBB_USB_CHGPTH_SUBTYPE:
1623 case SMBBP_USB_CHGPTH_SUBTYPE:
1624 case SMBCL_USB_CHGPTH_SUBTYPE:
1625 chip->usbin_valid_irq = spmi_get_irq_byname(spmi,
1626 spmi_resource, "usbin-valid");
1627 if (chip->usbin_valid_irq < 0) {
1628 pr_err("Unable to get usbin irq\n");
1629 return rc;
1630 }
1631 rc = devm_request_irq(chip->dev, chip->usbin_valid_irq,
1632 qpnp_chg_usb_usbin_valid_irq_handler,
1633 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07001634 "usbin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001635 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07001636 pr_err("Can't request %d usbin-valid: %d\n",
David Keitel0f35be42013-04-16 11:10:40 -07001637 chip->usbin_valid_irq, rc);
1638 return rc;
1639 }
David Keitel344c6972013-04-09 19:28:21 -07001640
1641 chip->chg_gone_irq = spmi_get_irq_byname(spmi,
1642 spmi_resource, "chg-gone");
1643 if (chip->chg_gone_irq < 0) {
1644 pr_err("Unable to get chg-gone irq\n");
1645 return rc;
1646 }
1647 rc = devm_request_irq(chip->dev, chip->chg_gone_irq,
1648 qpnp_chg_usb_chg_gone_irq_handler,
1649 IRQF_TRIGGER_RISING,
David Keitelc9f19172013-04-29 11:01:26 -07001650 "chg-gone", chip);
David Keitel344c6972013-04-09 19:28:21 -07001651 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07001652 pr_err("Can't request %d chg-gone: %d\n",
David Keitel344c6972013-04-09 19:28:21 -07001653 chip->chg_gone_irq, rc);
1654 return rc;
1655 }
David Keitel0f35be42013-04-16 11:10:40 -07001656 enable_irq_wake(chip->usbin_valid_irq);
David Keitel344c6972013-04-09 19:28:21 -07001657 enable_irq_wake(chip->chg_gone_irq);
David Keitel0f35be42013-04-16 11:10:40 -07001658 break;
1659 case SMBB_DC_CHGPTH_SUBTYPE:
1660 chip->dcin_valid_irq = spmi_get_irq_byname(spmi,
1661 spmi_resource, "dcin-valid");
1662 if (chip->dcin_valid_irq < 0) {
1663 pr_err("Unable to get dcin irq\n");
1664 return -rc;
1665 }
1666 rc = devm_request_irq(chip->dev, chip->dcin_valid_irq,
1667 qpnp_chg_dc_dcin_valid_irq_handler,
1668 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07001669 "dcin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001670 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07001671 pr_err("Can't request %d dcin-valid: %d\n",
David Keitel0f35be42013-04-16 11:10:40 -07001672 chip->dcin_valid_irq, rc);
1673 return rc;
1674 }
1675
1676 enable_irq_wake(chip->dcin_valid_irq);
1677 break;
1678 }
1679 }
1680
1681 return rc;
1682}
1683
David Keitel80668952012-07-27 14:25:49 -07001684#define WDOG_EN_BIT BIT(7)
1685static int
1686qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
1687 struct spmi_resource *spmi_resource)
1688{
1689 int rc = 0;
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08001690 u8 reg;
David Keitel80668952012-07-27 14:25:49 -07001691
1692 switch (subtype) {
1693 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08001694 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07001695 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07001696 rc = qpnp_chg_vinmin_set(chip, chip->min_voltage_mv);
1697 if (rc) {
1698 pr_debug("failed setting min_voltage rc=%d\n", rc);
1699 return rc;
1700 }
1701 rc = qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
1702 if (rc) {
1703 pr_debug("failed setting max_voltage rc=%d\n", rc);
1704 return rc;
1705 }
1706 rc = qpnp_chg_vddsafe_set(chip, chip->safe_voltage_mv);
1707 if (rc) {
1708 pr_debug("failed setting safe_voltage rc=%d\n", rc);
1709 return rc;
1710 }
David Keitel454ee842013-03-08 16:19:11 -08001711 rc = qpnp_chg_vbatdet_set(chip,
1712 chip->max_voltage_mv - chip->resume_delta_mv);
David Keitel5d44fa52012-12-03 16:37:31 -08001713 if (rc) {
1714 pr_debug("failed setting resume_voltage rc=%d\n", rc);
1715 return rc;
1716 }
David Keitel80668952012-07-27 14:25:49 -07001717 rc = qpnp_chg_ibatmax_set(chip, chip->max_bat_chg_current);
1718 if (rc) {
1719 pr_debug("failed setting ibatmax rc=%d\n", rc);
1720 return rc;
1721 }
David Keitel365c4c42013-03-08 16:20:40 -08001722 if (chip->term_current) {
1723 rc = qpnp_chg_ibatterm_set(chip, chip->term_current);
1724 if (rc) {
1725 pr_debug("failed setting ibatterm rc=%d\n", rc);
1726 return rc;
1727 }
David Keitel80668952012-07-27 14:25:49 -07001728 }
David Keitel5d44fa52012-12-03 16:37:31 -08001729 rc = qpnp_chg_ibatsafe_set(chip, chip->safe_current);
1730 if (rc) {
1731 pr_debug("failed setting ibat_Safe rc=%d\n", rc);
1732 return rc;
1733 }
David Keitela4b7b592013-04-11 18:34:35 -07001734 rc = qpnp_chg_tchg_max_set(chip, chip->tchg_mins);
1735 if (rc) {
1736 pr_debug("failed setting tchg_mins rc=%d\n", rc);
1737 return rc;
1738 }
1739
David Keitel80668952012-07-27 14:25:49 -07001740 /* HACK: Disable wdog */
1741 rc = qpnp_chg_masked_write(chip, chip->chgr_base + 0x62,
1742 0xFF, 0xA0, 1);
1743
David Keitelb4e43542013-04-09 17:30:41 -07001744 /* HACK: use analog EOC */
David Keitel80668952012-07-27 14:25:49 -07001745 rc = qpnp_chg_masked_write(chip, chip->chgr_base +
1746 CHGR_IBAT_TERM_CHGR,
David Keitelb4e43542013-04-09 17:30:41 -07001747 0x80, 0x00, 1);
David Keitel80668952012-07-27 14:25:49 -07001748
David Keitel80668952012-07-27 14:25:49 -07001749 break;
1750 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08001751 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07001752 case SMBCL_BUCK_SUBTYPE:
David Keitel9201df32013-01-10 18:38:34 -08001753 rc = qpnp_chg_masked_write(chip,
1754 chip->chgr_base + CHGR_BUCK_BCK_VBAT_REG_MODE,
1755 BUCK_VBAT_REG_NODE_SEL_BIT,
1756 BUCK_VBAT_REG_NODE_SEL_BIT, 1);
1757 if (rc) {
1758 pr_debug("failed to enable IR drop comp rc=%d\n", rc);
1759 return rc;
1760 }
David Keitel80668952012-07-27 14:25:49 -07001761 break;
1762 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08001763 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07001764 case SMBCL_BAT_IF_SUBTYPE:
David Keitel85ae4342013-04-16 11:46:00 -07001765 /* Force on VREF_BAT_THM */
1766 rc = qpnp_chg_masked_write(chip,
1767 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
1768 VREF_BATT_THERM_FORCE_ON,
1769 VREF_BATT_THERM_FORCE_ON, 1);
1770 if (rc) {
1771 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
1772 return rc;
1773 }
David Keitel80668952012-07-27 14:25:49 -07001774 break;
1775 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08001776 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07001777 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07001778 chip->usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
1779 if (chip->usb_present) {
1780 rc = qpnp_chg_masked_write(chip,
1781 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
1782 ENUM_T_STOP_BIT,
1783 ENUM_T_STOP_BIT, 1);
1784 if (rc) {
1785 pr_err("failed to write enum stop rc=%d\n", rc);
1786 return -ENXIO;
1787 }
1788 }
David Keiteld681cda2012-10-02 15:44:21 -07001789
1790 rc = qpnp_chg_masked_write(chip,
David Keitel5c3a7702012-12-20 11:13:21 -08001791 chip->usb_chgpth_base + USB_OVP_CTL,
1792 USB_VALID_DEB_20MS,
1793 USB_VALID_DEB_20MS, 1);
1794
1795 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -07001796 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
1797 ENUM_T_STOP_BIT,
1798 ENUM_T_STOP_BIT, 1);
1799
David Keitel344c6972013-04-09 19:28:21 -07001800 rc = qpnp_chg_masked_write(chip,
1801 chip->usb_chgpth_base + SEC_ACCESS,
1802 0xFF,
1803 0xA5, 1);
1804
1805 rc = qpnp_chg_masked_write(chip,
1806 chip->usb_chgpth_base + USB_CHG_GONE_REV_BST,
1807 0xFF,
1808 0x80, 1);
1809
David Keitel80668952012-07-27 14:25:49 -07001810 break;
1811 case SMBB_DC_CHGPTH_SUBTYPE:
1812 break;
1813 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08001814 case SMBBP_BOOST_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07001815 break;
1816 case SMBB_MISC_SUBTYPE:
David Keitelfe51cb92013-04-02 19:42:58 -07001817 chip->type = SMBB;
David Keitelf2170cc2013-02-20 17:49:03 -08001818 case SMBBP_MISC_SUBTYPE:
David Keitelfe51cb92013-04-02 19:42:58 -07001819 chip->type = SMBBP;
David Keitel46c9f7b2013-04-02 19:54:12 -07001820 case SMBCL_MISC_SUBTYPE:
1821 chip->type = SMBCL;
David Keitel80668952012-07-27 14:25:49 -07001822 pr_debug("Setting BOOT_DONE\n");
1823 rc = qpnp_chg_masked_write(chip,
1824 chip->misc_base + CHGR_MISC_BOOT_DONE,
1825 CHGR_BOOT_DONE, CHGR_BOOT_DONE, 1);
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08001826 rc = qpnp_chg_read(chip, &reg,
1827 chip->misc_base + MISC_REVISION2, 1);
1828 if (rc) {
1829 pr_err("failed to read revision register rc=%d\n", rc);
1830 return rc;
1831 }
David Keitel80668952012-07-27 14:25:49 -07001832
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08001833 chip->revision = reg;
David Keitel80668952012-07-27 14:25:49 -07001834 break;
1835 default:
1836 pr_err("Invalid peripheral subtype\n");
1837 }
1838 return rc;
1839}
1840
David Keitel112ba9c2013-04-12 18:40:43 -07001841#define OF_PROP_READ(chip, prop, qpnp_dt_property, retval, optional) \
1842do { \
1843 if (retval) \
1844 break; \
1845 \
1846 retval = of_property_read_u32(chip->spmi->dev.of_node, \
1847 "qcom," qpnp_dt_property, \
1848 &chip->prop); \
1849 \
1850 if ((retval == -EINVAL) && optional) \
1851 retval = 0; \
1852 else if (retval) \
1853 pr_err("Error reading " #qpnp_dt_property \
1854 " property rc = %d\n", rc); \
1855} while (0)
1856
1857static int
1858qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
1859{
1860 int rc = 0;
1861
1862 OF_PROP_READ(chip, max_voltage_mv, "vddmax-mv", rc, 0);
1863 OF_PROP_READ(chip, min_voltage_mv, "vinmin-mv", rc, 0);
1864 OF_PROP_READ(chip, safe_voltage_mv, "vddsafe-mv", rc, 0);
1865 OF_PROP_READ(chip, resume_delta_mv, "vbatdet-delta-mv", rc, 0);
1866 OF_PROP_READ(chip, safe_current, "ibatsafe-ma", rc, 0);
1867 OF_PROP_READ(chip, max_bat_chg_current, "ibatmax-ma", rc, 0);
1868 if (rc)
1869 pr_err("failed to read required dt parameters %d\n", rc);
1870
1871 OF_PROP_READ(chip, term_current, "ibatterm-ma", rc, 1);
1872 OF_PROP_READ(chip, maxinput_dc_ma, "maxinput-dc-ma", rc, 1);
1873 OF_PROP_READ(chip, maxinput_usb_ma, "maxinput-usb-ma", rc, 1);
1874 OF_PROP_READ(chip, warm_bat_decidegc, "warm-bat-decidegc", rc, 1);
1875 OF_PROP_READ(chip, cool_bat_decidegc, "cool-bat-decidegc", rc, 1);
David Keitela4b7b592013-04-11 18:34:35 -07001876 OF_PROP_READ(chip, tchg_mins, "tchg-mins", rc, 1);
David Keitel112ba9c2013-04-12 18:40:43 -07001877 if (rc)
1878 return rc;
1879
1880 /* Look up JEITA compliance parameters if cool and warm temp provided */
1881 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
1882 rc = qpnp_adc_tm_is_ready();
1883 if (rc) {
1884 pr_err("tm not ready %d\n", rc);
1885 return rc;
1886 }
1887
1888 OF_PROP_READ(chip, warm_bat_chg_ma, "ibatmax-warm-ma", rc, 1);
1889 OF_PROP_READ(chip, cool_bat_chg_ma, "ibatmax-cool-ma", rc, 1);
1890 OF_PROP_READ(chip, warm_bat_mv, "warm-bat-mv", rc, 1);
1891 OF_PROP_READ(chip, cool_bat_mv, "cool-bat-mv", rc, 1);
1892 if (rc)
1893 return rc;
1894 }
1895
1896 /* Get the charging-disabled property */
1897 chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
1898 "qcom,charging-disabled");
1899
1900 /* Get the fake-batt-values property */
1901 chip->use_default_batt_values =
1902 of_property_read_bool(chip->spmi->dev.of_node,
1903 "qcom,use-default-batt-values");
1904
1905 /* Disable charging when faking battery values */
1906 if (chip->use_default_batt_values)
1907 chip->charging_disabled = true;
1908
1909 of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
1910 &(chip->thermal_levels));
1911
1912 if (chip->thermal_levels > sizeof(int)) {
1913 chip->thermal_mitigation = kzalloc(
1914 chip->thermal_levels,
1915 GFP_KERNEL);
1916
1917 if (chip->thermal_mitigation == NULL) {
1918 pr_err("thermal mitigation kzalloc() failed.\n");
1919 return rc;
1920 }
1921
1922 chip->thermal_levels /= sizeof(int);
1923 rc = of_property_read_u32_array(chip->spmi->dev.of_node,
1924 "qcom,thermal-mitigation",
1925 chip->thermal_mitigation, chip->thermal_levels);
1926 if (rc) {
1927 pr_err("qcom,thermal-mitigation missing in dt\n");
1928 return rc;
1929 }
1930 }
1931
1932 return rc;
1933}
1934
David Keitel80668952012-07-27 14:25:49 -07001935static int __devinit
1936qpnp_charger_probe(struct spmi_device *spmi)
1937{
1938 u8 subtype;
1939 struct qpnp_chg_chip *chip;
1940 struct resource *resource;
1941 struct spmi_resource *spmi_resource;
Xiaozhe Shid5d21412013-02-06 17:14:41 -08001942 bool present;
David Keitel80668952012-07-27 14:25:49 -07001943 int rc = 0;
1944
1945 chip = kzalloc(sizeof *chip, GFP_KERNEL);
1946 if (chip == NULL) {
1947 pr_err("kzalloc() failed.\n");
1948 return -ENOMEM;
1949 }
1950
David Keitel80668952012-07-27 14:25:49 -07001951 chip->dev = &(spmi->dev);
1952 chip->spmi = spmi;
1953
1954 chip->usb_psy = power_supply_get_by_name("usb");
1955 if (!chip->usb_psy) {
1956 pr_err("usb supply not found deferring probe\n");
1957 rc = -EPROBE_DEFER;
1958 goto fail_chg_enable;
1959 }
1960
David Keitel112ba9c2013-04-12 18:40:43 -07001961 /* Get all device tree properties */
1962 rc = qpnp_charger_read_dt_props(chip);
1963 if (rc)
David Keitel80668952012-07-27 14:25:49 -07001964 goto fail_chg_enable;
David Keitel3dd5e0f2012-12-12 18:12:36 -08001965
David Keitel80668952012-07-27 14:25:49 -07001966 spmi_for_each_container_dev(spmi_resource, spmi) {
1967 if (!spmi_resource) {
1968 pr_err("qpnp_chg: spmi resource absent\n");
1969 rc = -ENXIO;
1970 goto fail_chg_enable;
1971 }
1972
1973 resource = spmi_get_resource(spmi, spmi_resource,
1974 IORESOURCE_MEM, 0);
1975 if (!(resource && resource->start)) {
1976 pr_err("node %s IO resource absent!\n",
1977 spmi->dev.of_node->full_name);
1978 rc = -ENXIO;
1979 goto fail_chg_enable;
1980 }
1981
1982 rc = qpnp_chg_read(chip, &subtype,
1983 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
1984 if (rc) {
1985 pr_err("Peripheral subtype read failed rc=%d\n", rc);
1986 goto fail_chg_enable;
1987 }
1988
1989 switch (subtype) {
1990 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08001991 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07001992 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07001993 chip->chgr_base = resource->start;
1994 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
1995 if (rc) {
1996 pr_err("Failed to init subtype 0x%x rc=%d\n",
1997 subtype, rc);
1998 goto fail_chg_enable;
1999 }
2000 break;
2001 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002002 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002003 case SMBCL_BUCK_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002004 chip->buck_base = resource->start;
2005 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2006 if (rc) {
2007 pr_err("Failed to init subtype 0x%x rc=%d\n",
2008 subtype, rc);
2009 goto fail_chg_enable;
2010 }
David Keitel344c6972013-04-09 19:28:21 -07002011
2012 rc = qpnp_chg_masked_write(chip,
2013 chip->buck_base + SEC_ACCESS,
2014 0xFF,
2015 0xA5, 1);
2016
2017 rc = qpnp_chg_masked_write(chip,
2018 chip->buck_base + BUCK_VCHG_OV,
2019 0xff,
2020 0x00, 1);
2021
2022 rc = qpnp_chg_masked_write(chip,
2023 chip->buck_base + SEC_ACCESS,
2024 0xFF,
2025 0xA5, 1);
2026
2027 rc = qpnp_chg_masked_write(chip,
2028 chip->buck_base + BUCK_TEST_SMBC_MODES,
2029 0xFF,
2030 0x80, 1);
2031
David Keitel80668952012-07-27 14:25:49 -07002032 break;
2033 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002034 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002035 case SMBCL_BAT_IF_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002036 chip->bat_if_base = resource->start;
2037 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2038 if (rc) {
2039 pr_err("Failed to init subtype 0x%x rc=%d\n",
2040 subtype, rc);
2041 goto fail_chg_enable;
2042 }
2043 break;
2044 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002045 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002046 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002047 chip->usb_chgpth_base = resource->start;
2048 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2049 if (rc) {
2050 pr_err("Failed to init subtype 0x%x rc=%d\n",
2051 subtype, rc);
2052 goto fail_chg_enable;
2053 }
2054 break;
2055 case SMBB_DC_CHGPTH_SUBTYPE:
2056 chip->dc_chgpth_base = resource->start;
2057 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2058 if (rc) {
2059 pr_err("Failed to init subtype 0x%x rc=%d\n",
2060 subtype, rc);
2061 goto fail_chg_enable;
2062 }
2063 break;
2064 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002065 case SMBBP_BOOST_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002066 chip->boost_base = resource->start;
2067 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2068 if (rc) {
2069 pr_err("Failed to init subtype 0x%x rc=%d\n",
2070 subtype, rc);
2071 goto fail_chg_enable;
2072 }
2073 break;
2074 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002075 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002076 case SMBCL_MISC_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002077 chip->misc_base = resource->start;
2078 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2079 if (rc) {
2080 pr_err("Failed to init subtype=0x%x rc=%d\n",
2081 subtype, rc);
2082 goto fail_chg_enable;
2083 }
2084 break;
2085 default:
2086 pr_err("Invalid peripheral subtype=0x%x\n", subtype);
2087 rc = -EINVAL;
2088 goto fail_chg_enable;
2089 }
2090 }
2091 dev_set_drvdata(&spmi->dev, chip);
2092 device_init_wakeup(&spmi->dev, 1);
2093
David Keitelf2170cc2013-02-20 17:49:03 -08002094 if (chip->bat_if_base) {
2095 rc = qpnp_vadc_is_ready();
2096 if (rc)
2097 goto fail_chg_enable;
David Keitel80668952012-07-27 14:25:49 -07002098
Xiaozhe Shid5d21412013-02-06 17:14:41 -08002099 /* if bms exists, notify it of the presence of the battery */
2100 if (!chip->bms_psy)
2101 chip->bms_psy = power_supply_get_by_name("bms");
2102 if (chip->bms_psy) {
2103 present = get_prop_batt_present(chip);
2104 power_supply_set_present(chip->bms_psy, present);
2105 }
2106
David Keitelf2170cc2013-02-20 17:49:03 -08002107 chip->batt_psy.name = "battery";
2108 chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
2109 chip->batt_psy.properties = msm_batt_power_props;
2110 chip->batt_psy.num_properties =
2111 ARRAY_SIZE(msm_batt_power_props);
2112 chip->batt_psy.get_property = qpnp_batt_power_get_property;
2113 chip->batt_psy.set_property = qpnp_batt_power_set_property;
2114 chip->batt_psy.property_is_writeable =
2115 qpnp_batt_property_is_writeable;
2116 chip->batt_psy.external_power_changed =
David Keitel80668952012-07-27 14:25:49 -07002117 qpnp_batt_external_power_changed;
2118
David Keitelf2170cc2013-02-20 17:49:03 -08002119 rc = power_supply_register(chip->dev, &chip->batt_psy);
2120 if (rc < 0) {
2121 pr_err("batt failed to register rc = %d\n", rc);
2122 goto fail_chg_enable;
2123 }
David Keitel79f4c932013-04-03 16:08:39 -07002124 INIT_WORK(&chip->adc_measure_work,
2125 qpnp_bat_if_adc_measure_work);
David Keitelc7093b02013-02-14 12:50:04 -08002126 }
2127
David Keitel5910eea2013-05-02 15:32:25 -07002128 INIT_DELAYED_WORK(&chip->arb_stop_work, qpnp_arb_stop_work);
2129
David Keitelf2170cc2013-02-20 17:49:03 -08002130 if (chip->dc_chgpth_base) {
2131 chip->dc_psy.name = "qpnp-dc";
2132 chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
2133 chip->dc_psy.supplied_to = pm_power_supplied_to;
2134 chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
2135 chip->dc_psy.properties = pm_power_props_mains;
2136 chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
2137 chip->dc_psy.get_property = qpnp_power_get_property_mains;
2138
2139 rc = power_supply_register(chip->dev, &chip->dc_psy);
2140 if (rc < 0) {
2141 pr_err("power_supply_register dc failed rc=%d\n", rc);
2142 goto unregister_batt;
2143 }
David Keitel80668952012-07-27 14:25:49 -07002144 }
2145
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002146 /* Turn on appropriate workaround flags */
2147 qpnp_chg_setup_flags(chip);
2148
David Keitel80668952012-07-27 14:25:49 -07002149 power_supply_set_present(chip->usb_psy,
2150 qpnp_chg_is_usb_chg_plugged_in(chip));
2151
David Keitelf2170cc2013-02-20 17:49:03 -08002152 if (chip->maxinput_dc_ma && chip->dc_chgpth_base) {
David Keitel22ed2232013-01-28 11:04:07 -08002153 rc = qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
2154 if (rc) {
2155 pr_err("Error setting idcmax property %d\n", rc);
David Keitelf2170cc2013-02-20 17:49:03 -08002156 goto unregister_batt;
David Keitel22ed2232013-01-28 11:04:07 -08002157 }
2158 }
2159
David Keitel0c1a4532013-03-21 16:39:06 -07002160 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2161 chip->adc_param.low_temp = chip->cool_bat_decidegc;
2162 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel454ee842013-03-08 16:19:11 -08002163 chip->adc_param.timer_interval = ADC_MEAS2_INTERVAL_1S;
2164 chip->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
2165 chip->adc_param.btm_ctx = chip;
2166 chip->adc_param.threshold_notification =
2167 qpnp_chg_adc_notification;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -08002168 chip->adc_param.channel = LR_MUX1_BATT_THERM;
David Keitel0c1a4532013-03-21 16:39:06 -07002169
2170 if (get_prop_batt_present(chip)) {
2171 rc = qpnp_adc_tm_channel_measure(&chip->adc_param);
2172 if (rc) {
2173 pr_err("request ADC error %d\n", rc);
2174 goto fail_chg_enable;
2175 }
David Keitel454ee842013-03-08 16:19:11 -08002176 }
2177 }
2178
David Keitel03ee6b52012-10-22 12:25:19 -07002179 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitelb1ddb742012-11-06 19:05:51 -08002180 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
David Keitelbf359042012-10-19 16:54:58 -07002181
David Keitel0f35be42013-04-16 11:10:40 -07002182 rc = qpnp_chg_request_irqs(chip);
2183 if (rc) {
2184 pr_err("failed to request interrupts %d\n", rc);
2185 goto unregister_batt;
2186 }
2187
Abhijeet Dharmapurikar2d996b12013-01-03 17:48:02 -08002188 pr_info("success chg_dis = %d, usb = %d, dc = %d b_health = %d batt_present = %d\n",
2189 chip->charging_disabled,
2190 qpnp_chg_is_usb_chg_plugged_in(chip),
2191 qpnp_chg_is_dc_chg_plugged_in(chip),
2192 get_prop_batt_present(chip),
2193 get_prop_batt_health(chip));
David Keitel80668952012-07-27 14:25:49 -07002194 return 0;
2195
David Keitelc7093b02013-02-14 12:50:04 -08002196unregister_batt:
David Keitelf2170cc2013-02-20 17:49:03 -08002197 if (chip->bat_if_base)
2198 power_supply_unregister(&chip->batt_psy);
David Keitel80668952012-07-27 14:25:49 -07002199fail_chg_enable:
David Keitelbe208252013-01-31 14:49:25 -08002200 kfree(chip->thermal_mitigation);
David Keitel80668952012-07-27 14:25:49 -07002201 kfree(chip);
2202 dev_set_drvdata(&spmi->dev, NULL);
2203 return rc;
2204}
2205
2206static int __devexit
2207qpnp_charger_remove(struct spmi_device *spmi)
2208{
2209 struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
David Keitel0c1a4532013-03-21 16:39:06 -07002210 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
2211 && chip->batt_present) {
2212 qpnp_adc_tm_disable_chan_meas(&chip->adc_param);
2213 }
David Keitel79f4c932013-04-03 16:08:39 -07002214 cancel_work_sync(&chip->adc_measure_work);
2215
David Keitel80668952012-07-27 14:25:49 -07002216 dev_set_drvdata(&spmi->dev, NULL);
2217 kfree(chip);
2218
2219 return 0;
2220}
2221
David Keitel85ae4342013-04-16 11:46:00 -07002222static int qpnp_chg_resume(struct device *dev)
2223{
2224 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2225 int rc = 0;
2226
2227 rc = qpnp_chg_masked_write(chip,
2228 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2229 VREF_BATT_THERM_FORCE_ON,
2230 VREF_BATT_THERM_FORCE_ON, 1);
2231 if (rc)
2232 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
2233
2234 return rc;
2235}
2236
2237static int qpnp_chg_suspend(struct device *dev)
2238{
2239 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2240 int rc = 0;
2241
2242 rc = qpnp_chg_masked_write(chip,
2243 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2244 VREF_BATT_THERM_FORCE_ON,
2245 VREF_BAT_THM_ENABLED_FSM, 1);
2246 if (rc)
2247 pr_debug("failed to enable FSM ctrl VREF_BAT_THM rc=%d\n", rc);
2248
2249 return rc;
2250}
2251
David Keitel723d5012013-05-03 13:17:27 -07002252static const struct dev_pm_ops qpnp_chg_pm_ops = {
David Keitel85ae4342013-04-16 11:46:00 -07002253 .resume = qpnp_chg_resume,
2254 .suspend = qpnp_chg_suspend,
2255};
2256
David Keitel80668952012-07-27 14:25:49 -07002257static struct spmi_driver qpnp_charger_driver = {
2258 .probe = qpnp_charger_probe,
2259 .remove = __devexit_p(qpnp_charger_remove),
2260 .driver = {
David Keitel723d5012013-05-03 13:17:27 -07002261 .name = QPNP_CHARGER_DEV_NAME,
2262 .owner = THIS_MODULE,
2263 .of_match_table = qpnp_charger_match_table,
2264 .pm = &qpnp_chg_pm_ops,
David Keitel80668952012-07-27 14:25:49 -07002265 },
2266};
2267
2268/**
2269 * qpnp_chg_init() - register spmi driver for qpnp-chg
2270 */
2271int __init
2272qpnp_chg_init(void)
2273{
2274 return spmi_driver_register(&qpnp_charger_driver);
2275}
2276module_init(qpnp_chg_init);
2277
2278static void __exit
2279qpnp_chg_exit(void)
2280{
2281 spmi_driver_unregister(&qpnp_charger_driver);
2282}
2283module_exit(qpnp_chg_exit);
2284
2285
2286MODULE_DESCRIPTION("QPNP charger driver");
2287MODULE_LICENSE("GPL v2");
2288MODULE_ALIAS("platform:" QPNP_CHARGER_DEV_NAME);