blob: 352889d54a6c215950bd17b42d0d3886d76f9dcd [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 Keitel6dc4ed42013-05-17 11:08:58 -070028#include <linux/regulator/driver.h>
29#include <linux/regulator/of_regulator.h>
30#include <linux/regulator/machine.h>
David Keitel80668952012-07-27 14:25:49 -070031
32/* Interrupt offsets */
33#define INT_RT_STS(base) (base + 0x10)
34#define INT_SET_TYPE(base) (base + 0x11)
35#define INT_POLARITY_HIGH(base) (base + 0x12)
36#define INT_POLARITY_LOW(base) (base + 0x13)
37#define INT_LATCHED_CLR(base) (base + 0x14)
38#define INT_EN_SET(base) (base + 0x15)
39#define INT_EN_CLR(base) (base + 0x16)
40#define INT_LATCHED_STS(base) (base + 0x18)
41#define INT_PENDING_STS(base) (base + 0x19)
42#define INT_MID_SEL(base) (base + 0x1A)
43#define INT_PRIORITY(base) (base + 0x1B)
44
45/* Peripheral register offsets */
46#define CHGR_CHG_OPTION 0x08
47#define CHGR_ATC_STATUS 0x0A
48#define CHGR_VBAT_STATUS 0x0B
49#define CHGR_IBAT_BMS 0x0C
50#define CHGR_IBAT_STS 0x0D
51#define CHGR_VDD_MAX 0x40
52#define CHGR_VDD_SAFE 0x41
53#define CHGR_VDD_MAX_STEP 0x42
54#define CHGR_IBAT_MAX 0x44
55#define CHGR_IBAT_SAFE 0x45
56#define CHGR_VIN_MIN 0x47
57#define CHGR_VIN_MIN_STEP 0x48
58#define CHGR_CHG_CTRL 0x49
59#define CHGR_CHG_FAILED 0x4A
60#define CHGR_ATC_CTRL 0x4B
61#define CHGR_ATC_FAILED 0x4C
62#define CHGR_VBAT_TRKL 0x50
63#define CHGR_VBAT_WEAK 0x52
64#define CHGR_IBAT_ATC_A 0x54
65#define CHGR_IBAT_ATC_B 0x55
66#define CHGR_IBAT_TERM_CHGR 0x5B
67#define CHGR_IBAT_TERM_BMS 0x5C
68#define CHGR_VBAT_DET 0x5D
69#define CHGR_TTRKL_MAX 0x5F
70#define CHGR_TTRKL_MAX_EN 0x60
71#define CHGR_TCHG_MAX 0x61
72#define CHGR_CHG_WDOG_TIME 0x62
73#define CHGR_CHG_WDOG_DLY 0x63
74#define CHGR_CHG_WDOG_PET 0x64
75#define CHGR_CHG_WDOG_EN 0x65
David Keitel9201df32013-01-10 18:38:34 -080076#define CHGR_IR_DROP_COMPEN 0x67
David Keitel22ed2232013-01-28 11:04:07 -080077#define CHGR_I_MAX_REG 0x44
David Keiteld681cda2012-10-02 15:44:21 -070078#define CHGR_USB_USB_SUSP 0x47
David Keitel6f865cd2012-11-30 15:04:32 -080079#define CHGR_USB_USB_OTG_CTL 0x48
David Keitel80668952012-07-27 14:25:49 -070080#define CHGR_USB_ENUM_T_STOP 0x4E
81#define CHGR_CHG_TEMP_THRESH 0x66
82#define CHGR_BAT_IF_PRES_STATUS 0x08
David Keiteld681cda2012-10-02 15:44:21 -070083#define CHGR_STATUS 0x09
David Keitel80668952012-07-27 14:25:49 -070084#define CHGR_BAT_IF_VCP 0x42
85#define CHGR_BAT_IF_BATFET_CTRL1 0x90
86#define CHGR_MISC_BOOT_DONE 0x42
David Keitel9fd07382013-05-02 15:37:44 -070087#define CHGR_BUCK_COMPARATOR_OVRIDE_1 0xEB
David Keiteld681cda2012-10-02 15:44:21 -070088#define CHGR_BUCK_COMPARATOR_OVRIDE_3 0xED
David Keitel9201df32013-01-10 18:38:34 -080089#define CHGR_BUCK_BCK_VBAT_REG_MODE 0x74
Sridhar Parasuramae183bd2012-12-21 09:28:46 -080090#define MISC_REVISION2 0x01
David Keitel5c3a7702012-12-20 11:13:21 -080091#define USB_OVP_CTL 0x42
David Keitel344c6972013-04-09 19:28:21 -070092#define USB_CHG_GONE_REV_BST 0xED
93#define BUCK_VCHG_OV 0x77
94#define BUCK_TEST_SMBC_MODES 0xE6
David Keiteld681cda2012-10-02 15:44:21 -070095#define SEC_ACCESS 0xD0
David Keitel85ae4342013-04-16 11:46:00 -070096#define BAT_IF_VREF_BAT_THM_CTRL 0x4A
David Keitel796882d2013-05-14 18:01:11 -070097#define BAT_IF_BPD_CTRL 0x48
David Keitel6dc4ed42013-05-17 11:08:58 -070098#define BOOST_VSET 0x41
99#define BOOST_ENABLE_CONTROL 0x46
David Keitel33f58952013-05-20 16:17:36 -0700100#define COMP_OVR1 0xEA
101
David Keitel80668952012-07-27 14:25:49 -0700102#define REG_OFFSET_PERP_SUBTYPE 0x05
David Keitel6dc4ed42013-05-17 11:08:58 -0700103
David Keitelf2170cc2013-02-20 17:49:03 -0800104/* SMBB peripheral subtype values */
David Keitel80668952012-07-27 14:25:49 -0700105#define SMBB_CHGR_SUBTYPE 0x01
106#define SMBB_BUCK_SUBTYPE 0x02
107#define SMBB_BAT_IF_SUBTYPE 0x03
108#define SMBB_USB_CHGPTH_SUBTYPE 0x04
109#define SMBB_DC_CHGPTH_SUBTYPE 0x05
110#define SMBB_BOOST_SUBTYPE 0x06
111#define SMBB_MISC_SUBTYPE 0x07
112
David Keitelf2170cc2013-02-20 17:49:03 -0800113/* SMBB peripheral subtype values */
114#define SMBBP_CHGR_SUBTYPE 0x31
115#define SMBBP_BUCK_SUBTYPE 0x32
116#define SMBBP_BAT_IF_SUBTYPE 0x33
117#define SMBBP_USB_CHGPTH_SUBTYPE 0x34
118#define SMBBP_BOOST_SUBTYPE 0x36
119#define SMBBP_MISC_SUBTYPE 0x37
120
David Keitel46c9f7b2013-04-02 19:54:12 -0700121/* SMBCL peripheral subtype values */
122#define SMBCL_CHGR_SUBTYPE 0x41
123#define SMBCL_BUCK_SUBTYPE 0x42
124#define SMBCL_BAT_IF_SUBTYPE 0x43
125#define SMBCL_USB_CHGPTH_SUBTYPE 0x44
126#define SMBCL_MISC_SUBTYPE 0x47
127
David Keitel80668952012-07-27 14:25:49 -0700128#define QPNP_CHARGER_DEV_NAME "qcom,qpnp-charger"
129
David Keitelb80eda82012-10-15 10:49:11 -0700130/* Status bits and masks */
131#define CHGR_BOOT_DONE BIT(7)
132#define CHGR_CHG_EN BIT(7)
133#define CHGR_ON_BAT_FORCE_BIT BIT(0)
David Keitel5c3a7702012-12-20 11:13:21 -0800134#define USB_VALID_DEB_20MS 0x03
David Keitel9201df32013-01-10 18:38:34 -0800135#define BUCK_VBAT_REG_NODE_SEL_BIT BIT(0)
David Keitel85ae4342013-04-16 11:46:00 -0700136#define VREF_BATT_THERM_FORCE_ON 0xC0
David Keitel796882d2013-05-14 18:01:11 -0700137#define BAT_IF_BPD_CTRL_SEL 0x03
David Keitel85ae4342013-04-16 11:46:00 -0700138#define VREF_BAT_THM_ENABLED_FSM 0x80
David Keitel796882d2013-05-14 18:01:11 -0700139#define REV_BST_DETECTED BIT(0)
140#define BAT_THM_EN BIT(1)
141#define BAT_ID_EN BIT(0)
David Keitel6dc4ed42013-05-17 11:08:58 -0700142#define BOOST_PWR_EN BIT(7)
David Keitelb80eda82012-10-15 10:49:11 -0700143
David Keitel80668952012-07-27 14:25:49 -0700144/* Interrupt definitions */
145/* smbb_chg_interrupts */
146#define CHG_DONE_IRQ BIT(7)
147#define CHG_FAILED_IRQ BIT(6)
148#define FAST_CHG_ON_IRQ BIT(5)
149#define TRKL_CHG_ON_IRQ BIT(4)
150#define STATE_CHANGE_ON_IR BIT(3)
151#define CHGWDDOG_IRQ BIT(2)
152#define VBAT_DET_HI_IRQ BIT(1)
153#define VBAT_DET_LOW_IRQ BIT(0)
154
155/* smbb_buck_interrupts */
156#define VDD_LOOP_IRQ BIT(6)
157#define IBAT_LOOP_IRQ BIT(5)
158#define ICHG_LOOP_IRQ BIT(4)
159#define VCHG_LOOP_IRQ BIT(3)
160#define OVERTEMP_IRQ BIT(2)
161#define VREF_OV_IRQ BIT(1)
162#define VBAT_OV_IRQ BIT(0)
163
164/* smbb_bat_if_interrupts */
165#define PSI_IRQ BIT(4)
166#define VCP_ON_IRQ BIT(3)
167#define BAT_FET_ON_IRQ BIT(2)
168#define BAT_TEMP_OK_IRQ BIT(1)
169#define BATT_PRES_IRQ BIT(0)
170
171/* smbb_usb_interrupts */
172#define CHG_GONE_IRQ BIT(2)
173#define USBIN_VALID_IRQ BIT(1)
174#define COARSE_DET_USB_IRQ BIT(0)
175
176/* smbb_dc_interrupts */
177#define DCIN_VALID_IRQ BIT(1)
178#define COARSE_DET_DC_IRQ BIT(0)
179
180/* smbb_boost_interrupts */
181#define LIMIT_ERROR_IRQ BIT(1)
182#define BOOST_PWR_OK_IRQ BIT(0)
183
184/* smbb_misc_interrupts */
185#define TFTWDOG_IRQ BIT(0)
186
David Keitelfe51cb92013-04-02 19:42:58 -0700187/* SMBB types */
188#define SMBB BIT(1)
189#define SMBBP BIT(2)
190#define SMBCL BIT(3)
191
David Keiteld681cda2012-10-02 15:44:21 -0700192/* Workaround flags */
193#define CHG_FLAGS_VCP_WA BIT(0)
David Keitel33f58952013-05-20 16:17:36 -0700194#define BOOST_FLASH_WA BIT(1)
David Keiteld681cda2012-10-02 15:44:21 -0700195
David Keitel47185a62013-05-15 18:54:10 -0700196struct qpnp_chg_irq {
197 unsigned int irq;
198 unsigned long disabled;
199};
200
David Keitel6dc4ed42013-05-17 11:08:58 -0700201struct qpnp_chg_regulator {
202 struct regulator_desc rdesc;
203 struct regulator_dev *rdev;
204};
205
David Keitel80668952012-07-27 14:25:49 -0700206/**
207 * struct qpnp_chg_chip - device information
208 * @dev: device pointer to access the parent
209 * @spmi: spmi pointer to access spmi information
210 * @chgr_base: charger peripheral base address
211 * @buck_base: buck peripheral base address
212 * @bat_if_base: battery interface peripheral base address
213 * @usb_chgpth_base: USB charge path peripheral base address
214 * @dc_chgpth_base: DC charge path peripheral base address
215 * @boost_base: boost peripheral base address
216 * @misc_base: misc peripheral base address
217 * @freq_base: freq peripheral base address
David Keitel454ee842013-03-08 16:19:11 -0800218 * @bat_is_cool: indicates that battery is cool
219 * @bat_is_warm: indicates that battery is warm
David Keitel80668952012-07-27 14:25:49 -0700220 * @chg_done: indicates that charging is completed
221 * @usb_present: present status of usb
222 * @dc_present: present status of dc
David Keitel42ae0aa2013-03-08 16:20:10 -0800223 * @batt_present: present status of battery
David Keitel3dd5e0f2012-12-12 18:12:36 -0800224 * @use_default_batt_values: flag to report default battery properties
David Keitel80668952012-07-27 14:25:49 -0700225 * @max_voltage_mv: the max volts the batt should be charged up to
David Keitel5d44fa52012-12-03 16:37:31 -0800226 * @min_voltage_mv: min battery voltage before turning the FET on
David Keitel454ee842013-03-08 16:19:11 -0800227 * @max_bat_chg_current: maximum battery charge current in mA
228 * @warm_bat_chg_ma: warm battery maximum charge current in mA
229 * @cool_bat_chg_ma: cool battery maximum charge current in mA
230 * @warm_bat_mv: warm temperature battery target voltage
231 * @cool_bat_mv: cool temperature battery target voltage
232 * @resume_delta_mv: voltage delta at which battery resumes charging
David Keitel80668952012-07-27 14:25:49 -0700233 * @term_current: the charging based term current
David Keitel5d44fa52012-12-03 16:37:31 -0800234 * @safe_current: battery safety current setting
David Keitel22ed2232013-01-28 11:04:07 -0800235 * @maxinput_usb_ma: Maximum Input current USB
236 * @maxinput_dc_ma: Maximum Input current DC
David Keitel0c1a4532013-03-21 16:39:06 -0700237 * @warm_bat_decidegc Warm battery temperature in degree Celsius
238 * @cool_bat_decidegc Cool battery temperature in degree Celsius
David Keitel80668952012-07-27 14:25:49 -0700239 * @revision: PMIC revision
David Keitelfe51cb92013-04-02 19:42:58 -0700240 * @type: SMBB type
241 * @tchg_mins maximum allowed software initiated charge time
David Keitelbe208252013-01-31 14:49:25 -0800242 * @thermal_levels amount of thermal mitigation levels
243 * @thermal_mitigation thermal mitigation level values
244 * @therm_lvl_sel thermal mitigation level selection
David Keitel80668952012-07-27 14:25:49 -0700245 * @dc_psy power supply to export information to userspace
246 * @usb_psy power supply to export information to userspace
247 * @bms_psy power supply to export information to userspace
248 * @batt_psy: power supply to export information to userspace
David Keiteld681cda2012-10-02 15:44:21 -0700249 * @flags: flags to activate specific workarounds
250 * throughout the driver
David Keitel80668952012-07-27 14:25:49 -0700251 *
252 */
253struct qpnp_chg_chip {
254 struct device *dev;
255 struct spmi_device *spmi;
256 u16 chgr_base;
257 u16 buck_base;
258 u16 bat_if_base;
259 u16 usb_chgpth_base;
260 u16 dc_chgpth_base;
261 u16 boost_base;
262 u16 misc_base;
263 u16 freq_base;
David Keitel47185a62013-05-15 18:54:10 -0700264 struct qpnp_chg_irq usbin_valid;
265 struct qpnp_chg_irq dcin_valid;
266 struct qpnp_chg_irq chg_gone;
267 struct qpnp_chg_irq chg_fastchg;
268 struct qpnp_chg_irq chg_trklchg;
269 struct qpnp_chg_irq chg_failed;
270 struct qpnp_chg_irq chg_vbatdet_lo;
271 struct qpnp_chg_irq batt_pres;
David Keitel454ee842013-03-08 16:19:11 -0800272 bool bat_is_cool;
273 bool bat_is_warm;
David Keitel80668952012-07-27 14:25:49 -0700274 bool chg_done;
275 bool usb_present;
276 bool dc_present;
David Keitel42ae0aa2013-03-08 16:20:10 -0800277 bool batt_present;
David Keitel03ee6b52012-10-22 12:25:19 -0700278 bool charging_disabled;
David Keitel3dd5e0f2012-12-12 18:12:36 -0800279 bool use_default_batt_values;
David Keitel8b68d2d2013-05-14 23:36:51 -0700280 bool duty_cycle_100p;
David Keitel796882d2013-05-14 18:01:11 -0700281 unsigned int bpd_detection;
David Keitel80668952012-07-27 14:25:49 -0700282 unsigned int max_bat_chg_current;
David Keitel454ee842013-03-08 16:19:11 -0800283 unsigned int warm_bat_chg_ma;
284 unsigned int cool_bat_chg_ma;
David Keitel80668952012-07-27 14:25:49 -0700285 unsigned int safe_voltage_mv;
286 unsigned int max_voltage_mv;
287 unsigned int min_voltage_mv;
David Keitel454ee842013-03-08 16:19:11 -0800288 unsigned int warm_bat_mv;
289 unsigned int cool_bat_mv;
290 unsigned int resume_delta_mv;
David Keitel9fd07382013-05-02 15:37:44 -0700291 int term_current;
David Keitel22ed2232013-01-28 11:04:07 -0800292 unsigned int maxinput_usb_ma;
293 unsigned int maxinput_dc_ma;
David Keitel0c1a4532013-03-21 16:39:06 -0700294 unsigned int warm_bat_decidegc;
295 unsigned int cool_bat_decidegc;
David Keitel5d44fa52012-12-03 16:37:31 -0800296 unsigned int safe_current;
David Keitel80668952012-07-27 14:25:49 -0700297 unsigned int revision;
David Keitelfe51cb92013-04-02 19:42:58 -0700298 unsigned int type;
299 unsigned int tchg_mins;
David Keitelbe208252013-01-31 14:49:25 -0800300 unsigned int thermal_levels;
301 unsigned int therm_lvl_sel;
302 unsigned int *thermal_mitigation;
David Keitel80668952012-07-27 14:25:49 -0700303 struct power_supply dc_psy;
304 struct power_supply *usb_psy;
305 struct power_supply *bms_psy;
306 struct power_supply batt_psy;
David Keiteld681cda2012-10-02 15:44:21 -0700307 uint32_t flags;
David Keitel454ee842013-03-08 16:19:11 -0800308 struct qpnp_adc_tm_btm_param adc_param;
David Keitel79f4c932013-04-03 16:08:39 -0700309 struct work_struct adc_measure_work;
David Keitel344c6972013-04-09 19:28:21 -0700310 struct delayed_work arb_stop_work;
David Keitel9fd07382013-05-02 15:37:44 -0700311 struct delayed_work eoc_work;
312 struct wake_lock eoc_wake_lock;
David Keitel6dc4ed42013-05-17 11:08:58 -0700313 struct qpnp_chg_regulator otg_vreg;
314 struct qpnp_chg_regulator boost_vreg;
David Keitel80668952012-07-27 14:25:49 -0700315};
316
David Keitel47185a62013-05-15 18:54:10 -0700317
David Keitel80668952012-07-27 14:25:49 -0700318static struct of_device_id qpnp_charger_match_table[] = {
319 { .compatible = QPNP_CHARGER_DEV_NAME, },
320 {}
321};
322
David Keitel796882d2013-05-14 18:01:11 -0700323#define BPD_MAX 3
324
325static const char *bpd_list[BPD_MAX] = {
326 "bpd_thm",
327 "bpd_id",
328 "bpd_thm_id",
329};
330
331static inline int
332get_bpd(const char *name)
333{
334 int i = 0;
335 for (i = 0 ; i < BPD_MAX; i++) {
336 if (strcmp(name, bpd_list[i]) == 0)
337 return i;
338 }
339 return -EINVAL;
340}
341
David Keitel80668952012-07-27 14:25:49 -0700342static int
343qpnp_chg_read(struct qpnp_chg_chip *chip, u8 *val,
344 u16 base, int count)
345{
346 int rc;
347 struct spmi_device *spmi = chip->spmi;
348
349 rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val,
350 count);
351 if (rc) {
352 pr_err("SPMI read failed base=0x%02x sid=0x%02x rc=%d\n", base,
353 spmi->sid, rc);
354 return rc;
355 }
356 return 0;
357}
358
359static int
360qpnp_chg_write(struct qpnp_chg_chip *chip, u8 *val,
361 u16 base, int count)
362{
363 int rc;
364 struct spmi_device *spmi = chip->spmi;
365
366 rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val,
367 count);
368 if (rc) {
369 pr_err("write failed base=0x%02x sid=0x%02x rc=%d\n",
370 base, spmi->sid, rc);
371 return rc;
372 }
373
374 return 0;
375}
376
377static int
378qpnp_chg_masked_write(struct qpnp_chg_chip *chip, u16 base,
379 u8 mask, u8 val, int count)
380{
381 int rc;
382 u8 reg;
383
384 rc = qpnp_chg_read(chip, &reg, base, count);
385 if (rc) {
386 pr_err("spmi read failed: addr=%03X, rc=%d\n", base, rc);
387 return rc;
388 }
389 pr_debug("addr = 0x%x read 0x%x\n", base, reg);
390
391 reg &= ~mask;
392 reg |= val & mask;
393
394 pr_debug("Writing 0x%x\n", reg);
395
396 rc = qpnp_chg_write(chip, &reg, base, count);
397 if (rc) {
398 pr_err("spmi write failed: addr=%03X, rc=%d\n", base, rc);
399 return rc;
400 }
401
402 return 0;
403}
404
David Keitel47185a62013-05-15 18:54:10 -0700405static void
406qpnp_chg_enable_irq(struct qpnp_chg_irq *irq)
407{
408 if (__test_and_clear_bit(0, &irq->disabled)) {
409 pr_debug("number = %d\n", irq->irq);
410 enable_irq(irq->irq);
411 }
412}
413
414static void
415qpnp_chg_disable_irq(struct qpnp_chg_irq *irq)
416{
417 if (!__test_and_set_bit(0, &irq->disabled)) {
418 pr_debug("number = %d\n", irq->irq);
419 disable_irq_nosync(irq->irq);
420 }
421}
422
David Keitel6f865cd2012-11-30 15:04:32 -0800423#define USB_OTG_EN_BIT BIT(0)
424static int
425qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
426{
427 u8 usb_otg_en;
428 int rc;
429
430 rc = qpnp_chg_read(chip, &usb_otg_en,
431 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
432 1);
433
434 if (rc) {
435 pr_err("spmi read failed: addr=%03X, rc=%d\n",
436 chip->usb_chgpth_base + CHGR_STATUS, rc);
437 return rc;
438 }
439 pr_debug("usb otg en 0x%x\n", usb_otg_en);
440
441 return (usb_otg_en & USB_OTG_EN_BIT) ? 1 : 0;
442}
443
David Keitel42ae0aa2013-03-08 16:20:10 -0800444static int
David Keitel6dc4ed42013-05-17 11:08:58 -0700445qpnp_chg_is_boost_en_set(struct qpnp_chg_chip *chip)
446{
447 u8 boost_en_ctl;
448 int rc;
449
450 rc = qpnp_chg_read(chip, &boost_en_ctl,
451 chip->boost_base + BOOST_ENABLE_CONTROL, 1);
452 if (rc) {
453 pr_err("spmi read failed: addr=%03X, rc=%d\n",
454 chip->boost_base + BOOST_ENABLE_CONTROL, rc);
455 return rc;
456 }
457
458 pr_debug("boost en 0x%x\n", boost_en_ctl);
459
460 return (boost_en_ctl & BOOST_PWR_EN) ? 1 : 0;
461}
462
463static int
David Keitel42ae0aa2013-03-08 16:20:10 -0800464qpnp_chg_is_batt_present(struct qpnp_chg_chip *chip)
465{
466 u8 batt_pres_rt_sts;
467 int rc;
468
469 rc = qpnp_chg_read(chip, &batt_pres_rt_sts,
470 INT_RT_STS(chip->bat_if_base), 1);
471 if (rc) {
472 pr_err("spmi read failed: addr=%03X, rc=%d\n",
473 INT_RT_STS(chip->bat_if_base), rc);
474 return rc;
475 }
476
477 return (batt_pres_rt_sts & BATT_PRES_IRQ) ? 1 : 0;
478}
479
David Keiteld681cda2012-10-02 15:44:21 -0700480#define USB_VALID_BIT BIT(7)
David Keitel80668952012-07-27 14:25:49 -0700481static int
482qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip)
483{
484 u8 usbin_valid_rt_sts;
485 int rc;
486
487 rc = qpnp_chg_read(chip, &usbin_valid_rt_sts,
David Keiteld681cda2012-10-02 15:44:21 -0700488 chip->usb_chgpth_base + CHGR_STATUS , 1);
David Keitel80668952012-07-27 14:25:49 -0700489
490 if (rc) {
491 pr_err("spmi read failed: addr=%03X, rc=%d\n",
David Keiteld681cda2012-10-02 15:44:21 -0700492 chip->usb_chgpth_base + CHGR_STATUS, rc);
David Keitel80668952012-07-27 14:25:49 -0700493 return rc;
494 }
495 pr_debug("chgr usb sts 0x%x\n", usbin_valid_rt_sts);
496
David Keiteld681cda2012-10-02 15:44:21 -0700497 return (usbin_valid_rt_sts & USB_VALID_BIT) ? 1 : 0;
David Keitel80668952012-07-27 14:25:49 -0700498}
499
500static int
501qpnp_chg_is_dc_chg_plugged_in(struct qpnp_chg_chip *chip)
502{
503 u8 dcin_valid_rt_sts;
504 int rc;
505
David Keitelf2170cc2013-02-20 17:49:03 -0800506 if (!chip->dc_chgpth_base)
507 return 0;
508
David Keitel80668952012-07-27 14:25:49 -0700509 rc = qpnp_chg_read(chip, &dcin_valid_rt_sts,
510 INT_RT_STS(chip->dc_chgpth_base), 1);
511 if (rc) {
512 pr_err("spmi read failed: addr=%03X, rc=%d\n",
513 INT_RT_STS(chip->dc_chgpth_base), rc);
514 return rc;
515 }
516
517 return (dcin_valid_rt_sts & DCIN_VALID_IRQ) ? 1 : 0;
518}
519
David Keitel22ed2232013-01-28 11:04:07 -0800520#define QPNP_CHG_I_MAX_MIN_100 100
521#define QPNP_CHG_I_MAX_MIN_150 150
522#define QPNP_CHG_I_MAX_MIN_MA 200
523#define QPNP_CHG_I_MAX_MAX_MA 2500
524#define QPNP_CHG_I_MAXSTEP_MA 100
525static int
526qpnp_chg_idcmax_set(struct qpnp_chg_chip *chip, int mA)
527{
528 int rc = 0;
529 u8 dc = 0;
530
531 if (mA < QPNP_CHG_I_MAX_MIN_100
532 || mA > QPNP_CHG_I_MAX_MAX_MA) {
533 pr_err("bad mA=%d asked to set\n", mA);
534 return -EINVAL;
535 }
536
537 if (mA == QPNP_CHG_I_MAX_MIN_100) {
538 dc = 0x00;
539 pr_debug("current=%d setting %02x\n", mA, dc);
540 return qpnp_chg_write(chip, &dc,
541 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
542 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
543 dc = 0x01;
544 pr_debug("current=%d setting %02x\n", mA, dc);
545 return qpnp_chg_write(chip, &dc,
546 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
547 }
548
549 dc = mA / QPNP_CHG_I_MAXSTEP_MA;
550
551 pr_debug("current=%d setting 0x%x\n", mA, dc);
552 rc = qpnp_chg_write(chip, &dc,
553 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
554
555 return rc;
556}
557
David Keitel80668952012-07-27 14:25:49 -0700558static int
559qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
560{
David Keiteld681cda2012-10-02 15:44:21 -0700561 int rc = 0;
562 u8 usb_reg = 0, temp = 8;
David Keitel80668952012-07-27 14:25:49 -0700563
David Keitel22ed2232013-01-28 11:04:07 -0800564 if (mA < QPNP_CHG_I_MAX_MIN_100
565 || mA > QPNP_CHG_I_MAX_MAX_MA) {
David Keitel80668952012-07-27 14:25:49 -0700566 pr_err("bad mA=%d asked to set\n", mA);
567 return -EINVAL;
568 }
569
David Keitel22ed2232013-01-28 11:04:07 -0800570 if (mA == QPNP_CHG_I_MAX_MIN_100) {
571 usb_reg = 0x00;
572 pr_debug("current=%d setting %02x\n", mA, usb_reg);
573 return qpnp_chg_write(chip, &usb_reg,
574 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
575 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
576 usb_reg = 0x01;
577 pr_debug("current=%d setting %02x\n", mA, usb_reg);
578 return qpnp_chg_write(chip, &usb_reg,
579 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
580 }
581
582 /* Impose input current limit */
583 if (chip->maxinput_usb_ma)
584 mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
585
586 usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
David Keitel80668952012-07-27 14:25:49 -0700587
David Keiteld681cda2012-10-02 15:44:21 -0700588 if (chip->flags & CHG_FLAGS_VCP_WA) {
589 temp = 0xA5;
590 rc = qpnp_chg_write(chip, &temp,
591 chip->buck_base + SEC_ACCESS, 1);
592 rc = qpnp_chg_masked_write(chip,
593 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
594 0x0C, 0x0C, 1);
595 }
596
David Keitel80668952012-07-27 14:25:49 -0700597 pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
David Keiteld681cda2012-10-02 15:44:21 -0700598 rc = qpnp_chg_write(chip, &usb_reg,
David Keitel22ed2232013-01-28 11:04:07 -0800599 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
David Keiteld681cda2012-10-02 15:44:21 -0700600
601 if (chip->flags & CHG_FLAGS_VCP_WA) {
602 temp = 0xA5;
603 udelay(200);
604 rc = qpnp_chg_write(chip, &temp,
605 chip->buck_base + SEC_ACCESS, 1);
606 rc = qpnp_chg_masked_write(chip,
607 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
608 0x0C, 0x00, 1);
609 }
610
611 return rc;
612}
613
614#define USB_SUSPEND_BIT BIT(0)
615static int
616qpnp_chg_usb_suspend_enable(struct qpnp_chg_chip *chip, int enable)
617{
618 return qpnp_chg_masked_write(chip,
619 chip->usb_chgpth_base + CHGR_USB_USB_SUSP,
620 USB_SUSPEND_BIT,
621 enable ? USB_SUSPEND_BIT : 0, 1);
David Keitel80668952012-07-27 14:25:49 -0700622}
623
David Keitel344c6972013-04-09 19:28:21 -0700624static int
625qpnp_chg_charge_en(struct qpnp_chg_chip *chip, int enable)
626{
627 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
628 CHGR_CHG_EN,
629 enable ? CHGR_CHG_EN : 0, 1);
630}
631
632static int
633qpnp_chg_force_run_on_batt(struct qpnp_chg_chip *chip, int disable)
634{
635 /* Don't run on battery for batteryless hardware */
636 if (chip->use_default_batt_values)
637 return 0;
David Keitel4d66ea02013-04-30 10:57:58 -0700638 /* Don't force on battery if battery is not present */
639 if (!qpnp_chg_is_batt_present(chip))
640 return 0;
David Keitel344c6972013-04-09 19:28:21 -0700641
642 /* This bit forces the charger to run off of the battery rather
643 * than a connected charger */
644 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
645 CHGR_ON_BAT_FORCE_BIT,
646 disable ? CHGR_ON_BAT_FORCE_BIT : 0, 1);
647}
648
David Keitel8b68d2d2013-05-14 23:36:51 -0700649#define BUCK_DUTY_MASK_100P 0x30
650static int
651qpnp_buck_set_100_duty_cycle_enable(struct qpnp_chg_chip *chip, int enable)
652{
653 int rc;
654
655 pr_debug("enable: %d\n", enable);
656
657 rc = qpnp_chg_masked_write(chip,
658 chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
659 if (rc) {
660 pr_debug("failed to write sec access rc=%d\n", rc);
661 return rc;
662 }
663
664 rc = qpnp_chg_masked_write(chip,
665 chip->buck_base + BUCK_TEST_SMBC_MODES,
666 BUCK_DUTY_MASK_100P, enable ? 0x00 : 0x10, 1);
667 if (rc) {
668 pr_debug("failed enable 100p duty cycle rc=%d\n", rc);
669 return rc;
670 }
671
672 return rc;
673}
674
David Keitel9fd07382013-05-02 15:37:44 -0700675#define COMPATATOR_OVERRIDE_0 0x80
676static int
677qpnp_chg_toggle_chg_done_logic(struct qpnp_chg_chip *chip, int enable)
678{
679 int rc;
680
681 pr_debug("toggle: %d\n", enable);
682
683 rc = qpnp_chg_masked_write(chip,
684 chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
685 if (rc) {
686 pr_debug("failed to write sec access rc=%d\n", rc);
687 return rc;
688 }
689
690 rc = qpnp_chg_masked_write(chip,
691 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_1,
692 0xC0, enable ? 0x00 : COMPATATOR_OVERRIDE_0, 1);
693 if (rc) {
694 pr_debug("failed to toggle chg done override rc=%d\n", rc);
695 return rc;
696 }
697
698 return rc;
699}
700
701#define QPNP_CHG_VBATDET_MIN_MV 3240
702#define QPNP_CHG_VBATDET_MAX_MV 5780
703#define QPNP_CHG_VBATDET_STEP_MV 20
704static int
705qpnp_chg_vbatdet_set(struct qpnp_chg_chip *chip, int vbatdet_mv)
706{
707 u8 temp;
708
709 if (vbatdet_mv < QPNP_CHG_VBATDET_MIN_MV
710 || vbatdet_mv > QPNP_CHG_VBATDET_MAX_MV) {
711 pr_err("bad mV=%d asked to set\n", vbatdet_mv);
712 return -EINVAL;
713 }
714 temp = (vbatdet_mv - QPNP_CHG_VBATDET_MIN_MV)
715 / QPNP_CHG_VBATDET_STEP_MV;
716
717 pr_debug("voltage=%d setting %02x\n", vbatdet_mv, temp);
718 return qpnp_chg_write(chip, &temp,
719 chip->chgr_base + CHGR_VBAT_DET, 1);
720}
721
David Keitel344c6972013-04-09 19:28:21 -0700722static void
723qpnp_arb_stop_work(struct work_struct *work)
724{
725 struct delayed_work *dwork = to_delayed_work(work);
726 struct qpnp_chg_chip *chip = container_of(dwork,
727 struct qpnp_chg_chip, arb_stop_work);
728
David Keitel9fd07382013-05-02 15:37:44 -0700729 if (!chip->chg_done)
730 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitel344c6972013-04-09 19:28:21 -0700731 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
732}
733
734static void
735qpnp_bat_if_adc_measure_work(struct work_struct *work)
David Keitel79f4c932013-04-03 16:08:39 -0700736{
737 struct qpnp_chg_chip *chip = container_of(work,
738 struct qpnp_chg_chip, adc_measure_work);
739
740 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
741 pr_err("request ADC error\n");
742}
743
David Keitel9fd07382013-05-02 15:37:44 -0700744#define EOC_CHECK_PERIOD_MS 10000
745static irqreturn_t
746qpnp_chg_vbatdet_lo_irq_handler(int irq, void *_chip)
747{
748 struct qpnp_chg_chip *chip = _chip;
749 u8 chg_sts = 0;
750 int rc;
751
752 pr_debug("vbatdet-lo triggered\n");
753
754 rc = qpnp_chg_read(chip, &chg_sts, INT_RT_STS(chip->chgr_base), 1);
755 if (rc)
756 pr_err("failed to read chg_sts rc=%d\n", rc);
757
758 pr_debug("chg_done chg_sts: 0x%x triggered\n", chg_sts);
759 if (!chip->charging_disabled && (chg_sts & FAST_CHG_ON_IRQ)) {
760 schedule_delayed_work(&chip->eoc_work,
761 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
762 wake_lock(&chip->eoc_wake_lock);
David Keitel47185a62013-05-15 18:54:10 -0700763 qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -0700764 } else {
765 qpnp_chg_charge_en(chip, !chip->charging_disabled);
766 }
767
768 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700769 if (chip->dc_chgpth_base)
770 power_supply_changed(&chip->dc_psy);
771 if (chip->bat_if_base)
772 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700773 return IRQ_HANDLED;
774}
775
David Keitel344c6972013-04-09 19:28:21 -0700776#define ARB_STOP_WORK_MS 1000
777static irqreturn_t
778qpnp_chg_usb_chg_gone_irq_handler(int irq, void *_chip)
779{
780 struct qpnp_chg_chip *chip = _chip;
781
782 pr_debug("chg_gone triggered\n");
783 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
784 qpnp_chg_charge_en(chip, 0);
David Keitel9fd07382013-05-02 15:37:44 -0700785 qpnp_chg_force_run_on_batt(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -0700786 schedule_delayed_work(&chip->arb_stop_work,
787 msecs_to_jiffies(ARB_STOP_WORK_MS));
788 }
789
790 return IRQ_HANDLED;
791}
792
David Keitel80668952012-07-27 14:25:49 -0700793#define ENUM_T_STOP_BIT BIT(0)
794static irqreturn_t
795qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
796{
797 struct qpnp_chg_chip *chip = _chip;
David Keitel6f865cd2012-11-30 15:04:32 -0800798 int usb_present, host_mode;
David Keitel80668952012-07-27 14:25:49 -0700799
800 usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
David Keitel6f865cd2012-11-30 15:04:32 -0800801 host_mode = qpnp_chg_is_otg_en_set(chip);
802 pr_debug("usbin-valid triggered: %d host_mode: %d\n",
803 usb_present, host_mode);
804
805 /* In host mode notifications cmoe from USB supply */
806 if (host_mode)
807 return IRQ_HANDLED;
David Keitel80668952012-07-27 14:25:49 -0700808
809 if (chip->usb_present ^ usb_present) {
810 chip->usb_present = usb_present;
David Keitel9fd07382013-05-02 15:37:44 -0700811 if (!usb_present) {
David Keitel344c6972013-04-09 19:28:21 -0700812 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel9fd07382013-05-02 15:37:44 -0700813 chip->chg_done = false;
814 } else {
815 schedule_delayed_work(&chip->eoc_work,
816 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
817 }
David Keitel344c6972013-04-09 19:28:21 -0700818
David Keitel9fd07382013-05-02 15:37:44 -0700819 power_supply_set_present(chip->usb_psy, chip->usb_present);
David Keitel80668952012-07-27 14:25:49 -0700820 }
821
822 return IRQ_HANDLED;
823}
824
David Keitel7450dcd2013-01-29 18:41:41 -0800825static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800826qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
827{
828 struct qpnp_chg_chip *chip = _chip;
829 int batt_present;
830
831 batt_present = qpnp_chg_is_batt_present(chip);
832 pr_debug("batt-pres triggered: %d\n", batt_present);
833
834 if (chip->batt_present ^ batt_present) {
835 chip->batt_present = batt_present;
836 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700837 power_supply_changed(chip->usb_psy);
David Keitel0c1a4532013-03-21 16:39:06 -0700838
839 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
840 && batt_present) {
David Keitel79f4c932013-04-03 16:08:39 -0700841 schedule_work(&chip->adc_measure_work);
David Keitel0c1a4532013-03-21 16:39:06 -0700842 }
David Keitel42ae0aa2013-03-08 16:20:10 -0800843 }
844
845 return IRQ_HANDLED;
846}
847
848static irqreturn_t
David Keitel7450dcd2013-01-29 18:41:41 -0800849qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
850{
851 struct qpnp_chg_chip *chip = _chip;
852 int dc_present;
853
854 dc_present = qpnp_chg_is_dc_chg_plugged_in(chip);
855 pr_debug("dcin-valid triggered: %d\n", dc_present);
856
857 if (chip->dc_present ^ dc_present) {
858 chip->dc_present = dc_present;
David Keitel9fd07382013-05-02 15:37:44 -0700859 if (!dc_present)
860 chip->chg_done = false;
861 else
862 schedule_delayed_work(&chip->eoc_work,
863 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
David Keitel7450dcd2013-01-29 18:41:41 -0800864 power_supply_changed(&chip->dc_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700865 power_supply_changed(&chip->batt_psy);
David Keitel7450dcd2013-01-29 18:41:41 -0800866 }
867
868 return IRQ_HANDLED;
869}
870
David Keitel80668952012-07-27 14:25:49 -0700871#define CHGR_CHG_FAILED_BIT BIT(7)
872static irqreturn_t
873qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
874{
875 struct qpnp_chg_chip *chip = _chip;
David Keitel4429b1f2012-10-18 10:42:50 -0700876 int rc;
David Keitel80668952012-07-27 14:25:49 -0700877
David Keitel9fd07382013-05-02 15:37:44 -0700878 pr_debug("chg_failed triggered\n");
879
David Keitel80668952012-07-27 14:25:49 -0700880 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -0700881 chip->chgr_base + CHGR_CHG_FAILED,
David Keitel80668952012-07-27 14:25:49 -0700882 CHGR_CHG_FAILED_BIT,
883 CHGR_CHG_FAILED_BIT, 1);
884 if (rc)
885 pr_err("Failed to write chg_fail clear bit!\n");
886
David Keiteldbcef092013-05-14 14:48:30 -0700887 if (chip->bat_if_base)
888 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700889 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700890 if (chip->dc_chgpth_base)
891 power_supply_changed(&chip->dc_psy);
David Keitel80668952012-07-27 14:25:49 -0700892 return IRQ_HANDLED;
893}
894
895static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800896qpnp_chg_chgr_chg_trklchg_irq_handler(int irq, void *_chip)
897{
898 struct qpnp_chg_chip *chip = _chip;
899
900 pr_debug("TRKL IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800901
902 chip->chg_done = false;
David Keiteldbcef092013-05-14 14:48:30 -0700903 if (chip->bat_if_base)
904 power_supply_changed(&chip->batt_psy);
David Keitel42ae0aa2013-03-08 16:20:10 -0800905
906 return IRQ_HANDLED;
907}
908
909static irqreturn_t
910qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
911{
912 struct qpnp_chg_chip *chip = _chip;
913
914 pr_debug("FAST_CHG IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800915 chip->chg_done = false;
David Keiteldbcef092013-05-14 14:48:30 -0700916 if (chip->bat_if_base)
917 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700918 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700919 if (chip->dc_chgpth_base)
920 power_supply_changed(&chip->dc_psy);
David Keitel47185a62013-05-15 18:54:10 -0700921 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel42ae0aa2013-03-08 16:20:10 -0800922
923 return IRQ_HANDLED;
924}
925
David Keitel03ee6b52012-10-22 12:25:19 -0700926static int
927qpnp_batt_property_is_writeable(struct power_supply *psy,
928 enum power_supply_property psp)
929{
930 switch (psp) {
931 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitelbe208252013-01-31 14:49:25 -0800932 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
David Keitel03ee6b52012-10-22 12:25:19 -0700933 return 1;
934 default:
935 break;
936 }
937
938 return 0;
939}
940
David Keitel6f865cd2012-11-30 15:04:32 -0800941static int
David Keitelbe208252013-01-31 14:49:25 -0800942qpnp_chg_buck_control(struct qpnp_chg_chip *chip, int enable)
943{
944 int rc;
945
946 if (chip->charging_disabled && enable) {
947 pr_debug("Charging disabled\n");
948 return 0;
949 }
950
951 rc = qpnp_chg_charge_en(chip, enable);
952 if (rc) {
953 pr_err("Failed to control charging %d\n", rc);
954 return rc;
955 }
956
957 rc = qpnp_chg_force_run_on_batt(chip, !enable);
958 if (rc)
959 pr_err("Failed to control charging %d\n", rc);
960
961 return rc;
962}
963
David Keitel454ee842013-03-08 16:19:11 -0800964static int
965switch_usb_to_charge_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800966{
967 int rc;
968
969 pr_debug("switch to charge mode\n");
970 if (!qpnp_chg_is_otg_en_set(chip))
971 return 0;
972
973 /* enable usb ovp fet */
974 rc = qpnp_chg_masked_write(chip,
975 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
976 USB_OTG_EN_BIT,
977 0, 1);
978 if (rc) {
979 pr_err("Failed to turn on usb ovp rc = %d\n", rc);
980 return rc;
981 }
982
983 rc = qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
984 if (rc) {
985 pr_err("Failed re-enable charging rc = %d\n", rc);
986 return rc;
987 }
988
989 return 0;
990}
991
David Keitel454ee842013-03-08 16:19:11 -0800992static int
993switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800994{
995 int rc;
996
997 pr_debug("switch to host mode\n");
998 if (qpnp_chg_is_otg_en_set(chip))
999 return 0;
1000
1001 rc = qpnp_chg_force_run_on_batt(chip, 1);
1002 if (rc) {
1003 pr_err("Failed to disable charging rc = %d\n", rc);
1004 return rc;
1005 }
1006
1007 /* force usb ovp fet off */
1008 rc = qpnp_chg_masked_write(chip,
1009 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
1010 USB_OTG_EN_BIT,
1011 USB_OTG_EN_BIT, 1);
1012 if (rc) {
1013 pr_err("Failed to turn off usb ovp rc = %d\n", rc);
1014 return rc;
1015 }
1016
1017 return 0;
1018}
1019
David Keitel80668952012-07-27 14:25:49 -07001020static enum power_supply_property pm_power_props_mains[] = {
1021 POWER_SUPPLY_PROP_PRESENT,
1022 POWER_SUPPLY_PROP_ONLINE,
1023};
1024
1025static enum power_supply_property msm_batt_power_props[] = {
David Keitelb80eda82012-10-15 10:49:11 -07001026 POWER_SUPPLY_PROP_CHARGING_ENABLED,
David Keitel80668952012-07-27 14:25:49 -07001027 POWER_SUPPLY_PROP_STATUS,
1028 POWER_SUPPLY_PROP_CHARGE_TYPE,
1029 POWER_SUPPLY_PROP_HEALTH,
1030 POWER_SUPPLY_PROP_PRESENT,
1031 POWER_SUPPLY_PROP_TECHNOLOGY,
1032 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
1033 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
1034 POWER_SUPPLY_PROP_VOLTAGE_NOW,
1035 POWER_SUPPLY_PROP_CAPACITY,
1036 POWER_SUPPLY_PROP_CURRENT_NOW,
1037 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
1038 POWER_SUPPLY_PROP_TEMP,
David Keitelbe208252013-01-31 14:49:25 -08001039 POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
David Keitel80668952012-07-27 14:25:49 -07001040};
1041
1042static char *pm_power_supplied_to[] = {
1043 "battery",
1044};
1045
Xiaozhe Shi890fbf42013-05-02 16:42:53 -07001046static char *pm_batt_supplied_to[] = {
1047 "bms",
1048};
1049
David Keitel80668952012-07-27 14:25:49 -07001050#define USB_WALL_THRESHOLD_MA 500
1051static int
1052qpnp_power_get_property_mains(struct power_supply *psy,
1053 enum power_supply_property psp,
1054 union power_supply_propval *val)
1055{
1056 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1057 dc_psy);
1058
1059 switch (psp) {
1060 case POWER_SUPPLY_PROP_PRESENT:
1061 case POWER_SUPPLY_PROP_ONLINE:
1062 val->intval = 0;
David Keitel03ee6b52012-10-22 12:25:19 -07001063 if (chip->charging_disabled)
David Keitel80668952012-07-27 14:25:49 -07001064 return 0;
1065
1066 val->intval = qpnp_chg_is_dc_chg_plugged_in(chip);
1067 break;
1068 default:
1069 return -EINVAL;
1070 }
1071 return 0;
1072}
1073
1074static int
1075get_prop_battery_voltage_now(struct qpnp_chg_chip *chip)
1076{
1077 int rc = 0;
1078 struct qpnp_vadc_result results;
1079
David Keitelfe51cb92013-04-02 19:42:58 -07001080 if (chip->revision == 0 && chip->type == SMBB) {
1081 pr_err("vbat reading not supported for 1.0 rc=%d\n", rc);
1082 return 0;
1083 } else {
David Keitel80668952012-07-27 14:25:49 -07001084 rc = qpnp_vadc_read(VBAT_SNS, &results);
1085 if (rc) {
1086 pr_err("Unable to read vbat rc=%d\n", rc);
1087 return 0;
1088 }
1089 return results.physical;
David Keitel80668952012-07-27 14:25:49 -07001090 }
1091}
1092
1093#define BATT_PRES_BIT BIT(7)
1094static int
1095get_prop_batt_present(struct qpnp_chg_chip *chip)
1096{
1097 u8 batt_present;
1098 int rc;
1099
1100 rc = qpnp_chg_read(chip, &batt_present,
1101 chip->bat_if_base + CHGR_BAT_IF_PRES_STATUS, 1);
1102 if (rc) {
1103 pr_err("Couldn't read battery status read failed rc=%d\n", rc);
1104 return 0;
1105 };
1106 return (batt_present & BATT_PRES_BIT) ? 1 : 0;
1107}
1108
1109#define BATT_TEMP_HOT BIT(6)
1110#define BATT_TEMP_OK BIT(7)
1111static int
1112get_prop_batt_health(struct qpnp_chg_chip *chip)
1113{
1114 u8 batt_health;
1115 int rc;
1116
1117 rc = qpnp_chg_read(chip, &batt_health,
David Keiteld681cda2012-10-02 15:44:21 -07001118 chip->bat_if_base + CHGR_STATUS, 1);
David Keitel80668952012-07-27 14:25:49 -07001119 if (rc) {
1120 pr_err("Couldn't read battery health read failed rc=%d\n", rc);
1121 return POWER_SUPPLY_HEALTH_UNKNOWN;
1122 };
1123
1124 if (BATT_TEMP_OK & batt_health)
1125 return POWER_SUPPLY_HEALTH_GOOD;
1126 if (BATT_TEMP_HOT & batt_health)
1127 return POWER_SUPPLY_HEALTH_OVERHEAT;
1128 else
1129 return POWER_SUPPLY_HEALTH_COLD;
1130}
1131
1132static int
1133get_prop_charge_type(struct qpnp_chg_chip *chip)
1134{
1135 int rc;
1136 u8 chgr_sts;
1137
1138 if (!get_prop_batt_present(chip))
1139 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1140
1141 rc = qpnp_chg_read(chip, &chgr_sts,
1142 INT_RT_STS(chip->chgr_base), 1);
1143 if (rc) {
1144 pr_err("failed to read interrupt sts %d\n", rc);
1145 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1146 }
1147
1148 if (chgr_sts & TRKL_CHG_ON_IRQ)
1149 return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
1150 if (chgr_sts & FAST_CHG_ON_IRQ)
1151 return POWER_SUPPLY_CHARGE_TYPE_FAST;
1152
1153 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1154}
1155
1156static int
1157get_prop_batt_status(struct qpnp_chg_chip *chip)
1158{
1159 int rc;
1160 u8 chgr_sts;
1161
David Keitel9fd07382013-05-02 15:37:44 -07001162 if ((qpnp_chg_is_usb_chg_plugged_in(chip) ||
1163 qpnp_chg_is_dc_chg_plugged_in(chip)) && chip->chg_done) {
David Keitelc9ffe842013-01-25 19:37:51 -08001164 return POWER_SUPPLY_STATUS_FULL;
David Keitel9fd07382013-05-02 15:37:44 -07001165 }
David Keitelc9ffe842013-01-25 19:37:51 -08001166
David Keitel9fd07382013-05-02 15:37:44 -07001167 rc = qpnp_chg_read(chip, &chgr_sts, INT_RT_STS(chip->chgr_base), 1);
David Keitel80668952012-07-27 14:25:49 -07001168 if (rc) {
1169 pr_err("failed to read interrupt sts %d\n", rc);
David Keitelc9ffe842013-01-25 19:37:51 -08001170 return POWER_SUPPLY_CHARGE_TYPE_NONE;
David Keitel80668952012-07-27 14:25:49 -07001171 }
1172
David Keitel80668952012-07-27 14:25:49 -07001173 if (chgr_sts & TRKL_CHG_ON_IRQ)
1174 return POWER_SUPPLY_STATUS_CHARGING;
1175 if (chgr_sts & FAST_CHG_ON_IRQ)
1176 return POWER_SUPPLY_STATUS_CHARGING;
1177
1178 return POWER_SUPPLY_STATUS_DISCHARGING;
1179}
1180
1181static int
1182get_prop_current_now(struct qpnp_chg_chip *chip)
1183{
1184 union power_supply_propval ret = {0,};
1185
1186 if (chip->bms_psy) {
1187 chip->bms_psy->get_property(chip->bms_psy,
1188 POWER_SUPPLY_PROP_CURRENT_NOW, &ret);
1189 return ret.intval;
1190 } else {
1191 pr_debug("No BMS supply registered return 0\n");
1192 }
1193
1194 return 0;
1195}
1196
1197static int
1198get_prop_full_design(struct qpnp_chg_chip *chip)
1199{
1200 union power_supply_propval ret = {0,};
1201
1202 if (chip->bms_psy) {
1203 chip->bms_psy->get_property(chip->bms_psy,
1204 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, &ret);
1205 return ret.intval;
1206 } else {
1207 pr_debug("No BMS supply registered return 0\n");
1208 }
1209
1210 return 0;
1211}
1212
1213#define DEFAULT_CAPACITY 50
1214static int
1215get_prop_capacity(struct qpnp_chg_chip *chip)
1216{
1217 union power_supply_propval ret = {0,};
1218
David Keitel3dd5e0f2012-12-12 18:12:36 -08001219 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1220 return DEFAULT_CAPACITY;
1221
David Keitel80668952012-07-27 14:25:49 -07001222 if (chip->bms_psy) {
1223 chip->bms_psy->get_property(chip->bms_psy,
1224 POWER_SUPPLY_PROP_CAPACITY, &ret);
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001225 if (ret.intval == 0) {
David Keiteleeca08f2013-05-17 16:40:46 -07001226 if (!qpnp_chg_is_usb_chg_plugged_in(chip)
1227 && !qpnp_chg_is_usb_chg_plugged_in(chip))
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001228 pr_warn_ratelimited("Battery 0, CHG absent\n");
1229 }
David Keitel80668952012-07-27 14:25:49 -07001230 return ret.intval;
1231 } else {
1232 pr_debug("No BMS supply registered return 50\n");
1233 }
1234
1235 /* return default capacity to avoid userspace
1236 * from shutting down unecessarily */
1237 return DEFAULT_CAPACITY;
1238}
1239
David Keitel3dd5e0f2012-12-12 18:12:36 -08001240#define DEFAULT_TEMP 250
David Keitel80668952012-07-27 14:25:49 -07001241#define MAX_TOLERABLE_BATT_TEMP_DDC 680
1242static int
1243get_prop_batt_temp(struct qpnp_chg_chip *chip)
1244{
1245 int rc = 0;
1246 struct qpnp_vadc_result results;
1247
David Keitel3dd5e0f2012-12-12 18:12:36 -08001248 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1249 return DEFAULT_TEMP;
1250
David Keitel80668952012-07-27 14:25:49 -07001251 if (chip->revision > 0) {
1252 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
1253 if (rc) {
1254 pr_debug("Unable to read batt temperature rc=%d\n", rc);
1255 return 0;
1256 }
1257 pr_debug("get_bat_temp %d %lld\n",
1258 results.adc_code, results.physical);
1259 return (int)results.physical;
1260 } else {
1261 pr_debug("batt temp not supported for PMIC 1.0 rc=%d\n", rc);
1262 }
1263
1264 /* return default temperature to avoid userspace
1265 * from shutting down unecessarily */
1266 return DEFAULT_TEMP;
1267}
1268
1269static void
1270qpnp_batt_external_power_changed(struct power_supply *psy)
1271{
1272 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1273 batt_psy);
1274 union power_supply_propval ret = {0,};
1275
1276 if (!chip->bms_psy)
1277 chip->bms_psy = power_supply_get_by_name("bms");
1278
1279 chip->usb_psy->get_property(chip->usb_psy,
1280 POWER_SUPPLY_PROP_ONLINE, &ret);
1281
David Keitelc69f2d62013-03-17 14:52:35 -07001282 /* Only honour requests while USB is present */
1283 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001284 chip->usb_psy->get_property(chip->usb_psy,
1285 POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
David Keitel87473252013-03-21 14:39:45 -07001286 if (ret.intval <= 2 && !chip->use_default_batt_values &&
1287 get_prop_batt_present(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001288 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -07001289 qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
David Keitelc69f2d62013-03-17 14:52:35 -07001290 } else {
David Keiteld681cda2012-10-02 15:44:21 -07001291 qpnp_chg_usb_suspend_enable(chip, 0);
David Keitel359ab652013-03-21 17:46:00 -07001292 qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
David Keitelc69f2d62013-03-17 14:52:35 -07001293 }
David Keitel80668952012-07-27 14:25:49 -07001294 }
1295
1296 pr_debug("end of power supply changed\n");
1297 power_supply_changed(&chip->batt_psy);
1298}
1299
1300static int
1301qpnp_batt_power_get_property(struct power_supply *psy,
1302 enum power_supply_property psp,
1303 union power_supply_propval *val)
1304{
1305 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1306 batt_psy);
1307
1308 switch (psp) {
1309 case POWER_SUPPLY_PROP_STATUS:
1310 val->intval = get_prop_batt_status(chip);
1311 break;
1312 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1313 val->intval = get_prop_charge_type(chip);
1314 break;
1315 case POWER_SUPPLY_PROP_HEALTH:
1316 val->intval = get_prop_batt_health(chip);
1317 break;
1318 case POWER_SUPPLY_PROP_PRESENT:
1319 val->intval = get_prop_batt_present(chip);
1320 break;
1321 case POWER_SUPPLY_PROP_TECHNOLOGY:
1322 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
1323 break;
1324 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
1325 val->intval = chip->max_voltage_mv * 1000;
1326 break;
1327 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
1328 val->intval = chip->min_voltage_mv * 1000;
1329 break;
1330 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1331 val->intval = get_prop_battery_voltage_now(chip);
1332 break;
1333 case POWER_SUPPLY_PROP_TEMP:
1334 val->intval = get_prop_batt_temp(chip);
1335 break;
1336 case POWER_SUPPLY_PROP_CAPACITY:
1337 val->intval = get_prop_capacity(chip);
1338 break;
1339 case POWER_SUPPLY_PROP_CURRENT_NOW:
1340 val->intval = get_prop_current_now(chip);
1341 break;
1342 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1343 val->intval = get_prop_full_design(chip);
1344 break;
David Keitelb80eda82012-10-15 10:49:11 -07001345 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitel03ee6b52012-10-22 12:25:19 -07001346 val->intval = !(chip->charging_disabled);
David Keitelb80eda82012-10-15 10:49:11 -07001347 break;
David Keitelbe208252013-01-31 14:49:25 -08001348 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1349 val->intval = chip->therm_lvl_sel;
David Keitelb80eda82012-10-15 10:49:11 -07001350 break;
1351 default:
1352 return -EINVAL;
1353 }
1354
David Keitelb80eda82012-10-15 10:49:11 -07001355 return 0;
David Keitel80668952012-07-27 14:25:49 -07001356}
1357
David Keitel80668952012-07-27 14:25:49 -07001358#define QPNP_CHG_VINMIN_MIN_MV 3400
1359#define QPNP_CHG_VINMIN_HIGH_MIN_MV 5600
1360#define QPNP_CHG_VINMIN_HIGH_MIN_VAL 0x2B
1361#define QPNP_CHG_VINMIN_MAX_MV 9600
1362#define QPNP_CHG_VINMIN_STEP_MV 50
1363#define QPNP_CHG_VINMIN_STEP_HIGH_MV 200
1364#define QPNP_CHG_VINMIN_MASK 0x1F
1365static int
1366qpnp_chg_vinmin_set(struct qpnp_chg_chip *chip, int voltage)
1367{
1368 u8 temp;
1369
1370 if (voltage < QPNP_CHG_VINMIN_MIN_MV
1371 || voltage > QPNP_CHG_VINMIN_MAX_MV) {
1372 pr_err("bad mV=%d asked to set\n", voltage);
1373 return -EINVAL;
1374 }
1375 if (voltage >= QPNP_CHG_VINMIN_HIGH_MIN_MV) {
1376 temp = QPNP_CHG_VINMIN_HIGH_MIN_VAL;
1377 temp += (voltage - QPNP_CHG_VINMIN_MIN_MV)
1378 / QPNP_CHG_VINMIN_STEP_HIGH_MV;
1379 } else {
1380 temp = (voltage - QPNP_CHG_VINMIN_MIN_MV)
1381 / QPNP_CHG_VINMIN_STEP_MV;
1382 }
1383
1384 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1385 return qpnp_chg_masked_write(chip,
1386 chip->chgr_base + CHGR_VIN_MIN,
1387 QPNP_CHG_VINMIN_MASK, temp, 1);
1388}
1389
David Keitel5d44fa52012-12-03 16:37:31 -08001390#define QPNP_CHG_IBATSAFE_MIN_MA 100
1391#define QPNP_CHG_IBATSAFE_MAX_MA 3250
1392#define QPNP_CHG_I_STEP_MA 50
1393#define QPNP_CHG_I_MIN_MA 100
1394#define QPNP_CHG_I_MASK 0x3F
1395static int
1396qpnp_chg_ibatsafe_set(struct qpnp_chg_chip *chip, int safe_current)
1397{
1398 u8 temp;
1399
1400 if (safe_current < QPNP_CHG_IBATSAFE_MIN_MA
1401 || safe_current > QPNP_CHG_IBATSAFE_MAX_MA) {
1402 pr_err("bad mA=%d asked to set\n", safe_current);
1403 return -EINVAL;
1404 }
1405
1406 temp = (safe_current - QPNP_CHG_IBATSAFE_MIN_MA)
1407 / QPNP_CHG_I_STEP_MA;
1408 return qpnp_chg_masked_write(chip,
1409 chip->chgr_base + CHGR_IBAT_SAFE,
1410 QPNP_CHG_I_MASK, temp, 1);
1411}
David Keitel80668952012-07-27 14:25:49 -07001412
1413#define QPNP_CHG_ITERM_MIN_MA 100
1414#define QPNP_CHG_ITERM_MAX_MA 250
1415#define QPNP_CHG_ITERM_STEP_MA 50
1416#define QPNP_CHG_ITERM_MASK 0x03
1417static int
1418qpnp_chg_ibatterm_set(struct qpnp_chg_chip *chip, int term_current)
1419{
1420 u8 temp;
1421
1422 if (term_current < QPNP_CHG_ITERM_MIN_MA
1423 || term_current > QPNP_CHG_ITERM_MAX_MA) {
1424 pr_err("bad mA=%d asked to set\n", term_current);
1425 return -EINVAL;
1426 }
1427
1428 temp = (term_current - QPNP_CHG_ITERM_MIN_MA)
1429 / QPNP_CHG_ITERM_STEP_MA;
1430 return qpnp_chg_masked_write(chip,
1431 chip->chgr_base + CHGR_IBAT_TERM_CHGR,
1432 QPNP_CHG_ITERM_MASK, temp, 1);
1433}
1434
David Keitelff5d0472013-04-04 11:36:06 -07001435#define QPNP_CHG_IBATMAX_MIN 50
David Keitel80668952012-07-27 14:25:49 -07001436#define QPNP_CHG_IBATMAX_MAX 3250
David Keitel80668952012-07-27 14:25:49 -07001437static int
1438qpnp_chg_ibatmax_set(struct qpnp_chg_chip *chip, int chg_current)
1439{
1440 u8 temp;
1441
1442 if (chg_current < QPNP_CHG_IBATMAX_MIN
1443 || chg_current > QPNP_CHG_IBATMAX_MAX) {
1444 pr_err("bad mA=%d asked to set\n", chg_current);
1445 return -EINVAL;
1446 }
David Keitelff5d0472013-04-04 11:36:06 -07001447 temp = chg_current / QPNP_CHG_I_STEP_MA;
David Keitel80668952012-07-27 14:25:49 -07001448 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_IBAT_MAX,
1449 QPNP_CHG_I_MASK, temp, 1);
1450}
1451
David Keitela4b7b592013-04-11 18:34:35 -07001452#define QPNP_CHG_TCHG_MASK 0x7F
1453#define QPNP_CHG_TCHG_MIN 4
1454#define QPNP_CHG_TCHG_MAX 512
1455#define QPNP_CHG_TCHG_STEP 4
1456static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
1457{
1458 u8 temp;
1459
1460 if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
1461 pr_err("bad max minutes =%d asked to set\n", minutes);
1462 return -EINVAL;
1463 }
1464
1465 temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
1466 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
David Keitela1d16442013-05-09 14:47:37 -07001467 QPNP_CHG_TCHG_MASK, temp, 1);
David Keitela4b7b592013-04-11 18:34:35 -07001468}
David Keitel80668952012-07-27 14:25:49 -07001469
1470#define QPNP_CHG_V_MIN_MV 3240
1471#define QPNP_CHG_V_MAX_MV 4500
1472#define QPNP_CHG_V_STEP_MV 10
1473static int
1474qpnp_chg_vddsafe_set(struct qpnp_chg_chip *chip, int voltage)
1475{
1476 u8 temp;
1477
1478 if (voltage < QPNP_CHG_V_MIN_MV
1479 || voltage > QPNP_CHG_V_MAX_MV) {
1480 pr_err("bad mV=%d asked to set\n", voltage);
1481 return -EINVAL;
1482 }
1483 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1484 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1485 return qpnp_chg_write(chip, &temp,
1486 chip->chgr_base + CHGR_VDD_SAFE, 1);
1487}
1488
1489#define QPNP_CHG_VDDMAX_MIN 3400
1490static int
1491qpnp_chg_vddmax_set(struct qpnp_chg_chip *chip, int voltage)
1492{
1493 u8 temp = 0;
1494
1495 if (voltage < QPNP_CHG_VDDMAX_MIN
1496 || voltage > QPNP_CHG_V_MAX_MV) {
1497 pr_err("bad mV=%d asked to set\n", voltage);
1498 return -EINVAL;
1499 }
1500
1501 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1502
1503 pr_debug("voltage=%d setting %02x\n", voltage, temp);
David Keitel454ee842013-03-08 16:19:11 -08001504 return qpnp_chg_write(chip, &temp, chip->chgr_base + CHGR_VDD_MAX, 1);
1505}
1506
David Keitel6dc4ed42013-05-17 11:08:58 -07001507#define BOOST_MIN_UV 4200000
1508#define BOOST_MAX_UV 5500000
1509#define BOOST_STEP_UV 50000
1510#define BOOST_MIN 16
1511#define N_BOOST_V ((BOOST_MAX_UV - BOOST_MIN_UV) / BOOST_STEP_UV + 1)
1512static int
1513qpnp_boost_vset(struct qpnp_chg_chip *chip, int voltage)
1514{
1515 u8 reg = 0;
1516
1517 if (voltage < BOOST_MIN_UV || voltage > BOOST_MAX_UV) {
1518 pr_err("invalid voltage requested %d uV\n", voltage);
1519 return -EINVAL;
1520 }
1521
1522 reg = DIV_ROUND_UP(voltage - BOOST_MIN_UV, BOOST_STEP_UV) + BOOST_MIN;
1523
1524 pr_debug("voltage=%d setting %02x\n", voltage, reg);
1525 return qpnp_chg_write(chip, &reg, chip->boost_base + BOOST_VSET, 1);
1526}
1527
1528static int
1529qpnp_boost_vget_uv(struct qpnp_chg_chip *chip)
1530{
1531 int rc;
1532 u8 boost_reg;
1533
1534 rc = qpnp_chg_read(chip, &boost_reg,
1535 chip->boost_base + BOOST_VSET, 1);
1536 if (rc) {
1537 pr_err("failed to read BOOST_VSET rc=%d\n", rc);
1538 return rc;
1539 }
1540
1541 if (boost_reg < BOOST_MIN) {
1542 pr_err("Invalid reading from 0x%x\n", boost_reg);
1543 return -EINVAL;
1544 }
1545
1546 return BOOST_MIN_UV + ((boost_reg - BOOST_MIN) * BOOST_STEP_UV);
1547}
1548
David Keitel454ee842013-03-08 16:19:11 -08001549/* JEITA compliance logic */
1550static void
1551qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
1552{
1553 if (chip->bat_is_cool)
1554 qpnp_chg_vddmax_set(chip, chip->cool_bat_mv);
1555 else if (chip->bat_is_warm)
1556 qpnp_chg_vddmax_set(chip, chip->warm_bat_mv);
1557 else
1558 qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
1559}
1560
1561static void
1562qpnp_chg_set_appropriate_vbatdet(struct qpnp_chg_chip *chip)
1563{
1564 if (chip->bat_is_cool)
1565 qpnp_chg_vbatdet_set(chip, chip->cool_bat_mv
1566 - chip->resume_delta_mv);
1567 else if (chip->bat_is_warm)
1568 qpnp_chg_vbatdet_set(chip, chip->warm_bat_mv
1569 - chip->resume_delta_mv);
1570 else
1571 qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
1572 - chip->resume_delta_mv);
David Keitel80668952012-07-27 14:25:49 -07001573}
1574
David Keitelbe208252013-01-31 14:49:25 -08001575static void
1576qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
1577{
1578 unsigned int chg_current = chip->max_bat_chg_current;
1579
David Keitel454ee842013-03-08 16:19:11 -08001580 if (chip->bat_is_cool)
1581 chg_current = min(chg_current, chip->cool_bat_chg_ma);
1582
1583 if (chip->bat_is_warm)
1584 chg_current = min(chg_current, chip->warm_bat_chg_ma);
1585
David Keitelbe208252013-01-31 14:49:25 -08001586 if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
1587 chg_current = min(chg_current,
1588 chip->thermal_mitigation[chip->therm_lvl_sel]);
1589
1590 pr_debug("setting %d mA\n", chg_current);
1591 qpnp_chg_ibatmax_set(chip, chg_current);
1592}
1593
1594static void
1595qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
1596{
1597 if (lvl_sel >= 0 && lvl_sel < chip->thermal_levels) {
1598 chip->therm_lvl_sel = lvl_sel;
1599 if (lvl_sel == (chip->thermal_levels - 1)) {
1600 /* disable charging if highest value selected */
1601 qpnp_chg_buck_control(chip, 0);
1602 } else {
1603 qpnp_chg_buck_control(chip, 1);
1604 qpnp_chg_set_appropriate_battery_current(chip);
1605 }
1606 } else {
1607 pr_err("Unsupported level selected %d\n", lvl_sel);
1608 }
1609}
1610
David Keitel6dc4ed42013-05-17 11:08:58 -07001611/* OTG regulator operations */
1612static int
1613qpnp_chg_regulator_otg_enable(struct regulator_dev *rdev)
1614{
1615 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1616
1617 return switch_usb_to_host_mode(chip);
1618}
1619
1620static int
1621qpnp_chg_regulator_otg_disable(struct regulator_dev *rdev)
1622{
1623 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1624
1625 return switch_usb_to_charge_mode(chip);
1626}
1627
1628static int
1629qpnp_chg_regulator_otg_is_enabled(struct regulator_dev *rdev)
1630{
1631 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1632
1633 return qpnp_chg_is_otg_en_set(chip);
1634}
1635
1636static int
1637qpnp_chg_regulator_boost_enable(struct regulator_dev *rdev)
1638{
1639 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
David Keitel33f58952013-05-20 16:17:36 -07001640 int rc;
1641
1642 if (qpnp_chg_is_usb_chg_plugged_in(chip) &&
1643 (chip->flags & BOOST_FLASH_WA)) {
1644 qpnp_chg_usb_suspend_enable(chip, 1);
1645
1646 rc = qpnp_chg_masked_write(chip,
1647 chip->usb_chgpth_base + SEC_ACCESS,
1648 0xFF,
1649 0xA5, 1);
1650 if (rc) {
1651 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1652 return rc;
1653 }
1654
1655 rc = qpnp_chg_masked_write(chip,
1656 chip->usb_chgpth_base + COMP_OVR1,
1657 0xFF,
1658 0x2F, 1);
1659 if (rc) {
1660 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1661 return rc;
1662 }
1663 }
David Keitel6dc4ed42013-05-17 11:08:58 -07001664
1665 return qpnp_chg_masked_write(chip,
1666 chip->boost_base + BOOST_ENABLE_CONTROL,
1667 BOOST_PWR_EN,
1668 BOOST_PWR_EN, 1);
1669}
1670
1671/* Boost regulator operations */
David Keitel33f58952013-05-20 16:17:36 -07001672#define ABOVE_VBAT_WEAK BIT(1)
David Keitel6dc4ed42013-05-17 11:08:58 -07001673static int
1674qpnp_chg_regulator_boost_disable(struct regulator_dev *rdev)
1675{
1676 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
David Keitel33f58952013-05-20 16:17:36 -07001677 int rc;
1678 u8 vbat_sts;
David Keitel6dc4ed42013-05-17 11:08:58 -07001679
David Keitel33f58952013-05-20 16:17:36 -07001680 rc = qpnp_chg_masked_write(chip,
David Keitel6dc4ed42013-05-17 11:08:58 -07001681 chip->boost_base + BOOST_ENABLE_CONTROL,
1682 BOOST_PWR_EN,
1683 0, 1);
David Keitel33f58952013-05-20 16:17:36 -07001684 if (rc) {
1685 pr_err("failed to disable boost rc=%d\n", rc);
1686 return rc;
1687 }
1688
1689 rc = qpnp_chg_read(chip, &vbat_sts,
1690 chip->chgr_base + CHGR_VBAT_STATUS, 1);
1691 if (rc) {
1692 pr_err("failed to read bat sts rc=%d\n", rc);
1693 return rc;
1694 }
1695
1696 if (!(vbat_sts & ABOVE_VBAT_WEAK) && (chip->flags & BOOST_FLASH_WA)) {
1697 rc = qpnp_chg_masked_write(chip,
1698 chip->chgr_base + SEC_ACCESS,
1699 0xFF,
1700 0xA5, 1);
1701 if (rc) {
1702 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1703 return rc;
1704 }
1705
1706 rc = qpnp_chg_masked_write(chip,
1707 chip->chgr_base + COMP_OVR1,
1708 0xFF,
1709 0x20, 1);
1710 if (rc) {
1711 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1712 return rc;
1713 }
1714
1715 usleep(2000);
1716
1717 rc = qpnp_chg_masked_write(chip,
1718 chip->chgr_base + SEC_ACCESS,
1719 0xFF,
1720 0xA5, 1);
1721 if (rc) {
1722 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1723 return rc;
1724 }
1725
1726 rc = qpnp_chg_masked_write(chip,
1727 chip->chgr_base + COMP_OVR1,
1728 0xFF,
1729 0x00, 1);
1730 if (rc) {
1731 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1732 return rc;
1733 }
1734 }
1735
1736 if (qpnp_chg_is_usb_chg_plugged_in(chip)
1737 && (chip->flags & BOOST_FLASH_WA)) {
1738 rc = qpnp_chg_masked_write(chip,
1739 chip->usb_chgpth_base + SEC_ACCESS,
1740 0xFF,
1741 0xA5, 1);
1742 if (rc) {
1743 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1744 return rc;
1745 }
1746
1747 rc = qpnp_chg_masked_write(chip,
1748 chip->usb_chgpth_base + COMP_OVR1,
1749 0xFF,
1750 0x00, 1);
1751 if (rc) {
1752 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1753 return rc;
1754 }
1755
1756 usleep(1000);
1757
1758 qpnp_chg_usb_suspend_enable(chip, 0);
1759 }
1760
1761 return rc;
David Keitel6dc4ed42013-05-17 11:08:58 -07001762}
1763
1764static int
1765qpnp_chg_regulator_boost_is_enabled(struct regulator_dev *rdev)
1766{
1767 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1768
1769 return qpnp_chg_is_boost_en_set(chip);
1770}
1771
1772static int
1773qpnp_chg_regulator_boost_set_voltage(struct regulator_dev *rdev,
1774 int min_uV, int max_uV, unsigned *selector)
1775{
1776 int uV = min_uV;
1777 int rc;
1778 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1779
1780 if (uV < BOOST_MIN_UV && max_uV >= BOOST_MIN_UV)
1781 uV = BOOST_MIN_UV;
1782
1783
1784 if (uV < BOOST_MIN_UV || uV > BOOST_MAX_UV) {
1785 pr_err("request %d uV is out of bounds\n", uV);
1786 return -EINVAL;
1787 }
1788
1789 *selector = DIV_ROUND_UP(uV - BOOST_MIN_UV, BOOST_STEP_UV);
1790 if ((*selector * BOOST_STEP_UV + BOOST_MIN_UV) > max_uV) {
1791 pr_err("no available setpoint [%d, %d] uV\n", min_uV, max_uV);
1792 return -EINVAL;
1793 }
1794
1795 rc = qpnp_boost_vset(chip, uV);
1796
1797 return rc;
1798}
1799
1800static int
1801qpnp_chg_regulator_boost_get_voltage(struct regulator_dev *rdev)
1802{
1803 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1804
1805 return qpnp_boost_vget_uv(chip);
1806}
1807
1808static int
1809qpnp_chg_regulator_boost_list_voltage(struct regulator_dev *rdev,
1810 unsigned selector)
1811{
1812 if (selector >= N_BOOST_V)
1813 return 0;
1814
1815 return BOOST_MIN_UV + (selector * BOOST_STEP_UV);
1816}
1817
1818static struct regulator_ops qpnp_chg_otg_reg_ops = {
1819 .enable = qpnp_chg_regulator_otg_enable,
1820 .disable = qpnp_chg_regulator_otg_disable,
1821 .is_enabled = qpnp_chg_regulator_otg_is_enabled,
1822};
1823
1824static struct regulator_ops qpnp_chg_boost_reg_ops = {
1825 .enable = qpnp_chg_regulator_boost_enable,
1826 .disable = qpnp_chg_regulator_boost_disable,
1827 .is_enabled = qpnp_chg_regulator_boost_is_enabled,
1828 .set_voltage = qpnp_chg_regulator_boost_set_voltage,
1829 .get_voltage = qpnp_chg_regulator_boost_get_voltage,
1830 .list_voltage = qpnp_chg_regulator_boost_list_voltage,
1831};
1832
David Keitel9fd07382013-05-02 15:37:44 -07001833#define CONSECUTIVE_COUNT 3
1834static void
1835qpnp_eoc_work(struct work_struct *work)
1836{
1837 struct delayed_work *dwork = to_delayed_work(work);
1838 struct qpnp_chg_chip *chip = container_of(dwork,
1839 struct qpnp_chg_chip, eoc_work);
1840 static int count;
1841 int ibat_ma, vbat_mv, rc = 0;
1842 u8 batt_sts = 0, buck_sts = 0, chg_sts = 0;
1843
1844 wake_lock(&chip->eoc_wake_lock);
1845 qpnp_chg_charge_en(chip, !chip->charging_disabled);
1846
1847 rc = qpnp_chg_read(chip, &batt_sts, INT_RT_STS(chip->bat_if_base), 1);
1848 if (rc) {
1849 pr_err("failed to read batt_if rc=%d\n", rc);
1850 return;
1851 }
1852
1853 rc = qpnp_chg_read(chip, &buck_sts, INT_RT_STS(chip->buck_base), 1);
1854 if (rc) {
1855 pr_err("failed to read buck rc=%d\n", rc);
1856 return;
1857 }
1858
1859 rc = qpnp_chg_read(chip, &chg_sts, INT_RT_STS(chip->chgr_base), 1);
1860 if (rc) {
1861 pr_err("failed to read chg_sts rc=%d\n", rc);
1862 return;
1863 }
1864
1865 pr_debug("chgr: 0x%x, bat_if: 0x%x, buck: 0x%x\n",
1866 chg_sts, batt_sts, buck_sts);
1867
1868 if (!qpnp_chg_is_usb_chg_plugged_in(chip) &&
1869 !qpnp_chg_is_dc_chg_plugged_in(chip)) {
1870 pr_debug("no chg connected, stopping\n");
1871 goto stop_eoc;
1872 }
1873
1874 if ((batt_sts & BAT_FET_ON_IRQ) && (chg_sts & FAST_CHG_ON_IRQ
1875 || chg_sts & TRKL_CHG_ON_IRQ)) {
1876 ibat_ma = get_prop_current_now(chip) / 1000;
1877 vbat_mv = get_prop_battery_voltage_now(chip) / 1000;
1878 pr_debug("ibat_ma: %d term_current =%d\n",
1879 ibat_ma, chip->term_current);
1880 if (ibat_ma > chip->term_current) {
1881 pr_debug("charging but increase in current demand\n");
1882 count = 0;
1883 } else if ((ibat_ma * -1) < chip->term_current) {
1884 if (count == CONSECUTIVE_COUNT) {
1885 pr_info("End of Charging\n");
1886 qpnp_chg_charge_en(chip, 0);
1887 chip->chg_done = true;
1888 power_supply_changed(&chip->batt_psy);
David Keitel47185a62013-05-15 18:54:10 -07001889 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -07001890 goto stop_eoc;
1891 } else {
1892 count += 1;
1893 pr_debug("EOC count = %d\n", count);
1894 }
1895 } else if ((!(chg_sts & VBAT_DET_LOW_IRQ)) && (vbat_mv <
1896 (chip->max_voltage_mv - chip->resume_delta_mv))) {
1897 pr_debug("woke up too early\n");
David Keitel47185a62013-05-15 18:54:10 -07001898 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -07001899 goto stop_eoc;
1900 }
1901 } else {
1902 pr_debug("not charging\n");
1903 goto stop_eoc;
1904 }
1905
1906 schedule_delayed_work(&chip->eoc_work,
1907 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
1908 return;
1909
1910stop_eoc:
1911 count = 0;
1912 wake_unlock(&chip->eoc_wake_lock);
1913}
1914
David Keitel0c1a4532013-03-21 16:39:06 -07001915#define HYSTERISIS_DECIDEGC 20
David Keitel454ee842013-03-08 16:19:11 -08001916static void
1917qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
1918{
1919 struct qpnp_chg_chip *chip = ctx;
1920 bool bat_warm = 0, bat_cool = 0;
David Keitel1219a802013-03-21 16:37:21 -07001921 int temp;
David Keitel454ee842013-03-08 16:19:11 -08001922
1923 if (state >= ADC_TM_STATE_NUM) {
1924 pr_err("invalid notification %d\n", state);
1925 return;
1926 }
1927
David Keitel1219a802013-03-21 16:37:21 -07001928 temp = get_prop_batt_temp(chip);
David Keitel454ee842013-03-08 16:19:11 -08001929
David Keitel1219a802013-03-21 16:37:21 -07001930 pr_debug("temp = %d state = %s\n", temp,
1931 state == ADC_TM_WARM_STATE ? "warm" : "cool");
1932
1933 if (state == ADC_TM_WARM_STATE) {
1934 if (temp > chip->warm_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07001935 /* Normal to warm */
David Keitel454ee842013-03-08 16:19:11 -08001936 bat_warm = true;
1937 bat_cool = false;
1938 chip->adc_param.low_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07001939 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07001940 chip->adc_param.state_request =
1941 ADC_TM_COOL_THR_ENABLE;
1942 } else if (temp >
1943 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07001944 /* Cool to normal */
David Keitel454ee842013-03-08 16:19:11 -08001945 bat_warm = false;
1946 bat_cool = false;
David Keitel1219a802013-03-21 16:37:21 -07001947
1948 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel0c1a4532013-03-21 16:39:06 -07001949 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07001950 chip->adc_param.state_request =
1951 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08001952 }
1953 } else {
David Keitel1219a802013-03-21 16:37:21 -07001954 if (temp < chip->cool_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07001955 /* Normal to cool */
David Keitel454ee842013-03-08 16:19:11 -08001956 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07001957 bat_cool = true;
David Keitel454ee842013-03-08 16:19:11 -08001958 chip->adc_param.high_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07001959 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07001960 chip->adc_param.state_request =
1961 ADC_TM_WARM_THR_ENABLE;
David Keitel3e37e5a2013-04-18 10:42:30 -07001962 } else if (temp <
David Keitel1219a802013-03-21 16:37:21 -07001963 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07001964 /* Warm to normal */
David Keitel454ee842013-03-08 16:19:11 -08001965 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07001966 bat_cool = false;
1967
David Keitel0c1a4532013-03-21 16:39:06 -07001968 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07001969 chip->adc_param.high_temp = chip->warm_bat_decidegc;
1970 chip->adc_param.state_request =
1971 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08001972 }
1973 }
1974
1975 if (chip->bat_is_cool ^ bat_cool || chip->bat_is_warm ^ bat_warm) {
David Keitel1219a802013-03-21 16:37:21 -07001976 chip->bat_is_cool = bat_cool;
1977 chip->bat_is_warm = bat_warm;
1978
David Keitel454ee842013-03-08 16:19:11 -08001979 /* set appropriate voltages and currents */
1980 qpnp_chg_set_appropriate_vddmax(chip);
1981 qpnp_chg_set_appropriate_battery_current(chip);
1982 qpnp_chg_set_appropriate_vbatdet(chip);
David Keitel454ee842013-03-08 16:19:11 -08001983 }
1984
David Keitel1219a802013-03-21 16:37:21 -07001985 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
1986 pr_err("request ADC error\n");
David Keitel454ee842013-03-08 16:19:11 -08001987}
1988
David Keitelbe208252013-01-31 14:49:25 -08001989static int
1990qpnp_batt_power_set_property(struct power_supply *psy,
1991 enum power_supply_property psp,
1992 const union power_supply_propval *val)
1993{
1994 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1995 batt_psy);
1996
1997 switch (psp) {
1998 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
1999 chip->charging_disabled = !(val->intval);
2000 qpnp_chg_charge_en(chip, !chip->charging_disabled);
2001 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
2002 break;
2003 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
2004 qpnp_batt_system_temp_level_set(chip, val->intval);
2005 break;
2006 default:
2007 return -EINVAL;
2008 }
2009
2010 power_supply_changed(&chip->batt_psy);
2011 return 0;
2012}
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002013
2014static void
2015qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
David Keiteld681cda2012-10-02 15:44:21 -07002016{
David Keitelfe51cb92013-04-02 19:42:58 -07002017 if (chip->revision > 0 && chip->type == SMBB)
David Keiteld681cda2012-10-02 15:44:21 -07002018 chip->flags |= CHG_FLAGS_VCP_WA;
David Keitel33f58952013-05-20 16:17:36 -07002019 if (chip->type == SMBB)
2020 chip->flags |= BOOST_FLASH_WA;
David Keiteld681cda2012-10-02 15:44:21 -07002021}
2022
David Keitel0f35be42013-04-16 11:10:40 -07002023static int
2024qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
2025{
2026 int rc = 0;
2027 struct resource *resource;
2028 struct spmi_resource *spmi_resource;
2029 u8 subtype;
2030 struct spmi_device *spmi = chip->spmi;
2031
2032 spmi_for_each_container_dev(spmi_resource, chip->spmi) {
2033 if (!spmi_resource) {
2034 pr_err("qpnp_chg: spmi resource absent\n");
2035 return rc;
2036 }
2037
2038 resource = spmi_get_resource(spmi, spmi_resource,
2039 IORESOURCE_MEM, 0);
2040 if (!(resource && resource->start)) {
2041 pr_err("node %s IO resource absent!\n",
2042 spmi->dev.of_node->full_name);
2043 return rc;
2044 }
2045
2046 rc = qpnp_chg_read(chip, &subtype,
2047 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2048 if (rc) {
2049 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2050 return rc;
2051 }
2052
2053 switch (subtype) {
2054 case SMBB_CHGR_SUBTYPE:
2055 case SMBBP_CHGR_SUBTYPE:
2056 case SMBCL_CHGR_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002057 chip->chg_fastchg.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002058 spmi_resource, "fast-chg-on");
David Keitel47185a62013-05-15 18:54:10 -07002059 if (chip->chg_fastchg.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002060 pr_err("Unable to get fast-chg-on irq\n");
2061 return rc;
2062 }
2063
David Keitel47185a62013-05-15 18:54:10 -07002064 chip->chg_trklchg.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002065 spmi_resource, "trkl-chg-on");
David Keitel47185a62013-05-15 18:54:10 -07002066 if (chip->chg_trklchg.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002067 pr_err("Unable to get trkl-chg-on irq\n");
2068 return rc;
2069 }
2070
David Keitel47185a62013-05-15 18:54:10 -07002071 chip->chg_failed.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002072 spmi_resource, "chg-failed");
David Keitel47185a62013-05-15 18:54:10 -07002073 if (chip->chg_failed.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002074 pr_err("Unable to get chg_failed irq\n");
2075 return rc;
2076 }
2077
David Keitel47185a62013-05-15 18:54:10 -07002078 chip->chg_vbatdet_lo.irq = spmi_get_irq_byname(spmi,
David Keitel9fd07382013-05-02 15:37:44 -07002079 spmi_resource, "vbat-det-lo");
David Keitel47185a62013-05-15 18:54:10 -07002080 if (chip->chg_vbatdet_lo.irq < 0) {
David Keitel9fd07382013-05-02 15:37:44 -07002081 pr_err("Unable to get fast-chg-on irq\n");
2082 return rc;
2083 }
2084
David Keitel47185a62013-05-15 18:54:10 -07002085 rc |= devm_request_irq(chip->dev, chip->chg_failed.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002086 qpnp_chg_chgr_chg_failed_irq_handler,
David Keitelc9f19172013-04-29 11:01:26 -07002087 IRQF_TRIGGER_RISING, "chg-failed", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002088 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002089 pr_err("Can't request %d chg-failed: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002090 chip->chg_failed.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002091 return rc;
2092 }
2093
David Keitel47185a62013-05-15 18:54:10 -07002094 rc |= devm_request_irq(chip->dev, chip->chg_fastchg.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002095 qpnp_chg_chgr_chg_fastchg_irq_handler,
2096 IRQF_TRIGGER_RISING,
2097 "fast-chg-on", chip);
2098 if (rc < 0) {
2099 pr_err("Can't request %d fast-chg-on: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002100 chip->chg_fastchg.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002101 return rc;
2102 }
2103
David Keitel47185a62013-05-15 18:54:10 -07002104 rc |= devm_request_irq(chip->dev, chip->chg_trklchg.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002105 qpnp_chg_chgr_chg_trklchg_irq_handler,
2106 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002107 "trkl-chg-on", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002108 if (rc < 0) {
2109 pr_err("Can't request %d trkl-chg-on: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002110 chip->chg_trklchg.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002111 return rc;
2112 }
David Keitel9fd07382013-05-02 15:37:44 -07002113
2114 rc |= devm_request_irq(chip->dev,
David Keitel47185a62013-05-15 18:54:10 -07002115 chip->chg_vbatdet_lo.irq,
David Keitel9fd07382013-05-02 15:37:44 -07002116 qpnp_chg_vbatdet_lo_irq_handler,
2117 IRQF_TRIGGER_RISING,
2118 "vbat-det-lo", chip);
2119 if (rc < 0) {
2120 pr_err("Can't request %d vbat-det-lo: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002121 chip->chg_vbatdet_lo.irq, rc);
David Keitel9fd07382013-05-02 15:37:44 -07002122 return rc;
2123 }
2124
David Keitel47185a62013-05-15 18:54:10 -07002125 enable_irq_wake(chip->chg_trklchg.irq);
2126 enable_irq_wake(chip->chg_failed.irq);
2127 qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
2128 enable_irq_wake(chip->chg_vbatdet_lo.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002129
2130 break;
2131 case SMBB_BAT_IF_SUBTYPE:
2132 case SMBBP_BAT_IF_SUBTYPE:
2133 case SMBCL_BAT_IF_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002134 chip->batt_pres.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002135 spmi_resource, "batt-pres");
David Keitel47185a62013-05-15 18:54:10 -07002136 if (chip->batt_pres.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002137 pr_err("Unable to get batt-pres irq\n");
2138 return rc;
2139 }
David Keitel47185a62013-05-15 18:54:10 -07002140 rc = devm_request_irq(chip->dev, chip->batt_pres.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002141 qpnp_chg_bat_if_batt_pres_irq_handler,
2142 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002143 "batt-pres", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002144 if (rc < 0) {
2145 pr_err("Can't request %d batt-pres irq: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002146 chip->batt_pres.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002147 return rc;
2148 }
2149
David Keitel47185a62013-05-15 18:54:10 -07002150 enable_irq_wake(chip->batt_pres.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002151 break;
2152 case SMBB_USB_CHGPTH_SUBTYPE:
2153 case SMBBP_USB_CHGPTH_SUBTYPE:
2154 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002155 chip->usbin_valid.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002156 spmi_resource, "usbin-valid");
David Keitel47185a62013-05-15 18:54:10 -07002157 if (chip->usbin_valid.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002158 pr_err("Unable to get usbin irq\n");
2159 return rc;
2160 }
David Keitel47185a62013-05-15 18:54:10 -07002161 rc = devm_request_irq(chip->dev, chip->usbin_valid.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002162 qpnp_chg_usb_usbin_valid_irq_handler,
2163 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002164 "usbin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002165 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002166 pr_err("Can't request %d usbin-valid: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002167 chip->usbin_valid.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002168 return rc;
2169 }
David Keitel344c6972013-04-09 19:28:21 -07002170
David Keitel47185a62013-05-15 18:54:10 -07002171 chip->chg_gone.irq = spmi_get_irq_byname(spmi,
David Keitel344c6972013-04-09 19:28:21 -07002172 spmi_resource, "chg-gone");
David Keitel47185a62013-05-15 18:54:10 -07002173 if (chip->chg_gone.irq < 0) {
David Keitel344c6972013-04-09 19:28:21 -07002174 pr_err("Unable to get chg-gone irq\n");
2175 return rc;
2176 }
David Keitel47185a62013-05-15 18:54:10 -07002177 rc = devm_request_irq(chip->dev, chip->chg_gone.irq,
David Keitel344c6972013-04-09 19:28:21 -07002178 qpnp_chg_usb_chg_gone_irq_handler,
2179 IRQF_TRIGGER_RISING,
David Keitelc9f19172013-04-29 11:01:26 -07002180 "chg-gone", chip);
David Keitel344c6972013-04-09 19:28:21 -07002181 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002182 pr_err("Can't request %d chg-gone: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002183 chip->chg_gone.irq, rc);
David Keitel344c6972013-04-09 19:28:21 -07002184 return rc;
2185 }
David Keitel47185a62013-05-15 18:54:10 -07002186
2187 enable_irq_wake(chip->usbin_valid.irq);
2188 enable_irq_wake(chip->chg_gone.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002189 break;
2190 case SMBB_DC_CHGPTH_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002191 chip->dcin_valid.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002192 spmi_resource, "dcin-valid");
David Keitel47185a62013-05-15 18:54:10 -07002193 if (chip->dcin_valid.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002194 pr_err("Unable to get dcin irq\n");
2195 return -rc;
2196 }
David Keitel47185a62013-05-15 18:54:10 -07002197 rc = devm_request_irq(chip->dev, chip->dcin_valid.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002198 qpnp_chg_dc_dcin_valid_irq_handler,
2199 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002200 "dcin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002201 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002202 pr_err("Can't request %d dcin-valid: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002203 chip->dcin_valid.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002204 return rc;
2205 }
2206
David Keitel47185a62013-05-15 18:54:10 -07002207 enable_irq_wake(chip->dcin_valid.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002208 break;
2209 }
2210 }
2211
2212 return rc;
2213}
2214
David Keitel80668952012-07-27 14:25:49 -07002215#define WDOG_EN_BIT BIT(7)
2216static int
2217qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
2218 struct spmi_resource *spmi_resource)
2219{
2220 int rc = 0;
David Keitel796882d2013-05-14 18:01:11 -07002221 u8 reg = 0;
David Keitel6dc4ed42013-05-17 11:08:58 -07002222 struct regulator_init_data *init_data;
2223 struct regulator_desc *rdesc;
David Keitel80668952012-07-27 14:25:49 -07002224
2225 switch (subtype) {
2226 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002227 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002228 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002229 rc = qpnp_chg_vinmin_set(chip, chip->min_voltage_mv);
2230 if (rc) {
2231 pr_debug("failed setting min_voltage rc=%d\n", rc);
2232 return rc;
2233 }
2234 rc = qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
2235 if (rc) {
2236 pr_debug("failed setting max_voltage rc=%d\n", rc);
2237 return rc;
2238 }
2239 rc = qpnp_chg_vddsafe_set(chip, chip->safe_voltage_mv);
2240 if (rc) {
2241 pr_debug("failed setting safe_voltage rc=%d\n", rc);
2242 return rc;
2243 }
David Keitel454ee842013-03-08 16:19:11 -08002244 rc = qpnp_chg_vbatdet_set(chip,
2245 chip->max_voltage_mv - chip->resume_delta_mv);
David Keitel5d44fa52012-12-03 16:37:31 -08002246 if (rc) {
2247 pr_debug("failed setting resume_voltage rc=%d\n", rc);
2248 return rc;
2249 }
David Keitel80668952012-07-27 14:25:49 -07002250 rc = qpnp_chg_ibatmax_set(chip, chip->max_bat_chg_current);
2251 if (rc) {
2252 pr_debug("failed setting ibatmax rc=%d\n", rc);
2253 return rc;
2254 }
David Keitel365c4c42013-03-08 16:20:40 -08002255 if (chip->term_current) {
2256 rc = qpnp_chg_ibatterm_set(chip, chip->term_current);
2257 if (rc) {
2258 pr_debug("failed setting ibatterm rc=%d\n", rc);
2259 return rc;
2260 }
David Keitel80668952012-07-27 14:25:49 -07002261 }
David Keitel5d44fa52012-12-03 16:37:31 -08002262 rc = qpnp_chg_ibatsafe_set(chip, chip->safe_current);
2263 if (rc) {
2264 pr_debug("failed setting ibat_Safe rc=%d\n", rc);
2265 return rc;
2266 }
David Keitela4b7b592013-04-11 18:34:35 -07002267 rc = qpnp_chg_tchg_max_set(chip, chip->tchg_mins);
2268 if (rc) {
2269 pr_debug("failed setting tchg_mins rc=%d\n", rc);
2270 return rc;
2271 }
2272
David Keitel80668952012-07-27 14:25:49 -07002273 /* HACK: Disable wdog */
2274 rc = qpnp_chg_masked_write(chip, chip->chgr_base + 0x62,
2275 0xFF, 0xA0, 1);
2276
David Keitelb4e43542013-04-09 17:30:41 -07002277 /* HACK: use analog EOC */
David Keitel80668952012-07-27 14:25:49 -07002278 rc = qpnp_chg_masked_write(chip, chip->chgr_base +
2279 CHGR_IBAT_TERM_CHGR,
David Keitel9fd07382013-05-02 15:37:44 -07002280 0xFF, 0x08, 1);
David Keitel80668952012-07-27 14:25:49 -07002281
David Keitel80668952012-07-27 14:25:49 -07002282 break;
2283 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002284 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002285 case SMBCL_BUCK_SUBTYPE:
David Keitel9fd07382013-05-02 15:37:44 -07002286 rc = qpnp_chg_toggle_chg_done_logic(chip, 0);
2287 if (rc)
2288 return rc;
2289
David Keitel9201df32013-01-10 18:38:34 -08002290 rc = qpnp_chg_masked_write(chip,
2291 chip->chgr_base + CHGR_BUCK_BCK_VBAT_REG_MODE,
2292 BUCK_VBAT_REG_NODE_SEL_BIT,
2293 BUCK_VBAT_REG_NODE_SEL_BIT, 1);
2294 if (rc) {
2295 pr_debug("failed to enable IR drop comp rc=%d\n", rc);
2296 return rc;
2297 }
David Keitel80668952012-07-27 14:25:49 -07002298 break;
2299 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002300 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002301 case SMBCL_BAT_IF_SUBTYPE:
David Keitel796882d2013-05-14 18:01:11 -07002302 /* Select battery presence detection */
2303 if (chip->bpd_detection == 1)
2304 reg = BAT_ID_EN;
2305 else if (chip->bpd_detection == 2)
2306 reg = BAT_ID_EN | BAT_THM_EN;
2307
2308 rc = qpnp_chg_masked_write(chip,
2309 chip->bat_if_base + BAT_IF_BPD_CTRL,
2310 BAT_IF_BPD_CTRL_SEL,
2311 reg, 1);
2312 if (rc) {
2313 pr_debug("failed to chose BPD rc=%d\n", rc);
2314 return rc;
2315 }
David Keitel85ae4342013-04-16 11:46:00 -07002316 /* Force on VREF_BAT_THM */
2317 rc = qpnp_chg_masked_write(chip,
2318 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2319 VREF_BATT_THERM_FORCE_ON,
2320 VREF_BATT_THERM_FORCE_ON, 1);
2321 if (rc) {
2322 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
2323 return rc;
2324 }
David Keitel80668952012-07-27 14:25:49 -07002325 break;
2326 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002327 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002328 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel9fd07382013-05-02 15:37:44 -07002329 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel80668952012-07-27 14:25:49 -07002330 rc = qpnp_chg_masked_write(chip,
2331 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
2332 ENUM_T_STOP_BIT,
2333 ENUM_T_STOP_BIT, 1);
2334 if (rc) {
2335 pr_err("failed to write enum stop rc=%d\n", rc);
2336 return -ENXIO;
2337 }
2338 }
David Keiteld681cda2012-10-02 15:44:21 -07002339
David Keitel6dc4ed42013-05-17 11:08:58 -07002340 init_data = of_get_regulator_init_data(chip->dev,
2341 spmi_resource->of_node);
2342 if (!init_data) {
2343 pr_err("unable to allocate memory\n");
2344 return -ENOMEM;
2345 }
2346
2347 if (init_data->constraints.name) {
2348 if (of_get_property(chip->dev->of_node,
2349 "otg-parent-supply", NULL))
2350 init_data->supply_regulator = "otg-parent";
2351
2352 rdesc = &(chip->otg_vreg.rdesc);
2353 rdesc->owner = THIS_MODULE;
2354 rdesc->type = REGULATOR_VOLTAGE;
2355 rdesc->ops = &qpnp_chg_otg_reg_ops;
2356 rdesc->name = init_data->constraints.name;
2357
2358 init_data->constraints.valid_ops_mask
2359 |= REGULATOR_CHANGE_STATUS;
2360
2361 chip->otg_vreg.rdev = regulator_register(rdesc,
2362 chip->dev, init_data, chip,
2363 spmi_resource->of_node);
2364 if (IS_ERR(chip->otg_vreg.rdev)) {
2365 rc = PTR_ERR(chip->otg_vreg.rdev);
David Collinscbb12132013-05-28 10:47:28 -07002366 chip->otg_vreg.rdev = NULL;
David Keitel6dc4ed42013-05-17 11:08:58 -07002367 if (rc != -EPROBE_DEFER)
2368 pr_err("OTG reg failed, rc=%d\n", rc);
2369 return rc;
2370 }
2371 }
2372
David Keiteld681cda2012-10-02 15:44:21 -07002373 rc = qpnp_chg_masked_write(chip,
David Keitel5c3a7702012-12-20 11:13:21 -08002374 chip->usb_chgpth_base + USB_OVP_CTL,
2375 USB_VALID_DEB_20MS,
2376 USB_VALID_DEB_20MS, 1);
2377
2378 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -07002379 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
2380 ENUM_T_STOP_BIT,
2381 ENUM_T_STOP_BIT, 1);
2382
David Keitel344c6972013-04-09 19:28:21 -07002383 rc = qpnp_chg_masked_write(chip,
2384 chip->usb_chgpth_base + SEC_ACCESS,
2385 0xFF,
2386 0xA5, 1);
2387
2388 rc = qpnp_chg_masked_write(chip,
2389 chip->usb_chgpth_base + USB_CHG_GONE_REV_BST,
2390 0xFF,
2391 0x80, 1);
2392
David Keitel80668952012-07-27 14:25:49 -07002393 break;
2394 case SMBB_DC_CHGPTH_SUBTYPE:
2395 break;
2396 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002397 case SMBBP_BOOST_SUBTYPE:
David Keitel6dc4ed42013-05-17 11:08:58 -07002398 init_data = of_get_regulator_init_data(chip->dev,
2399 spmi_resource->of_node);
2400 if (!init_data) {
2401 pr_err("unable to allocate memory\n");
2402 return -ENOMEM;
2403 }
2404
2405 if (init_data->constraints.name) {
2406 if (of_get_property(chip->dev->of_node,
2407 "boost-parent-supply", NULL))
2408 init_data->supply_regulator = "boost-parent";
2409
2410 rdesc = &(chip->boost_vreg.rdesc);
2411 rdesc->owner = THIS_MODULE;
2412 rdesc->type = REGULATOR_VOLTAGE;
2413 rdesc->ops = &qpnp_chg_boost_reg_ops;
2414 rdesc->name = init_data->constraints.name;
2415
2416 init_data->constraints.valid_ops_mask
2417 |= REGULATOR_CHANGE_STATUS
2418 | REGULATOR_CHANGE_VOLTAGE;
2419
2420 chip->boost_vreg.rdev = regulator_register(rdesc,
2421 chip->dev, init_data, chip,
2422 spmi_resource->of_node);
2423 if (IS_ERR(chip->boost_vreg.rdev)) {
2424 rc = PTR_ERR(chip->boost_vreg.rdev);
David Collinscbb12132013-05-28 10:47:28 -07002425 chip->boost_vreg.rdev = NULL;
David Keitel6dc4ed42013-05-17 11:08:58 -07002426 if (rc != -EPROBE_DEFER)
2427 pr_err("boost reg failed, rc=%d\n", rc);
2428 return rc;
2429 }
2430 }
David Keitel80668952012-07-27 14:25:49 -07002431 break;
2432 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002433 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002434 case SMBCL_MISC_SUBTYPE:
David Keitel52d685e2013-05-02 11:59:05 -07002435 if (subtype == SMBB_MISC_SUBTYPE)
2436 chip->type = SMBB;
2437 else if (subtype == SMBBP_MISC_SUBTYPE)
2438 chip->type = SMBBP;
2439 else if (subtype == SMBCL_MISC_SUBTYPE)
2440 chip->type = SMBCL;
2441
David Keitel80668952012-07-27 14:25:49 -07002442 pr_debug("Setting BOOT_DONE\n");
2443 rc = qpnp_chg_masked_write(chip,
2444 chip->misc_base + CHGR_MISC_BOOT_DONE,
2445 CHGR_BOOT_DONE, CHGR_BOOT_DONE, 1);
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002446 rc = qpnp_chg_read(chip, &reg,
2447 chip->misc_base + MISC_REVISION2, 1);
2448 if (rc) {
2449 pr_err("failed to read revision register rc=%d\n", rc);
2450 return rc;
2451 }
David Keitel80668952012-07-27 14:25:49 -07002452
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002453 chip->revision = reg;
David Keitel80668952012-07-27 14:25:49 -07002454 break;
2455 default:
2456 pr_err("Invalid peripheral subtype\n");
2457 }
2458 return rc;
2459}
2460
David Keitel112ba9c2013-04-12 18:40:43 -07002461#define OF_PROP_READ(chip, prop, qpnp_dt_property, retval, optional) \
2462do { \
2463 if (retval) \
2464 break; \
2465 \
2466 retval = of_property_read_u32(chip->spmi->dev.of_node, \
2467 "qcom," qpnp_dt_property, \
2468 &chip->prop); \
2469 \
2470 if ((retval == -EINVAL) && optional) \
2471 retval = 0; \
2472 else if (retval) \
2473 pr_err("Error reading " #qpnp_dt_property \
2474 " property rc = %d\n", rc); \
2475} while (0)
2476
2477static int
2478qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
2479{
2480 int rc = 0;
David Keitel796882d2013-05-14 18:01:11 -07002481 const char *bpd;
David Keitel112ba9c2013-04-12 18:40:43 -07002482
2483 OF_PROP_READ(chip, max_voltage_mv, "vddmax-mv", rc, 0);
2484 OF_PROP_READ(chip, min_voltage_mv, "vinmin-mv", rc, 0);
2485 OF_PROP_READ(chip, safe_voltage_mv, "vddsafe-mv", rc, 0);
2486 OF_PROP_READ(chip, resume_delta_mv, "vbatdet-delta-mv", rc, 0);
2487 OF_PROP_READ(chip, safe_current, "ibatsafe-ma", rc, 0);
2488 OF_PROP_READ(chip, max_bat_chg_current, "ibatmax-ma", rc, 0);
2489 if (rc)
2490 pr_err("failed to read required dt parameters %d\n", rc);
2491
2492 OF_PROP_READ(chip, term_current, "ibatterm-ma", rc, 1);
2493 OF_PROP_READ(chip, maxinput_dc_ma, "maxinput-dc-ma", rc, 1);
2494 OF_PROP_READ(chip, maxinput_usb_ma, "maxinput-usb-ma", rc, 1);
2495 OF_PROP_READ(chip, warm_bat_decidegc, "warm-bat-decidegc", rc, 1);
2496 OF_PROP_READ(chip, cool_bat_decidegc, "cool-bat-decidegc", rc, 1);
David Keitela4b7b592013-04-11 18:34:35 -07002497 OF_PROP_READ(chip, tchg_mins, "tchg-mins", rc, 1);
David Keitel112ba9c2013-04-12 18:40:43 -07002498 if (rc)
2499 return rc;
2500
David Keitel796882d2013-05-14 18:01:11 -07002501 rc = of_property_read_string(chip->spmi->dev.of_node,
2502 "qcom,bpd-detection", &bpd);
2503 if (rc) {
2504 pr_debug("no bpd-detection specified, ignored\n");
2505 } else {
2506 chip->bpd_detection = get_bpd(bpd);
2507 if (chip->bpd_detection < 0) {
2508 pr_err("failed to determine bpd schema %d\n", rc);
2509 return rc;
2510 }
2511 }
2512
David Keitel112ba9c2013-04-12 18:40:43 -07002513 /* Look up JEITA compliance parameters if cool and warm temp provided */
2514 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2515 rc = qpnp_adc_tm_is_ready();
2516 if (rc) {
2517 pr_err("tm not ready %d\n", rc);
2518 return rc;
2519 }
2520
2521 OF_PROP_READ(chip, warm_bat_chg_ma, "ibatmax-warm-ma", rc, 1);
2522 OF_PROP_READ(chip, cool_bat_chg_ma, "ibatmax-cool-ma", rc, 1);
2523 OF_PROP_READ(chip, warm_bat_mv, "warm-bat-mv", rc, 1);
2524 OF_PROP_READ(chip, cool_bat_mv, "cool-bat-mv", rc, 1);
2525 if (rc)
2526 return rc;
2527 }
2528
2529 /* Get the charging-disabled property */
2530 chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
2531 "qcom,charging-disabled");
2532
David Keitel8b68d2d2013-05-14 23:36:51 -07002533 /* Get the duty-cycle-100p property */
2534 chip->duty_cycle_100p = of_property_read_bool(
2535 chip->spmi->dev.of_node,
2536 "qcom,duty-cycle-100p");
2537 if (chip->duty_cycle_100p) {
2538 rc = qpnp_buck_set_100_duty_cycle_enable(chip, 1);
2539 if (rc) {
2540 pr_err("failed to enable duty cycle %d\n", rc);
2541 return rc;
2542 }
2543 }
2544
David Keitel112ba9c2013-04-12 18:40:43 -07002545 /* Get the fake-batt-values property */
2546 chip->use_default_batt_values =
2547 of_property_read_bool(chip->spmi->dev.of_node,
2548 "qcom,use-default-batt-values");
2549
2550 /* Disable charging when faking battery values */
2551 if (chip->use_default_batt_values)
2552 chip->charging_disabled = true;
2553
2554 of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
2555 &(chip->thermal_levels));
2556
2557 if (chip->thermal_levels > sizeof(int)) {
2558 chip->thermal_mitigation = kzalloc(
2559 chip->thermal_levels,
2560 GFP_KERNEL);
2561
2562 if (chip->thermal_mitigation == NULL) {
2563 pr_err("thermal mitigation kzalloc() failed.\n");
2564 return rc;
2565 }
2566
2567 chip->thermal_levels /= sizeof(int);
2568 rc = of_property_read_u32_array(chip->spmi->dev.of_node,
2569 "qcom,thermal-mitigation",
2570 chip->thermal_mitigation, chip->thermal_levels);
2571 if (rc) {
2572 pr_err("qcom,thermal-mitigation missing in dt\n");
2573 return rc;
2574 }
2575 }
2576
2577 return rc;
2578}
2579
David Keitel80668952012-07-27 14:25:49 -07002580static int __devinit
2581qpnp_charger_probe(struct spmi_device *spmi)
2582{
2583 u8 subtype;
2584 struct qpnp_chg_chip *chip;
2585 struct resource *resource;
2586 struct spmi_resource *spmi_resource;
2587 int rc = 0;
2588
2589 chip = kzalloc(sizeof *chip, GFP_KERNEL);
2590 if (chip == NULL) {
2591 pr_err("kzalloc() failed.\n");
2592 return -ENOMEM;
2593 }
2594
David Keitel80668952012-07-27 14:25:49 -07002595 chip->dev = &(spmi->dev);
2596 chip->spmi = spmi;
2597
2598 chip->usb_psy = power_supply_get_by_name("usb");
2599 if (!chip->usb_psy) {
2600 pr_err("usb supply not found deferring probe\n");
2601 rc = -EPROBE_DEFER;
2602 goto fail_chg_enable;
2603 }
2604
David Keitel112ba9c2013-04-12 18:40:43 -07002605 /* Get all device tree properties */
2606 rc = qpnp_charger_read_dt_props(chip);
2607 if (rc)
David Keitel80668952012-07-27 14:25:49 -07002608 goto fail_chg_enable;
David Keitel3dd5e0f2012-12-12 18:12:36 -08002609
David Keitel80668952012-07-27 14:25:49 -07002610 spmi_for_each_container_dev(spmi_resource, spmi) {
2611 if (!spmi_resource) {
2612 pr_err("qpnp_chg: spmi resource absent\n");
2613 rc = -ENXIO;
2614 goto fail_chg_enable;
2615 }
2616
2617 resource = spmi_get_resource(spmi, spmi_resource,
2618 IORESOURCE_MEM, 0);
2619 if (!(resource && resource->start)) {
2620 pr_err("node %s IO resource absent!\n",
2621 spmi->dev.of_node->full_name);
2622 rc = -ENXIO;
2623 goto fail_chg_enable;
2624 }
2625
2626 rc = qpnp_chg_read(chip, &subtype,
2627 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2628 if (rc) {
2629 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2630 goto fail_chg_enable;
2631 }
2632
2633 switch (subtype) {
2634 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002635 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002636 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002637 chip->chgr_base = resource->start;
2638 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2639 if (rc) {
2640 pr_err("Failed to init subtype 0x%x rc=%d\n",
2641 subtype, rc);
2642 goto fail_chg_enable;
2643 }
2644 break;
2645 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002646 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002647 case SMBCL_BUCK_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002648 chip->buck_base = resource->start;
2649 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2650 if (rc) {
2651 pr_err("Failed to init subtype 0x%x rc=%d\n",
2652 subtype, rc);
2653 goto fail_chg_enable;
2654 }
David Keitel344c6972013-04-09 19:28:21 -07002655
2656 rc = qpnp_chg_masked_write(chip,
2657 chip->buck_base + SEC_ACCESS,
2658 0xFF,
2659 0xA5, 1);
2660
2661 rc = qpnp_chg_masked_write(chip,
2662 chip->buck_base + BUCK_VCHG_OV,
2663 0xff,
2664 0x00, 1);
2665
2666 rc = qpnp_chg_masked_write(chip,
2667 chip->buck_base + SEC_ACCESS,
2668 0xFF,
2669 0xA5, 1);
2670
2671 rc = qpnp_chg_masked_write(chip,
2672 chip->buck_base + BUCK_TEST_SMBC_MODES,
2673 0xFF,
2674 0x80, 1);
2675
David Keitel80668952012-07-27 14:25:49 -07002676 break;
2677 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002678 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002679 case SMBCL_BAT_IF_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002680 chip->bat_if_base = resource->start;
2681 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2682 if (rc) {
2683 pr_err("Failed to init subtype 0x%x rc=%d\n",
2684 subtype, rc);
2685 goto fail_chg_enable;
2686 }
2687 break;
2688 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002689 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002690 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002691 chip->usb_chgpth_base = resource->start;
2692 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2693 if (rc) {
David Keitel6dc4ed42013-05-17 11:08:58 -07002694 if (rc != -EPROBE_DEFER)
2695 pr_err("Failed to init subtype 0x%x rc=%d\n",
David Keitel80668952012-07-27 14:25:49 -07002696 subtype, rc);
2697 goto fail_chg_enable;
2698 }
2699 break;
2700 case SMBB_DC_CHGPTH_SUBTYPE:
2701 chip->dc_chgpth_base = resource->start;
2702 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2703 if (rc) {
2704 pr_err("Failed to init subtype 0x%x rc=%d\n",
2705 subtype, rc);
2706 goto fail_chg_enable;
2707 }
2708 break;
2709 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002710 case SMBBP_BOOST_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002711 chip->boost_base = resource->start;
2712 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2713 if (rc) {
David Keitel6dc4ed42013-05-17 11:08:58 -07002714 if (rc != -EPROBE_DEFER)
2715 pr_err("Failed to init subtype 0x%x rc=%d\n",
David Keitel80668952012-07-27 14:25:49 -07002716 subtype, rc);
2717 goto fail_chg_enable;
2718 }
2719 break;
2720 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002721 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002722 case SMBCL_MISC_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002723 chip->misc_base = resource->start;
2724 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2725 if (rc) {
2726 pr_err("Failed to init subtype=0x%x rc=%d\n",
2727 subtype, rc);
2728 goto fail_chg_enable;
2729 }
2730 break;
2731 default:
2732 pr_err("Invalid peripheral subtype=0x%x\n", subtype);
2733 rc = -EINVAL;
2734 goto fail_chg_enable;
2735 }
2736 }
2737 dev_set_drvdata(&spmi->dev, chip);
2738 device_init_wakeup(&spmi->dev, 1);
2739
David Keitelf2170cc2013-02-20 17:49:03 -08002740 if (chip->bat_if_base) {
2741 rc = qpnp_vadc_is_ready();
2742 if (rc)
2743 goto fail_chg_enable;
David Keitel80668952012-07-27 14:25:49 -07002744
David Keitelf2170cc2013-02-20 17:49:03 -08002745 chip->batt_psy.name = "battery";
2746 chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
2747 chip->batt_psy.properties = msm_batt_power_props;
2748 chip->batt_psy.num_properties =
2749 ARRAY_SIZE(msm_batt_power_props);
2750 chip->batt_psy.get_property = qpnp_batt_power_get_property;
2751 chip->batt_psy.set_property = qpnp_batt_power_set_property;
2752 chip->batt_psy.property_is_writeable =
2753 qpnp_batt_property_is_writeable;
2754 chip->batt_psy.external_power_changed =
David Keitel80668952012-07-27 14:25:49 -07002755 qpnp_batt_external_power_changed;
Xiaozhe Shi890fbf42013-05-02 16:42:53 -07002756 chip->batt_psy.supplied_to = pm_batt_supplied_to;
2757 chip->batt_psy.num_supplicants =
2758 ARRAY_SIZE(pm_batt_supplied_to);
David Keitel80668952012-07-27 14:25:49 -07002759
David Keitelf2170cc2013-02-20 17:49:03 -08002760 rc = power_supply_register(chip->dev, &chip->batt_psy);
2761 if (rc < 0) {
2762 pr_err("batt failed to register rc = %d\n", rc);
2763 goto fail_chg_enable;
2764 }
David Keitel79f4c932013-04-03 16:08:39 -07002765 INIT_WORK(&chip->adc_measure_work,
2766 qpnp_bat_if_adc_measure_work);
David Keitelc7093b02013-02-14 12:50:04 -08002767 }
2768
David Keitel9fd07382013-05-02 15:37:44 -07002769 wake_lock_init(&chip->eoc_wake_lock,
2770 WAKE_LOCK_SUSPEND, "qpnp-chg-eoc-lock");
2771 INIT_DELAYED_WORK(&chip->eoc_work, qpnp_eoc_work);
David Keitel5910eea2013-05-02 15:32:25 -07002772 INIT_DELAYED_WORK(&chip->arb_stop_work, qpnp_arb_stop_work);
2773
David Keitelf2170cc2013-02-20 17:49:03 -08002774 if (chip->dc_chgpth_base) {
2775 chip->dc_psy.name = "qpnp-dc";
2776 chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
2777 chip->dc_psy.supplied_to = pm_power_supplied_to;
2778 chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
2779 chip->dc_psy.properties = pm_power_props_mains;
2780 chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
2781 chip->dc_psy.get_property = qpnp_power_get_property_mains;
2782
2783 rc = power_supply_register(chip->dev, &chip->dc_psy);
2784 if (rc < 0) {
2785 pr_err("power_supply_register dc failed rc=%d\n", rc);
2786 goto unregister_batt;
2787 }
David Keitel80668952012-07-27 14:25:49 -07002788 }
2789
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002790 /* Turn on appropriate workaround flags */
2791 qpnp_chg_setup_flags(chip);
2792
David Keitelf2170cc2013-02-20 17:49:03 -08002793 if (chip->maxinput_dc_ma && chip->dc_chgpth_base) {
David Keitel22ed2232013-01-28 11:04:07 -08002794 rc = qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
2795 if (rc) {
2796 pr_err("Error setting idcmax property %d\n", rc);
David Keitelf2170cc2013-02-20 17:49:03 -08002797 goto unregister_batt;
David Keitel22ed2232013-01-28 11:04:07 -08002798 }
2799 }
2800
David Keitel0c1a4532013-03-21 16:39:06 -07002801 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2802 chip->adc_param.low_temp = chip->cool_bat_decidegc;
2803 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel454ee842013-03-08 16:19:11 -08002804 chip->adc_param.timer_interval = ADC_MEAS2_INTERVAL_1S;
2805 chip->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
2806 chip->adc_param.btm_ctx = chip;
2807 chip->adc_param.threshold_notification =
2808 qpnp_chg_adc_notification;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -08002809 chip->adc_param.channel = LR_MUX1_BATT_THERM;
David Keitel0c1a4532013-03-21 16:39:06 -07002810
2811 if (get_prop_batt_present(chip)) {
2812 rc = qpnp_adc_tm_channel_measure(&chip->adc_param);
2813 if (rc) {
2814 pr_err("request ADC error %d\n", rc);
2815 goto fail_chg_enable;
2816 }
David Keitel454ee842013-03-08 16:19:11 -08002817 }
2818 }
2819
David Keitel03ee6b52012-10-22 12:25:19 -07002820 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitelb1ddb742012-11-06 19:05:51 -08002821 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
David Keitelbf359042012-10-19 16:54:58 -07002822
David Keitel0f35be42013-04-16 11:10:40 -07002823 rc = qpnp_chg_request_irqs(chip);
2824 if (rc) {
2825 pr_err("failed to request interrupts %d\n", rc);
2826 goto unregister_batt;
2827 }
2828
David Keitel9fd07382013-05-02 15:37:44 -07002829 qpnp_chg_usb_usbin_valid_irq_handler(USBIN_VALID_IRQ, chip);
2830 power_supply_set_present(chip->usb_psy,
2831 qpnp_chg_is_usb_chg_plugged_in(chip));
2832
David Keitel3c62b472013-05-06 15:38:11 -07002833 /* Set USB psy online to avoid userspace from shutting down if battery
2834 * capacity is at zero and no chargers online. */
2835 if (qpnp_chg_is_usb_chg_plugged_in(chip))
2836 power_supply_set_online(chip->usb_psy, 1);
2837
David Keitel796882d2013-05-14 18:01:11 -07002838 pr_info("success chg_dis = %d, bpd = %d, usb = %d, dc = %d b_health = %d batt_present = %d\n",
Abhijeet Dharmapurikar2d996b12013-01-03 17:48:02 -08002839 chip->charging_disabled,
David Keitel796882d2013-05-14 18:01:11 -07002840 chip->bpd_detection,
Abhijeet Dharmapurikar2d996b12013-01-03 17:48:02 -08002841 qpnp_chg_is_usb_chg_plugged_in(chip),
2842 qpnp_chg_is_dc_chg_plugged_in(chip),
2843 get_prop_batt_present(chip),
2844 get_prop_batt_health(chip));
David Keitel80668952012-07-27 14:25:49 -07002845 return 0;
2846
David Keitelc7093b02013-02-14 12:50:04 -08002847unregister_batt:
David Keitelf2170cc2013-02-20 17:49:03 -08002848 if (chip->bat_if_base)
2849 power_supply_unregister(&chip->batt_psy);
David Keitel80668952012-07-27 14:25:49 -07002850fail_chg_enable:
David Collinscbb12132013-05-28 10:47:28 -07002851 regulator_unregister(chip->otg_vreg.rdev);
2852 regulator_unregister(chip->boost_vreg.rdev);
David Keitelbe208252013-01-31 14:49:25 -08002853 kfree(chip->thermal_mitigation);
David Keitel80668952012-07-27 14:25:49 -07002854 kfree(chip);
2855 dev_set_drvdata(&spmi->dev, NULL);
2856 return rc;
2857}
2858
2859static int __devexit
2860qpnp_charger_remove(struct spmi_device *spmi)
2861{
2862 struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
David Keitel0c1a4532013-03-21 16:39:06 -07002863 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
2864 && chip->batt_present) {
2865 qpnp_adc_tm_disable_chan_meas(&chip->adc_param);
2866 }
David Keitel79f4c932013-04-03 16:08:39 -07002867 cancel_work_sync(&chip->adc_measure_work);
David Keitel9fd07382013-05-02 15:37:44 -07002868 cancel_delayed_work_sync(&chip->eoc_work);
David Keitel79f4c932013-04-03 16:08:39 -07002869
David Collinscbb12132013-05-28 10:47:28 -07002870 regulator_unregister(chip->otg_vreg.rdev);
2871 regulator_unregister(chip->boost_vreg.rdev);
David Keitel6dc4ed42013-05-17 11:08:58 -07002872
David Keitel80668952012-07-27 14:25:49 -07002873 dev_set_drvdata(&spmi->dev, NULL);
2874 kfree(chip);
2875
2876 return 0;
2877}
2878
David Keitel85ae4342013-04-16 11:46:00 -07002879static int qpnp_chg_resume(struct device *dev)
2880{
2881 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2882 int rc = 0;
2883
2884 rc = qpnp_chg_masked_write(chip,
2885 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2886 VREF_BATT_THERM_FORCE_ON,
2887 VREF_BATT_THERM_FORCE_ON, 1);
2888 if (rc)
2889 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
2890
2891 return rc;
2892}
2893
2894static int qpnp_chg_suspend(struct device *dev)
2895{
2896 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2897 int rc = 0;
2898
2899 rc = qpnp_chg_masked_write(chip,
2900 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2901 VREF_BATT_THERM_FORCE_ON,
2902 VREF_BAT_THM_ENABLED_FSM, 1);
2903 if (rc)
2904 pr_debug("failed to enable FSM ctrl VREF_BAT_THM rc=%d\n", rc);
2905
2906 return rc;
2907}
2908
David Keitel723d5012013-05-03 13:17:27 -07002909static const struct dev_pm_ops qpnp_chg_pm_ops = {
David Keitel85ae4342013-04-16 11:46:00 -07002910 .resume = qpnp_chg_resume,
2911 .suspend = qpnp_chg_suspend,
2912};
2913
David Keitel80668952012-07-27 14:25:49 -07002914static struct spmi_driver qpnp_charger_driver = {
2915 .probe = qpnp_charger_probe,
2916 .remove = __devexit_p(qpnp_charger_remove),
2917 .driver = {
David Keitel723d5012013-05-03 13:17:27 -07002918 .name = QPNP_CHARGER_DEV_NAME,
2919 .owner = THIS_MODULE,
2920 .of_match_table = qpnp_charger_match_table,
2921 .pm = &qpnp_chg_pm_ops,
David Keitel80668952012-07-27 14:25:49 -07002922 },
2923};
2924
2925/**
2926 * qpnp_chg_init() - register spmi driver for qpnp-chg
2927 */
2928int __init
2929qpnp_chg_init(void)
2930{
2931 return spmi_driver_register(&qpnp_charger_driver);
2932}
2933module_init(qpnp_chg_init);
2934
2935static void __exit
2936qpnp_chg_exit(void)
2937{
2938 spmi_driver_unregister(&qpnp_charger_driver);
2939}
2940module_exit(qpnp_chg_exit);
2941
2942
2943MODULE_DESCRIPTION("QPNP charger driver");
2944MODULE_LICENSE("GPL v2");
2945MODULE_ALIAS("platform:" QPNP_CHARGER_DEV_NAME);