blob: e7eb46266705713946590675d3a56d5c72171815 [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;
Xiaozhe Shi79a8c492013-05-24 13:09:23 -0700288 int set_vddmax_mv;
289 int delta_vddmax_mv;
David Keitel454ee842013-03-08 16:19:11 -0800290 unsigned int warm_bat_mv;
291 unsigned int cool_bat_mv;
292 unsigned int resume_delta_mv;
David Keitel9fd07382013-05-02 15:37:44 -0700293 int term_current;
David Keitel22ed2232013-01-28 11:04:07 -0800294 unsigned int maxinput_usb_ma;
295 unsigned int maxinput_dc_ma;
David Keitel0c1a4532013-03-21 16:39:06 -0700296 unsigned int warm_bat_decidegc;
297 unsigned int cool_bat_decidegc;
David Keitel5d44fa52012-12-03 16:37:31 -0800298 unsigned int safe_current;
David Keitel80668952012-07-27 14:25:49 -0700299 unsigned int revision;
David Keitelfe51cb92013-04-02 19:42:58 -0700300 unsigned int type;
301 unsigned int tchg_mins;
David Keitelbe208252013-01-31 14:49:25 -0800302 unsigned int thermal_levels;
303 unsigned int therm_lvl_sel;
304 unsigned int *thermal_mitigation;
David Keitel80668952012-07-27 14:25:49 -0700305 struct power_supply dc_psy;
306 struct power_supply *usb_psy;
307 struct power_supply *bms_psy;
308 struct power_supply batt_psy;
David Keiteld681cda2012-10-02 15:44:21 -0700309 uint32_t flags;
David Keitel454ee842013-03-08 16:19:11 -0800310 struct qpnp_adc_tm_btm_param adc_param;
David Keitel79f4c932013-04-03 16:08:39 -0700311 struct work_struct adc_measure_work;
David Keitel344c6972013-04-09 19:28:21 -0700312 struct delayed_work arb_stop_work;
David Keitel9fd07382013-05-02 15:37:44 -0700313 struct delayed_work eoc_work;
314 struct wake_lock eoc_wake_lock;
David Keitel6dc4ed42013-05-17 11:08:58 -0700315 struct qpnp_chg_regulator otg_vreg;
316 struct qpnp_chg_regulator boost_vreg;
David Keitel80668952012-07-27 14:25:49 -0700317};
318
David Keitel47185a62013-05-15 18:54:10 -0700319
David Keitel80668952012-07-27 14:25:49 -0700320static struct of_device_id qpnp_charger_match_table[] = {
321 { .compatible = QPNP_CHARGER_DEV_NAME, },
322 {}
323};
324
David Keitel0ef282b2013-05-29 16:04:57 -0700325enum bpd_type {
326 BPD_TYPE_BAT_ID,
327 BPD_TYPE_BAT_THM,
328 BPD_TYPE_BAT_THM_BAT_ID,
329};
David Keitel796882d2013-05-14 18:01:11 -0700330
David Keitel0ef282b2013-05-29 16:04:57 -0700331static const char * const bpd_label[] = {
332 [BPD_TYPE_BAT_ID] = "bpd_id",
333 [BPD_TYPE_BAT_THM] = "bpd_thm",
334 [BPD_TYPE_BAT_THM_BAT_ID] = "bpd_thm_id",
David Keitel796882d2013-05-14 18:01:11 -0700335};
336
337static inline int
338get_bpd(const char *name)
339{
340 int i = 0;
David Keitel0ef282b2013-05-29 16:04:57 -0700341 for (i = 0; i < ARRAY_SIZE(bpd_label); i++) {
342 if (strcmp(bpd_label[i], name) == 0)
David Keitel796882d2013-05-14 18:01:11 -0700343 return i;
344 }
345 return -EINVAL;
346}
347
David Keitel80668952012-07-27 14:25:49 -0700348static int
349qpnp_chg_read(struct qpnp_chg_chip *chip, u8 *val,
350 u16 base, int count)
351{
David Keitel39093572013-06-05 15:32:30 -0700352 int rc = 0;
David Keitel80668952012-07-27 14:25:49 -0700353 struct spmi_device *spmi = chip->spmi;
354
David Keitel39093572013-06-05 15:32:30 -0700355 if (base == 0) {
356 pr_err("base cannot be zero base=0x%02x sid=0x%02x rc=%d\n",
357 base, spmi->sid, rc);
358 return -EINVAL;
359 }
360
361 rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val, count);
David Keitel80668952012-07-27 14:25:49 -0700362 if (rc) {
363 pr_err("SPMI read failed base=0x%02x sid=0x%02x rc=%d\n", base,
364 spmi->sid, rc);
365 return rc;
366 }
367 return 0;
368}
369
370static int
371qpnp_chg_write(struct qpnp_chg_chip *chip, u8 *val,
372 u16 base, int count)
373{
David Keitel39093572013-06-05 15:32:30 -0700374 int rc = 0;
David Keitel80668952012-07-27 14:25:49 -0700375 struct spmi_device *spmi = chip->spmi;
376
David Keitel39093572013-06-05 15:32:30 -0700377 if (base == 0) {
378 pr_err("base cannot be zero base=0x%02x sid=0x%02x rc=%d\n",
379 base, spmi->sid, rc);
380 return -EINVAL;
381 }
382
383 rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val, count);
David Keitel80668952012-07-27 14:25:49 -0700384 if (rc) {
385 pr_err("write failed base=0x%02x sid=0x%02x rc=%d\n",
386 base, spmi->sid, rc);
387 return rc;
388 }
389
390 return 0;
391}
392
393static int
394qpnp_chg_masked_write(struct qpnp_chg_chip *chip, u16 base,
395 u8 mask, u8 val, int count)
396{
397 int rc;
398 u8 reg;
399
400 rc = qpnp_chg_read(chip, &reg, base, count);
401 if (rc) {
402 pr_err("spmi read failed: addr=%03X, rc=%d\n", base, rc);
403 return rc;
404 }
405 pr_debug("addr = 0x%x read 0x%x\n", base, reg);
406
407 reg &= ~mask;
408 reg |= val & mask;
409
410 pr_debug("Writing 0x%x\n", reg);
411
412 rc = qpnp_chg_write(chip, &reg, base, count);
413 if (rc) {
414 pr_err("spmi write failed: addr=%03X, rc=%d\n", base, rc);
415 return rc;
416 }
417
418 return 0;
419}
420
David Keitel47185a62013-05-15 18:54:10 -0700421static void
422qpnp_chg_enable_irq(struct qpnp_chg_irq *irq)
423{
424 if (__test_and_clear_bit(0, &irq->disabled)) {
425 pr_debug("number = %d\n", irq->irq);
426 enable_irq(irq->irq);
427 }
428}
429
430static void
431qpnp_chg_disable_irq(struct qpnp_chg_irq *irq)
432{
433 if (!__test_and_set_bit(0, &irq->disabled)) {
434 pr_debug("number = %d\n", irq->irq);
435 disable_irq_nosync(irq->irq);
436 }
437}
438
David Keitel6f865cd2012-11-30 15:04:32 -0800439#define USB_OTG_EN_BIT BIT(0)
440static int
441qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
442{
443 u8 usb_otg_en;
444 int rc;
445
446 rc = qpnp_chg_read(chip, &usb_otg_en,
447 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
448 1);
449
450 if (rc) {
451 pr_err("spmi read failed: addr=%03X, rc=%d\n",
452 chip->usb_chgpth_base + CHGR_STATUS, rc);
453 return rc;
454 }
455 pr_debug("usb otg en 0x%x\n", usb_otg_en);
456
457 return (usb_otg_en & USB_OTG_EN_BIT) ? 1 : 0;
458}
459
David Keitel42ae0aa2013-03-08 16:20:10 -0800460static int
David Keitel6dc4ed42013-05-17 11:08:58 -0700461qpnp_chg_is_boost_en_set(struct qpnp_chg_chip *chip)
462{
463 u8 boost_en_ctl;
464 int rc;
465
466 rc = qpnp_chg_read(chip, &boost_en_ctl,
467 chip->boost_base + BOOST_ENABLE_CONTROL, 1);
468 if (rc) {
469 pr_err("spmi read failed: addr=%03X, rc=%d\n",
470 chip->boost_base + BOOST_ENABLE_CONTROL, rc);
471 return rc;
472 }
473
474 pr_debug("boost en 0x%x\n", boost_en_ctl);
475
476 return (boost_en_ctl & BOOST_PWR_EN) ? 1 : 0;
477}
478
479static int
David Keitel42ae0aa2013-03-08 16:20:10 -0800480qpnp_chg_is_batt_present(struct qpnp_chg_chip *chip)
481{
482 u8 batt_pres_rt_sts;
483 int rc;
484
485 rc = qpnp_chg_read(chip, &batt_pres_rt_sts,
486 INT_RT_STS(chip->bat_if_base), 1);
487 if (rc) {
488 pr_err("spmi read failed: addr=%03X, rc=%d\n",
489 INT_RT_STS(chip->bat_if_base), rc);
490 return rc;
491 }
492
493 return (batt_pres_rt_sts & BATT_PRES_IRQ) ? 1 : 0;
494}
495
David Keiteld681cda2012-10-02 15:44:21 -0700496#define USB_VALID_BIT BIT(7)
David Keitel80668952012-07-27 14:25:49 -0700497static int
498qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip)
499{
500 u8 usbin_valid_rt_sts;
501 int rc;
502
503 rc = qpnp_chg_read(chip, &usbin_valid_rt_sts,
David Keiteld681cda2012-10-02 15:44:21 -0700504 chip->usb_chgpth_base + CHGR_STATUS , 1);
David Keitel80668952012-07-27 14:25:49 -0700505
506 if (rc) {
507 pr_err("spmi read failed: addr=%03X, rc=%d\n",
David Keiteld681cda2012-10-02 15:44:21 -0700508 chip->usb_chgpth_base + CHGR_STATUS, rc);
David Keitel80668952012-07-27 14:25:49 -0700509 return rc;
510 }
511 pr_debug("chgr usb sts 0x%x\n", usbin_valid_rt_sts);
512
David Keiteld681cda2012-10-02 15:44:21 -0700513 return (usbin_valid_rt_sts & USB_VALID_BIT) ? 1 : 0;
David Keitel80668952012-07-27 14:25:49 -0700514}
515
516static int
517qpnp_chg_is_dc_chg_plugged_in(struct qpnp_chg_chip *chip)
518{
519 u8 dcin_valid_rt_sts;
520 int rc;
521
David Keitelf2170cc2013-02-20 17:49:03 -0800522 if (!chip->dc_chgpth_base)
523 return 0;
524
David Keitel80668952012-07-27 14:25:49 -0700525 rc = qpnp_chg_read(chip, &dcin_valid_rt_sts,
526 INT_RT_STS(chip->dc_chgpth_base), 1);
527 if (rc) {
528 pr_err("spmi read failed: addr=%03X, rc=%d\n",
529 INT_RT_STS(chip->dc_chgpth_base), rc);
530 return rc;
531 }
532
533 return (dcin_valid_rt_sts & DCIN_VALID_IRQ) ? 1 : 0;
534}
535
David Keitel22ed2232013-01-28 11:04:07 -0800536#define QPNP_CHG_I_MAX_MIN_100 100
537#define QPNP_CHG_I_MAX_MIN_150 150
538#define QPNP_CHG_I_MAX_MIN_MA 200
539#define QPNP_CHG_I_MAX_MAX_MA 2500
540#define QPNP_CHG_I_MAXSTEP_MA 100
541static int
542qpnp_chg_idcmax_set(struct qpnp_chg_chip *chip, int mA)
543{
544 int rc = 0;
545 u8 dc = 0;
546
547 if (mA < QPNP_CHG_I_MAX_MIN_100
548 || mA > QPNP_CHG_I_MAX_MAX_MA) {
549 pr_err("bad mA=%d asked to set\n", mA);
550 return -EINVAL;
551 }
552
553 if (mA == QPNP_CHG_I_MAX_MIN_100) {
554 dc = 0x00;
555 pr_debug("current=%d setting %02x\n", mA, dc);
556 return qpnp_chg_write(chip, &dc,
557 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
558 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
559 dc = 0x01;
560 pr_debug("current=%d setting %02x\n", mA, dc);
561 return qpnp_chg_write(chip, &dc,
562 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
563 }
564
565 dc = mA / QPNP_CHG_I_MAXSTEP_MA;
566
567 pr_debug("current=%d setting 0x%x\n", mA, dc);
568 rc = qpnp_chg_write(chip, &dc,
569 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
570
571 return rc;
572}
573
David Keitel80668952012-07-27 14:25:49 -0700574static int
575qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
576{
David Keiteld681cda2012-10-02 15:44:21 -0700577 int rc = 0;
578 u8 usb_reg = 0, temp = 8;
David Keitel80668952012-07-27 14:25:49 -0700579
David Keitel22ed2232013-01-28 11:04:07 -0800580 if (mA < QPNP_CHG_I_MAX_MIN_100
581 || mA > QPNP_CHG_I_MAX_MAX_MA) {
David Keitel80668952012-07-27 14:25:49 -0700582 pr_err("bad mA=%d asked to set\n", mA);
583 return -EINVAL;
584 }
585
David Keitel22ed2232013-01-28 11:04:07 -0800586 if (mA == QPNP_CHG_I_MAX_MIN_100) {
587 usb_reg = 0x00;
588 pr_debug("current=%d setting %02x\n", mA, usb_reg);
589 return qpnp_chg_write(chip, &usb_reg,
590 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
591 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
592 usb_reg = 0x01;
593 pr_debug("current=%d setting %02x\n", mA, usb_reg);
594 return qpnp_chg_write(chip, &usb_reg,
595 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
596 }
597
598 /* Impose input current limit */
599 if (chip->maxinput_usb_ma)
600 mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
601
602 usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
David Keitel80668952012-07-27 14:25:49 -0700603
David Keiteld681cda2012-10-02 15:44:21 -0700604 if (chip->flags & CHG_FLAGS_VCP_WA) {
605 temp = 0xA5;
606 rc = qpnp_chg_write(chip, &temp,
607 chip->buck_base + SEC_ACCESS, 1);
608 rc = qpnp_chg_masked_write(chip,
609 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
610 0x0C, 0x0C, 1);
611 }
612
David Keitel80668952012-07-27 14:25:49 -0700613 pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
David Keiteld681cda2012-10-02 15:44:21 -0700614 rc = qpnp_chg_write(chip, &usb_reg,
David Keitel22ed2232013-01-28 11:04:07 -0800615 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
David Keiteld681cda2012-10-02 15:44:21 -0700616
617 if (chip->flags & CHG_FLAGS_VCP_WA) {
618 temp = 0xA5;
619 udelay(200);
620 rc = qpnp_chg_write(chip, &temp,
621 chip->buck_base + SEC_ACCESS, 1);
622 rc = qpnp_chg_masked_write(chip,
623 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
624 0x0C, 0x00, 1);
625 }
626
627 return rc;
628}
629
630#define USB_SUSPEND_BIT BIT(0)
631static int
632qpnp_chg_usb_suspend_enable(struct qpnp_chg_chip *chip, int enable)
633{
634 return qpnp_chg_masked_write(chip,
635 chip->usb_chgpth_base + CHGR_USB_USB_SUSP,
636 USB_SUSPEND_BIT,
637 enable ? USB_SUSPEND_BIT : 0, 1);
David Keitel80668952012-07-27 14:25:49 -0700638}
639
David Keitel344c6972013-04-09 19:28:21 -0700640static int
641qpnp_chg_charge_en(struct qpnp_chg_chip *chip, int enable)
642{
643 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
644 CHGR_CHG_EN,
645 enable ? CHGR_CHG_EN : 0, 1);
646}
647
648static int
649qpnp_chg_force_run_on_batt(struct qpnp_chg_chip *chip, int disable)
650{
651 /* Don't run on battery for batteryless hardware */
652 if (chip->use_default_batt_values)
653 return 0;
David Keitel4d66ea02013-04-30 10:57:58 -0700654 /* Don't force on battery if battery is not present */
655 if (!qpnp_chg_is_batt_present(chip))
656 return 0;
David Keitel344c6972013-04-09 19:28:21 -0700657
658 /* This bit forces the charger to run off of the battery rather
659 * than a connected charger */
660 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
661 CHGR_ON_BAT_FORCE_BIT,
662 disable ? CHGR_ON_BAT_FORCE_BIT : 0, 1);
663}
664
David Keitel8b68d2d2013-05-14 23:36:51 -0700665#define BUCK_DUTY_MASK_100P 0x30
666static int
667qpnp_buck_set_100_duty_cycle_enable(struct qpnp_chg_chip *chip, int enable)
668{
669 int rc;
670
671 pr_debug("enable: %d\n", enable);
672
673 rc = qpnp_chg_masked_write(chip,
674 chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
675 if (rc) {
676 pr_debug("failed to write sec access rc=%d\n", rc);
677 return rc;
678 }
679
680 rc = qpnp_chg_masked_write(chip,
681 chip->buck_base + BUCK_TEST_SMBC_MODES,
682 BUCK_DUTY_MASK_100P, enable ? 0x00 : 0x10, 1);
683 if (rc) {
684 pr_debug("failed enable 100p duty cycle rc=%d\n", rc);
685 return rc;
686 }
687
688 return rc;
689}
690
David Keitel9fd07382013-05-02 15:37:44 -0700691#define COMPATATOR_OVERRIDE_0 0x80
692static int
693qpnp_chg_toggle_chg_done_logic(struct qpnp_chg_chip *chip, int enable)
694{
695 int rc;
696
697 pr_debug("toggle: %d\n", enable);
698
699 rc = qpnp_chg_masked_write(chip,
700 chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
701 if (rc) {
702 pr_debug("failed to write sec access rc=%d\n", rc);
703 return rc;
704 }
705
706 rc = qpnp_chg_masked_write(chip,
707 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_1,
708 0xC0, enable ? 0x00 : COMPATATOR_OVERRIDE_0, 1);
709 if (rc) {
710 pr_debug("failed to toggle chg done override rc=%d\n", rc);
711 return rc;
712 }
713
714 return rc;
715}
716
717#define QPNP_CHG_VBATDET_MIN_MV 3240
718#define QPNP_CHG_VBATDET_MAX_MV 5780
719#define QPNP_CHG_VBATDET_STEP_MV 20
720static int
721qpnp_chg_vbatdet_set(struct qpnp_chg_chip *chip, int vbatdet_mv)
722{
723 u8 temp;
724
725 if (vbatdet_mv < QPNP_CHG_VBATDET_MIN_MV
726 || vbatdet_mv > QPNP_CHG_VBATDET_MAX_MV) {
727 pr_err("bad mV=%d asked to set\n", vbatdet_mv);
728 return -EINVAL;
729 }
730 temp = (vbatdet_mv - QPNP_CHG_VBATDET_MIN_MV)
731 / QPNP_CHG_VBATDET_STEP_MV;
732
733 pr_debug("voltage=%d setting %02x\n", vbatdet_mv, temp);
734 return qpnp_chg_write(chip, &temp,
735 chip->chgr_base + CHGR_VBAT_DET, 1);
736}
737
David Keitel344c6972013-04-09 19:28:21 -0700738static void
739qpnp_arb_stop_work(struct work_struct *work)
740{
741 struct delayed_work *dwork = to_delayed_work(work);
742 struct qpnp_chg_chip *chip = container_of(dwork,
743 struct qpnp_chg_chip, arb_stop_work);
744
David Keitel9fd07382013-05-02 15:37:44 -0700745 if (!chip->chg_done)
746 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitel344c6972013-04-09 19:28:21 -0700747 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
748}
749
750static void
751qpnp_bat_if_adc_measure_work(struct work_struct *work)
David Keitel79f4c932013-04-03 16:08:39 -0700752{
753 struct qpnp_chg_chip *chip = container_of(work,
754 struct qpnp_chg_chip, adc_measure_work);
755
756 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
757 pr_err("request ADC error\n");
758}
759
David Keitel9fd07382013-05-02 15:37:44 -0700760#define EOC_CHECK_PERIOD_MS 10000
761static irqreturn_t
762qpnp_chg_vbatdet_lo_irq_handler(int irq, void *_chip)
763{
764 struct qpnp_chg_chip *chip = _chip;
765 u8 chg_sts = 0;
766 int rc;
767
768 pr_debug("vbatdet-lo triggered\n");
769
770 rc = qpnp_chg_read(chip, &chg_sts, INT_RT_STS(chip->chgr_base), 1);
771 if (rc)
772 pr_err("failed to read chg_sts rc=%d\n", rc);
773
774 pr_debug("chg_done chg_sts: 0x%x triggered\n", chg_sts);
775 if (!chip->charging_disabled && (chg_sts & FAST_CHG_ON_IRQ)) {
776 schedule_delayed_work(&chip->eoc_work,
777 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
778 wake_lock(&chip->eoc_wake_lock);
David Keitel47185a62013-05-15 18:54:10 -0700779 qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -0700780 } else {
781 qpnp_chg_charge_en(chip, !chip->charging_disabled);
782 }
783
784 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700785 if (chip->dc_chgpth_base)
786 power_supply_changed(&chip->dc_psy);
787 if (chip->bat_if_base)
788 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700789 return IRQ_HANDLED;
790}
791
David Keitel344c6972013-04-09 19:28:21 -0700792#define ARB_STOP_WORK_MS 1000
793static irqreturn_t
794qpnp_chg_usb_chg_gone_irq_handler(int irq, void *_chip)
795{
796 struct qpnp_chg_chip *chip = _chip;
797
798 pr_debug("chg_gone triggered\n");
799 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
800 qpnp_chg_charge_en(chip, 0);
David Keitel9fd07382013-05-02 15:37:44 -0700801 qpnp_chg_force_run_on_batt(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -0700802 schedule_delayed_work(&chip->arb_stop_work,
803 msecs_to_jiffies(ARB_STOP_WORK_MS));
804 }
805
806 return IRQ_HANDLED;
807}
808
David Keitel80668952012-07-27 14:25:49 -0700809#define ENUM_T_STOP_BIT BIT(0)
810static irqreturn_t
811qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
812{
813 struct qpnp_chg_chip *chip = _chip;
David Keitel6f865cd2012-11-30 15:04:32 -0800814 int usb_present, host_mode;
David Keitel80668952012-07-27 14:25:49 -0700815
816 usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
David Keitel6f865cd2012-11-30 15:04:32 -0800817 host_mode = qpnp_chg_is_otg_en_set(chip);
818 pr_debug("usbin-valid triggered: %d host_mode: %d\n",
819 usb_present, host_mode);
820
821 /* In host mode notifications cmoe from USB supply */
822 if (host_mode)
823 return IRQ_HANDLED;
David Keitel80668952012-07-27 14:25:49 -0700824
825 if (chip->usb_present ^ usb_present) {
826 chip->usb_present = usb_present;
David Keitel9fd07382013-05-02 15:37:44 -0700827 if (!usb_present) {
David Keitel344c6972013-04-09 19:28:21 -0700828 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel9fd07382013-05-02 15:37:44 -0700829 chip->chg_done = false;
830 } else {
831 schedule_delayed_work(&chip->eoc_work,
832 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
833 }
David Keitel344c6972013-04-09 19:28:21 -0700834
David Keitel9fd07382013-05-02 15:37:44 -0700835 power_supply_set_present(chip->usb_psy, chip->usb_present);
David Keitel80668952012-07-27 14:25:49 -0700836 }
837
838 return IRQ_HANDLED;
839}
840
David Keitel7450dcd2013-01-29 18:41:41 -0800841static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800842qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
843{
844 struct qpnp_chg_chip *chip = _chip;
845 int batt_present;
846
847 batt_present = qpnp_chg_is_batt_present(chip);
848 pr_debug("batt-pres triggered: %d\n", batt_present);
849
850 if (chip->batt_present ^ batt_present) {
851 chip->batt_present = batt_present;
852 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700853 power_supply_changed(chip->usb_psy);
David Keitel0c1a4532013-03-21 16:39:06 -0700854
855 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
856 && batt_present) {
David Keitel79f4c932013-04-03 16:08:39 -0700857 schedule_work(&chip->adc_measure_work);
David Keitel0c1a4532013-03-21 16:39:06 -0700858 }
David Keitel42ae0aa2013-03-08 16:20:10 -0800859 }
860
861 return IRQ_HANDLED;
862}
863
864static irqreturn_t
David Keitel7450dcd2013-01-29 18:41:41 -0800865qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
866{
867 struct qpnp_chg_chip *chip = _chip;
868 int dc_present;
869
870 dc_present = qpnp_chg_is_dc_chg_plugged_in(chip);
871 pr_debug("dcin-valid triggered: %d\n", dc_present);
872
873 if (chip->dc_present ^ dc_present) {
874 chip->dc_present = dc_present;
David Keitel9fd07382013-05-02 15:37:44 -0700875 if (!dc_present)
876 chip->chg_done = false;
877 else
878 schedule_delayed_work(&chip->eoc_work,
879 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
David Keitel7450dcd2013-01-29 18:41:41 -0800880 power_supply_changed(&chip->dc_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700881 power_supply_changed(&chip->batt_psy);
David Keitel7450dcd2013-01-29 18:41:41 -0800882 }
883
884 return IRQ_HANDLED;
885}
886
David Keitel80668952012-07-27 14:25:49 -0700887#define CHGR_CHG_FAILED_BIT BIT(7)
888static irqreturn_t
889qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
890{
891 struct qpnp_chg_chip *chip = _chip;
David Keitel4429b1f2012-10-18 10:42:50 -0700892 int rc;
David Keitel80668952012-07-27 14:25:49 -0700893
David Keitel9fd07382013-05-02 15:37:44 -0700894 pr_debug("chg_failed triggered\n");
895
David Keitel80668952012-07-27 14:25:49 -0700896 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -0700897 chip->chgr_base + CHGR_CHG_FAILED,
David Keitel80668952012-07-27 14:25:49 -0700898 CHGR_CHG_FAILED_BIT,
899 CHGR_CHG_FAILED_BIT, 1);
900 if (rc)
901 pr_err("Failed to write chg_fail clear bit!\n");
902
David Keiteldbcef092013-05-14 14:48:30 -0700903 if (chip->bat_if_base)
904 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700905 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700906 if (chip->dc_chgpth_base)
907 power_supply_changed(&chip->dc_psy);
David Keitel80668952012-07-27 14:25:49 -0700908 return IRQ_HANDLED;
909}
910
911static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800912qpnp_chg_chgr_chg_trklchg_irq_handler(int irq, void *_chip)
913{
914 struct qpnp_chg_chip *chip = _chip;
915
916 pr_debug("TRKL IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800917
918 chip->chg_done = false;
David Keiteldbcef092013-05-14 14:48:30 -0700919 if (chip->bat_if_base)
920 power_supply_changed(&chip->batt_psy);
David Keitel42ae0aa2013-03-08 16:20:10 -0800921
922 return IRQ_HANDLED;
923}
924
925static irqreturn_t
926qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
927{
928 struct qpnp_chg_chip *chip = _chip;
929
930 pr_debug("FAST_CHG IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800931 chip->chg_done = false;
David Keiteldbcef092013-05-14 14:48:30 -0700932 if (chip->bat_if_base)
933 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700934 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700935 if (chip->dc_chgpth_base)
936 power_supply_changed(&chip->dc_psy);
David Keitel47185a62013-05-15 18:54:10 -0700937 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel42ae0aa2013-03-08 16:20:10 -0800938
939 return IRQ_HANDLED;
940}
941
David Keitel03ee6b52012-10-22 12:25:19 -0700942static int
943qpnp_batt_property_is_writeable(struct power_supply *psy,
944 enum power_supply_property psp)
945{
946 switch (psp) {
947 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitelbe208252013-01-31 14:49:25 -0800948 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
David Keitel03ee6b52012-10-22 12:25:19 -0700949 return 1;
950 default:
951 break;
952 }
953
954 return 0;
955}
956
David Keitel6f865cd2012-11-30 15:04:32 -0800957static int
David Keitelbe208252013-01-31 14:49:25 -0800958qpnp_chg_buck_control(struct qpnp_chg_chip *chip, int enable)
959{
960 int rc;
961
962 if (chip->charging_disabled && enable) {
963 pr_debug("Charging disabled\n");
964 return 0;
965 }
966
967 rc = qpnp_chg_charge_en(chip, enable);
968 if (rc) {
969 pr_err("Failed to control charging %d\n", rc);
970 return rc;
971 }
972
973 rc = qpnp_chg_force_run_on_batt(chip, !enable);
974 if (rc)
975 pr_err("Failed to control charging %d\n", rc);
976
977 return rc;
978}
979
David Keitel454ee842013-03-08 16:19:11 -0800980static int
981switch_usb_to_charge_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800982{
983 int rc;
984
985 pr_debug("switch to charge mode\n");
986 if (!qpnp_chg_is_otg_en_set(chip))
987 return 0;
988
989 /* enable usb ovp fet */
990 rc = qpnp_chg_masked_write(chip,
991 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
992 USB_OTG_EN_BIT,
993 0, 1);
994 if (rc) {
995 pr_err("Failed to turn on usb ovp rc = %d\n", rc);
996 return rc;
997 }
998
999 rc = qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
1000 if (rc) {
1001 pr_err("Failed re-enable charging rc = %d\n", rc);
1002 return rc;
1003 }
1004
1005 return 0;
1006}
1007
David Keitel454ee842013-03-08 16:19:11 -08001008static int
1009switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -08001010{
1011 int rc;
1012
1013 pr_debug("switch to host mode\n");
1014 if (qpnp_chg_is_otg_en_set(chip))
1015 return 0;
1016
1017 rc = qpnp_chg_force_run_on_batt(chip, 1);
1018 if (rc) {
1019 pr_err("Failed to disable charging rc = %d\n", rc);
1020 return rc;
1021 }
1022
1023 /* force usb ovp fet off */
1024 rc = qpnp_chg_masked_write(chip,
1025 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
1026 USB_OTG_EN_BIT,
1027 USB_OTG_EN_BIT, 1);
1028 if (rc) {
1029 pr_err("Failed to turn off usb ovp rc = %d\n", rc);
1030 return rc;
1031 }
1032
1033 return 0;
1034}
1035
David Keitel80668952012-07-27 14:25:49 -07001036static enum power_supply_property pm_power_props_mains[] = {
1037 POWER_SUPPLY_PROP_PRESENT,
1038 POWER_SUPPLY_PROP_ONLINE,
1039};
1040
1041static enum power_supply_property msm_batt_power_props[] = {
David Keitelb80eda82012-10-15 10:49:11 -07001042 POWER_SUPPLY_PROP_CHARGING_ENABLED,
David Keitel80668952012-07-27 14:25:49 -07001043 POWER_SUPPLY_PROP_STATUS,
1044 POWER_SUPPLY_PROP_CHARGE_TYPE,
1045 POWER_SUPPLY_PROP_HEALTH,
1046 POWER_SUPPLY_PROP_PRESENT,
1047 POWER_SUPPLY_PROP_TECHNOLOGY,
1048 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
1049 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
1050 POWER_SUPPLY_PROP_VOLTAGE_NOW,
1051 POWER_SUPPLY_PROP_CAPACITY,
1052 POWER_SUPPLY_PROP_CURRENT_NOW,
1053 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
1054 POWER_SUPPLY_PROP_TEMP,
David Keitelbe208252013-01-31 14:49:25 -08001055 POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
Anirudh Ghayal9dd582d2013-06-07 17:48:58 +05301056 POWER_SUPPLY_PROP_CYCLE_COUNT,
David Keitel80668952012-07-27 14:25:49 -07001057};
1058
1059static char *pm_power_supplied_to[] = {
1060 "battery",
1061};
1062
Xiaozhe Shi890fbf42013-05-02 16:42:53 -07001063static char *pm_batt_supplied_to[] = {
1064 "bms",
1065};
1066
David Keitel80668952012-07-27 14:25:49 -07001067#define USB_WALL_THRESHOLD_MA 500
1068static int
1069qpnp_power_get_property_mains(struct power_supply *psy,
1070 enum power_supply_property psp,
1071 union power_supply_propval *val)
1072{
1073 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1074 dc_psy);
1075
1076 switch (psp) {
1077 case POWER_SUPPLY_PROP_PRESENT:
1078 case POWER_SUPPLY_PROP_ONLINE:
1079 val->intval = 0;
David Keitel03ee6b52012-10-22 12:25:19 -07001080 if (chip->charging_disabled)
David Keitel80668952012-07-27 14:25:49 -07001081 return 0;
1082
1083 val->intval = qpnp_chg_is_dc_chg_plugged_in(chip);
1084 break;
1085 default:
1086 return -EINVAL;
1087 }
1088 return 0;
1089}
1090
1091static int
1092get_prop_battery_voltage_now(struct qpnp_chg_chip *chip)
1093{
1094 int rc = 0;
1095 struct qpnp_vadc_result results;
1096
David Keitelfe51cb92013-04-02 19:42:58 -07001097 if (chip->revision == 0 && chip->type == SMBB) {
1098 pr_err("vbat reading not supported for 1.0 rc=%d\n", rc);
1099 return 0;
1100 } else {
David Keitel80668952012-07-27 14:25:49 -07001101 rc = qpnp_vadc_read(VBAT_SNS, &results);
1102 if (rc) {
1103 pr_err("Unable to read vbat rc=%d\n", rc);
1104 return 0;
1105 }
1106 return results.physical;
David Keitel80668952012-07-27 14:25:49 -07001107 }
1108}
1109
1110#define BATT_PRES_BIT BIT(7)
1111static int
1112get_prop_batt_present(struct qpnp_chg_chip *chip)
1113{
1114 u8 batt_present;
1115 int rc;
1116
1117 rc = qpnp_chg_read(chip, &batt_present,
1118 chip->bat_if_base + CHGR_BAT_IF_PRES_STATUS, 1);
1119 if (rc) {
1120 pr_err("Couldn't read battery status read failed rc=%d\n", rc);
1121 return 0;
1122 };
1123 return (batt_present & BATT_PRES_BIT) ? 1 : 0;
1124}
1125
1126#define BATT_TEMP_HOT BIT(6)
1127#define BATT_TEMP_OK BIT(7)
1128static int
1129get_prop_batt_health(struct qpnp_chg_chip *chip)
1130{
1131 u8 batt_health;
1132 int rc;
1133
1134 rc = qpnp_chg_read(chip, &batt_health,
David Keiteld681cda2012-10-02 15:44:21 -07001135 chip->bat_if_base + CHGR_STATUS, 1);
David Keitel80668952012-07-27 14:25:49 -07001136 if (rc) {
1137 pr_err("Couldn't read battery health read failed rc=%d\n", rc);
1138 return POWER_SUPPLY_HEALTH_UNKNOWN;
1139 };
1140
1141 if (BATT_TEMP_OK & batt_health)
1142 return POWER_SUPPLY_HEALTH_GOOD;
1143 if (BATT_TEMP_HOT & batt_health)
1144 return POWER_SUPPLY_HEALTH_OVERHEAT;
1145 else
1146 return POWER_SUPPLY_HEALTH_COLD;
1147}
1148
1149static int
1150get_prop_charge_type(struct qpnp_chg_chip *chip)
1151{
1152 int rc;
1153 u8 chgr_sts;
1154
1155 if (!get_prop_batt_present(chip))
1156 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1157
1158 rc = qpnp_chg_read(chip, &chgr_sts,
1159 INT_RT_STS(chip->chgr_base), 1);
1160 if (rc) {
1161 pr_err("failed to read interrupt sts %d\n", rc);
1162 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1163 }
1164
1165 if (chgr_sts & TRKL_CHG_ON_IRQ)
1166 return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
1167 if (chgr_sts & FAST_CHG_ON_IRQ)
1168 return POWER_SUPPLY_CHARGE_TYPE_FAST;
1169
1170 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1171}
1172
1173static int
1174get_prop_batt_status(struct qpnp_chg_chip *chip)
1175{
1176 int rc;
1177 u8 chgr_sts;
1178
David Keitel9fd07382013-05-02 15:37:44 -07001179 if ((qpnp_chg_is_usb_chg_plugged_in(chip) ||
1180 qpnp_chg_is_dc_chg_plugged_in(chip)) && chip->chg_done) {
David Keitelc9ffe842013-01-25 19:37:51 -08001181 return POWER_SUPPLY_STATUS_FULL;
David Keitel9fd07382013-05-02 15:37:44 -07001182 }
David Keitelc9ffe842013-01-25 19:37:51 -08001183
David Keitel9fd07382013-05-02 15:37:44 -07001184 rc = qpnp_chg_read(chip, &chgr_sts, INT_RT_STS(chip->chgr_base), 1);
David Keitel80668952012-07-27 14:25:49 -07001185 if (rc) {
1186 pr_err("failed to read interrupt sts %d\n", rc);
David Keitelc9ffe842013-01-25 19:37:51 -08001187 return POWER_SUPPLY_CHARGE_TYPE_NONE;
David Keitel80668952012-07-27 14:25:49 -07001188 }
1189
David Keitel80668952012-07-27 14:25:49 -07001190 if (chgr_sts & TRKL_CHG_ON_IRQ)
1191 return POWER_SUPPLY_STATUS_CHARGING;
1192 if (chgr_sts & FAST_CHG_ON_IRQ)
1193 return POWER_SUPPLY_STATUS_CHARGING;
1194
1195 return POWER_SUPPLY_STATUS_DISCHARGING;
1196}
1197
1198static int
1199get_prop_current_now(struct qpnp_chg_chip *chip)
1200{
1201 union power_supply_propval ret = {0,};
1202
1203 if (chip->bms_psy) {
1204 chip->bms_psy->get_property(chip->bms_psy,
1205 POWER_SUPPLY_PROP_CURRENT_NOW, &ret);
1206 return ret.intval;
1207 } else {
1208 pr_debug("No BMS supply registered return 0\n");
1209 }
1210
1211 return 0;
1212}
1213
1214static int
1215get_prop_full_design(struct qpnp_chg_chip *chip)
1216{
1217 union power_supply_propval ret = {0,};
1218
1219 if (chip->bms_psy) {
1220 chip->bms_psy->get_property(chip->bms_psy,
1221 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, &ret);
1222 return ret.intval;
1223 } else {
1224 pr_debug("No BMS supply registered return 0\n");
1225 }
1226
1227 return 0;
1228}
1229
1230#define DEFAULT_CAPACITY 50
1231static int
1232get_prop_capacity(struct qpnp_chg_chip *chip)
1233{
1234 union power_supply_propval ret = {0,};
1235
David Keitel3dd5e0f2012-12-12 18:12:36 -08001236 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1237 return DEFAULT_CAPACITY;
1238
David Keitel80668952012-07-27 14:25:49 -07001239 if (chip->bms_psy) {
1240 chip->bms_psy->get_property(chip->bms_psy,
1241 POWER_SUPPLY_PROP_CAPACITY, &ret);
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001242 if (ret.intval == 0) {
David Keiteleeca08f2013-05-17 16:40:46 -07001243 if (!qpnp_chg_is_usb_chg_plugged_in(chip)
1244 && !qpnp_chg_is_usb_chg_plugged_in(chip))
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001245 pr_warn_ratelimited("Battery 0, CHG absent\n");
1246 }
David Keitel80668952012-07-27 14:25:49 -07001247 return ret.intval;
1248 } else {
1249 pr_debug("No BMS supply registered return 50\n");
1250 }
1251
1252 /* return default capacity to avoid userspace
1253 * from shutting down unecessarily */
1254 return DEFAULT_CAPACITY;
1255}
1256
David Keitel3dd5e0f2012-12-12 18:12:36 -08001257#define DEFAULT_TEMP 250
David Keitel80668952012-07-27 14:25:49 -07001258#define MAX_TOLERABLE_BATT_TEMP_DDC 680
1259static int
1260get_prop_batt_temp(struct qpnp_chg_chip *chip)
1261{
1262 int rc = 0;
1263 struct qpnp_vadc_result results;
1264
David Keitel3dd5e0f2012-12-12 18:12:36 -08001265 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1266 return DEFAULT_TEMP;
1267
David Keitel80668952012-07-27 14:25:49 -07001268 if (chip->revision > 0) {
1269 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
1270 if (rc) {
1271 pr_debug("Unable to read batt temperature rc=%d\n", rc);
1272 return 0;
1273 }
1274 pr_debug("get_bat_temp %d %lld\n",
1275 results.adc_code, results.physical);
1276 return (int)results.physical;
1277 } else {
1278 pr_debug("batt temp not supported for PMIC 1.0 rc=%d\n", rc);
1279 }
1280
1281 /* return default temperature to avoid userspace
1282 * from shutting down unecessarily */
1283 return DEFAULT_TEMP;
1284}
1285
Anirudh Ghayal9dd582d2013-06-07 17:48:58 +05301286static int get_prop_cycle_count(struct qpnp_chg_chip *chip)
1287{
1288 union power_supply_propval ret = {0,};
1289
1290 if (chip->bms_psy)
1291 chip->bms_psy->get_property(chip->bms_psy,
1292 POWER_SUPPLY_PROP_CYCLE_COUNT, &ret);
1293 return ret.intval;
1294}
1295
David Keitel80668952012-07-27 14:25:49 -07001296static void
1297qpnp_batt_external_power_changed(struct power_supply *psy)
1298{
1299 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1300 batt_psy);
1301 union power_supply_propval ret = {0,};
1302
1303 if (!chip->bms_psy)
1304 chip->bms_psy = power_supply_get_by_name("bms");
1305
1306 chip->usb_psy->get_property(chip->usb_psy,
1307 POWER_SUPPLY_PROP_ONLINE, &ret);
1308
David Keitelc69f2d62013-03-17 14:52:35 -07001309 /* Only honour requests while USB is present */
1310 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001311 chip->usb_psy->get_property(chip->usb_psy,
1312 POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
David Keitel87473252013-03-21 14:39:45 -07001313 if (ret.intval <= 2 && !chip->use_default_batt_values &&
1314 get_prop_batt_present(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001315 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -07001316 qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
David Keitelc69f2d62013-03-17 14:52:35 -07001317 } else {
David Keiteld681cda2012-10-02 15:44:21 -07001318 qpnp_chg_usb_suspend_enable(chip, 0);
David Keitel359ab652013-03-21 17:46:00 -07001319 qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
David Keitelc69f2d62013-03-17 14:52:35 -07001320 }
David Keitel80668952012-07-27 14:25:49 -07001321 }
1322
1323 pr_debug("end of power supply changed\n");
1324 power_supply_changed(&chip->batt_psy);
1325}
1326
1327static int
1328qpnp_batt_power_get_property(struct power_supply *psy,
1329 enum power_supply_property psp,
1330 union power_supply_propval *val)
1331{
1332 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1333 batt_psy);
1334
1335 switch (psp) {
1336 case POWER_SUPPLY_PROP_STATUS:
1337 val->intval = get_prop_batt_status(chip);
1338 break;
1339 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1340 val->intval = get_prop_charge_type(chip);
1341 break;
1342 case POWER_SUPPLY_PROP_HEALTH:
1343 val->intval = get_prop_batt_health(chip);
1344 break;
1345 case POWER_SUPPLY_PROP_PRESENT:
1346 val->intval = get_prop_batt_present(chip);
1347 break;
1348 case POWER_SUPPLY_PROP_TECHNOLOGY:
1349 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
1350 break;
1351 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
1352 val->intval = chip->max_voltage_mv * 1000;
1353 break;
1354 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
1355 val->intval = chip->min_voltage_mv * 1000;
1356 break;
1357 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1358 val->intval = get_prop_battery_voltage_now(chip);
1359 break;
1360 case POWER_SUPPLY_PROP_TEMP:
1361 val->intval = get_prop_batt_temp(chip);
1362 break;
1363 case POWER_SUPPLY_PROP_CAPACITY:
1364 val->intval = get_prop_capacity(chip);
1365 break;
1366 case POWER_SUPPLY_PROP_CURRENT_NOW:
1367 val->intval = get_prop_current_now(chip);
1368 break;
1369 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1370 val->intval = get_prop_full_design(chip);
1371 break;
David Keitelb80eda82012-10-15 10:49:11 -07001372 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitel03ee6b52012-10-22 12:25:19 -07001373 val->intval = !(chip->charging_disabled);
David Keitelb80eda82012-10-15 10:49:11 -07001374 break;
David Keitelbe208252013-01-31 14:49:25 -08001375 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1376 val->intval = chip->therm_lvl_sel;
David Keitelb80eda82012-10-15 10:49:11 -07001377 break;
Anirudh Ghayal9dd582d2013-06-07 17:48:58 +05301378 case POWER_SUPPLY_PROP_CYCLE_COUNT:
1379 val->intval = get_prop_cycle_count(chip);
1380 break;
David Keitelb80eda82012-10-15 10:49:11 -07001381 default:
1382 return -EINVAL;
1383 }
1384
David Keitelb80eda82012-10-15 10:49:11 -07001385 return 0;
David Keitel80668952012-07-27 14:25:49 -07001386}
1387
David Keitel80668952012-07-27 14:25:49 -07001388#define QPNP_CHG_VINMIN_MIN_MV 3400
1389#define QPNP_CHG_VINMIN_HIGH_MIN_MV 5600
1390#define QPNP_CHG_VINMIN_HIGH_MIN_VAL 0x2B
1391#define QPNP_CHG_VINMIN_MAX_MV 9600
1392#define QPNP_CHG_VINMIN_STEP_MV 50
1393#define QPNP_CHG_VINMIN_STEP_HIGH_MV 200
1394#define QPNP_CHG_VINMIN_MASK 0x1F
1395static int
1396qpnp_chg_vinmin_set(struct qpnp_chg_chip *chip, int voltage)
1397{
1398 u8 temp;
1399
1400 if (voltage < QPNP_CHG_VINMIN_MIN_MV
1401 || voltage > QPNP_CHG_VINMIN_MAX_MV) {
1402 pr_err("bad mV=%d asked to set\n", voltage);
1403 return -EINVAL;
1404 }
1405 if (voltage >= QPNP_CHG_VINMIN_HIGH_MIN_MV) {
1406 temp = QPNP_CHG_VINMIN_HIGH_MIN_VAL;
1407 temp += (voltage - QPNP_CHG_VINMIN_MIN_MV)
1408 / QPNP_CHG_VINMIN_STEP_HIGH_MV;
1409 } else {
1410 temp = (voltage - QPNP_CHG_VINMIN_MIN_MV)
1411 / QPNP_CHG_VINMIN_STEP_MV;
1412 }
1413
1414 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1415 return qpnp_chg_masked_write(chip,
1416 chip->chgr_base + CHGR_VIN_MIN,
1417 QPNP_CHG_VINMIN_MASK, temp, 1);
1418}
1419
David Keitel5d44fa52012-12-03 16:37:31 -08001420#define QPNP_CHG_IBATSAFE_MIN_MA 100
1421#define QPNP_CHG_IBATSAFE_MAX_MA 3250
1422#define QPNP_CHG_I_STEP_MA 50
1423#define QPNP_CHG_I_MIN_MA 100
1424#define QPNP_CHG_I_MASK 0x3F
1425static int
1426qpnp_chg_ibatsafe_set(struct qpnp_chg_chip *chip, int safe_current)
1427{
1428 u8 temp;
1429
1430 if (safe_current < QPNP_CHG_IBATSAFE_MIN_MA
1431 || safe_current > QPNP_CHG_IBATSAFE_MAX_MA) {
1432 pr_err("bad mA=%d asked to set\n", safe_current);
1433 return -EINVAL;
1434 }
1435
1436 temp = (safe_current - QPNP_CHG_IBATSAFE_MIN_MA)
1437 / QPNP_CHG_I_STEP_MA;
1438 return qpnp_chg_masked_write(chip,
1439 chip->chgr_base + CHGR_IBAT_SAFE,
1440 QPNP_CHG_I_MASK, temp, 1);
1441}
David Keitel80668952012-07-27 14:25:49 -07001442
1443#define QPNP_CHG_ITERM_MIN_MA 100
1444#define QPNP_CHG_ITERM_MAX_MA 250
1445#define QPNP_CHG_ITERM_STEP_MA 50
1446#define QPNP_CHG_ITERM_MASK 0x03
1447static int
1448qpnp_chg_ibatterm_set(struct qpnp_chg_chip *chip, int term_current)
1449{
1450 u8 temp;
1451
1452 if (term_current < QPNP_CHG_ITERM_MIN_MA
1453 || term_current > QPNP_CHG_ITERM_MAX_MA) {
1454 pr_err("bad mA=%d asked to set\n", term_current);
1455 return -EINVAL;
1456 }
1457
1458 temp = (term_current - QPNP_CHG_ITERM_MIN_MA)
1459 / QPNP_CHG_ITERM_STEP_MA;
1460 return qpnp_chg_masked_write(chip,
1461 chip->chgr_base + CHGR_IBAT_TERM_CHGR,
1462 QPNP_CHG_ITERM_MASK, temp, 1);
1463}
1464
David Keitelff5d0472013-04-04 11:36:06 -07001465#define QPNP_CHG_IBATMAX_MIN 50
David Keitel80668952012-07-27 14:25:49 -07001466#define QPNP_CHG_IBATMAX_MAX 3250
David Keitel80668952012-07-27 14:25:49 -07001467static int
1468qpnp_chg_ibatmax_set(struct qpnp_chg_chip *chip, int chg_current)
1469{
1470 u8 temp;
1471
1472 if (chg_current < QPNP_CHG_IBATMAX_MIN
1473 || chg_current > QPNP_CHG_IBATMAX_MAX) {
1474 pr_err("bad mA=%d asked to set\n", chg_current);
1475 return -EINVAL;
1476 }
David Keitelff5d0472013-04-04 11:36:06 -07001477 temp = chg_current / QPNP_CHG_I_STEP_MA;
David Keitel80668952012-07-27 14:25:49 -07001478 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_IBAT_MAX,
1479 QPNP_CHG_I_MASK, temp, 1);
1480}
1481
David Keitela4b7b592013-04-11 18:34:35 -07001482#define QPNP_CHG_TCHG_MASK 0x7F
1483#define QPNP_CHG_TCHG_MIN 4
1484#define QPNP_CHG_TCHG_MAX 512
1485#define QPNP_CHG_TCHG_STEP 4
1486static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
1487{
1488 u8 temp;
1489
1490 if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
1491 pr_err("bad max minutes =%d asked to set\n", minutes);
1492 return -EINVAL;
1493 }
1494
1495 temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
1496 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
David Keitela1d16442013-05-09 14:47:37 -07001497 QPNP_CHG_TCHG_MASK, temp, 1);
David Keitela4b7b592013-04-11 18:34:35 -07001498}
David Keitel80668952012-07-27 14:25:49 -07001499
1500#define QPNP_CHG_V_MIN_MV 3240
1501#define QPNP_CHG_V_MAX_MV 4500
1502#define QPNP_CHG_V_STEP_MV 10
1503static int
1504qpnp_chg_vddsafe_set(struct qpnp_chg_chip *chip, int voltage)
1505{
1506 u8 temp;
1507
1508 if (voltage < QPNP_CHG_V_MIN_MV
1509 || voltage > QPNP_CHG_V_MAX_MV) {
1510 pr_err("bad mV=%d asked to set\n", voltage);
1511 return -EINVAL;
1512 }
1513 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1514 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1515 return qpnp_chg_write(chip, &temp,
1516 chip->chgr_base + CHGR_VDD_SAFE, 1);
1517}
1518
1519#define QPNP_CHG_VDDMAX_MIN 3400
1520static int
1521qpnp_chg_vddmax_set(struct qpnp_chg_chip *chip, int voltage)
1522{
1523 u8 temp = 0;
1524
1525 if (voltage < QPNP_CHG_VDDMAX_MIN
1526 || voltage > QPNP_CHG_V_MAX_MV) {
1527 pr_err("bad mV=%d asked to set\n", voltage);
1528 return -EINVAL;
1529 }
Xiaozhe Shi79a8c492013-05-24 13:09:23 -07001530 chip->set_vddmax_mv = voltage + chip->delta_vddmax_mv;
David Keitel80668952012-07-27 14:25:49 -07001531
Xiaozhe Shi79a8c492013-05-24 13:09:23 -07001532 temp = (chip->set_vddmax_mv - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
David Keitel80668952012-07-27 14:25:49 -07001533
Xiaozhe Shi79a8c492013-05-24 13:09:23 -07001534 pr_debug("voltage=%d setting %02x\n", chip->set_vddmax_mv, temp);
David Keitel454ee842013-03-08 16:19:11 -08001535 return qpnp_chg_write(chip, &temp, chip->chgr_base + CHGR_VDD_MAX, 1);
1536}
1537
David Keitel6dc4ed42013-05-17 11:08:58 -07001538#define BOOST_MIN_UV 4200000
1539#define BOOST_MAX_UV 5500000
1540#define BOOST_STEP_UV 50000
1541#define BOOST_MIN 16
1542#define N_BOOST_V ((BOOST_MAX_UV - BOOST_MIN_UV) / BOOST_STEP_UV + 1)
1543static int
1544qpnp_boost_vset(struct qpnp_chg_chip *chip, int voltage)
1545{
1546 u8 reg = 0;
1547
1548 if (voltage < BOOST_MIN_UV || voltage > BOOST_MAX_UV) {
1549 pr_err("invalid voltage requested %d uV\n", voltage);
1550 return -EINVAL;
1551 }
1552
1553 reg = DIV_ROUND_UP(voltage - BOOST_MIN_UV, BOOST_STEP_UV) + BOOST_MIN;
1554
1555 pr_debug("voltage=%d setting %02x\n", voltage, reg);
1556 return qpnp_chg_write(chip, &reg, chip->boost_base + BOOST_VSET, 1);
1557}
1558
1559static int
1560qpnp_boost_vget_uv(struct qpnp_chg_chip *chip)
1561{
1562 int rc;
1563 u8 boost_reg;
1564
1565 rc = qpnp_chg_read(chip, &boost_reg,
1566 chip->boost_base + BOOST_VSET, 1);
1567 if (rc) {
1568 pr_err("failed to read BOOST_VSET rc=%d\n", rc);
1569 return rc;
1570 }
1571
1572 if (boost_reg < BOOST_MIN) {
1573 pr_err("Invalid reading from 0x%x\n", boost_reg);
1574 return -EINVAL;
1575 }
1576
1577 return BOOST_MIN_UV + ((boost_reg - BOOST_MIN) * BOOST_STEP_UV);
1578}
1579
David Keitel454ee842013-03-08 16:19:11 -08001580/* JEITA compliance logic */
1581static void
1582qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
1583{
1584 if (chip->bat_is_cool)
1585 qpnp_chg_vddmax_set(chip, chip->cool_bat_mv);
1586 else if (chip->bat_is_warm)
1587 qpnp_chg_vddmax_set(chip, chip->warm_bat_mv);
1588 else
1589 qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
1590}
1591
1592static void
1593qpnp_chg_set_appropriate_vbatdet(struct qpnp_chg_chip *chip)
1594{
1595 if (chip->bat_is_cool)
1596 qpnp_chg_vbatdet_set(chip, chip->cool_bat_mv
1597 - chip->resume_delta_mv);
1598 else if (chip->bat_is_warm)
1599 qpnp_chg_vbatdet_set(chip, chip->warm_bat_mv
1600 - chip->resume_delta_mv);
1601 else
1602 qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
1603 - chip->resume_delta_mv);
David Keitel80668952012-07-27 14:25:49 -07001604}
1605
David Keitelbe208252013-01-31 14:49:25 -08001606static void
1607qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
1608{
1609 unsigned int chg_current = chip->max_bat_chg_current;
1610
David Keitel454ee842013-03-08 16:19:11 -08001611 if (chip->bat_is_cool)
1612 chg_current = min(chg_current, chip->cool_bat_chg_ma);
1613
1614 if (chip->bat_is_warm)
1615 chg_current = min(chg_current, chip->warm_bat_chg_ma);
1616
David Keitelbe208252013-01-31 14:49:25 -08001617 if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
1618 chg_current = min(chg_current,
1619 chip->thermal_mitigation[chip->therm_lvl_sel]);
1620
1621 pr_debug("setting %d mA\n", chg_current);
1622 qpnp_chg_ibatmax_set(chip, chg_current);
1623}
1624
1625static void
1626qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
1627{
1628 if (lvl_sel >= 0 && lvl_sel < chip->thermal_levels) {
1629 chip->therm_lvl_sel = lvl_sel;
1630 if (lvl_sel == (chip->thermal_levels - 1)) {
1631 /* disable charging if highest value selected */
1632 qpnp_chg_buck_control(chip, 0);
1633 } else {
1634 qpnp_chg_buck_control(chip, 1);
1635 qpnp_chg_set_appropriate_battery_current(chip);
1636 }
1637 } else {
1638 pr_err("Unsupported level selected %d\n", lvl_sel);
1639 }
1640}
1641
David Keitel6dc4ed42013-05-17 11:08:58 -07001642/* OTG regulator operations */
1643static int
1644qpnp_chg_regulator_otg_enable(struct regulator_dev *rdev)
1645{
1646 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1647
1648 return switch_usb_to_host_mode(chip);
1649}
1650
1651static int
1652qpnp_chg_regulator_otg_disable(struct regulator_dev *rdev)
1653{
1654 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1655
1656 return switch_usb_to_charge_mode(chip);
1657}
1658
1659static int
1660qpnp_chg_regulator_otg_is_enabled(struct regulator_dev *rdev)
1661{
1662 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1663
1664 return qpnp_chg_is_otg_en_set(chip);
1665}
1666
1667static int
1668qpnp_chg_regulator_boost_enable(struct regulator_dev *rdev)
1669{
1670 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
David Keitel33f58952013-05-20 16:17:36 -07001671 int rc;
1672
1673 if (qpnp_chg_is_usb_chg_plugged_in(chip) &&
1674 (chip->flags & BOOST_FLASH_WA)) {
1675 qpnp_chg_usb_suspend_enable(chip, 1);
1676
1677 rc = qpnp_chg_masked_write(chip,
1678 chip->usb_chgpth_base + SEC_ACCESS,
1679 0xFF,
1680 0xA5, 1);
1681 if (rc) {
1682 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1683 return rc;
1684 }
1685
1686 rc = qpnp_chg_masked_write(chip,
1687 chip->usb_chgpth_base + COMP_OVR1,
1688 0xFF,
1689 0x2F, 1);
1690 if (rc) {
1691 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1692 return rc;
1693 }
1694 }
David Keitel6dc4ed42013-05-17 11:08:58 -07001695
1696 return qpnp_chg_masked_write(chip,
1697 chip->boost_base + BOOST_ENABLE_CONTROL,
1698 BOOST_PWR_EN,
1699 BOOST_PWR_EN, 1);
1700}
1701
1702/* Boost regulator operations */
David Keitel33f58952013-05-20 16:17:36 -07001703#define ABOVE_VBAT_WEAK BIT(1)
David Keitel6dc4ed42013-05-17 11:08:58 -07001704static int
1705qpnp_chg_regulator_boost_disable(struct regulator_dev *rdev)
1706{
1707 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
David Keitel33f58952013-05-20 16:17:36 -07001708 int rc;
1709 u8 vbat_sts;
David Keitel6dc4ed42013-05-17 11:08:58 -07001710
David Keitel33f58952013-05-20 16:17:36 -07001711 rc = qpnp_chg_masked_write(chip,
David Keitel6dc4ed42013-05-17 11:08:58 -07001712 chip->boost_base + BOOST_ENABLE_CONTROL,
1713 BOOST_PWR_EN,
1714 0, 1);
David Keitel33f58952013-05-20 16:17:36 -07001715 if (rc) {
1716 pr_err("failed to disable boost rc=%d\n", rc);
1717 return rc;
1718 }
1719
1720 rc = qpnp_chg_read(chip, &vbat_sts,
1721 chip->chgr_base + CHGR_VBAT_STATUS, 1);
1722 if (rc) {
1723 pr_err("failed to read bat sts rc=%d\n", rc);
1724 return rc;
1725 }
1726
1727 if (!(vbat_sts & ABOVE_VBAT_WEAK) && (chip->flags & BOOST_FLASH_WA)) {
1728 rc = qpnp_chg_masked_write(chip,
1729 chip->chgr_base + SEC_ACCESS,
1730 0xFF,
1731 0xA5, 1);
1732 if (rc) {
1733 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1734 return rc;
1735 }
1736
1737 rc = qpnp_chg_masked_write(chip,
1738 chip->chgr_base + COMP_OVR1,
1739 0xFF,
1740 0x20, 1);
1741 if (rc) {
1742 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1743 return rc;
1744 }
1745
1746 usleep(2000);
1747
1748 rc = qpnp_chg_masked_write(chip,
1749 chip->chgr_base + SEC_ACCESS,
1750 0xFF,
1751 0xA5, 1);
1752 if (rc) {
1753 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1754 return rc;
1755 }
1756
1757 rc = qpnp_chg_masked_write(chip,
1758 chip->chgr_base + COMP_OVR1,
1759 0xFF,
1760 0x00, 1);
1761 if (rc) {
1762 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1763 return rc;
1764 }
1765 }
1766
1767 if (qpnp_chg_is_usb_chg_plugged_in(chip)
1768 && (chip->flags & BOOST_FLASH_WA)) {
1769 rc = qpnp_chg_masked_write(chip,
1770 chip->usb_chgpth_base + SEC_ACCESS,
1771 0xFF,
1772 0xA5, 1);
1773 if (rc) {
1774 pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
1775 return rc;
1776 }
1777
1778 rc = qpnp_chg_masked_write(chip,
1779 chip->usb_chgpth_base + COMP_OVR1,
1780 0xFF,
1781 0x00, 1);
1782 if (rc) {
1783 pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
1784 return rc;
1785 }
1786
1787 usleep(1000);
1788
1789 qpnp_chg_usb_suspend_enable(chip, 0);
1790 }
1791
1792 return rc;
David Keitel6dc4ed42013-05-17 11:08:58 -07001793}
1794
1795static int
1796qpnp_chg_regulator_boost_is_enabled(struct regulator_dev *rdev)
1797{
1798 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1799
1800 return qpnp_chg_is_boost_en_set(chip);
1801}
1802
1803static int
1804qpnp_chg_regulator_boost_set_voltage(struct regulator_dev *rdev,
1805 int min_uV, int max_uV, unsigned *selector)
1806{
1807 int uV = min_uV;
1808 int rc;
1809 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1810
1811 if (uV < BOOST_MIN_UV && max_uV >= BOOST_MIN_UV)
1812 uV = BOOST_MIN_UV;
1813
1814
1815 if (uV < BOOST_MIN_UV || uV > BOOST_MAX_UV) {
1816 pr_err("request %d uV is out of bounds\n", uV);
1817 return -EINVAL;
1818 }
1819
1820 *selector = DIV_ROUND_UP(uV - BOOST_MIN_UV, BOOST_STEP_UV);
1821 if ((*selector * BOOST_STEP_UV + BOOST_MIN_UV) > max_uV) {
1822 pr_err("no available setpoint [%d, %d] uV\n", min_uV, max_uV);
1823 return -EINVAL;
1824 }
1825
1826 rc = qpnp_boost_vset(chip, uV);
1827
1828 return rc;
1829}
1830
1831static int
1832qpnp_chg_regulator_boost_get_voltage(struct regulator_dev *rdev)
1833{
1834 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1835
1836 return qpnp_boost_vget_uv(chip);
1837}
1838
1839static int
1840qpnp_chg_regulator_boost_list_voltage(struct regulator_dev *rdev,
1841 unsigned selector)
1842{
1843 if (selector >= N_BOOST_V)
1844 return 0;
1845
1846 return BOOST_MIN_UV + (selector * BOOST_STEP_UV);
1847}
1848
1849static struct regulator_ops qpnp_chg_otg_reg_ops = {
1850 .enable = qpnp_chg_regulator_otg_enable,
1851 .disable = qpnp_chg_regulator_otg_disable,
1852 .is_enabled = qpnp_chg_regulator_otg_is_enabled,
1853};
1854
1855static struct regulator_ops qpnp_chg_boost_reg_ops = {
1856 .enable = qpnp_chg_regulator_boost_enable,
1857 .disable = qpnp_chg_regulator_boost_disable,
1858 .is_enabled = qpnp_chg_regulator_boost_is_enabled,
1859 .set_voltage = qpnp_chg_regulator_boost_set_voltage,
1860 .get_voltage = qpnp_chg_regulator_boost_get_voltage,
1861 .list_voltage = qpnp_chg_regulator_boost_list_voltage,
1862};
1863
Xiaozhe Shi79a8c492013-05-24 13:09:23 -07001864#define MIN_DELTA_MV_TO_INCREASE_VDD_MAX 13
1865#define MAX_DELTA_VDD_MAX_MV 30
1866static void
1867qpnp_chg_adjust_vddmax(struct qpnp_chg_chip *chip, int vbat_mv)
1868{
1869 int delta_mv, closest_delta_mv, sign;
1870
1871 delta_mv = chip->max_voltage_mv - vbat_mv;
1872 if (delta_mv > 0 && delta_mv < MIN_DELTA_MV_TO_INCREASE_VDD_MAX) {
1873 pr_debug("vbat is not low enough to increase vdd\n");
1874 return;
1875 }
1876
1877 sign = delta_mv > 0 ? 1 : -1;
1878 closest_delta_mv = ((delta_mv + sign * QPNP_CHG_V_STEP_MV / 2)
1879 / QPNP_CHG_V_STEP_MV) * QPNP_CHG_V_STEP_MV;
1880 pr_debug("max_voltage = %d, vbat_mv = %d, delta_mv = %d, closest = %d\n",
1881 chip->max_voltage_mv, vbat_mv,
1882 delta_mv, closest_delta_mv);
1883 chip->delta_vddmax_mv = clamp(chip->delta_vddmax_mv + closest_delta_mv,
1884 -MAX_DELTA_VDD_MAX_MV, MAX_DELTA_VDD_MAX_MV);
1885 pr_debug("using delta_vddmax_mv = %d\n", chip->delta_vddmax_mv);
1886 qpnp_chg_set_appropriate_vddmax(chip);
1887}
1888
David Keitel9fd07382013-05-02 15:37:44 -07001889#define CONSECUTIVE_COUNT 3
1890static void
1891qpnp_eoc_work(struct work_struct *work)
1892{
1893 struct delayed_work *dwork = to_delayed_work(work);
1894 struct qpnp_chg_chip *chip = container_of(dwork,
1895 struct qpnp_chg_chip, eoc_work);
1896 static int count;
1897 int ibat_ma, vbat_mv, rc = 0;
1898 u8 batt_sts = 0, buck_sts = 0, chg_sts = 0;
1899
1900 wake_lock(&chip->eoc_wake_lock);
1901 qpnp_chg_charge_en(chip, !chip->charging_disabled);
1902
1903 rc = qpnp_chg_read(chip, &batt_sts, INT_RT_STS(chip->bat_if_base), 1);
1904 if (rc) {
1905 pr_err("failed to read batt_if rc=%d\n", rc);
1906 return;
1907 }
1908
1909 rc = qpnp_chg_read(chip, &buck_sts, INT_RT_STS(chip->buck_base), 1);
1910 if (rc) {
1911 pr_err("failed to read buck rc=%d\n", rc);
1912 return;
1913 }
1914
1915 rc = qpnp_chg_read(chip, &chg_sts, INT_RT_STS(chip->chgr_base), 1);
1916 if (rc) {
1917 pr_err("failed to read chg_sts rc=%d\n", rc);
1918 return;
1919 }
1920
1921 pr_debug("chgr: 0x%x, bat_if: 0x%x, buck: 0x%x\n",
1922 chg_sts, batt_sts, buck_sts);
1923
1924 if (!qpnp_chg_is_usb_chg_plugged_in(chip) &&
1925 !qpnp_chg_is_dc_chg_plugged_in(chip)) {
1926 pr_debug("no chg connected, stopping\n");
1927 goto stop_eoc;
1928 }
1929
1930 if ((batt_sts & BAT_FET_ON_IRQ) && (chg_sts & FAST_CHG_ON_IRQ
1931 || chg_sts & TRKL_CHG_ON_IRQ)) {
1932 ibat_ma = get_prop_current_now(chip) / 1000;
1933 vbat_mv = get_prop_battery_voltage_now(chip) / 1000;
Xiaozhe Shi22af5fe2013-05-29 10:38:30 -07001934
1935 pr_debug("ibat_ma = %d vbat_mv = %d term_current_ma = %d\n",
1936 ibat_ma, vbat_mv, chip->term_current);
1937
1938 if ((!(chg_sts & VBAT_DET_LOW_IRQ)) && (vbat_mv <
1939 (chip->max_voltage_mv - chip->resume_delta_mv))) {
1940 pr_debug("woke up too early\n");
1941 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
1942 goto stop_eoc;
1943 }
1944
Xiaozhe Shi79a8c492013-05-24 13:09:23 -07001945 if (buck_sts & VDD_LOOP_IRQ)
1946 qpnp_chg_adjust_vddmax(chip, vbat_mv);
1947
Xiaozhe Shi22af5fe2013-05-29 10:38:30 -07001948 if (!(buck_sts & VDD_LOOP_IRQ)) {
1949 pr_debug("Not in CV\n");
David Keitel9fd07382013-05-02 15:37:44 -07001950 count = 0;
Xiaozhe Shi22af5fe2013-05-29 10:38:30 -07001951 } else if ((ibat_ma * -1) > chip->term_current) {
1952 pr_debug("Not at EOC, battery current too high\n");
1953 count = 0;
1954 } else if (ibat_ma > 0) {
1955 pr_debug("Charging but system demand increased\n");
1956 count = 0;
1957 } else {
David Keitel9fd07382013-05-02 15:37:44 -07001958 if (count == CONSECUTIVE_COUNT) {
1959 pr_info("End of Charging\n");
1960 qpnp_chg_charge_en(chip, 0);
1961 chip->chg_done = true;
1962 power_supply_changed(&chip->batt_psy);
David Keitel47185a62013-05-15 18:54:10 -07001963 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -07001964 goto stop_eoc;
1965 } else {
1966 count += 1;
1967 pr_debug("EOC count = %d\n", count);
1968 }
David Keitel9fd07382013-05-02 15:37:44 -07001969 }
1970 } else {
1971 pr_debug("not charging\n");
1972 goto stop_eoc;
1973 }
1974
1975 schedule_delayed_work(&chip->eoc_work,
1976 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
1977 return;
1978
1979stop_eoc:
1980 count = 0;
1981 wake_unlock(&chip->eoc_wake_lock);
1982}
1983
David Keitel0c1a4532013-03-21 16:39:06 -07001984#define HYSTERISIS_DECIDEGC 20
David Keitel454ee842013-03-08 16:19:11 -08001985static void
1986qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
1987{
1988 struct qpnp_chg_chip *chip = ctx;
1989 bool bat_warm = 0, bat_cool = 0;
David Keitel1219a802013-03-21 16:37:21 -07001990 int temp;
David Keitel454ee842013-03-08 16:19:11 -08001991
1992 if (state >= ADC_TM_STATE_NUM) {
1993 pr_err("invalid notification %d\n", state);
1994 return;
1995 }
1996
David Keitel1219a802013-03-21 16:37:21 -07001997 temp = get_prop_batt_temp(chip);
David Keitel454ee842013-03-08 16:19:11 -08001998
David Keitel1219a802013-03-21 16:37:21 -07001999 pr_debug("temp = %d state = %s\n", temp,
2000 state == ADC_TM_WARM_STATE ? "warm" : "cool");
2001
2002 if (state == ADC_TM_WARM_STATE) {
2003 if (temp > chip->warm_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07002004 /* Normal to warm */
David Keitel454ee842013-03-08 16:19:11 -08002005 bat_warm = true;
2006 bat_cool = false;
2007 chip->adc_param.low_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07002008 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07002009 chip->adc_param.state_request =
2010 ADC_TM_COOL_THR_ENABLE;
2011 } else if (temp >
2012 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07002013 /* Cool to normal */
David Keitel454ee842013-03-08 16:19:11 -08002014 bat_warm = false;
2015 bat_cool = false;
David Keitel1219a802013-03-21 16:37:21 -07002016
2017 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel0c1a4532013-03-21 16:39:06 -07002018 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07002019 chip->adc_param.state_request =
2020 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08002021 }
2022 } else {
David Keitel1219a802013-03-21 16:37:21 -07002023 if (temp < chip->cool_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07002024 /* Normal to cool */
David Keitel454ee842013-03-08 16:19:11 -08002025 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07002026 bat_cool = true;
David Keitel454ee842013-03-08 16:19:11 -08002027 chip->adc_param.high_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07002028 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07002029 chip->adc_param.state_request =
2030 ADC_TM_WARM_THR_ENABLE;
David Keitel3e37e5a2013-04-18 10:42:30 -07002031 } else if (temp <
David Keitel1219a802013-03-21 16:37:21 -07002032 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07002033 /* Warm to normal */
David Keitel454ee842013-03-08 16:19:11 -08002034 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07002035 bat_cool = false;
2036
David Keitel0c1a4532013-03-21 16:39:06 -07002037 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07002038 chip->adc_param.high_temp = chip->warm_bat_decidegc;
2039 chip->adc_param.state_request =
2040 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08002041 }
2042 }
2043
2044 if (chip->bat_is_cool ^ bat_cool || chip->bat_is_warm ^ bat_warm) {
David Keitel1219a802013-03-21 16:37:21 -07002045 chip->bat_is_cool = bat_cool;
2046 chip->bat_is_warm = bat_warm;
2047
David Keitel454ee842013-03-08 16:19:11 -08002048 /* set appropriate voltages and currents */
2049 qpnp_chg_set_appropriate_vddmax(chip);
2050 qpnp_chg_set_appropriate_battery_current(chip);
2051 qpnp_chg_set_appropriate_vbatdet(chip);
David Keitel454ee842013-03-08 16:19:11 -08002052 }
2053
David Keitel1219a802013-03-21 16:37:21 -07002054 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
2055 pr_err("request ADC error\n");
David Keitel454ee842013-03-08 16:19:11 -08002056}
2057
David Keitelbe208252013-01-31 14:49:25 -08002058static int
2059qpnp_batt_power_set_property(struct power_supply *psy,
2060 enum power_supply_property psp,
2061 const union power_supply_propval *val)
2062{
2063 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
2064 batt_psy);
2065
2066 switch (psp) {
2067 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
2068 chip->charging_disabled = !(val->intval);
2069 qpnp_chg_charge_en(chip, !chip->charging_disabled);
2070 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
2071 break;
2072 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
2073 qpnp_batt_system_temp_level_set(chip, val->intval);
2074 break;
2075 default:
2076 return -EINVAL;
2077 }
2078
2079 power_supply_changed(&chip->batt_psy);
2080 return 0;
2081}
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002082
2083static void
2084qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
David Keiteld681cda2012-10-02 15:44:21 -07002085{
David Keitelfe51cb92013-04-02 19:42:58 -07002086 if (chip->revision > 0 && chip->type == SMBB)
David Keiteld681cda2012-10-02 15:44:21 -07002087 chip->flags |= CHG_FLAGS_VCP_WA;
David Keitel33f58952013-05-20 16:17:36 -07002088 if (chip->type == SMBB)
2089 chip->flags |= BOOST_FLASH_WA;
David Keitel14288042013-06-04 15:16:46 -07002090 if (chip->type == SMBBP)
2091 chip->flags |= BOOST_FLASH_WA;
David Keiteld681cda2012-10-02 15:44:21 -07002092}
2093
David Keitel0f35be42013-04-16 11:10:40 -07002094static int
2095qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
2096{
2097 int rc = 0;
2098 struct resource *resource;
2099 struct spmi_resource *spmi_resource;
2100 u8 subtype;
2101 struct spmi_device *spmi = chip->spmi;
2102
2103 spmi_for_each_container_dev(spmi_resource, chip->spmi) {
2104 if (!spmi_resource) {
2105 pr_err("qpnp_chg: spmi resource absent\n");
2106 return rc;
2107 }
2108
2109 resource = spmi_get_resource(spmi, spmi_resource,
2110 IORESOURCE_MEM, 0);
2111 if (!(resource && resource->start)) {
2112 pr_err("node %s IO resource absent!\n",
2113 spmi->dev.of_node->full_name);
2114 return rc;
2115 }
2116
2117 rc = qpnp_chg_read(chip, &subtype,
2118 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2119 if (rc) {
2120 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2121 return rc;
2122 }
2123
2124 switch (subtype) {
2125 case SMBB_CHGR_SUBTYPE:
2126 case SMBBP_CHGR_SUBTYPE:
2127 case SMBCL_CHGR_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002128 chip->chg_fastchg.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002129 spmi_resource, "fast-chg-on");
David Keitel47185a62013-05-15 18:54:10 -07002130 if (chip->chg_fastchg.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002131 pr_err("Unable to get fast-chg-on irq\n");
2132 return rc;
2133 }
2134
David Keitel47185a62013-05-15 18:54:10 -07002135 chip->chg_trklchg.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002136 spmi_resource, "trkl-chg-on");
David Keitel47185a62013-05-15 18:54:10 -07002137 if (chip->chg_trklchg.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002138 pr_err("Unable to get trkl-chg-on irq\n");
2139 return rc;
2140 }
2141
David Keitel47185a62013-05-15 18:54:10 -07002142 chip->chg_failed.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002143 spmi_resource, "chg-failed");
David Keitel47185a62013-05-15 18:54:10 -07002144 if (chip->chg_failed.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002145 pr_err("Unable to get chg_failed irq\n");
2146 return rc;
2147 }
2148
David Keitel47185a62013-05-15 18:54:10 -07002149 chip->chg_vbatdet_lo.irq = spmi_get_irq_byname(spmi,
David Keitel9fd07382013-05-02 15:37:44 -07002150 spmi_resource, "vbat-det-lo");
David Keitel47185a62013-05-15 18:54:10 -07002151 if (chip->chg_vbatdet_lo.irq < 0) {
David Keitel9fd07382013-05-02 15:37:44 -07002152 pr_err("Unable to get fast-chg-on irq\n");
2153 return rc;
2154 }
2155
David Keitel47185a62013-05-15 18:54:10 -07002156 rc |= devm_request_irq(chip->dev, chip->chg_failed.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002157 qpnp_chg_chgr_chg_failed_irq_handler,
David Keitelc9f19172013-04-29 11:01:26 -07002158 IRQF_TRIGGER_RISING, "chg-failed", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002159 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002160 pr_err("Can't request %d chg-failed: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002161 chip->chg_failed.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002162 return rc;
2163 }
2164
David Keitel47185a62013-05-15 18:54:10 -07002165 rc |= devm_request_irq(chip->dev, chip->chg_fastchg.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002166 qpnp_chg_chgr_chg_fastchg_irq_handler,
2167 IRQF_TRIGGER_RISING,
2168 "fast-chg-on", chip);
2169 if (rc < 0) {
2170 pr_err("Can't request %d fast-chg-on: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002171 chip->chg_fastchg.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002172 return rc;
2173 }
2174
David Keitel47185a62013-05-15 18:54:10 -07002175 rc |= devm_request_irq(chip->dev, chip->chg_trklchg.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002176 qpnp_chg_chgr_chg_trklchg_irq_handler,
2177 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002178 "trkl-chg-on", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002179 if (rc < 0) {
2180 pr_err("Can't request %d trkl-chg-on: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002181 chip->chg_trklchg.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002182 return rc;
2183 }
David Keitel9fd07382013-05-02 15:37:44 -07002184
2185 rc |= devm_request_irq(chip->dev,
David Keitel47185a62013-05-15 18:54:10 -07002186 chip->chg_vbatdet_lo.irq,
David Keitel9fd07382013-05-02 15:37:44 -07002187 qpnp_chg_vbatdet_lo_irq_handler,
David Keiteld98e2822013-06-05 11:37:34 -07002188 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitel9fd07382013-05-02 15:37:44 -07002189 "vbat-det-lo", chip);
2190 if (rc < 0) {
2191 pr_err("Can't request %d vbat-det-lo: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002192 chip->chg_vbatdet_lo.irq, rc);
David Keitel9fd07382013-05-02 15:37:44 -07002193 return rc;
2194 }
2195
David Keitel47185a62013-05-15 18:54:10 -07002196 enable_irq_wake(chip->chg_trklchg.irq);
2197 enable_irq_wake(chip->chg_failed.irq);
2198 qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
2199 enable_irq_wake(chip->chg_vbatdet_lo.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002200
2201 break;
2202 case SMBB_BAT_IF_SUBTYPE:
2203 case SMBBP_BAT_IF_SUBTYPE:
2204 case SMBCL_BAT_IF_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002205 chip->batt_pres.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002206 spmi_resource, "batt-pres");
David Keitel47185a62013-05-15 18:54:10 -07002207 if (chip->batt_pres.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002208 pr_err("Unable to get batt-pres irq\n");
2209 return rc;
2210 }
David Keitel47185a62013-05-15 18:54:10 -07002211 rc = devm_request_irq(chip->dev, chip->batt_pres.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002212 qpnp_chg_bat_if_batt_pres_irq_handler,
2213 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002214 "batt-pres", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002215 if (rc < 0) {
2216 pr_err("Can't request %d batt-pres irq: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002217 chip->batt_pres.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002218 return rc;
2219 }
2220
David Keitel47185a62013-05-15 18:54:10 -07002221 enable_irq_wake(chip->batt_pres.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002222 break;
2223 case SMBB_USB_CHGPTH_SUBTYPE:
2224 case SMBBP_USB_CHGPTH_SUBTYPE:
2225 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002226 chip->usbin_valid.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002227 spmi_resource, "usbin-valid");
David Keitel47185a62013-05-15 18:54:10 -07002228 if (chip->usbin_valid.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002229 pr_err("Unable to get usbin irq\n");
2230 return rc;
2231 }
David Keitel47185a62013-05-15 18:54:10 -07002232 rc = devm_request_irq(chip->dev, chip->usbin_valid.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002233 qpnp_chg_usb_usbin_valid_irq_handler,
2234 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002235 "usbin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002236 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002237 pr_err("Can't request %d usbin-valid: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002238 chip->usbin_valid.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002239 return rc;
2240 }
David Keitel344c6972013-04-09 19:28:21 -07002241
David Keitel47185a62013-05-15 18:54:10 -07002242 chip->chg_gone.irq = spmi_get_irq_byname(spmi,
David Keitel344c6972013-04-09 19:28:21 -07002243 spmi_resource, "chg-gone");
David Keitel47185a62013-05-15 18:54:10 -07002244 if (chip->chg_gone.irq < 0) {
David Keitel344c6972013-04-09 19:28:21 -07002245 pr_err("Unable to get chg-gone irq\n");
2246 return rc;
2247 }
David Keitel47185a62013-05-15 18:54:10 -07002248 rc = devm_request_irq(chip->dev, chip->chg_gone.irq,
David Keitel344c6972013-04-09 19:28:21 -07002249 qpnp_chg_usb_chg_gone_irq_handler,
2250 IRQF_TRIGGER_RISING,
David Keitelc9f19172013-04-29 11:01:26 -07002251 "chg-gone", chip);
David Keitel344c6972013-04-09 19:28:21 -07002252 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002253 pr_err("Can't request %d chg-gone: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002254 chip->chg_gone.irq, rc);
David Keitel344c6972013-04-09 19:28:21 -07002255 return rc;
2256 }
David Keitel47185a62013-05-15 18:54:10 -07002257
2258 enable_irq_wake(chip->usbin_valid.irq);
2259 enable_irq_wake(chip->chg_gone.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002260 break;
2261 case SMBB_DC_CHGPTH_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002262 chip->dcin_valid.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002263 spmi_resource, "dcin-valid");
David Keitel47185a62013-05-15 18:54:10 -07002264 if (chip->dcin_valid.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002265 pr_err("Unable to get dcin irq\n");
2266 return -rc;
2267 }
David Keitel47185a62013-05-15 18:54:10 -07002268 rc = devm_request_irq(chip->dev, chip->dcin_valid.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002269 qpnp_chg_dc_dcin_valid_irq_handler,
2270 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002271 "dcin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002272 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002273 pr_err("Can't request %d dcin-valid: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002274 chip->dcin_valid.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002275 return rc;
2276 }
2277
David Keitel47185a62013-05-15 18:54:10 -07002278 enable_irq_wake(chip->dcin_valid.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002279 break;
2280 }
2281 }
2282
2283 return rc;
2284}
2285
David Keitel80668952012-07-27 14:25:49 -07002286#define WDOG_EN_BIT BIT(7)
2287static int
2288qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
2289 struct spmi_resource *spmi_resource)
2290{
2291 int rc = 0;
David Keitel796882d2013-05-14 18:01:11 -07002292 u8 reg = 0;
David Keitel6dc4ed42013-05-17 11:08:58 -07002293 struct regulator_init_data *init_data;
2294 struct regulator_desc *rdesc;
David Keitel80668952012-07-27 14:25:49 -07002295
2296 switch (subtype) {
2297 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002298 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002299 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002300 rc = qpnp_chg_vinmin_set(chip, chip->min_voltage_mv);
2301 if (rc) {
2302 pr_debug("failed setting min_voltage rc=%d\n", rc);
2303 return rc;
2304 }
2305 rc = qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
2306 if (rc) {
2307 pr_debug("failed setting max_voltage rc=%d\n", rc);
2308 return rc;
2309 }
2310 rc = qpnp_chg_vddsafe_set(chip, chip->safe_voltage_mv);
2311 if (rc) {
2312 pr_debug("failed setting safe_voltage rc=%d\n", rc);
2313 return rc;
2314 }
David Keitel454ee842013-03-08 16:19:11 -08002315 rc = qpnp_chg_vbatdet_set(chip,
2316 chip->max_voltage_mv - chip->resume_delta_mv);
David Keitel5d44fa52012-12-03 16:37:31 -08002317 if (rc) {
2318 pr_debug("failed setting resume_voltage rc=%d\n", rc);
2319 return rc;
2320 }
David Keitel80668952012-07-27 14:25:49 -07002321 rc = qpnp_chg_ibatmax_set(chip, chip->max_bat_chg_current);
2322 if (rc) {
2323 pr_debug("failed setting ibatmax rc=%d\n", rc);
2324 return rc;
2325 }
David Keitel365c4c42013-03-08 16:20:40 -08002326 if (chip->term_current) {
2327 rc = qpnp_chg_ibatterm_set(chip, chip->term_current);
2328 if (rc) {
2329 pr_debug("failed setting ibatterm rc=%d\n", rc);
2330 return rc;
2331 }
David Keitel80668952012-07-27 14:25:49 -07002332 }
David Keitel5d44fa52012-12-03 16:37:31 -08002333 rc = qpnp_chg_ibatsafe_set(chip, chip->safe_current);
2334 if (rc) {
2335 pr_debug("failed setting ibat_Safe rc=%d\n", rc);
2336 return rc;
2337 }
David Keitela4b7b592013-04-11 18:34:35 -07002338 rc = qpnp_chg_tchg_max_set(chip, chip->tchg_mins);
2339 if (rc) {
2340 pr_debug("failed setting tchg_mins rc=%d\n", rc);
2341 return rc;
2342 }
2343
David Keitel80668952012-07-27 14:25:49 -07002344 /* HACK: Disable wdog */
2345 rc = qpnp_chg_masked_write(chip, chip->chgr_base + 0x62,
2346 0xFF, 0xA0, 1);
2347
David Keitelb4e43542013-04-09 17:30:41 -07002348 /* HACK: use analog EOC */
David Keitel80668952012-07-27 14:25:49 -07002349 rc = qpnp_chg_masked_write(chip, chip->chgr_base +
2350 CHGR_IBAT_TERM_CHGR,
David Keitel9fd07382013-05-02 15:37:44 -07002351 0xFF, 0x08, 1);
David Keitel80668952012-07-27 14:25:49 -07002352
David Keitel80668952012-07-27 14:25:49 -07002353 break;
2354 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002355 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002356 case SMBCL_BUCK_SUBTYPE:
David Keitel9fd07382013-05-02 15:37:44 -07002357 rc = qpnp_chg_toggle_chg_done_logic(chip, 0);
2358 if (rc)
2359 return rc;
2360
David Keitel9201df32013-01-10 18:38:34 -08002361 rc = qpnp_chg_masked_write(chip,
David Keitel5adc7942013-05-21 13:45:17 -07002362 chip->buck_base + CHGR_BUCK_BCK_VBAT_REG_MODE,
David Keitel9201df32013-01-10 18:38:34 -08002363 BUCK_VBAT_REG_NODE_SEL_BIT,
2364 BUCK_VBAT_REG_NODE_SEL_BIT, 1);
2365 if (rc) {
2366 pr_debug("failed to enable IR drop comp rc=%d\n", rc);
2367 return rc;
2368 }
David Keitel80668952012-07-27 14:25:49 -07002369 break;
2370 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002371 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002372 case SMBCL_BAT_IF_SUBTYPE:
David Keitel796882d2013-05-14 18:01:11 -07002373 /* Select battery presence detection */
David Keitel0ef282b2013-05-29 16:04:57 -07002374 switch (chip->bpd_detection) {
2375 case BPD_TYPE_BAT_THM:
2376 reg = BAT_THM_EN;
2377 break;
2378 case BPD_TYPE_BAT_ID:
David Keitel796882d2013-05-14 18:01:11 -07002379 reg = BAT_ID_EN;
David Keitel0ef282b2013-05-29 16:04:57 -07002380 break;
2381 case BPD_TYPE_BAT_THM_BAT_ID:
2382 reg = BAT_THM_EN | BAT_ID_EN;
2383 break;
2384 default:
2385 reg = BAT_THM_EN;
2386 break;
2387 }
David Keitel796882d2013-05-14 18:01:11 -07002388
2389 rc = qpnp_chg_masked_write(chip,
2390 chip->bat_if_base + BAT_IF_BPD_CTRL,
2391 BAT_IF_BPD_CTRL_SEL,
2392 reg, 1);
2393 if (rc) {
2394 pr_debug("failed to chose BPD rc=%d\n", rc);
2395 return rc;
2396 }
David Keitel85ae4342013-04-16 11:46:00 -07002397 /* Force on VREF_BAT_THM */
2398 rc = qpnp_chg_masked_write(chip,
2399 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2400 VREF_BATT_THERM_FORCE_ON,
2401 VREF_BATT_THERM_FORCE_ON, 1);
2402 if (rc) {
2403 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
2404 return rc;
2405 }
David Keitel80668952012-07-27 14:25:49 -07002406 break;
2407 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002408 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002409 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel9fd07382013-05-02 15:37:44 -07002410 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel80668952012-07-27 14:25:49 -07002411 rc = qpnp_chg_masked_write(chip,
2412 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
2413 ENUM_T_STOP_BIT,
2414 ENUM_T_STOP_BIT, 1);
2415 if (rc) {
2416 pr_err("failed to write enum stop rc=%d\n", rc);
2417 return -ENXIO;
2418 }
2419 }
David Keiteld681cda2012-10-02 15:44:21 -07002420
David Keitel6dc4ed42013-05-17 11:08:58 -07002421 init_data = of_get_regulator_init_data(chip->dev,
2422 spmi_resource->of_node);
2423 if (!init_data) {
2424 pr_err("unable to allocate memory\n");
2425 return -ENOMEM;
2426 }
2427
2428 if (init_data->constraints.name) {
2429 if (of_get_property(chip->dev->of_node,
2430 "otg-parent-supply", NULL))
2431 init_data->supply_regulator = "otg-parent";
2432
2433 rdesc = &(chip->otg_vreg.rdesc);
2434 rdesc->owner = THIS_MODULE;
2435 rdesc->type = REGULATOR_VOLTAGE;
2436 rdesc->ops = &qpnp_chg_otg_reg_ops;
2437 rdesc->name = init_data->constraints.name;
2438
2439 init_data->constraints.valid_ops_mask
2440 |= REGULATOR_CHANGE_STATUS;
2441
2442 chip->otg_vreg.rdev = regulator_register(rdesc,
2443 chip->dev, init_data, chip,
2444 spmi_resource->of_node);
2445 if (IS_ERR(chip->otg_vreg.rdev)) {
2446 rc = PTR_ERR(chip->otg_vreg.rdev);
David Collinscbb12132013-05-28 10:47:28 -07002447 chip->otg_vreg.rdev = NULL;
David Keitel6dc4ed42013-05-17 11:08:58 -07002448 if (rc != -EPROBE_DEFER)
2449 pr_err("OTG reg failed, rc=%d\n", rc);
2450 return rc;
2451 }
2452 }
2453
David Keiteld681cda2012-10-02 15:44:21 -07002454 rc = qpnp_chg_masked_write(chip,
David Keitel5c3a7702012-12-20 11:13:21 -08002455 chip->usb_chgpth_base + USB_OVP_CTL,
2456 USB_VALID_DEB_20MS,
2457 USB_VALID_DEB_20MS, 1);
2458
2459 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -07002460 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
2461 ENUM_T_STOP_BIT,
2462 ENUM_T_STOP_BIT, 1);
2463
David Keitel344c6972013-04-09 19:28:21 -07002464 rc = qpnp_chg_masked_write(chip,
2465 chip->usb_chgpth_base + SEC_ACCESS,
2466 0xFF,
2467 0xA5, 1);
2468
2469 rc = qpnp_chg_masked_write(chip,
2470 chip->usb_chgpth_base + USB_CHG_GONE_REV_BST,
2471 0xFF,
2472 0x80, 1);
2473
David Keitel80668952012-07-27 14:25:49 -07002474 break;
2475 case SMBB_DC_CHGPTH_SUBTYPE:
2476 break;
2477 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002478 case SMBBP_BOOST_SUBTYPE:
David Keitel6dc4ed42013-05-17 11:08:58 -07002479 init_data = of_get_regulator_init_data(chip->dev,
2480 spmi_resource->of_node);
2481 if (!init_data) {
2482 pr_err("unable to allocate memory\n");
2483 return -ENOMEM;
2484 }
2485
2486 if (init_data->constraints.name) {
2487 if (of_get_property(chip->dev->of_node,
2488 "boost-parent-supply", NULL))
2489 init_data->supply_regulator = "boost-parent";
2490
2491 rdesc = &(chip->boost_vreg.rdesc);
2492 rdesc->owner = THIS_MODULE;
2493 rdesc->type = REGULATOR_VOLTAGE;
2494 rdesc->ops = &qpnp_chg_boost_reg_ops;
2495 rdesc->name = init_data->constraints.name;
2496
2497 init_data->constraints.valid_ops_mask
2498 |= REGULATOR_CHANGE_STATUS
2499 | REGULATOR_CHANGE_VOLTAGE;
2500
2501 chip->boost_vreg.rdev = regulator_register(rdesc,
2502 chip->dev, init_data, chip,
2503 spmi_resource->of_node);
2504 if (IS_ERR(chip->boost_vreg.rdev)) {
2505 rc = PTR_ERR(chip->boost_vreg.rdev);
David Collinscbb12132013-05-28 10:47:28 -07002506 chip->boost_vreg.rdev = NULL;
David Keitel6dc4ed42013-05-17 11:08:58 -07002507 if (rc != -EPROBE_DEFER)
2508 pr_err("boost reg failed, rc=%d\n", rc);
2509 return rc;
2510 }
2511 }
David Keitel80668952012-07-27 14:25:49 -07002512 break;
2513 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002514 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002515 case SMBCL_MISC_SUBTYPE:
David Keitel52d685e2013-05-02 11:59:05 -07002516 if (subtype == SMBB_MISC_SUBTYPE)
2517 chip->type = SMBB;
2518 else if (subtype == SMBBP_MISC_SUBTYPE)
2519 chip->type = SMBBP;
2520 else if (subtype == SMBCL_MISC_SUBTYPE)
2521 chip->type = SMBCL;
2522
David Keitel80668952012-07-27 14:25:49 -07002523 pr_debug("Setting BOOT_DONE\n");
2524 rc = qpnp_chg_masked_write(chip,
2525 chip->misc_base + CHGR_MISC_BOOT_DONE,
2526 CHGR_BOOT_DONE, CHGR_BOOT_DONE, 1);
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002527 rc = qpnp_chg_read(chip, &reg,
2528 chip->misc_base + MISC_REVISION2, 1);
2529 if (rc) {
2530 pr_err("failed to read revision register rc=%d\n", rc);
2531 return rc;
2532 }
David Keitel80668952012-07-27 14:25:49 -07002533
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002534 chip->revision = reg;
David Keitel80668952012-07-27 14:25:49 -07002535 break;
2536 default:
2537 pr_err("Invalid peripheral subtype\n");
2538 }
2539 return rc;
2540}
2541
David Keitel112ba9c2013-04-12 18:40:43 -07002542#define OF_PROP_READ(chip, prop, qpnp_dt_property, retval, optional) \
2543do { \
2544 if (retval) \
2545 break; \
2546 \
2547 retval = of_property_read_u32(chip->spmi->dev.of_node, \
2548 "qcom," qpnp_dt_property, \
2549 &chip->prop); \
2550 \
2551 if ((retval == -EINVAL) && optional) \
2552 retval = 0; \
2553 else if (retval) \
2554 pr_err("Error reading " #qpnp_dt_property \
2555 " property rc = %d\n", rc); \
2556} while (0)
2557
2558static int
2559qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
2560{
2561 int rc = 0;
David Keitel796882d2013-05-14 18:01:11 -07002562 const char *bpd;
David Keitel112ba9c2013-04-12 18:40:43 -07002563
2564 OF_PROP_READ(chip, max_voltage_mv, "vddmax-mv", rc, 0);
2565 OF_PROP_READ(chip, min_voltage_mv, "vinmin-mv", rc, 0);
2566 OF_PROP_READ(chip, safe_voltage_mv, "vddsafe-mv", rc, 0);
2567 OF_PROP_READ(chip, resume_delta_mv, "vbatdet-delta-mv", rc, 0);
2568 OF_PROP_READ(chip, safe_current, "ibatsafe-ma", rc, 0);
2569 OF_PROP_READ(chip, max_bat_chg_current, "ibatmax-ma", rc, 0);
2570 if (rc)
2571 pr_err("failed to read required dt parameters %d\n", rc);
2572
2573 OF_PROP_READ(chip, term_current, "ibatterm-ma", rc, 1);
2574 OF_PROP_READ(chip, maxinput_dc_ma, "maxinput-dc-ma", rc, 1);
2575 OF_PROP_READ(chip, maxinput_usb_ma, "maxinput-usb-ma", rc, 1);
2576 OF_PROP_READ(chip, warm_bat_decidegc, "warm-bat-decidegc", rc, 1);
2577 OF_PROP_READ(chip, cool_bat_decidegc, "cool-bat-decidegc", rc, 1);
David Keitela4b7b592013-04-11 18:34:35 -07002578 OF_PROP_READ(chip, tchg_mins, "tchg-mins", rc, 1);
David Keitel112ba9c2013-04-12 18:40:43 -07002579 if (rc)
2580 return rc;
2581
David Keitel796882d2013-05-14 18:01:11 -07002582 rc = of_property_read_string(chip->spmi->dev.of_node,
2583 "qcom,bpd-detection", &bpd);
2584 if (rc) {
David Keitel0ef282b2013-05-29 16:04:57 -07002585 /* Select BAT_THM as default BPD scheme */
2586 chip->bpd_detection = BPD_TYPE_BAT_THM;
David Keitel796882d2013-05-14 18:01:11 -07002587 } else {
2588 chip->bpd_detection = get_bpd(bpd);
2589 if (chip->bpd_detection < 0) {
2590 pr_err("failed to determine bpd schema %d\n", rc);
2591 return rc;
2592 }
2593 }
2594
David Keitel112ba9c2013-04-12 18:40:43 -07002595 /* Look up JEITA compliance parameters if cool and warm temp provided */
2596 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2597 rc = qpnp_adc_tm_is_ready();
2598 if (rc) {
2599 pr_err("tm not ready %d\n", rc);
2600 return rc;
2601 }
2602
2603 OF_PROP_READ(chip, warm_bat_chg_ma, "ibatmax-warm-ma", rc, 1);
2604 OF_PROP_READ(chip, cool_bat_chg_ma, "ibatmax-cool-ma", rc, 1);
2605 OF_PROP_READ(chip, warm_bat_mv, "warm-bat-mv", rc, 1);
2606 OF_PROP_READ(chip, cool_bat_mv, "cool-bat-mv", rc, 1);
2607 if (rc)
2608 return rc;
2609 }
2610
2611 /* Get the charging-disabled property */
2612 chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
2613 "qcom,charging-disabled");
2614
David Keitel8b68d2d2013-05-14 23:36:51 -07002615 /* Get the duty-cycle-100p property */
2616 chip->duty_cycle_100p = of_property_read_bool(
2617 chip->spmi->dev.of_node,
2618 "qcom,duty-cycle-100p");
2619 if (chip->duty_cycle_100p) {
2620 rc = qpnp_buck_set_100_duty_cycle_enable(chip, 1);
2621 if (rc) {
2622 pr_err("failed to enable duty cycle %d\n", rc);
2623 return rc;
2624 }
2625 }
2626
David Keitel112ba9c2013-04-12 18:40:43 -07002627 /* Get the fake-batt-values property */
2628 chip->use_default_batt_values =
2629 of_property_read_bool(chip->spmi->dev.of_node,
2630 "qcom,use-default-batt-values");
2631
2632 /* Disable charging when faking battery values */
2633 if (chip->use_default_batt_values)
2634 chip->charging_disabled = true;
2635
2636 of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
2637 &(chip->thermal_levels));
2638
2639 if (chip->thermal_levels > sizeof(int)) {
2640 chip->thermal_mitigation = kzalloc(
2641 chip->thermal_levels,
2642 GFP_KERNEL);
2643
2644 if (chip->thermal_mitigation == NULL) {
2645 pr_err("thermal mitigation kzalloc() failed.\n");
2646 return rc;
2647 }
2648
2649 chip->thermal_levels /= sizeof(int);
2650 rc = of_property_read_u32_array(chip->spmi->dev.of_node,
2651 "qcom,thermal-mitigation",
2652 chip->thermal_mitigation, chip->thermal_levels);
2653 if (rc) {
2654 pr_err("qcom,thermal-mitigation missing in dt\n");
2655 return rc;
2656 }
2657 }
2658
2659 return rc;
2660}
2661
David Keitel80668952012-07-27 14:25:49 -07002662static int __devinit
2663qpnp_charger_probe(struct spmi_device *spmi)
2664{
2665 u8 subtype;
2666 struct qpnp_chg_chip *chip;
2667 struct resource *resource;
2668 struct spmi_resource *spmi_resource;
2669 int rc = 0;
2670
2671 chip = kzalloc(sizeof *chip, GFP_KERNEL);
2672 if (chip == NULL) {
2673 pr_err("kzalloc() failed.\n");
2674 return -ENOMEM;
2675 }
2676
David Keitel80668952012-07-27 14:25:49 -07002677 chip->dev = &(spmi->dev);
2678 chip->spmi = spmi;
2679
2680 chip->usb_psy = power_supply_get_by_name("usb");
2681 if (!chip->usb_psy) {
2682 pr_err("usb supply not found deferring probe\n");
2683 rc = -EPROBE_DEFER;
2684 goto fail_chg_enable;
2685 }
2686
David Keitel112ba9c2013-04-12 18:40:43 -07002687 /* Get all device tree properties */
2688 rc = qpnp_charger_read_dt_props(chip);
2689 if (rc)
David Keitel80668952012-07-27 14:25:49 -07002690 goto fail_chg_enable;
David Keitel3dd5e0f2012-12-12 18:12:36 -08002691
David Keiteldd87a172013-05-29 17:05:43 -07002692 /* Check if bat_if is set in DT and make sure VADC is present */
2693 spmi_for_each_container_dev(spmi_resource, spmi) {
2694 if (!spmi_resource) {
2695 pr_err("qpnp_chg: spmi resource absent\n");
2696 rc = -ENXIO;
2697 goto fail_chg_enable;
2698 }
2699
2700 resource = spmi_get_resource(spmi, spmi_resource,
2701 IORESOURCE_MEM, 0);
2702 if (!(resource && resource->start)) {
2703 pr_err("node %s IO resource absent!\n",
2704 spmi->dev.of_node->full_name);
2705 rc = -ENXIO;
2706 goto fail_chg_enable;
2707 }
2708
2709 rc = qpnp_chg_read(chip, &subtype,
2710 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2711 if (rc) {
2712 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2713 goto fail_chg_enable;
2714 }
2715
2716 if (subtype == SMBB_BAT_IF_SUBTYPE ||
2717 subtype == SMBBP_BAT_IF_SUBTYPE ||
2718 subtype == SMBCL_BAT_IF_SUBTYPE){
2719 rc = qpnp_vadc_is_ready();
2720 if (rc)
2721 goto fail_chg_enable;
2722 }
2723 }
2724
David Keitel80668952012-07-27 14:25:49 -07002725 spmi_for_each_container_dev(spmi_resource, spmi) {
2726 if (!spmi_resource) {
2727 pr_err("qpnp_chg: spmi resource absent\n");
2728 rc = -ENXIO;
2729 goto fail_chg_enable;
2730 }
2731
2732 resource = spmi_get_resource(spmi, spmi_resource,
2733 IORESOURCE_MEM, 0);
2734 if (!(resource && resource->start)) {
2735 pr_err("node %s IO resource absent!\n",
2736 spmi->dev.of_node->full_name);
2737 rc = -ENXIO;
2738 goto fail_chg_enable;
2739 }
2740
2741 rc = qpnp_chg_read(chip, &subtype,
2742 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2743 if (rc) {
2744 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2745 goto fail_chg_enable;
2746 }
2747
2748 switch (subtype) {
2749 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002750 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002751 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002752 chip->chgr_base = resource->start;
2753 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2754 if (rc) {
2755 pr_err("Failed to init subtype 0x%x rc=%d\n",
2756 subtype, rc);
2757 goto fail_chg_enable;
2758 }
2759 break;
2760 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002761 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002762 case SMBCL_BUCK_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002763 chip->buck_base = resource->start;
2764 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2765 if (rc) {
2766 pr_err("Failed to init subtype 0x%x rc=%d\n",
2767 subtype, rc);
2768 goto fail_chg_enable;
2769 }
David Keitel344c6972013-04-09 19:28:21 -07002770
2771 rc = qpnp_chg_masked_write(chip,
2772 chip->buck_base + SEC_ACCESS,
2773 0xFF,
2774 0xA5, 1);
2775
2776 rc = qpnp_chg_masked_write(chip,
2777 chip->buck_base + BUCK_VCHG_OV,
2778 0xff,
2779 0x00, 1);
2780
2781 rc = qpnp_chg_masked_write(chip,
2782 chip->buck_base + SEC_ACCESS,
2783 0xFF,
2784 0xA5, 1);
2785
2786 rc = qpnp_chg_masked_write(chip,
2787 chip->buck_base + BUCK_TEST_SMBC_MODES,
2788 0xFF,
2789 0x80, 1);
2790
David Keitel80668952012-07-27 14:25:49 -07002791 break;
2792 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002793 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002794 case SMBCL_BAT_IF_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002795 chip->bat_if_base = resource->start;
2796 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2797 if (rc) {
2798 pr_err("Failed to init subtype 0x%x rc=%d\n",
2799 subtype, rc);
2800 goto fail_chg_enable;
2801 }
2802 break;
2803 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002804 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002805 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002806 chip->usb_chgpth_base = resource->start;
2807 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2808 if (rc) {
David Keitel6dc4ed42013-05-17 11:08:58 -07002809 if (rc != -EPROBE_DEFER)
2810 pr_err("Failed to init subtype 0x%x rc=%d\n",
David Keitel80668952012-07-27 14:25:49 -07002811 subtype, rc);
2812 goto fail_chg_enable;
2813 }
2814 break;
2815 case SMBB_DC_CHGPTH_SUBTYPE:
2816 chip->dc_chgpth_base = resource->start;
2817 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2818 if (rc) {
2819 pr_err("Failed to init subtype 0x%x rc=%d\n",
2820 subtype, rc);
2821 goto fail_chg_enable;
2822 }
2823 break;
2824 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002825 case SMBBP_BOOST_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002826 chip->boost_base = resource->start;
2827 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2828 if (rc) {
David Keitel6dc4ed42013-05-17 11:08:58 -07002829 if (rc != -EPROBE_DEFER)
2830 pr_err("Failed to init subtype 0x%x rc=%d\n",
David Keitel80668952012-07-27 14:25:49 -07002831 subtype, rc);
2832 goto fail_chg_enable;
2833 }
2834 break;
2835 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002836 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002837 case SMBCL_MISC_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002838 chip->misc_base = resource->start;
2839 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2840 if (rc) {
2841 pr_err("Failed to init subtype=0x%x rc=%d\n",
2842 subtype, rc);
2843 goto fail_chg_enable;
2844 }
2845 break;
2846 default:
2847 pr_err("Invalid peripheral subtype=0x%x\n", subtype);
2848 rc = -EINVAL;
2849 goto fail_chg_enable;
2850 }
2851 }
2852 dev_set_drvdata(&spmi->dev, chip);
2853 device_init_wakeup(&spmi->dev, 1);
2854
David Keitelf2170cc2013-02-20 17:49:03 -08002855 if (chip->bat_if_base) {
David Keitelf2170cc2013-02-20 17:49:03 -08002856 chip->batt_psy.name = "battery";
2857 chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
2858 chip->batt_psy.properties = msm_batt_power_props;
2859 chip->batt_psy.num_properties =
2860 ARRAY_SIZE(msm_batt_power_props);
2861 chip->batt_psy.get_property = qpnp_batt_power_get_property;
2862 chip->batt_psy.set_property = qpnp_batt_power_set_property;
2863 chip->batt_psy.property_is_writeable =
2864 qpnp_batt_property_is_writeable;
2865 chip->batt_psy.external_power_changed =
David Keitel80668952012-07-27 14:25:49 -07002866 qpnp_batt_external_power_changed;
Xiaozhe Shi890fbf42013-05-02 16:42:53 -07002867 chip->batt_psy.supplied_to = pm_batt_supplied_to;
2868 chip->batt_psy.num_supplicants =
2869 ARRAY_SIZE(pm_batt_supplied_to);
David Keitel80668952012-07-27 14:25:49 -07002870
David Keitelf2170cc2013-02-20 17:49:03 -08002871 rc = power_supply_register(chip->dev, &chip->batt_psy);
2872 if (rc < 0) {
2873 pr_err("batt failed to register rc = %d\n", rc);
2874 goto fail_chg_enable;
2875 }
David Keitel79f4c932013-04-03 16:08:39 -07002876 INIT_WORK(&chip->adc_measure_work,
2877 qpnp_bat_if_adc_measure_work);
David Keitelc7093b02013-02-14 12:50:04 -08002878 }
2879
David Keitel9fd07382013-05-02 15:37:44 -07002880 wake_lock_init(&chip->eoc_wake_lock,
2881 WAKE_LOCK_SUSPEND, "qpnp-chg-eoc-lock");
2882 INIT_DELAYED_WORK(&chip->eoc_work, qpnp_eoc_work);
David Keitel5910eea2013-05-02 15:32:25 -07002883 INIT_DELAYED_WORK(&chip->arb_stop_work, qpnp_arb_stop_work);
2884
David Keitelf2170cc2013-02-20 17:49:03 -08002885 if (chip->dc_chgpth_base) {
2886 chip->dc_psy.name = "qpnp-dc";
2887 chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
2888 chip->dc_psy.supplied_to = pm_power_supplied_to;
2889 chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
2890 chip->dc_psy.properties = pm_power_props_mains;
2891 chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
2892 chip->dc_psy.get_property = qpnp_power_get_property_mains;
2893
2894 rc = power_supply_register(chip->dev, &chip->dc_psy);
2895 if (rc < 0) {
2896 pr_err("power_supply_register dc failed rc=%d\n", rc);
2897 goto unregister_batt;
2898 }
David Keitel80668952012-07-27 14:25:49 -07002899 }
2900
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002901 /* Turn on appropriate workaround flags */
2902 qpnp_chg_setup_flags(chip);
2903
David Keitelf2170cc2013-02-20 17:49:03 -08002904 if (chip->maxinput_dc_ma && chip->dc_chgpth_base) {
David Keitel22ed2232013-01-28 11:04:07 -08002905 rc = qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
2906 if (rc) {
2907 pr_err("Error setting idcmax property %d\n", rc);
David Keitelf2170cc2013-02-20 17:49:03 -08002908 goto unregister_batt;
David Keitel22ed2232013-01-28 11:04:07 -08002909 }
2910 }
2911
David Keitel0c1a4532013-03-21 16:39:06 -07002912 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2913 chip->adc_param.low_temp = chip->cool_bat_decidegc;
2914 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel454ee842013-03-08 16:19:11 -08002915 chip->adc_param.timer_interval = ADC_MEAS2_INTERVAL_1S;
2916 chip->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
2917 chip->adc_param.btm_ctx = chip;
2918 chip->adc_param.threshold_notification =
2919 qpnp_chg_adc_notification;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -08002920 chip->adc_param.channel = LR_MUX1_BATT_THERM;
David Keitel0c1a4532013-03-21 16:39:06 -07002921
2922 if (get_prop_batt_present(chip)) {
2923 rc = qpnp_adc_tm_channel_measure(&chip->adc_param);
2924 if (rc) {
2925 pr_err("request ADC error %d\n", rc);
2926 goto fail_chg_enable;
2927 }
David Keitel454ee842013-03-08 16:19:11 -08002928 }
2929 }
2930
David Keitel03ee6b52012-10-22 12:25:19 -07002931 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitelb1ddb742012-11-06 19:05:51 -08002932 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
Xiaozhe Shi79a8c492013-05-24 13:09:23 -07002933 qpnp_chg_set_appropriate_vddmax(chip);
David Keitelbf359042012-10-19 16:54:58 -07002934
David Keitel0f35be42013-04-16 11:10:40 -07002935 rc = qpnp_chg_request_irqs(chip);
2936 if (rc) {
2937 pr_err("failed to request interrupts %d\n", rc);
2938 goto unregister_batt;
2939 }
2940
David Keitel9fd07382013-05-02 15:37:44 -07002941 qpnp_chg_usb_usbin_valid_irq_handler(USBIN_VALID_IRQ, chip);
David Keiteld2efc392013-06-05 16:27:12 -07002942 qpnp_chg_dc_dcin_valid_irq_handler(DCIN_VALID_IRQ, chip);
David Keitel9fd07382013-05-02 15:37:44 -07002943 power_supply_set_present(chip->usb_psy,
2944 qpnp_chg_is_usb_chg_plugged_in(chip));
2945
David Keitel3c62b472013-05-06 15:38:11 -07002946 /* Set USB psy online to avoid userspace from shutting down if battery
2947 * capacity is at zero and no chargers online. */
2948 if (qpnp_chg_is_usb_chg_plugged_in(chip))
2949 power_supply_set_online(chip->usb_psy, 1);
2950
David Keitel796882d2013-05-14 18:01:11 -07002951 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 -08002952 chip->charging_disabled,
David Keitel796882d2013-05-14 18:01:11 -07002953 chip->bpd_detection,
Abhijeet Dharmapurikar2d996b12013-01-03 17:48:02 -08002954 qpnp_chg_is_usb_chg_plugged_in(chip),
2955 qpnp_chg_is_dc_chg_plugged_in(chip),
2956 get_prop_batt_present(chip),
2957 get_prop_batt_health(chip));
David Keitel80668952012-07-27 14:25:49 -07002958 return 0;
2959
David Keitelc7093b02013-02-14 12:50:04 -08002960unregister_batt:
David Keitelf2170cc2013-02-20 17:49:03 -08002961 if (chip->bat_if_base)
2962 power_supply_unregister(&chip->batt_psy);
David Keitel80668952012-07-27 14:25:49 -07002963fail_chg_enable:
David Collinscbb12132013-05-28 10:47:28 -07002964 regulator_unregister(chip->otg_vreg.rdev);
2965 regulator_unregister(chip->boost_vreg.rdev);
David Keitelbe208252013-01-31 14:49:25 -08002966 kfree(chip->thermal_mitigation);
David Keitel80668952012-07-27 14:25:49 -07002967 kfree(chip);
2968 dev_set_drvdata(&spmi->dev, NULL);
2969 return rc;
2970}
2971
2972static int __devexit
2973qpnp_charger_remove(struct spmi_device *spmi)
2974{
2975 struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
David Keitel0c1a4532013-03-21 16:39:06 -07002976 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
2977 && chip->batt_present) {
2978 qpnp_adc_tm_disable_chan_meas(&chip->adc_param);
2979 }
David Keitel79f4c932013-04-03 16:08:39 -07002980 cancel_work_sync(&chip->adc_measure_work);
David Keitel9fd07382013-05-02 15:37:44 -07002981 cancel_delayed_work_sync(&chip->eoc_work);
David Keitel79f4c932013-04-03 16:08:39 -07002982
David Collinscbb12132013-05-28 10:47:28 -07002983 regulator_unregister(chip->otg_vreg.rdev);
2984 regulator_unregister(chip->boost_vreg.rdev);
David Keitel6dc4ed42013-05-17 11:08:58 -07002985
David Keitel80668952012-07-27 14:25:49 -07002986 dev_set_drvdata(&spmi->dev, NULL);
2987 kfree(chip);
2988
2989 return 0;
2990}
2991
David Keitel85ae4342013-04-16 11:46:00 -07002992static int qpnp_chg_resume(struct device *dev)
2993{
2994 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2995 int rc = 0;
2996
David Keitel39093572013-06-05 15:32:30 -07002997 if (chip->bat_if_base) {
2998 rc = qpnp_chg_masked_write(chip,
2999 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
3000 VREF_BATT_THERM_FORCE_ON,
3001 VREF_BATT_THERM_FORCE_ON, 1);
3002 if (rc)
3003 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
3004 }
David Keitel85ae4342013-04-16 11:46:00 -07003005
3006 return rc;
3007}
3008
3009static int qpnp_chg_suspend(struct device *dev)
3010{
3011 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
3012 int rc = 0;
3013
David Keitel39093572013-06-05 15:32:30 -07003014 if (chip->bat_if_base) {
3015 rc = qpnp_chg_masked_write(chip,
3016 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
3017 VREF_BATT_THERM_FORCE_ON,
3018 VREF_BAT_THM_ENABLED_FSM, 1);
3019 if (rc)
3020 pr_debug("failed to set FSM VREF_BAT_THM rc=%d\n", rc);
3021 }
David Keitel85ae4342013-04-16 11:46:00 -07003022
3023 return rc;
3024}
3025
David Keitel723d5012013-05-03 13:17:27 -07003026static const struct dev_pm_ops qpnp_chg_pm_ops = {
David Keitel85ae4342013-04-16 11:46:00 -07003027 .resume = qpnp_chg_resume,
3028 .suspend = qpnp_chg_suspend,
3029};
3030
David Keitel80668952012-07-27 14:25:49 -07003031static struct spmi_driver qpnp_charger_driver = {
3032 .probe = qpnp_charger_probe,
3033 .remove = __devexit_p(qpnp_charger_remove),
3034 .driver = {
David Keitel723d5012013-05-03 13:17:27 -07003035 .name = QPNP_CHARGER_DEV_NAME,
3036 .owner = THIS_MODULE,
3037 .of_match_table = qpnp_charger_match_table,
3038 .pm = &qpnp_chg_pm_ops,
David Keitel80668952012-07-27 14:25:49 -07003039 },
3040};
3041
3042/**
3043 * qpnp_chg_init() - register spmi driver for qpnp-chg
3044 */
3045int __init
3046qpnp_chg_init(void)
3047{
3048 return spmi_driver_register(&qpnp_charger_driver);
3049}
3050module_init(qpnp_chg_init);
3051
3052static void __exit
3053qpnp_chg_exit(void)
3054{
3055 spmi_driver_unregister(&qpnp_charger_driver);
3056}
3057module_exit(qpnp_chg_exit);
3058
3059
3060MODULE_DESCRIPTION("QPNP charger driver");
3061MODULE_LICENSE("GPL v2");
3062MODULE_ALIAS("platform:" QPNP_CHARGER_DEV_NAME);