blob: b64a37a947b2daa75925a1ed3d5876bbc0461580 [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 Keitel80668952012-07-27 14:25:49 -0700100#define REG_OFFSET_PERP_SUBTYPE 0x05
David Keitel6dc4ed42013-05-17 11:08:58 -0700101
David Keitelf2170cc2013-02-20 17:49:03 -0800102/* SMBB peripheral subtype values */
David Keitel80668952012-07-27 14:25:49 -0700103#define SMBB_CHGR_SUBTYPE 0x01
104#define SMBB_BUCK_SUBTYPE 0x02
105#define SMBB_BAT_IF_SUBTYPE 0x03
106#define SMBB_USB_CHGPTH_SUBTYPE 0x04
107#define SMBB_DC_CHGPTH_SUBTYPE 0x05
108#define SMBB_BOOST_SUBTYPE 0x06
109#define SMBB_MISC_SUBTYPE 0x07
110
David Keitelf2170cc2013-02-20 17:49:03 -0800111/* SMBB peripheral subtype values */
112#define SMBBP_CHGR_SUBTYPE 0x31
113#define SMBBP_BUCK_SUBTYPE 0x32
114#define SMBBP_BAT_IF_SUBTYPE 0x33
115#define SMBBP_USB_CHGPTH_SUBTYPE 0x34
116#define SMBBP_BOOST_SUBTYPE 0x36
117#define SMBBP_MISC_SUBTYPE 0x37
118
David Keitel46c9f7b2013-04-02 19:54:12 -0700119/* SMBCL peripheral subtype values */
120#define SMBCL_CHGR_SUBTYPE 0x41
121#define SMBCL_BUCK_SUBTYPE 0x42
122#define SMBCL_BAT_IF_SUBTYPE 0x43
123#define SMBCL_USB_CHGPTH_SUBTYPE 0x44
124#define SMBCL_MISC_SUBTYPE 0x47
125
David Keitel80668952012-07-27 14:25:49 -0700126#define QPNP_CHARGER_DEV_NAME "qcom,qpnp-charger"
127
David Keitelb80eda82012-10-15 10:49:11 -0700128/* Status bits and masks */
129#define CHGR_BOOT_DONE BIT(7)
130#define CHGR_CHG_EN BIT(7)
131#define CHGR_ON_BAT_FORCE_BIT BIT(0)
David Keitel5c3a7702012-12-20 11:13:21 -0800132#define USB_VALID_DEB_20MS 0x03
David Keitel9201df32013-01-10 18:38:34 -0800133#define BUCK_VBAT_REG_NODE_SEL_BIT BIT(0)
David Keitel85ae4342013-04-16 11:46:00 -0700134#define VREF_BATT_THERM_FORCE_ON 0xC0
David Keitel796882d2013-05-14 18:01:11 -0700135#define BAT_IF_BPD_CTRL_SEL 0x03
David Keitel85ae4342013-04-16 11:46:00 -0700136#define VREF_BAT_THM_ENABLED_FSM 0x80
David Keitel796882d2013-05-14 18:01:11 -0700137#define REV_BST_DETECTED BIT(0)
138#define BAT_THM_EN BIT(1)
139#define BAT_ID_EN BIT(0)
David Keitel6dc4ed42013-05-17 11:08:58 -0700140#define BOOST_PWR_EN BIT(7)
David Keitelb80eda82012-10-15 10:49:11 -0700141
David Keitel80668952012-07-27 14:25:49 -0700142/* Interrupt definitions */
143/* smbb_chg_interrupts */
144#define CHG_DONE_IRQ BIT(7)
145#define CHG_FAILED_IRQ BIT(6)
146#define FAST_CHG_ON_IRQ BIT(5)
147#define TRKL_CHG_ON_IRQ BIT(4)
148#define STATE_CHANGE_ON_IR BIT(3)
149#define CHGWDDOG_IRQ BIT(2)
150#define VBAT_DET_HI_IRQ BIT(1)
151#define VBAT_DET_LOW_IRQ BIT(0)
152
153/* smbb_buck_interrupts */
154#define VDD_LOOP_IRQ BIT(6)
155#define IBAT_LOOP_IRQ BIT(5)
156#define ICHG_LOOP_IRQ BIT(4)
157#define VCHG_LOOP_IRQ BIT(3)
158#define OVERTEMP_IRQ BIT(2)
159#define VREF_OV_IRQ BIT(1)
160#define VBAT_OV_IRQ BIT(0)
161
162/* smbb_bat_if_interrupts */
163#define PSI_IRQ BIT(4)
164#define VCP_ON_IRQ BIT(3)
165#define BAT_FET_ON_IRQ BIT(2)
166#define BAT_TEMP_OK_IRQ BIT(1)
167#define BATT_PRES_IRQ BIT(0)
168
169/* smbb_usb_interrupts */
170#define CHG_GONE_IRQ BIT(2)
171#define USBIN_VALID_IRQ BIT(1)
172#define COARSE_DET_USB_IRQ BIT(0)
173
174/* smbb_dc_interrupts */
175#define DCIN_VALID_IRQ BIT(1)
176#define COARSE_DET_DC_IRQ BIT(0)
177
178/* smbb_boost_interrupts */
179#define LIMIT_ERROR_IRQ BIT(1)
180#define BOOST_PWR_OK_IRQ BIT(0)
181
182/* smbb_misc_interrupts */
183#define TFTWDOG_IRQ BIT(0)
184
David Keitelfe51cb92013-04-02 19:42:58 -0700185/* SMBB types */
186#define SMBB BIT(1)
187#define SMBBP BIT(2)
188#define SMBCL BIT(3)
189
David Keiteld681cda2012-10-02 15:44:21 -0700190/* Workaround flags */
191#define CHG_FLAGS_VCP_WA BIT(0)
192
David Keitel47185a62013-05-15 18:54:10 -0700193struct qpnp_chg_irq {
194 unsigned int irq;
195 unsigned long disabled;
196};
197
David Keitel6dc4ed42013-05-17 11:08:58 -0700198struct qpnp_chg_regulator {
199 struct regulator_desc rdesc;
200 struct regulator_dev *rdev;
201};
202
David Keitel80668952012-07-27 14:25:49 -0700203/**
204 * struct qpnp_chg_chip - device information
205 * @dev: device pointer to access the parent
206 * @spmi: spmi pointer to access spmi information
207 * @chgr_base: charger peripheral base address
208 * @buck_base: buck peripheral base address
209 * @bat_if_base: battery interface peripheral base address
210 * @usb_chgpth_base: USB charge path peripheral base address
211 * @dc_chgpth_base: DC charge path peripheral base address
212 * @boost_base: boost peripheral base address
213 * @misc_base: misc peripheral base address
214 * @freq_base: freq peripheral base address
David Keitel454ee842013-03-08 16:19:11 -0800215 * @bat_is_cool: indicates that battery is cool
216 * @bat_is_warm: indicates that battery is warm
David Keitel80668952012-07-27 14:25:49 -0700217 * @chg_done: indicates that charging is completed
218 * @usb_present: present status of usb
219 * @dc_present: present status of dc
David Keitel42ae0aa2013-03-08 16:20:10 -0800220 * @batt_present: present status of battery
David Keitel3dd5e0f2012-12-12 18:12:36 -0800221 * @use_default_batt_values: flag to report default battery properties
David Keitel80668952012-07-27 14:25:49 -0700222 * @max_voltage_mv: the max volts the batt should be charged up to
David Keitel5d44fa52012-12-03 16:37:31 -0800223 * @min_voltage_mv: min battery voltage before turning the FET on
David Keitel454ee842013-03-08 16:19:11 -0800224 * @max_bat_chg_current: maximum battery charge current in mA
225 * @warm_bat_chg_ma: warm battery maximum charge current in mA
226 * @cool_bat_chg_ma: cool battery maximum charge current in mA
227 * @warm_bat_mv: warm temperature battery target voltage
228 * @cool_bat_mv: cool temperature battery target voltage
229 * @resume_delta_mv: voltage delta at which battery resumes charging
David Keitel80668952012-07-27 14:25:49 -0700230 * @term_current: the charging based term current
David Keitel5d44fa52012-12-03 16:37:31 -0800231 * @safe_current: battery safety current setting
David Keitel22ed2232013-01-28 11:04:07 -0800232 * @maxinput_usb_ma: Maximum Input current USB
233 * @maxinput_dc_ma: Maximum Input current DC
David Keitel0c1a4532013-03-21 16:39:06 -0700234 * @warm_bat_decidegc Warm battery temperature in degree Celsius
235 * @cool_bat_decidegc Cool battery temperature in degree Celsius
David Keitel80668952012-07-27 14:25:49 -0700236 * @revision: PMIC revision
David Keitelfe51cb92013-04-02 19:42:58 -0700237 * @type: SMBB type
238 * @tchg_mins maximum allowed software initiated charge time
David Keitelbe208252013-01-31 14:49:25 -0800239 * @thermal_levels amount of thermal mitigation levels
240 * @thermal_mitigation thermal mitigation level values
241 * @therm_lvl_sel thermal mitigation level selection
David Keitel80668952012-07-27 14:25:49 -0700242 * @dc_psy power supply to export information to userspace
243 * @usb_psy power supply to export information to userspace
244 * @bms_psy power supply to export information to userspace
245 * @batt_psy: power supply to export information to userspace
David Keiteld681cda2012-10-02 15:44:21 -0700246 * @flags: flags to activate specific workarounds
247 * throughout the driver
David Keitel80668952012-07-27 14:25:49 -0700248 *
249 */
250struct qpnp_chg_chip {
251 struct device *dev;
252 struct spmi_device *spmi;
253 u16 chgr_base;
254 u16 buck_base;
255 u16 bat_if_base;
256 u16 usb_chgpth_base;
257 u16 dc_chgpth_base;
258 u16 boost_base;
259 u16 misc_base;
260 u16 freq_base;
David Keitel47185a62013-05-15 18:54:10 -0700261 struct qpnp_chg_irq usbin_valid;
262 struct qpnp_chg_irq dcin_valid;
263 struct qpnp_chg_irq chg_gone;
264 struct qpnp_chg_irq chg_fastchg;
265 struct qpnp_chg_irq chg_trklchg;
266 struct qpnp_chg_irq chg_failed;
267 struct qpnp_chg_irq chg_vbatdet_lo;
268 struct qpnp_chg_irq batt_pres;
David Keitel454ee842013-03-08 16:19:11 -0800269 bool bat_is_cool;
270 bool bat_is_warm;
David Keitel80668952012-07-27 14:25:49 -0700271 bool chg_done;
272 bool usb_present;
273 bool dc_present;
David Keitel42ae0aa2013-03-08 16:20:10 -0800274 bool batt_present;
David Keitel03ee6b52012-10-22 12:25:19 -0700275 bool charging_disabled;
David Keitel3dd5e0f2012-12-12 18:12:36 -0800276 bool use_default_batt_values;
David Keitel8b68d2d2013-05-14 23:36:51 -0700277 bool duty_cycle_100p;
David Keitel796882d2013-05-14 18:01:11 -0700278 unsigned int bpd_detection;
David Keitel80668952012-07-27 14:25:49 -0700279 unsigned int max_bat_chg_current;
David Keitel454ee842013-03-08 16:19:11 -0800280 unsigned int warm_bat_chg_ma;
281 unsigned int cool_bat_chg_ma;
David Keitel80668952012-07-27 14:25:49 -0700282 unsigned int safe_voltage_mv;
283 unsigned int max_voltage_mv;
284 unsigned int min_voltage_mv;
David Keitel454ee842013-03-08 16:19:11 -0800285 unsigned int warm_bat_mv;
286 unsigned int cool_bat_mv;
287 unsigned int resume_delta_mv;
David Keitel9fd07382013-05-02 15:37:44 -0700288 int term_current;
David Keitel22ed2232013-01-28 11:04:07 -0800289 unsigned int maxinput_usb_ma;
290 unsigned int maxinput_dc_ma;
David Keitel0c1a4532013-03-21 16:39:06 -0700291 unsigned int warm_bat_decidegc;
292 unsigned int cool_bat_decidegc;
David Keitel5d44fa52012-12-03 16:37:31 -0800293 unsigned int safe_current;
David Keitel80668952012-07-27 14:25:49 -0700294 unsigned int revision;
David Keitelfe51cb92013-04-02 19:42:58 -0700295 unsigned int type;
296 unsigned int tchg_mins;
David Keitelbe208252013-01-31 14:49:25 -0800297 unsigned int thermal_levels;
298 unsigned int therm_lvl_sel;
299 unsigned int *thermal_mitigation;
David Keitel80668952012-07-27 14:25:49 -0700300 struct power_supply dc_psy;
301 struct power_supply *usb_psy;
302 struct power_supply *bms_psy;
303 struct power_supply batt_psy;
David Keiteld681cda2012-10-02 15:44:21 -0700304 uint32_t flags;
David Keitel454ee842013-03-08 16:19:11 -0800305 struct qpnp_adc_tm_btm_param adc_param;
David Keitel79f4c932013-04-03 16:08:39 -0700306 struct work_struct adc_measure_work;
David Keitel344c6972013-04-09 19:28:21 -0700307 struct delayed_work arb_stop_work;
David Keitel9fd07382013-05-02 15:37:44 -0700308 struct delayed_work eoc_work;
309 struct wake_lock eoc_wake_lock;
David Keitel6dc4ed42013-05-17 11:08:58 -0700310 struct qpnp_chg_regulator otg_vreg;
311 struct qpnp_chg_regulator boost_vreg;
David Keitel80668952012-07-27 14:25:49 -0700312};
313
David Keitel47185a62013-05-15 18:54:10 -0700314
David Keitel80668952012-07-27 14:25:49 -0700315static struct of_device_id qpnp_charger_match_table[] = {
316 { .compatible = QPNP_CHARGER_DEV_NAME, },
317 {}
318};
319
David Keitel796882d2013-05-14 18:01:11 -0700320#define BPD_MAX 3
321
322static const char *bpd_list[BPD_MAX] = {
323 "bpd_thm",
324 "bpd_id",
325 "bpd_thm_id",
326};
327
328static inline int
329get_bpd(const char *name)
330{
331 int i = 0;
332 for (i = 0 ; i < BPD_MAX; i++) {
333 if (strcmp(name, bpd_list[i]) == 0)
334 return i;
335 }
336 return -EINVAL;
337}
338
David Keitel80668952012-07-27 14:25:49 -0700339static int
340qpnp_chg_read(struct qpnp_chg_chip *chip, u8 *val,
341 u16 base, int count)
342{
343 int rc;
344 struct spmi_device *spmi = chip->spmi;
345
346 rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val,
347 count);
348 if (rc) {
349 pr_err("SPMI read failed base=0x%02x sid=0x%02x rc=%d\n", base,
350 spmi->sid, rc);
351 return rc;
352 }
353 return 0;
354}
355
356static int
357qpnp_chg_write(struct qpnp_chg_chip *chip, u8 *val,
358 u16 base, int count)
359{
360 int rc;
361 struct spmi_device *spmi = chip->spmi;
362
363 rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val,
364 count);
365 if (rc) {
366 pr_err("write failed base=0x%02x sid=0x%02x rc=%d\n",
367 base, spmi->sid, rc);
368 return rc;
369 }
370
371 return 0;
372}
373
374static int
375qpnp_chg_masked_write(struct qpnp_chg_chip *chip, u16 base,
376 u8 mask, u8 val, int count)
377{
378 int rc;
379 u8 reg;
380
381 rc = qpnp_chg_read(chip, &reg, base, count);
382 if (rc) {
383 pr_err("spmi read failed: addr=%03X, rc=%d\n", base, rc);
384 return rc;
385 }
386 pr_debug("addr = 0x%x read 0x%x\n", base, reg);
387
388 reg &= ~mask;
389 reg |= val & mask;
390
391 pr_debug("Writing 0x%x\n", reg);
392
393 rc = qpnp_chg_write(chip, &reg, base, count);
394 if (rc) {
395 pr_err("spmi write failed: addr=%03X, rc=%d\n", base, rc);
396 return rc;
397 }
398
399 return 0;
400}
401
David Keitel47185a62013-05-15 18:54:10 -0700402static void
403qpnp_chg_enable_irq(struct qpnp_chg_irq *irq)
404{
405 if (__test_and_clear_bit(0, &irq->disabled)) {
406 pr_debug("number = %d\n", irq->irq);
407 enable_irq(irq->irq);
408 }
409}
410
411static void
412qpnp_chg_disable_irq(struct qpnp_chg_irq *irq)
413{
414 if (!__test_and_set_bit(0, &irq->disabled)) {
415 pr_debug("number = %d\n", irq->irq);
416 disable_irq_nosync(irq->irq);
417 }
418}
419
David Keitel6f865cd2012-11-30 15:04:32 -0800420#define USB_OTG_EN_BIT BIT(0)
421static int
422qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
423{
424 u8 usb_otg_en;
425 int rc;
426
427 rc = qpnp_chg_read(chip, &usb_otg_en,
428 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
429 1);
430
431 if (rc) {
432 pr_err("spmi read failed: addr=%03X, rc=%d\n",
433 chip->usb_chgpth_base + CHGR_STATUS, rc);
434 return rc;
435 }
436 pr_debug("usb otg en 0x%x\n", usb_otg_en);
437
438 return (usb_otg_en & USB_OTG_EN_BIT) ? 1 : 0;
439}
440
David Keitel42ae0aa2013-03-08 16:20:10 -0800441static int
David Keitel6dc4ed42013-05-17 11:08:58 -0700442qpnp_chg_is_boost_en_set(struct qpnp_chg_chip *chip)
443{
444 u8 boost_en_ctl;
445 int rc;
446
447 rc = qpnp_chg_read(chip, &boost_en_ctl,
448 chip->boost_base + BOOST_ENABLE_CONTROL, 1);
449 if (rc) {
450 pr_err("spmi read failed: addr=%03X, rc=%d\n",
451 chip->boost_base + BOOST_ENABLE_CONTROL, rc);
452 return rc;
453 }
454
455 pr_debug("boost en 0x%x\n", boost_en_ctl);
456
457 return (boost_en_ctl & BOOST_PWR_EN) ? 1 : 0;
458}
459
460static int
David Keitel42ae0aa2013-03-08 16:20:10 -0800461qpnp_chg_is_batt_present(struct qpnp_chg_chip *chip)
462{
463 u8 batt_pres_rt_sts;
464 int rc;
465
466 rc = qpnp_chg_read(chip, &batt_pres_rt_sts,
467 INT_RT_STS(chip->bat_if_base), 1);
468 if (rc) {
469 pr_err("spmi read failed: addr=%03X, rc=%d\n",
470 INT_RT_STS(chip->bat_if_base), rc);
471 return rc;
472 }
473
474 return (batt_pres_rt_sts & BATT_PRES_IRQ) ? 1 : 0;
475}
476
David Keiteld681cda2012-10-02 15:44:21 -0700477#define USB_VALID_BIT BIT(7)
David Keitel80668952012-07-27 14:25:49 -0700478static int
479qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip)
480{
481 u8 usbin_valid_rt_sts;
482 int rc;
483
484 rc = qpnp_chg_read(chip, &usbin_valid_rt_sts,
David Keiteld681cda2012-10-02 15:44:21 -0700485 chip->usb_chgpth_base + CHGR_STATUS , 1);
David Keitel80668952012-07-27 14:25:49 -0700486
487 if (rc) {
488 pr_err("spmi read failed: addr=%03X, rc=%d\n",
David Keiteld681cda2012-10-02 15:44:21 -0700489 chip->usb_chgpth_base + CHGR_STATUS, rc);
David Keitel80668952012-07-27 14:25:49 -0700490 return rc;
491 }
492 pr_debug("chgr usb sts 0x%x\n", usbin_valid_rt_sts);
493
David Keiteld681cda2012-10-02 15:44:21 -0700494 return (usbin_valid_rt_sts & USB_VALID_BIT) ? 1 : 0;
David Keitel80668952012-07-27 14:25:49 -0700495}
496
497static int
498qpnp_chg_is_dc_chg_plugged_in(struct qpnp_chg_chip *chip)
499{
500 u8 dcin_valid_rt_sts;
501 int rc;
502
David Keitelf2170cc2013-02-20 17:49:03 -0800503 if (!chip->dc_chgpth_base)
504 return 0;
505
David Keitel80668952012-07-27 14:25:49 -0700506 rc = qpnp_chg_read(chip, &dcin_valid_rt_sts,
507 INT_RT_STS(chip->dc_chgpth_base), 1);
508 if (rc) {
509 pr_err("spmi read failed: addr=%03X, rc=%d\n",
510 INT_RT_STS(chip->dc_chgpth_base), rc);
511 return rc;
512 }
513
514 return (dcin_valid_rt_sts & DCIN_VALID_IRQ) ? 1 : 0;
515}
516
David Keitel22ed2232013-01-28 11:04:07 -0800517#define QPNP_CHG_I_MAX_MIN_100 100
518#define QPNP_CHG_I_MAX_MIN_150 150
519#define QPNP_CHG_I_MAX_MIN_MA 200
520#define QPNP_CHG_I_MAX_MAX_MA 2500
521#define QPNP_CHG_I_MAXSTEP_MA 100
522static int
523qpnp_chg_idcmax_set(struct qpnp_chg_chip *chip, int mA)
524{
525 int rc = 0;
526 u8 dc = 0;
527
528 if (mA < QPNP_CHG_I_MAX_MIN_100
529 || mA > QPNP_CHG_I_MAX_MAX_MA) {
530 pr_err("bad mA=%d asked to set\n", mA);
531 return -EINVAL;
532 }
533
534 if (mA == QPNP_CHG_I_MAX_MIN_100) {
535 dc = 0x00;
536 pr_debug("current=%d setting %02x\n", mA, dc);
537 return qpnp_chg_write(chip, &dc,
538 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
539 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
540 dc = 0x01;
541 pr_debug("current=%d setting %02x\n", mA, dc);
542 return qpnp_chg_write(chip, &dc,
543 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
544 }
545
546 dc = mA / QPNP_CHG_I_MAXSTEP_MA;
547
548 pr_debug("current=%d setting 0x%x\n", mA, dc);
549 rc = qpnp_chg_write(chip, &dc,
550 chip->dc_chgpth_base + CHGR_I_MAX_REG, 1);
551
552 return rc;
553}
554
David Keitel80668952012-07-27 14:25:49 -0700555static int
556qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
557{
David Keiteld681cda2012-10-02 15:44:21 -0700558 int rc = 0;
559 u8 usb_reg = 0, temp = 8;
David Keitel80668952012-07-27 14:25:49 -0700560
David Keitel22ed2232013-01-28 11:04:07 -0800561 if (mA < QPNP_CHG_I_MAX_MIN_100
562 || mA > QPNP_CHG_I_MAX_MAX_MA) {
David Keitel80668952012-07-27 14:25:49 -0700563 pr_err("bad mA=%d asked to set\n", mA);
564 return -EINVAL;
565 }
566
David Keitel22ed2232013-01-28 11:04:07 -0800567 if (mA == QPNP_CHG_I_MAX_MIN_100) {
568 usb_reg = 0x00;
569 pr_debug("current=%d setting %02x\n", mA, usb_reg);
570 return qpnp_chg_write(chip, &usb_reg,
571 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
572 } else if (mA == QPNP_CHG_I_MAX_MIN_150) {
573 usb_reg = 0x01;
574 pr_debug("current=%d setting %02x\n", mA, usb_reg);
575 return qpnp_chg_write(chip, &usb_reg,
576 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
577 }
578
579 /* Impose input current limit */
580 if (chip->maxinput_usb_ma)
581 mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
582
583 usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
David Keitel80668952012-07-27 14:25:49 -0700584
David Keiteld681cda2012-10-02 15:44:21 -0700585 if (chip->flags & CHG_FLAGS_VCP_WA) {
586 temp = 0xA5;
587 rc = qpnp_chg_write(chip, &temp,
588 chip->buck_base + SEC_ACCESS, 1);
589 rc = qpnp_chg_masked_write(chip,
590 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
591 0x0C, 0x0C, 1);
592 }
593
David Keitel80668952012-07-27 14:25:49 -0700594 pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
David Keiteld681cda2012-10-02 15:44:21 -0700595 rc = qpnp_chg_write(chip, &usb_reg,
David Keitel22ed2232013-01-28 11:04:07 -0800596 chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
David Keiteld681cda2012-10-02 15:44:21 -0700597
598 if (chip->flags & CHG_FLAGS_VCP_WA) {
599 temp = 0xA5;
600 udelay(200);
601 rc = qpnp_chg_write(chip, &temp,
602 chip->buck_base + SEC_ACCESS, 1);
603 rc = qpnp_chg_masked_write(chip,
604 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_3,
605 0x0C, 0x00, 1);
606 }
607
608 return rc;
609}
610
611#define USB_SUSPEND_BIT BIT(0)
612static int
613qpnp_chg_usb_suspend_enable(struct qpnp_chg_chip *chip, int enable)
614{
615 return qpnp_chg_masked_write(chip,
616 chip->usb_chgpth_base + CHGR_USB_USB_SUSP,
617 USB_SUSPEND_BIT,
618 enable ? USB_SUSPEND_BIT : 0, 1);
David Keitel80668952012-07-27 14:25:49 -0700619}
620
David Keitel344c6972013-04-09 19:28:21 -0700621static int
622qpnp_chg_charge_en(struct qpnp_chg_chip *chip, int enable)
623{
624 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
625 CHGR_CHG_EN,
626 enable ? CHGR_CHG_EN : 0, 1);
627}
628
629static int
630qpnp_chg_force_run_on_batt(struct qpnp_chg_chip *chip, int disable)
631{
632 /* Don't run on battery for batteryless hardware */
633 if (chip->use_default_batt_values)
634 return 0;
David Keitel4d66ea02013-04-30 10:57:58 -0700635 /* Don't force on battery if battery is not present */
636 if (!qpnp_chg_is_batt_present(chip))
637 return 0;
David Keitel344c6972013-04-09 19:28:21 -0700638
639 /* This bit forces the charger to run off of the battery rather
640 * than a connected charger */
641 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
642 CHGR_ON_BAT_FORCE_BIT,
643 disable ? CHGR_ON_BAT_FORCE_BIT : 0, 1);
644}
645
David Keitel8b68d2d2013-05-14 23:36:51 -0700646#define BUCK_DUTY_MASK_100P 0x30
647static int
648qpnp_buck_set_100_duty_cycle_enable(struct qpnp_chg_chip *chip, int enable)
649{
650 int rc;
651
652 pr_debug("enable: %d\n", enable);
653
654 rc = qpnp_chg_masked_write(chip,
655 chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
656 if (rc) {
657 pr_debug("failed to write sec access rc=%d\n", rc);
658 return rc;
659 }
660
661 rc = qpnp_chg_masked_write(chip,
662 chip->buck_base + BUCK_TEST_SMBC_MODES,
663 BUCK_DUTY_MASK_100P, enable ? 0x00 : 0x10, 1);
664 if (rc) {
665 pr_debug("failed enable 100p duty cycle rc=%d\n", rc);
666 return rc;
667 }
668
669 return rc;
670}
671
David Keitel9fd07382013-05-02 15:37:44 -0700672#define COMPATATOR_OVERRIDE_0 0x80
673static int
674qpnp_chg_toggle_chg_done_logic(struct qpnp_chg_chip *chip, int enable)
675{
676 int rc;
677
678 pr_debug("toggle: %d\n", enable);
679
680 rc = qpnp_chg_masked_write(chip,
681 chip->buck_base + SEC_ACCESS, 0xA5, 0xA5, 1);
682 if (rc) {
683 pr_debug("failed to write sec access rc=%d\n", rc);
684 return rc;
685 }
686
687 rc = qpnp_chg_masked_write(chip,
688 chip->buck_base + CHGR_BUCK_COMPARATOR_OVRIDE_1,
689 0xC0, enable ? 0x00 : COMPATATOR_OVERRIDE_0, 1);
690 if (rc) {
691 pr_debug("failed to toggle chg done override rc=%d\n", rc);
692 return rc;
693 }
694
695 return rc;
696}
697
698#define QPNP_CHG_VBATDET_MIN_MV 3240
699#define QPNP_CHG_VBATDET_MAX_MV 5780
700#define QPNP_CHG_VBATDET_STEP_MV 20
701static int
702qpnp_chg_vbatdet_set(struct qpnp_chg_chip *chip, int vbatdet_mv)
703{
704 u8 temp;
705
706 if (vbatdet_mv < QPNP_CHG_VBATDET_MIN_MV
707 || vbatdet_mv > QPNP_CHG_VBATDET_MAX_MV) {
708 pr_err("bad mV=%d asked to set\n", vbatdet_mv);
709 return -EINVAL;
710 }
711 temp = (vbatdet_mv - QPNP_CHG_VBATDET_MIN_MV)
712 / QPNP_CHG_VBATDET_STEP_MV;
713
714 pr_debug("voltage=%d setting %02x\n", vbatdet_mv, temp);
715 return qpnp_chg_write(chip, &temp,
716 chip->chgr_base + CHGR_VBAT_DET, 1);
717}
718
David Keitel344c6972013-04-09 19:28:21 -0700719static void
720qpnp_arb_stop_work(struct work_struct *work)
721{
722 struct delayed_work *dwork = to_delayed_work(work);
723 struct qpnp_chg_chip *chip = container_of(dwork,
724 struct qpnp_chg_chip, arb_stop_work);
725
David Keitel9fd07382013-05-02 15:37:44 -0700726 if (!chip->chg_done)
727 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitel344c6972013-04-09 19:28:21 -0700728 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
729}
730
731static void
732qpnp_bat_if_adc_measure_work(struct work_struct *work)
David Keitel79f4c932013-04-03 16:08:39 -0700733{
734 struct qpnp_chg_chip *chip = container_of(work,
735 struct qpnp_chg_chip, adc_measure_work);
736
737 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
738 pr_err("request ADC error\n");
739}
740
David Keitel9fd07382013-05-02 15:37:44 -0700741#define EOC_CHECK_PERIOD_MS 10000
742static irqreturn_t
743qpnp_chg_vbatdet_lo_irq_handler(int irq, void *_chip)
744{
745 struct qpnp_chg_chip *chip = _chip;
746 u8 chg_sts = 0;
747 int rc;
748
749 pr_debug("vbatdet-lo triggered\n");
750
751 rc = qpnp_chg_read(chip, &chg_sts, INT_RT_STS(chip->chgr_base), 1);
752 if (rc)
753 pr_err("failed to read chg_sts rc=%d\n", rc);
754
755 pr_debug("chg_done chg_sts: 0x%x triggered\n", chg_sts);
756 if (!chip->charging_disabled && (chg_sts & FAST_CHG_ON_IRQ)) {
757 schedule_delayed_work(&chip->eoc_work,
758 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
759 wake_lock(&chip->eoc_wake_lock);
David Keitel47185a62013-05-15 18:54:10 -0700760 qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -0700761 } else {
762 qpnp_chg_charge_en(chip, !chip->charging_disabled);
763 }
764
765 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700766 if (chip->dc_chgpth_base)
767 power_supply_changed(&chip->dc_psy);
768 if (chip->bat_if_base)
769 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700770 return IRQ_HANDLED;
771}
772
David Keitel344c6972013-04-09 19:28:21 -0700773#define ARB_STOP_WORK_MS 1000
774static irqreturn_t
775qpnp_chg_usb_chg_gone_irq_handler(int irq, void *_chip)
776{
777 struct qpnp_chg_chip *chip = _chip;
778
779 pr_debug("chg_gone triggered\n");
780 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
781 qpnp_chg_charge_en(chip, 0);
David Keitel9fd07382013-05-02 15:37:44 -0700782 qpnp_chg_force_run_on_batt(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -0700783 schedule_delayed_work(&chip->arb_stop_work,
784 msecs_to_jiffies(ARB_STOP_WORK_MS));
785 }
786
787 return IRQ_HANDLED;
788}
789
David Keitel80668952012-07-27 14:25:49 -0700790#define ENUM_T_STOP_BIT BIT(0)
791static irqreturn_t
792qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
793{
794 struct qpnp_chg_chip *chip = _chip;
David Keitel6f865cd2012-11-30 15:04:32 -0800795 int usb_present, host_mode;
David Keitel80668952012-07-27 14:25:49 -0700796
797 usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
David Keitel6f865cd2012-11-30 15:04:32 -0800798 host_mode = qpnp_chg_is_otg_en_set(chip);
799 pr_debug("usbin-valid triggered: %d host_mode: %d\n",
800 usb_present, host_mode);
801
802 /* In host mode notifications cmoe from USB supply */
803 if (host_mode)
804 return IRQ_HANDLED;
David Keitel80668952012-07-27 14:25:49 -0700805
806 if (chip->usb_present ^ usb_present) {
807 chip->usb_present = usb_present;
David Keitel9fd07382013-05-02 15:37:44 -0700808 if (!usb_present) {
David Keitel344c6972013-04-09 19:28:21 -0700809 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel9fd07382013-05-02 15:37:44 -0700810 chip->chg_done = false;
811 } else {
812 schedule_delayed_work(&chip->eoc_work,
813 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
814 }
David Keitel344c6972013-04-09 19:28:21 -0700815
David Keitel9fd07382013-05-02 15:37:44 -0700816 power_supply_set_present(chip->usb_psy, chip->usb_present);
David Keitel80668952012-07-27 14:25:49 -0700817 }
818
819 return IRQ_HANDLED;
820}
821
David Keitel7450dcd2013-01-29 18:41:41 -0800822static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800823qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
824{
825 struct qpnp_chg_chip *chip = _chip;
826 int batt_present;
827
828 batt_present = qpnp_chg_is_batt_present(chip);
829 pr_debug("batt-pres triggered: %d\n", batt_present);
830
831 if (chip->batt_present ^ batt_present) {
832 chip->batt_present = batt_present;
833 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700834 power_supply_changed(chip->usb_psy);
David Keitel0c1a4532013-03-21 16:39:06 -0700835
836 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
837 && batt_present) {
David Keitel79f4c932013-04-03 16:08:39 -0700838 schedule_work(&chip->adc_measure_work);
David Keitel0c1a4532013-03-21 16:39:06 -0700839 }
David Keitel42ae0aa2013-03-08 16:20:10 -0800840 }
841
842 return IRQ_HANDLED;
843}
844
845static irqreturn_t
David Keitel7450dcd2013-01-29 18:41:41 -0800846qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
847{
848 struct qpnp_chg_chip *chip = _chip;
849 int dc_present;
850
851 dc_present = qpnp_chg_is_dc_chg_plugged_in(chip);
852 pr_debug("dcin-valid triggered: %d\n", dc_present);
853
854 if (chip->dc_present ^ dc_present) {
855 chip->dc_present = dc_present;
David Keitel9fd07382013-05-02 15:37:44 -0700856 if (!dc_present)
857 chip->chg_done = false;
858 else
859 schedule_delayed_work(&chip->eoc_work,
860 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
David Keitel7450dcd2013-01-29 18:41:41 -0800861 power_supply_changed(&chip->dc_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700862 power_supply_changed(&chip->batt_psy);
David Keitel7450dcd2013-01-29 18:41:41 -0800863 }
864
865 return IRQ_HANDLED;
866}
867
David Keitel80668952012-07-27 14:25:49 -0700868#define CHGR_CHG_FAILED_BIT BIT(7)
869static irqreturn_t
870qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
871{
872 struct qpnp_chg_chip *chip = _chip;
David Keitel4429b1f2012-10-18 10:42:50 -0700873 int rc;
David Keitel80668952012-07-27 14:25:49 -0700874
David Keitel9fd07382013-05-02 15:37:44 -0700875 pr_debug("chg_failed triggered\n");
876
David Keitel80668952012-07-27 14:25:49 -0700877 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -0700878 chip->chgr_base + CHGR_CHG_FAILED,
David Keitel80668952012-07-27 14:25:49 -0700879 CHGR_CHG_FAILED_BIT,
880 CHGR_CHG_FAILED_BIT, 1);
881 if (rc)
882 pr_err("Failed to write chg_fail clear bit!\n");
883
David Keiteldbcef092013-05-14 14:48:30 -0700884 if (chip->bat_if_base)
885 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700886 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700887 if (chip->dc_chgpth_base)
888 power_supply_changed(&chip->dc_psy);
David Keitel80668952012-07-27 14:25:49 -0700889 return IRQ_HANDLED;
890}
891
892static irqreturn_t
David Keitel42ae0aa2013-03-08 16:20:10 -0800893qpnp_chg_chgr_chg_trklchg_irq_handler(int irq, void *_chip)
894{
895 struct qpnp_chg_chip *chip = _chip;
896
897 pr_debug("TRKL IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800898
899 chip->chg_done = false;
David Keiteldbcef092013-05-14 14:48:30 -0700900 if (chip->bat_if_base)
901 power_supply_changed(&chip->batt_psy);
David Keitel42ae0aa2013-03-08 16:20:10 -0800902
903 return IRQ_HANDLED;
904}
905
906static irqreturn_t
907qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
908{
909 struct qpnp_chg_chip *chip = _chip;
910
911 pr_debug("FAST_CHG IRQ triggered\n");
David Keitelc9ffe842013-01-25 19:37:51 -0800912 chip->chg_done = false;
David Keiteldbcef092013-05-14 14:48:30 -0700913 if (chip->bat_if_base)
914 power_supply_changed(&chip->batt_psy);
David Keitel9fd07382013-05-02 15:37:44 -0700915 power_supply_changed(chip->usb_psy);
David Keiteldbcef092013-05-14 14:48:30 -0700916 if (chip->dc_chgpth_base)
917 power_supply_changed(&chip->dc_psy);
David Keitel47185a62013-05-15 18:54:10 -0700918 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel42ae0aa2013-03-08 16:20:10 -0800919
920 return IRQ_HANDLED;
921}
922
David Keitel03ee6b52012-10-22 12:25:19 -0700923static int
924qpnp_batt_property_is_writeable(struct power_supply *psy,
925 enum power_supply_property psp)
926{
927 switch (psp) {
928 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitelbe208252013-01-31 14:49:25 -0800929 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
David Keitel03ee6b52012-10-22 12:25:19 -0700930 return 1;
931 default:
932 break;
933 }
934
935 return 0;
936}
937
David Keitel6f865cd2012-11-30 15:04:32 -0800938static int
David Keitelbe208252013-01-31 14:49:25 -0800939qpnp_chg_buck_control(struct qpnp_chg_chip *chip, int enable)
940{
941 int rc;
942
943 if (chip->charging_disabled && enable) {
944 pr_debug("Charging disabled\n");
945 return 0;
946 }
947
948 rc = qpnp_chg_charge_en(chip, enable);
949 if (rc) {
950 pr_err("Failed to control charging %d\n", rc);
951 return rc;
952 }
953
954 rc = qpnp_chg_force_run_on_batt(chip, !enable);
955 if (rc)
956 pr_err("Failed to control charging %d\n", rc);
957
958 return rc;
959}
960
David Keitel454ee842013-03-08 16:19:11 -0800961static int
962switch_usb_to_charge_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800963{
964 int rc;
965
966 pr_debug("switch to charge mode\n");
967 if (!qpnp_chg_is_otg_en_set(chip))
968 return 0;
969
970 /* enable usb ovp fet */
971 rc = qpnp_chg_masked_write(chip,
972 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
973 USB_OTG_EN_BIT,
974 0, 1);
975 if (rc) {
976 pr_err("Failed to turn on usb ovp rc = %d\n", rc);
977 return rc;
978 }
979
980 rc = qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
981 if (rc) {
982 pr_err("Failed re-enable charging rc = %d\n", rc);
983 return rc;
984 }
985
986 return 0;
987}
988
David Keitel454ee842013-03-08 16:19:11 -0800989static int
990switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
David Keitel6f865cd2012-11-30 15:04:32 -0800991{
992 int rc;
993
994 pr_debug("switch to host mode\n");
995 if (qpnp_chg_is_otg_en_set(chip))
996 return 0;
997
998 rc = qpnp_chg_force_run_on_batt(chip, 1);
999 if (rc) {
1000 pr_err("Failed to disable charging rc = %d\n", rc);
1001 return rc;
1002 }
1003
1004 /* force usb ovp fet off */
1005 rc = qpnp_chg_masked_write(chip,
1006 chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
1007 USB_OTG_EN_BIT,
1008 USB_OTG_EN_BIT, 1);
1009 if (rc) {
1010 pr_err("Failed to turn off usb ovp rc = %d\n", rc);
1011 return rc;
1012 }
1013
1014 return 0;
1015}
1016
David Keitel80668952012-07-27 14:25:49 -07001017static enum power_supply_property pm_power_props_mains[] = {
1018 POWER_SUPPLY_PROP_PRESENT,
1019 POWER_SUPPLY_PROP_ONLINE,
1020};
1021
1022static enum power_supply_property msm_batt_power_props[] = {
David Keitelb80eda82012-10-15 10:49:11 -07001023 POWER_SUPPLY_PROP_CHARGING_ENABLED,
David Keitel80668952012-07-27 14:25:49 -07001024 POWER_SUPPLY_PROP_STATUS,
1025 POWER_SUPPLY_PROP_CHARGE_TYPE,
1026 POWER_SUPPLY_PROP_HEALTH,
1027 POWER_SUPPLY_PROP_PRESENT,
1028 POWER_SUPPLY_PROP_TECHNOLOGY,
1029 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
1030 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
1031 POWER_SUPPLY_PROP_VOLTAGE_NOW,
1032 POWER_SUPPLY_PROP_CAPACITY,
1033 POWER_SUPPLY_PROP_CURRENT_NOW,
1034 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
1035 POWER_SUPPLY_PROP_TEMP,
David Keitelbe208252013-01-31 14:49:25 -08001036 POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
David Keitel80668952012-07-27 14:25:49 -07001037};
1038
1039static char *pm_power_supplied_to[] = {
1040 "battery",
1041};
1042
Xiaozhe Shi890fbf42013-05-02 16:42:53 -07001043static char *pm_batt_supplied_to[] = {
1044 "bms",
1045};
1046
David Keitel80668952012-07-27 14:25:49 -07001047#define USB_WALL_THRESHOLD_MA 500
1048static int
1049qpnp_power_get_property_mains(struct power_supply *psy,
1050 enum power_supply_property psp,
1051 union power_supply_propval *val)
1052{
1053 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1054 dc_psy);
1055
1056 switch (psp) {
1057 case POWER_SUPPLY_PROP_PRESENT:
1058 case POWER_SUPPLY_PROP_ONLINE:
1059 val->intval = 0;
David Keitel03ee6b52012-10-22 12:25:19 -07001060 if (chip->charging_disabled)
David Keitel80668952012-07-27 14:25:49 -07001061 return 0;
1062
1063 val->intval = qpnp_chg_is_dc_chg_plugged_in(chip);
1064 break;
1065 default:
1066 return -EINVAL;
1067 }
1068 return 0;
1069}
1070
1071static int
1072get_prop_battery_voltage_now(struct qpnp_chg_chip *chip)
1073{
1074 int rc = 0;
1075 struct qpnp_vadc_result results;
1076
David Keitelfe51cb92013-04-02 19:42:58 -07001077 if (chip->revision == 0 && chip->type == SMBB) {
1078 pr_err("vbat reading not supported for 1.0 rc=%d\n", rc);
1079 return 0;
1080 } else {
David Keitel80668952012-07-27 14:25:49 -07001081 rc = qpnp_vadc_read(VBAT_SNS, &results);
1082 if (rc) {
1083 pr_err("Unable to read vbat rc=%d\n", rc);
1084 return 0;
1085 }
1086 return results.physical;
David Keitel80668952012-07-27 14:25:49 -07001087 }
1088}
1089
1090#define BATT_PRES_BIT BIT(7)
1091static int
1092get_prop_batt_present(struct qpnp_chg_chip *chip)
1093{
1094 u8 batt_present;
1095 int rc;
1096
1097 rc = qpnp_chg_read(chip, &batt_present,
1098 chip->bat_if_base + CHGR_BAT_IF_PRES_STATUS, 1);
1099 if (rc) {
1100 pr_err("Couldn't read battery status read failed rc=%d\n", rc);
1101 return 0;
1102 };
1103 return (batt_present & BATT_PRES_BIT) ? 1 : 0;
1104}
1105
1106#define BATT_TEMP_HOT BIT(6)
1107#define BATT_TEMP_OK BIT(7)
1108static int
1109get_prop_batt_health(struct qpnp_chg_chip *chip)
1110{
1111 u8 batt_health;
1112 int rc;
1113
1114 rc = qpnp_chg_read(chip, &batt_health,
David Keiteld681cda2012-10-02 15:44:21 -07001115 chip->bat_if_base + CHGR_STATUS, 1);
David Keitel80668952012-07-27 14:25:49 -07001116 if (rc) {
1117 pr_err("Couldn't read battery health read failed rc=%d\n", rc);
1118 return POWER_SUPPLY_HEALTH_UNKNOWN;
1119 };
1120
1121 if (BATT_TEMP_OK & batt_health)
1122 return POWER_SUPPLY_HEALTH_GOOD;
1123 if (BATT_TEMP_HOT & batt_health)
1124 return POWER_SUPPLY_HEALTH_OVERHEAT;
1125 else
1126 return POWER_SUPPLY_HEALTH_COLD;
1127}
1128
1129static int
1130get_prop_charge_type(struct qpnp_chg_chip *chip)
1131{
1132 int rc;
1133 u8 chgr_sts;
1134
1135 if (!get_prop_batt_present(chip))
1136 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1137
1138 rc = qpnp_chg_read(chip, &chgr_sts,
1139 INT_RT_STS(chip->chgr_base), 1);
1140 if (rc) {
1141 pr_err("failed to read interrupt sts %d\n", rc);
1142 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1143 }
1144
1145 if (chgr_sts & TRKL_CHG_ON_IRQ)
1146 return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
1147 if (chgr_sts & FAST_CHG_ON_IRQ)
1148 return POWER_SUPPLY_CHARGE_TYPE_FAST;
1149
1150 return POWER_SUPPLY_CHARGE_TYPE_NONE;
1151}
1152
1153static int
1154get_prop_batt_status(struct qpnp_chg_chip *chip)
1155{
1156 int rc;
1157 u8 chgr_sts;
1158
David Keitel9fd07382013-05-02 15:37:44 -07001159 if ((qpnp_chg_is_usb_chg_plugged_in(chip) ||
1160 qpnp_chg_is_dc_chg_plugged_in(chip)) && chip->chg_done) {
David Keitelc9ffe842013-01-25 19:37:51 -08001161 return POWER_SUPPLY_STATUS_FULL;
David Keitel9fd07382013-05-02 15:37:44 -07001162 }
David Keitelc9ffe842013-01-25 19:37:51 -08001163
David Keitel9fd07382013-05-02 15:37:44 -07001164 rc = qpnp_chg_read(chip, &chgr_sts, INT_RT_STS(chip->chgr_base), 1);
David Keitel80668952012-07-27 14:25:49 -07001165 if (rc) {
1166 pr_err("failed to read interrupt sts %d\n", rc);
David Keitelc9ffe842013-01-25 19:37:51 -08001167 return POWER_SUPPLY_CHARGE_TYPE_NONE;
David Keitel80668952012-07-27 14:25:49 -07001168 }
1169
David Keitel80668952012-07-27 14:25:49 -07001170 if (chgr_sts & TRKL_CHG_ON_IRQ)
1171 return POWER_SUPPLY_STATUS_CHARGING;
1172 if (chgr_sts & FAST_CHG_ON_IRQ)
1173 return POWER_SUPPLY_STATUS_CHARGING;
1174
1175 return POWER_SUPPLY_STATUS_DISCHARGING;
1176}
1177
1178static int
1179get_prop_current_now(struct qpnp_chg_chip *chip)
1180{
1181 union power_supply_propval ret = {0,};
1182
1183 if (chip->bms_psy) {
1184 chip->bms_psy->get_property(chip->bms_psy,
1185 POWER_SUPPLY_PROP_CURRENT_NOW, &ret);
1186 return ret.intval;
1187 } else {
1188 pr_debug("No BMS supply registered return 0\n");
1189 }
1190
1191 return 0;
1192}
1193
1194static int
1195get_prop_full_design(struct qpnp_chg_chip *chip)
1196{
1197 union power_supply_propval ret = {0,};
1198
1199 if (chip->bms_psy) {
1200 chip->bms_psy->get_property(chip->bms_psy,
1201 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, &ret);
1202 return ret.intval;
1203 } else {
1204 pr_debug("No BMS supply registered return 0\n");
1205 }
1206
1207 return 0;
1208}
1209
1210#define DEFAULT_CAPACITY 50
1211static int
1212get_prop_capacity(struct qpnp_chg_chip *chip)
1213{
1214 union power_supply_propval ret = {0,};
1215
David Keitel3dd5e0f2012-12-12 18:12:36 -08001216 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1217 return DEFAULT_CAPACITY;
1218
David Keitel80668952012-07-27 14:25:49 -07001219 if (chip->bms_psy) {
1220 chip->bms_psy->get_property(chip->bms_psy,
1221 POWER_SUPPLY_PROP_CAPACITY, &ret);
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001222 if (ret.intval == 0) {
David Keiteleeca08f2013-05-17 16:40:46 -07001223 if (!qpnp_chg_is_usb_chg_plugged_in(chip)
1224 && !qpnp_chg_is_usb_chg_plugged_in(chip))
Abhijeet Dharmapurikar53ce35a2013-03-29 16:14:16 -07001225 pr_warn_ratelimited("Battery 0, CHG absent\n");
1226 }
David Keitel80668952012-07-27 14:25:49 -07001227 return ret.intval;
1228 } else {
1229 pr_debug("No BMS supply registered return 50\n");
1230 }
1231
1232 /* return default capacity to avoid userspace
1233 * from shutting down unecessarily */
1234 return DEFAULT_CAPACITY;
1235}
1236
David Keitel3dd5e0f2012-12-12 18:12:36 -08001237#define DEFAULT_TEMP 250
David Keitel80668952012-07-27 14:25:49 -07001238#define MAX_TOLERABLE_BATT_TEMP_DDC 680
1239static int
1240get_prop_batt_temp(struct qpnp_chg_chip *chip)
1241{
1242 int rc = 0;
1243 struct qpnp_vadc_result results;
1244
David Keitel3dd5e0f2012-12-12 18:12:36 -08001245 if (chip->use_default_batt_values || !get_prop_batt_present(chip))
1246 return DEFAULT_TEMP;
1247
David Keitel80668952012-07-27 14:25:49 -07001248 if (chip->revision > 0) {
1249 rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
1250 if (rc) {
1251 pr_debug("Unable to read batt temperature rc=%d\n", rc);
1252 return 0;
1253 }
1254 pr_debug("get_bat_temp %d %lld\n",
1255 results.adc_code, results.physical);
1256 return (int)results.physical;
1257 } else {
1258 pr_debug("batt temp not supported for PMIC 1.0 rc=%d\n", rc);
1259 }
1260
1261 /* return default temperature to avoid userspace
1262 * from shutting down unecessarily */
1263 return DEFAULT_TEMP;
1264}
1265
1266static void
1267qpnp_batt_external_power_changed(struct power_supply *psy)
1268{
1269 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1270 batt_psy);
1271 union power_supply_propval ret = {0,};
1272
1273 if (!chip->bms_psy)
1274 chip->bms_psy = power_supply_get_by_name("bms");
1275
1276 chip->usb_psy->get_property(chip->usb_psy,
1277 POWER_SUPPLY_PROP_ONLINE, &ret);
1278
David Keitelc69f2d62013-03-17 14:52:35 -07001279 /* Only honour requests while USB is present */
1280 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001281 chip->usb_psy->get_property(chip->usb_psy,
1282 POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
David Keitel87473252013-03-21 14:39:45 -07001283 if (ret.intval <= 2 && !chip->use_default_batt_values &&
1284 get_prop_batt_present(chip)) {
David Keitel359ab652013-03-21 17:46:00 -07001285 qpnp_chg_usb_suspend_enable(chip, 1);
David Keitel344c6972013-04-09 19:28:21 -07001286 qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
David Keitelc69f2d62013-03-17 14:52:35 -07001287 } else {
David Keiteld681cda2012-10-02 15:44:21 -07001288 qpnp_chg_usb_suspend_enable(chip, 0);
David Keitel359ab652013-03-21 17:46:00 -07001289 qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
David Keitelc69f2d62013-03-17 14:52:35 -07001290 }
David Keitel80668952012-07-27 14:25:49 -07001291 }
1292
1293 pr_debug("end of power supply changed\n");
1294 power_supply_changed(&chip->batt_psy);
1295}
1296
1297static int
1298qpnp_batt_power_get_property(struct power_supply *psy,
1299 enum power_supply_property psp,
1300 union power_supply_propval *val)
1301{
1302 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1303 batt_psy);
1304
1305 switch (psp) {
1306 case POWER_SUPPLY_PROP_STATUS:
1307 val->intval = get_prop_batt_status(chip);
1308 break;
1309 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1310 val->intval = get_prop_charge_type(chip);
1311 break;
1312 case POWER_SUPPLY_PROP_HEALTH:
1313 val->intval = get_prop_batt_health(chip);
1314 break;
1315 case POWER_SUPPLY_PROP_PRESENT:
1316 val->intval = get_prop_batt_present(chip);
1317 break;
1318 case POWER_SUPPLY_PROP_TECHNOLOGY:
1319 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
1320 break;
1321 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
1322 val->intval = chip->max_voltage_mv * 1000;
1323 break;
1324 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
1325 val->intval = chip->min_voltage_mv * 1000;
1326 break;
1327 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1328 val->intval = get_prop_battery_voltage_now(chip);
1329 break;
1330 case POWER_SUPPLY_PROP_TEMP:
1331 val->intval = get_prop_batt_temp(chip);
1332 break;
1333 case POWER_SUPPLY_PROP_CAPACITY:
1334 val->intval = get_prop_capacity(chip);
1335 break;
1336 case POWER_SUPPLY_PROP_CURRENT_NOW:
1337 val->intval = get_prop_current_now(chip);
1338 break;
1339 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1340 val->intval = get_prop_full_design(chip);
1341 break;
David Keitelb80eda82012-10-15 10:49:11 -07001342 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
David Keitel03ee6b52012-10-22 12:25:19 -07001343 val->intval = !(chip->charging_disabled);
David Keitelb80eda82012-10-15 10:49:11 -07001344 break;
David Keitelbe208252013-01-31 14:49:25 -08001345 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1346 val->intval = chip->therm_lvl_sel;
David Keitelb80eda82012-10-15 10:49:11 -07001347 break;
1348 default:
1349 return -EINVAL;
1350 }
1351
David Keitelb80eda82012-10-15 10:49:11 -07001352 return 0;
David Keitel80668952012-07-27 14:25:49 -07001353}
1354
David Keitel80668952012-07-27 14:25:49 -07001355#define QPNP_CHG_VINMIN_MIN_MV 3400
1356#define QPNP_CHG_VINMIN_HIGH_MIN_MV 5600
1357#define QPNP_CHG_VINMIN_HIGH_MIN_VAL 0x2B
1358#define QPNP_CHG_VINMIN_MAX_MV 9600
1359#define QPNP_CHG_VINMIN_STEP_MV 50
1360#define QPNP_CHG_VINMIN_STEP_HIGH_MV 200
1361#define QPNP_CHG_VINMIN_MASK 0x1F
1362static int
1363qpnp_chg_vinmin_set(struct qpnp_chg_chip *chip, int voltage)
1364{
1365 u8 temp;
1366
1367 if (voltage < QPNP_CHG_VINMIN_MIN_MV
1368 || voltage > QPNP_CHG_VINMIN_MAX_MV) {
1369 pr_err("bad mV=%d asked to set\n", voltage);
1370 return -EINVAL;
1371 }
1372 if (voltage >= QPNP_CHG_VINMIN_HIGH_MIN_MV) {
1373 temp = QPNP_CHG_VINMIN_HIGH_MIN_VAL;
1374 temp += (voltage - QPNP_CHG_VINMIN_MIN_MV)
1375 / QPNP_CHG_VINMIN_STEP_HIGH_MV;
1376 } else {
1377 temp = (voltage - QPNP_CHG_VINMIN_MIN_MV)
1378 / QPNP_CHG_VINMIN_STEP_MV;
1379 }
1380
1381 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1382 return qpnp_chg_masked_write(chip,
1383 chip->chgr_base + CHGR_VIN_MIN,
1384 QPNP_CHG_VINMIN_MASK, temp, 1);
1385}
1386
David Keitel5d44fa52012-12-03 16:37:31 -08001387#define QPNP_CHG_IBATSAFE_MIN_MA 100
1388#define QPNP_CHG_IBATSAFE_MAX_MA 3250
1389#define QPNP_CHG_I_STEP_MA 50
1390#define QPNP_CHG_I_MIN_MA 100
1391#define QPNP_CHG_I_MASK 0x3F
1392static int
1393qpnp_chg_ibatsafe_set(struct qpnp_chg_chip *chip, int safe_current)
1394{
1395 u8 temp;
1396
1397 if (safe_current < QPNP_CHG_IBATSAFE_MIN_MA
1398 || safe_current > QPNP_CHG_IBATSAFE_MAX_MA) {
1399 pr_err("bad mA=%d asked to set\n", safe_current);
1400 return -EINVAL;
1401 }
1402
1403 temp = (safe_current - QPNP_CHG_IBATSAFE_MIN_MA)
1404 / QPNP_CHG_I_STEP_MA;
1405 return qpnp_chg_masked_write(chip,
1406 chip->chgr_base + CHGR_IBAT_SAFE,
1407 QPNP_CHG_I_MASK, temp, 1);
1408}
David Keitel80668952012-07-27 14:25:49 -07001409
1410#define QPNP_CHG_ITERM_MIN_MA 100
1411#define QPNP_CHG_ITERM_MAX_MA 250
1412#define QPNP_CHG_ITERM_STEP_MA 50
1413#define QPNP_CHG_ITERM_MASK 0x03
1414static int
1415qpnp_chg_ibatterm_set(struct qpnp_chg_chip *chip, int term_current)
1416{
1417 u8 temp;
1418
1419 if (term_current < QPNP_CHG_ITERM_MIN_MA
1420 || term_current > QPNP_CHG_ITERM_MAX_MA) {
1421 pr_err("bad mA=%d asked to set\n", term_current);
1422 return -EINVAL;
1423 }
1424
1425 temp = (term_current - QPNP_CHG_ITERM_MIN_MA)
1426 / QPNP_CHG_ITERM_STEP_MA;
1427 return qpnp_chg_masked_write(chip,
1428 chip->chgr_base + CHGR_IBAT_TERM_CHGR,
1429 QPNP_CHG_ITERM_MASK, temp, 1);
1430}
1431
David Keitelff5d0472013-04-04 11:36:06 -07001432#define QPNP_CHG_IBATMAX_MIN 50
David Keitel80668952012-07-27 14:25:49 -07001433#define QPNP_CHG_IBATMAX_MAX 3250
David Keitel80668952012-07-27 14:25:49 -07001434static int
1435qpnp_chg_ibatmax_set(struct qpnp_chg_chip *chip, int chg_current)
1436{
1437 u8 temp;
1438
1439 if (chg_current < QPNP_CHG_IBATMAX_MIN
1440 || chg_current > QPNP_CHG_IBATMAX_MAX) {
1441 pr_err("bad mA=%d asked to set\n", chg_current);
1442 return -EINVAL;
1443 }
David Keitelff5d0472013-04-04 11:36:06 -07001444 temp = chg_current / QPNP_CHG_I_STEP_MA;
David Keitel80668952012-07-27 14:25:49 -07001445 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_IBAT_MAX,
1446 QPNP_CHG_I_MASK, temp, 1);
1447}
1448
David Keitela4b7b592013-04-11 18:34:35 -07001449#define QPNP_CHG_TCHG_MASK 0x7F
1450#define QPNP_CHG_TCHG_MIN 4
1451#define QPNP_CHG_TCHG_MAX 512
1452#define QPNP_CHG_TCHG_STEP 4
1453static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
1454{
1455 u8 temp;
1456
1457 if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
1458 pr_err("bad max minutes =%d asked to set\n", minutes);
1459 return -EINVAL;
1460 }
1461
1462 temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
1463 return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
David Keitela1d16442013-05-09 14:47:37 -07001464 QPNP_CHG_TCHG_MASK, temp, 1);
David Keitela4b7b592013-04-11 18:34:35 -07001465}
David Keitel80668952012-07-27 14:25:49 -07001466
1467#define QPNP_CHG_V_MIN_MV 3240
1468#define QPNP_CHG_V_MAX_MV 4500
1469#define QPNP_CHG_V_STEP_MV 10
1470static int
1471qpnp_chg_vddsafe_set(struct qpnp_chg_chip *chip, int voltage)
1472{
1473 u8 temp;
1474
1475 if (voltage < QPNP_CHG_V_MIN_MV
1476 || voltage > QPNP_CHG_V_MAX_MV) {
1477 pr_err("bad mV=%d asked to set\n", voltage);
1478 return -EINVAL;
1479 }
1480 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1481 pr_debug("voltage=%d setting %02x\n", voltage, temp);
1482 return qpnp_chg_write(chip, &temp,
1483 chip->chgr_base + CHGR_VDD_SAFE, 1);
1484}
1485
1486#define QPNP_CHG_VDDMAX_MIN 3400
1487static int
1488qpnp_chg_vddmax_set(struct qpnp_chg_chip *chip, int voltage)
1489{
1490 u8 temp = 0;
1491
1492 if (voltage < QPNP_CHG_VDDMAX_MIN
1493 || voltage > QPNP_CHG_V_MAX_MV) {
1494 pr_err("bad mV=%d asked to set\n", voltage);
1495 return -EINVAL;
1496 }
1497
1498 temp = (voltage - QPNP_CHG_V_MIN_MV) / QPNP_CHG_V_STEP_MV;
1499
1500 pr_debug("voltage=%d setting %02x\n", voltage, temp);
David Keitel454ee842013-03-08 16:19:11 -08001501 return qpnp_chg_write(chip, &temp, chip->chgr_base + CHGR_VDD_MAX, 1);
1502}
1503
David Keitel6dc4ed42013-05-17 11:08:58 -07001504#define BOOST_MIN_UV 4200000
1505#define BOOST_MAX_UV 5500000
1506#define BOOST_STEP_UV 50000
1507#define BOOST_MIN 16
1508#define N_BOOST_V ((BOOST_MAX_UV - BOOST_MIN_UV) / BOOST_STEP_UV + 1)
1509static int
1510qpnp_boost_vset(struct qpnp_chg_chip *chip, int voltage)
1511{
1512 u8 reg = 0;
1513
1514 if (voltage < BOOST_MIN_UV || voltage > BOOST_MAX_UV) {
1515 pr_err("invalid voltage requested %d uV\n", voltage);
1516 return -EINVAL;
1517 }
1518
1519 reg = DIV_ROUND_UP(voltage - BOOST_MIN_UV, BOOST_STEP_UV) + BOOST_MIN;
1520
1521 pr_debug("voltage=%d setting %02x\n", voltage, reg);
1522 return qpnp_chg_write(chip, &reg, chip->boost_base + BOOST_VSET, 1);
1523}
1524
1525static int
1526qpnp_boost_vget_uv(struct qpnp_chg_chip *chip)
1527{
1528 int rc;
1529 u8 boost_reg;
1530
1531 rc = qpnp_chg_read(chip, &boost_reg,
1532 chip->boost_base + BOOST_VSET, 1);
1533 if (rc) {
1534 pr_err("failed to read BOOST_VSET rc=%d\n", rc);
1535 return rc;
1536 }
1537
1538 if (boost_reg < BOOST_MIN) {
1539 pr_err("Invalid reading from 0x%x\n", boost_reg);
1540 return -EINVAL;
1541 }
1542
1543 return BOOST_MIN_UV + ((boost_reg - BOOST_MIN) * BOOST_STEP_UV);
1544}
1545
David Keitel454ee842013-03-08 16:19:11 -08001546/* JEITA compliance logic */
1547static void
1548qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
1549{
1550 if (chip->bat_is_cool)
1551 qpnp_chg_vddmax_set(chip, chip->cool_bat_mv);
1552 else if (chip->bat_is_warm)
1553 qpnp_chg_vddmax_set(chip, chip->warm_bat_mv);
1554 else
1555 qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
1556}
1557
1558static void
1559qpnp_chg_set_appropriate_vbatdet(struct qpnp_chg_chip *chip)
1560{
1561 if (chip->bat_is_cool)
1562 qpnp_chg_vbatdet_set(chip, chip->cool_bat_mv
1563 - chip->resume_delta_mv);
1564 else if (chip->bat_is_warm)
1565 qpnp_chg_vbatdet_set(chip, chip->warm_bat_mv
1566 - chip->resume_delta_mv);
1567 else
1568 qpnp_chg_vbatdet_set(chip, chip->max_voltage_mv
1569 - chip->resume_delta_mv);
David Keitel80668952012-07-27 14:25:49 -07001570}
1571
David Keitelbe208252013-01-31 14:49:25 -08001572static void
1573qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
1574{
1575 unsigned int chg_current = chip->max_bat_chg_current;
1576
David Keitel454ee842013-03-08 16:19:11 -08001577 if (chip->bat_is_cool)
1578 chg_current = min(chg_current, chip->cool_bat_chg_ma);
1579
1580 if (chip->bat_is_warm)
1581 chg_current = min(chg_current, chip->warm_bat_chg_ma);
1582
David Keitelbe208252013-01-31 14:49:25 -08001583 if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
1584 chg_current = min(chg_current,
1585 chip->thermal_mitigation[chip->therm_lvl_sel]);
1586
1587 pr_debug("setting %d mA\n", chg_current);
1588 qpnp_chg_ibatmax_set(chip, chg_current);
1589}
1590
1591static void
1592qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
1593{
1594 if (lvl_sel >= 0 && lvl_sel < chip->thermal_levels) {
1595 chip->therm_lvl_sel = lvl_sel;
1596 if (lvl_sel == (chip->thermal_levels - 1)) {
1597 /* disable charging if highest value selected */
1598 qpnp_chg_buck_control(chip, 0);
1599 } else {
1600 qpnp_chg_buck_control(chip, 1);
1601 qpnp_chg_set_appropriate_battery_current(chip);
1602 }
1603 } else {
1604 pr_err("Unsupported level selected %d\n", lvl_sel);
1605 }
1606}
1607
David Keitel6dc4ed42013-05-17 11:08:58 -07001608/* OTG regulator operations */
1609static int
1610qpnp_chg_regulator_otg_enable(struct regulator_dev *rdev)
1611{
1612 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1613
1614 return switch_usb_to_host_mode(chip);
1615}
1616
1617static int
1618qpnp_chg_regulator_otg_disable(struct regulator_dev *rdev)
1619{
1620 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1621
1622 return switch_usb_to_charge_mode(chip);
1623}
1624
1625static int
1626qpnp_chg_regulator_otg_is_enabled(struct regulator_dev *rdev)
1627{
1628 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1629
1630 return qpnp_chg_is_otg_en_set(chip);
1631}
1632
1633static int
1634qpnp_chg_regulator_boost_enable(struct regulator_dev *rdev)
1635{
1636 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1637
1638 return qpnp_chg_masked_write(chip,
1639 chip->boost_base + BOOST_ENABLE_CONTROL,
1640 BOOST_PWR_EN,
1641 BOOST_PWR_EN, 1);
1642}
1643
1644/* Boost regulator operations */
1645static int
1646qpnp_chg_regulator_boost_disable(struct regulator_dev *rdev)
1647{
1648 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1649
1650 return qpnp_chg_masked_write(chip,
1651 chip->boost_base + BOOST_ENABLE_CONTROL,
1652 BOOST_PWR_EN,
1653 0, 1);
1654}
1655
1656static int
1657qpnp_chg_regulator_boost_is_enabled(struct regulator_dev *rdev)
1658{
1659 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1660
1661 return qpnp_chg_is_boost_en_set(chip);
1662}
1663
1664static int
1665qpnp_chg_regulator_boost_set_voltage(struct regulator_dev *rdev,
1666 int min_uV, int max_uV, unsigned *selector)
1667{
1668 int uV = min_uV;
1669 int rc;
1670 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1671
1672 if (uV < BOOST_MIN_UV && max_uV >= BOOST_MIN_UV)
1673 uV = BOOST_MIN_UV;
1674
1675
1676 if (uV < BOOST_MIN_UV || uV > BOOST_MAX_UV) {
1677 pr_err("request %d uV is out of bounds\n", uV);
1678 return -EINVAL;
1679 }
1680
1681 *selector = DIV_ROUND_UP(uV - BOOST_MIN_UV, BOOST_STEP_UV);
1682 if ((*selector * BOOST_STEP_UV + BOOST_MIN_UV) > max_uV) {
1683 pr_err("no available setpoint [%d, %d] uV\n", min_uV, max_uV);
1684 return -EINVAL;
1685 }
1686
1687 rc = qpnp_boost_vset(chip, uV);
1688
1689 return rc;
1690}
1691
1692static int
1693qpnp_chg_regulator_boost_get_voltage(struct regulator_dev *rdev)
1694{
1695 struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
1696
1697 return qpnp_boost_vget_uv(chip);
1698}
1699
1700static int
1701qpnp_chg_regulator_boost_list_voltage(struct regulator_dev *rdev,
1702 unsigned selector)
1703{
1704 if (selector >= N_BOOST_V)
1705 return 0;
1706
1707 return BOOST_MIN_UV + (selector * BOOST_STEP_UV);
1708}
1709
1710static struct regulator_ops qpnp_chg_otg_reg_ops = {
1711 .enable = qpnp_chg_regulator_otg_enable,
1712 .disable = qpnp_chg_regulator_otg_disable,
1713 .is_enabled = qpnp_chg_regulator_otg_is_enabled,
1714};
1715
1716static struct regulator_ops qpnp_chg_boost_reg_ops = {
1717 .enable = qpnp_chg_regulator_boost_enable,
1718 .disable = qpnp_chg_regulator_boost_disable,
1719 .is_enabled = qpnp_chg_regulator_boost_is_enabled,
1720 .set_voltage = qpnp_chg_regulator_boost_set_voltage,
1721 .get_voltage = qpnp_chg_regulator_boost_get_voltage,
1722 .list_voltage = qpnp_chg_regulator_boost_list_voltage,
1723};
1724
David Keitel9fd07382013-05-02 15:37:44 -07001725#define CONSECUTIVE_COUNT 3
1726static void
1727qpnp_eoc_work(struct work_struct *work)
1728{
1729 struct delayed_work *dwork = to_delayed_work(work);
1730 struct qpnp_chg_chip *chip = container_of(dwork,
1731 struct qpnp_chg_chip, eoc_work);
1732 static int count;
1733 int ibat_ma, vbat_mv, rc = 0;
1734 u8 batt_sts = 0, buck_sts = 0, chg_sts = 0;
1735
1736 wake_lock(&chip->eoc_wake_lock);
1737 qpnp_chg_charge_en(chip, !chip->charging_disabled);
1738
1739 rc = qpnp_chg_read(chip, &batt_sts, INT_RT_STS(chip->bat_if_base), 1);
1740 if (rc) {
1741 pr_err("failed to read batt_if rc=%d\n", rc);
1742 return;
1743 }
1744
1745 rc = qpnp_chg_read(chip, &buck_sts, INT_RT_STS(chip->buck_base), 1);
1746 if (rc) {
1747 pr_err("failed to read buck rc=%d\n", rc);
1748 return;
1749 }
1750
1751 rc = qpnp_chg_read(chip, &chg_sts, INT_RT_STS(chip->chgr_base), 1);
1752 if (rc) {
1753 pr_err("failed to read chg_sts rc=%d\n", rc);
1754 return;
1755 }
1756
1757 pr_debug("chgr: 0x%x, bat_if: 0x%x, buck: 0x%x\n",
1758 chg_sts, batt_sts, buck_sts);
1759
1760 if (!qpnp_chg_is_usb_chg_plugged_in(chip) &&
1761 !qpnp_chg_is_dc_chg_plugged_in(chip)) {
1762 pr_debug("no chg connected, stopping\n");
1763 goto stop_eoc;
1764 }
1765
1766 if ((batt_sts & BAT_FET_ON_IRQ) && (chg_sts & FAST_CHG_ON_IRQ
1767 || chg_sts & TRKL_CHG_ON_IRQ)) {
1768 ibat_ma = get_prop_current_now(chip) / 1000;
1769 vbat_mv = get_prop_battery_voltage_now(chip) / 1000;
1770 pr_debug("ibat_ma: %d term_current =%d\n",
1771 ibat_ma, chip->term_current);
1772 if (ibat_ma > chip->term_current) {
1773 pr_debug("charging but increase in current demand\n");
1774 count = 0;
1775 } else if ((ibat_ma * -1) < chip->term_current) {
1776 if (count == CONSECUTIVE_COUNT) {
1777 pr_info("End of Charging\n");
1778 qpnp_chg_charge_en(chip, 0);
1779 chip->chg_done = true;
1780 power_supply_changed(&chip->batt_psy);
David Keitel47185a62013-05-15 18:54:10 -07001781 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -07001782 goto stop_eoc;
1783 } else {
1784 count += 1;
1785 pr_debug("EOC count = %d\n", count);
1786 }
1787 } else if ((!(chg_sts & VBAT_DET_LOW_IRQ)) && (vbat_mv <
1788 (chip->max_voltage_mv - chip->resume_delta_mv))) {
1789 pr_debug("woke up too early\n");
David Keitel47185a62013-05-15 18:54:10 -07001790 qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
David Keitel9fd07382013-05-02 15:37:44 -07001791 goto stop_eoc;
1792 }
1793 } else {
1794 pr_debug("not charging\n");
1795 goto stop_eoc;
1796 }
1797
1798 schedule_delayed_work(&chip->eoc_work,
1799 msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
1800 return;
1801
1802stop_eoc:
1803 count = 0;
1804 wake_unlock(&chip->eoc_wake_lock);
1805}
1806
David Keitel0c1a4532013-03-21 16:39:06 -07001807#define HYSTERISIS_DECIDEGC 20
David Keitel454ee842013-03-08 16:19:11 -08001808static void
1809qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
1810{
1811 struct qpnp_chg_chip *chip = ctx;
1812 bool bat_warm = 0, bat_cool = 0;
David Keitel1219a802013-03-21 16:37:21 -07001813 int temp;
David Keitel454ee842013-03-08 16:19:11 -08001814
1815 if (state >= ADC_TM_STATE_NUM) {
1816 pr_err("invalid notification %d\n", state);
1817 return;
1818 }
1819
David Keitel1219a802013-03-21 16:37:21 -07001820 temp = get_prop_batt_temp(chip);
David Keitel454ee842013-03-08 16:19:11 -08001821
David Keitel1219a802013-03-21 16:37:21 -07001822 pr_debug("temp = %d state = %s\n", temp,
1823 state == ADC_TM_WARM_STATE ? "warm" : "cool");
1824
1825 if (state == ADC_TM_WARM_STATE) {
1826 if (temp > chip->warm_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07001827 /* Normal to warm */
David Keitel454ee842013-03-08 16:19:11 -08001828 bat_warm = true;
1829 bat_cool = false;
1830 chip->adc_param.low_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07001831 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07001832 chip->adc_param.state_request =
1833 ADC_TM_COOL_THR_ENABLE;
1834 } else if (temp >
1835 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07001836 /* Cool to normal */
David Keitel454ee842013-03-08 16:19:11 -08001837 bat_warm = false;
1838 bat_cool = false;
David Keitel1219a802013-03-21 16:37:21 -07001839
1840 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel0c1a4532013-03-21 16:39:06 -07001841 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07001842 chip->adc_param.state_request =
1843 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08001844 }
1845 } else {
David Keitel1219a802013-03-21 16:37:21 -07001846 if (temp < chip->cool_bat_decidegc) {
David Keitel3e37e5a2013-04-18 10:42:30 -07001847 /* Normal to cool */
David Keitel454ee842013-03-08 16:19:11 -08001848 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07001849 bat_cool = true;
David Keitel454ee842013-03-08 16:19:11 -08001850 chip->adc_param.high_temp =
David Keitel0c1a4532013-03-21 16:39:06 -07001851 chip->cool_bat_decidegc + HYSTERISIS_DECIDEGC;
David Keitel1219a802013-03-21 16:37:21 -07001852 chip->adc_param.state_request =
1853 ADC_TM_WARM_THR_ENABLE;
David Keitel3e37e5a2013-04-18 10:42:30 -07001854 } else if (temp <
David Keitel1219a802013-03-21 16:37:21 -07001855 chip->warm_bat_decidegc - HYSTERISIS_DECIDEGC){
David Keitel3e37e5a2013-04-18 10:42:30 -07001856 /* Warm to normal */
David Keitel454ee842013-03-08 16:19:11 -08001857 bat_warm = false;
David Keitel1219a802013-03-21 16:37:21 -07001858 bat_cool = false;
1859
David Keitel0c1a4532013-03-21 16:39:06 -07001860 chip->adc_param.low_temp = chip->cool_bat_decidegc;
David Keitel1219a802013-03-21 16:37:21 -07001861 chip->adc_param.high_temp = chip->warm_bat_decidegc;
1862 chip->adc_param.state_request =
1863 ADC_TM_HIGH_LOW_THR_ENABLE;
David Keitel454ee842013-03-08 16:19:11 -08001864 }
1865 }
1866
1867 if (chip->bat_is_cool ^ bat_cool || chip->bat_is_warm ^ bat_warm) {
David Keitel1219a802013-03-21 16:37:21 -07001868 chip->bat_is_cool = bat_cool;
1869 chip->bat_is_warm = bat_warm;
1870
David Keitel454ee842013-03-08 16:19:11 -08001871 /* set appropriate voltages and currents */
1872 qpnp_chg_set_appropriate_vddmax(chip);
1873 qpnp_chg_set_appropriate_battery_current(chip);
1874 qpnp_chg_set_appropriate_vbatdet(chip);
David Keitel454ee842013-03-08 16:19:11 -08001875 }
1876
David Keitel1219a802013-03-21 16:37:21 -07001877 if (qpnp_adc_tm_channel_measure(&chip->adc_param))
1878 pr_err("request ADC error\n");
David Keitel454ee842013-03-08 16:19:11 -08001879}
1880
David Keitelbe208252013-01-31 14:49:25 -08001881static int
1882qpnp_batt_power_set_property(struct power_supply *psy,
1883 enum power_supply_property psp,
1884 const union power_supply_propval *val)
1885{
1886 struct qpnp_chg_chip *chip = container_of(psy, struct qpnp_chg_chip,
1887 batt_psy);
1888
1889 switch (psp) {
1890 case POWER_SUPPLY_PROP_CHARGING_ENABLED:
1891 chip->charging_disabled = !(val->intval);
1892 qpnp_chg_charge_en(chip, !chip->charging_disabled);
1893 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
1894 break;
1895 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1896 qpnp_batt_system_temp_level_set(chip, val->intval);
1897 break;
1898 default:
1899 return -EINVAL;
1900 }
1901
1902 power_supply_changed(&chip->batt_psy);
1903 return 0;
1904}
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08001905
1906static void
1907qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
David Keiteld681cda2012-10-02 15:44:21 -07001908{
David Keitelfe51cb92013-04-02 19:42:58 -07001909 if (chip->revision > 0 && chip->type == SMBB)
David Keiteld681cda2012-10-02 15:44:21 -07001910 chip->flags |= CHG_FLAGS_VCP_WA;
1911}
1912
David Keitel0f35be42013-04-16 11:10:40 -07001913static int
1914qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
1915{
1916 int rc = 0;
1917 struct resource *resource;
1918 struct spmi_resource *spmi_resource;
1919 u8 subtype;
1920 struct spmi_device *spmi = chip->spmi;
1921
1922 spmi_for_each_container_dev(spmi_resource, chip->spmi) {
1923 if (!spmi_resource) {
1924 pr_err("qpnp_chg: spmi resource absent\n");
1925 return rc;
1926 }
1927
1928 resource = spmi_get_resource(spmi, spmi_resource,
1929 IORESOURCE_MEM, 0);
1930 if (!(resource && resource->start)) {
1931 pr_err("node %s IO resource absent!\n",
1932 spmi->dev.of_node->full_name);
1933 return rc;
1934 }
1935
1936 rc = qpnp_chg_read(chip, &subtype,
1937 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
1938 if (rc) {
1939 pr_err("Peripheral subtype read failed rc=%d\n", rc);
1940 return rc;
1941 }
1942
1943 switch (subtype) {
1944 case SMBB_CHGR_SUBTYPE:
1945 case SMBBP_CHGR_SUBTYPE:
1946 case SMBCL_CHGR_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07001947 chip->chg_fastchg.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07001948 spmi_resource, "fast-chg-on");
David Keitel47185a62013-05-15 18:54:10 -07001949 if (chip->chg_fastchg.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07001950 pr_err("Unable to get fast-chg-on irq\n");
1951 return rc;
1952 }
1953
David Keitel47185a62013-05-15 18:54:10 -07001954 chip->chg_trklchg.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07001955 spmi_resource, "trkl-chg-on");
David Keitel47185a62013-05-15 18:54:10 -07001956 if (chip->chg_trklchg.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07001957 pr_err("Unable to get trkl-chg-on irq\n");
1958 return rc;
1959 }
1960
David Keitel47185a62013-05-15 18:54:10 -07001961 chip->chg_failed.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07001962 spmi_resource, "chg-failed");
David Keitel47185a62013-05-15 18:54:10 -07001963 if (chip->chg_failed.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07001964 pr_err("Unable to get chg_failed irq\n");
1965 return rc;
1966 }
1967
David Keitel47185a62013-05-15 18:54:10 -07001968 chip->chg_vbatdet_lo.irq = spmi_get_irq_byname(spmi,
David Keitel9fd07382013-05-02 15:37:44 -07001969 spmi_resource, "vbat-det-lo");
David Keitel47185a62013-05-15 18:54:10 -07001970 if (chip->chg_vbatdet_lo.irq < 0) {
David Keitel9fd07382013-05-02 15:37:44 -07001971 pr_err("Unable to get fast-chg-on irq\n");
1972 return rc;
1973 }
1974
David Keitel47185a62013-05-15 18:54:10 -07001975 rc |= devm_request_irq(chip->dev, chip->chg_failed.irq,
David Keitel0f35be42013-04-16 11:10:40 -07001976 qpnp_chg_chgr_chg_failed_irq_handler,
David Keitelc9f19172013-04-29 11:01:26 -07001977 IRQF_TRIGGER_RISING, "chg-failed", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001978 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07001979 pr_err("Can't request %d chg-failed: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07001980 chip->chg_failed.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07001981 return rc;
1982 }
1983
David Keitel47185a62013-05-15 18:54:10 -07001984 rc |= devm_request_irq(chip->dev, chip->chg_fastchg.irq,
David Keitel0f35be42013-04-16 11:10:40 -07001985 qpnp_chg_chgr_chg_fastchg_irq_handler,
1986 IRQF_TRIGGER_RISING,
1987 "fast-chg-on", chip);
1988 if (rc < 0) {
1989 pr_err("Can't request %d fast-chg-on: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07001990 chip->chg_fastchg.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07001991 return rc;
1992 }
1993
David Keitel47185a62013-05-15 18:54:10 -07001994 rc |= devm_request_irq(chip->dev, chip->chg_trklchg.irq,
David Keitel0f35be42013-04-16 11:10:40 -07001995 qpnp_chg_chgr_chg_trklchg_irq_handler,
1996 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07001997 "trkl-chg-on", chip);
David Keitel0f35be42013-04-16 11:10:40 -07001998 if (rc < 0) {
1999 pr_err("Can't request %d trkl-chg-on: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002000 chip->chg_trklchg.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002001 return rc;
2002 }
David Keitel9fd07382013-05-02 15:37:44 -07002003
2004 rc |= devm_request_irq(chip->dev,
David Keitel47185a62013-05-15 18:54:10 -07002005 chip->chg_vbatdet_lo.irq,
David Keitel9fd07382013-05-02 15:37:44 -07002006 qpnp_chg_vbatdet_lo_irq_handler,
2007 IRQF_TRIGGER_RISING,
2008 "vbat-det-lo", chip);
2009 if (rc < 0) {
2010 pr_err("Can't request %d vbat-det-lo: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002011 chip->chg_vbatdet_lo.irq, rc);
David Keitel9fd07382013-05-02 15:37:44 -07002012 return rc;
2013 }
2014
David Keitel47185a62013-05-15 18:54:10 -07002015 enable_irq_wake(chip->chg_trklchg.irq);
2016 enable_irq_wake(chip->chg_failed.irq);
2017 qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
2018 enable_irq_wake(chip->chg_vbatdet_lo.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002019
2020 break;
2021 case SMBB_BAT_IF_SUBTYPE:
2022 case SMBBP_BAT_IF_SUBTYPE:
2023 case SMBCL_BAT_IF_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002024 chip->batt_pres.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002025 spmi_resource, "batt-pres");
David Keitel47185a62013-05-15 18:54:10 -07002026 if (chip->batt_pres.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002027 pr_err("Unable to get batt-pres irq\n");
2028 return rc;
2029 }
David Keitel47185a62013-05-15 18:54:10 -07002030 rc = devm_request_irq(chip->dev, chip->batt_pres.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002031 qpnp_chg_bat_if_batt_pres_irq_handler,
2032 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002033 "batt-pres", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002034 if (rc < 0) {
2035 pr_err("Can't request %d batt-pres irq: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002036 chip->batt_pres.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002037 return rc;
2038 }
2039
David Keitel47185a62013-05-15 18:54:10 -07002040 enable_irq_wake(chip->batt_pres.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002041 break;
2042 case SMBB_USB_CHGPTH_SUBTYPE:
2043 case SMBBP_USB_CHGPTH_SUBTYPE:
2044 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002045 chip->usbin_valid.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002046 spmi_resource, "usbin-valid");
David Keitel47185a62013-05-15 18:54:10 -07002047 if (chip->usbin_valid.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002048 pr_err("Unable to get usbin irq\n");
2049 return rc;
2050 }
David Keitel47185a62013-05-15 18:54:10 -07002051 rc = devm_request_irq(chip->dev, chip->usbin_valid.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002052 qpnp_chg_usb_usbin_valid_irq_handler,
2053 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002054 "usbin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002055 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002056 pr_err("Can't request %d usbin-valid: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002057 chip->usbin_valid.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002058 return rc;
2059 }
David Keitel344c6972013-04-09 19:28:21 -07002060
David Keitel47185a62013-05-15 18:54:10 -07002061 chip->chg_gone.irq = spmi_get_irq_byname(spmi,
David Keitel344c6972013-04-09 19:28:21 -07002062 spmi_resource, "chg-gone");
David Keitel47185a62013-05-15 18:54:10 -07002063 if (chip->chg_gone.irq < 0) {
David Keitel344c6972013-04-09 19:28:21 -07002064 pr_err("Unable to get chg-gone irq\n");
2065 return rc;
2066 }
David Keitel47185a62013-05-15 18:54:10 -07002067 rc = devm_request_irq(chip->dev, chip->chg_gone.irq,
David Keitel344c6972013-04-09 19:28:21 -07002068 qpnp_chg_usb_chg_gone_irq_handler,
2069 IRQF_TRIGGER_RISING,
David Keitelc9f19172013-04-29 11:01:26 -07002070 "chg-gone", chip);
David Keitel344c6972013-04-09 19:28:21 -07002071 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002072 pr_err("Can't request %d chg-gone: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002073 chip->chg_gone.irq, rc);
David Keitel344c6972013-04-09 19:28:21 -07002074 return rc;
2075 }
David Keitel47185a62013-05-15 18:54:10 -07002076
2077 enable_irq_wake(chip->usbin_valid.irq);
2078 enable_irq_wake(chip->chg_gone.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002079 break;
2080 case SMBB_DC_CHGPTH_SUBTYPE:
David Keitel47185a62013-05-15 18:54:10 -07002081 chip->dcin_valid.irq = spmi_get_irq_byname(spmi,
David Keitel0f35be42013-04-16 11:10:40 -07002082 spmi_resource, "dcin-valid");
David Keitel47185a62013-05-15 18:54:10 -07002083 if (chip->dcin_valid.irq < 0) {
David Keitel0f35be42013-04-16 11:10:40 -07002084 pr_err("Unable to get dcin irq\n");
2085 return -rc;
2086 }
David Keitel47185a62013-05-15 18:54:10 -07002087 rc = devm_request_irq(chip->dev, chip->dcin_valid.irq,
David Keitel0f35be42013-04-16 11:10:40 -07002088 qpnp_chg_dc_dcin_valid_irq_handler,
2089 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
David Keitelc9f19172013-04-29 11:01:26 -07002090 "dcin-valid", chip);
David Keitel0f35be42013-04-16 11:10:40 -07002091 if (rc < 0) {
David Keitelc9f19172013-04-29 11:01:26 -07002092 pr_err("Can't request %d dcin-valid: %d\n",
David Keitel47185a62013-05-15 18:54:10 -07002093 chip->dcin_valid.irq, rc);
David Keitel0f35be42013-04-16 11:10:40 -07002094 return rc;
2095 }
2096
David Keitel47185a62013-05-15 18:54:10 -07002097 enable_irq_wake(chip->dcin_valid.irq);
David Keitel0f35be42013-04-16 11:10:40 -07002098 break;
2099 }
2100 }
2101
2102 return rc;
2103}
2104
David Keitel80668952012-07-27 14:25:49 -07002105#define WDOG_EN_BIT BIT(7)
2106static int
2107qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
2108 struct spmi_resource *spmi_resource)
2109{
2110 int rc = 0;
David Keitel796882d2013-05-14 18:01:11 -07002111 u8 reg = 0;
David Keitel6dc4ed42013-05-17 11:08:58 -07002112 struct regulator_init_data *init_data;
2113 struct regulator_desc *rdesc;
David Keitel80668952012-07-27 14:25:49 -07002114
2115 switch (subtype) {
2116 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002117 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002118 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002119 rc = qpnp_chg_vinmin_set(chip, chip->min_voltage_mv);
2120 if (rc) {
2121 pr_debug("failed setting min_voltage rc=%d\n", rc);
2122 return rc;
2123 }
2124 rc = qpnp_chg_vddmax_set(chip, chip->max_voltage_mv);
2125 if (rc) {
2126 pr_debug("failed setting max_voltage rc=%d\n", rc);
2127 return rc;
2128 }
2129 rc = qpnp_chg_vddsafe_set(chip, chip->safe_voltage_mv);
2130 if (rc) {
2131 pr_debug("failed setting safe_voltage rc=%d\n", rc);
2132 return rc;
2133 }
David Keitel454ee842013-03-08 16:19:11 -08002134 rc = qpnp_chg_vbatdet_set(chip,
2135 chip->max_voltage_mv - chip->resume_delta_mv);
David Keitel5d44fa52012-12-03 16:37:31 -08002136 if (rc) {
2137 pr_debug("failed setting resume_voltage rc=%d\n", rc);
2138 return rc;
2139 }
David Keitel80668952012-07-27 14:25:49 -07002140 rc = qpnp_chg_ibatmax_set(chip, chip->max_bat_chg_current);
2141 if (rc) {
2142 pr_debug("failed setting ibatmax rc=%d\n", rc);
2143 return rc;
2144 }
David Keitel365c4c42013-03-08 16:20:40 -08002145 if (chip->term_current) {
2146 rc = qpnp_chg_ibatterm_set(chip, chip->term_current);
2147 if (rc) {
2148 pr_debug("failed setting ibatterm rc=%d\n", rc);
2149 return rc;
2150 }
David Keitel80668952012-07-27 14:25:49 -07002151 }
David Keitel5d44fa52012-12-03 16:37:31 -08002152 rc = qpnp_chg_ibatsafe_set(chip, chip->safe_current);
2153 if (rc) {
2154 pr_debug("failed setting ibat_Safe rc=%d\n", rc);
2155 return rc;
2156 }
David Keitela4b7b592013-04-11 18:34:35 -07002157 rc = qpnp_chg_tchg_max_set(chip, chip->tchg_mins);
2158 if (rc) {
2159 pr_debug("failed setting tchg_mins rc=%d\n", rc);
2160 return rc;
2161 }
2162
David Keitel80668952012-07-27 14:25:49 -07002163 /* HACK: Disable wdog */
2164 rc = qpnp_chg_masked_write(chip, chip->chgr_base + 0x62,
2165 0xFF, 0xA0, 1);
2166
David Keitelb4e43542013-04-09 17:30:41 -07002167 /* HACK: use analog EOC */
David Keitel80668952012-07-27 14:25:49 -07002168 rc = qpnp_chg_masked_write(chip, chip->chgr_base +
2169 CHGR_IBAT_TERM_CHGR,
David Keitel9fd07382013-05-02 15:37:44 -07002170 0xFF, 0x08, 1);
David Keitel80668952012-07-27 14:25:49 -07002171
David Keitel80668952012-07-27 14:25:49 -07002172 break;
2173 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002174 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002175 case SMBCL_BUCK_SUBTYPE:
David Keitel9fd07382013-05-02 15:37:44 -07002176 rc = qpnp_chg_toggle_chg_done_logic(chip, 0);
2177 if (rc)
2178 return rc;
2179
David Keitel9201df32013-01-10 18:38:34 -08002180 rc = qpnp_chg_masked_write(chip,
2181 chip->chgr_base + CHGR_BUCK_BCK_VBAT_REG_MODE,
2182 BUCK_VBAT_REG_NODE_SEL_BIT,
2183 BUCK_VBAT_REG_NODE_SEL_BIT, 1);
2184 if (rc) {
2185 pr_debug("failed to enable IR drop comp rc=%d\n", rc);
2186 return rc;
2187 }
David Keitel80668952012-07-27 14:25:49 -07002188 break;
2189 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002190 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002191 case SMBCL_BAT_IF_SUBTYPE:
David Keitel796882d2013-05-14 18:01:11 -07002192 /* Select battery presence detection */
2193 if (chip->bpd_detection == 1)
2194 reg = BAT_ID_EN;
2195 else if (chip->bpd_detection == 2)
2196 reg = BAT_ID_EN | BAT_THM_EN;
2197
2198 rc = qpnp_chg_masked_write(chip,
2199 chip->bat_if_base + BAT_IF_BPD_CTRL,
2200 BAT_IF_BPD_CTRL_SEL,
2201 reg, 1);
2202 if (rc) {
2203 pr_debug("failed to chose BPD rc=%d\n", rc);
2204 return rc;
2205 }
David Keitel85ae4342013-04-16 11:46:00 -07002206 /* Force on VREF_BAT_THM */
2207 rc = qpnp_chg_masked_write(chip,
2208 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2209 VREF_BATT_THERM_FORCE_ON,
2210 VREF_BATT_THERM_FORCE_ON, 1);
2211 if (rc) {
2212 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
2213 return rc;
2214 }
David Keitel80668952012-07-27 14:25:49 -07002215 break;
2216 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002217 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002218 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel9fd07382013-05-02 15:37:44 -07002219 if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
David Keitel80668952012-07-27 14:25:49 -07002220 rc = qpnp_chg_masked_write(chip,
2221 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
2222 ENUM_T_STOP_BIT,
2223 ENUM_T_STOP_BIT, 1);
2224 if (rc) {
2225 pr_err("failed to write enum stop rc=%d\n", rc);
2226 return -ENXIO;
2227 }
2228 }
David Keiteld681cda2012-10-02 15:44:21 -07002229
David Keitel6dc4ed42013-05-17 11:08:58 -07002230 init_data = of_get_regulator_init_data(chip->dev,
2231 spmi_resource->of_node);
2232 if (!init_data) {
2233 pr_err("unable to allocate memory\n");
2234 return -ENOMEM;
2235 }
2236
2237 if (init_data->constraints.name) {
2238 if (of_get_property(chip->dev->of_node,
2239 "otg-parent-supply", NULL))
2240 init_data->supply_regulator = "otg-parent";
2241
2242 rdesc = &(chip->otg_vreg.rdesc);
2243 rdesc->owner = THIS_MODULE;
2244 rdesc->type = REGULATOR_VOLTAGE;
2245 rdesc->ops = &qpnp_chg_otg_reg_ops;
2246 rdesc->name = init_data->constraints.name;
2247
2248 init_data->constraints.valid_ops_mask
2249 |= REGULATOR_CHANGE_STATUS;
2250
2251 chip->otg_vreg.rdev = regulator_register(rdesc,
2252 chip->dev, init_data, chip,
2253 spmi_resource->of_node);
2254 if (IS_ERR(chip->otg_vreg.rdev)) {
2255 rc = PTR_ERR(chip->otg_vreg.rdev);
2256 if (rc != -EPROBE_DEFER)
2257 pr_err("OTG reg failed, rc=%d\n", rc);
2258 return rc;
2259 }
2260 }
2261
David Keiteld681cda2012-10-02 15:44:21 -07002262 rc = qpnp_chg_masked_write(chip,
David Keitel5c3a7702012-12-20 11:13:21 -08002263 chip->usb_chgpth_base + USB_OVP_CTL,
2264 USB_VALID_DEB_20MS,
2265 USB_VALID_DEB_20MS, 1);
2266
2267 rc = qpnp_chg_masked_write(chip,
David Keiteld681cda2012-10-02 15:44:21 -07002268 chip->usb_chgpth_base + CHGR_USB_ENUM_T_STOP,
2269 ENUM_T_STOP_BIT,
2270 ENUM_T_STOP_BIT, 1);
2271
David Keitel344c6972013-04-09 19:28:21 -07002272 rc = qpnp_chg_masked_write(chip,
2273 chip->usb_chgpth_base + SEC_ACCESS,
2274 0xFF,
2275 0xA5, 1);
2276
2277 rc = qpnp_chg_masked_write(chip,
2278 chip->usb_chgpth_base + USB_CHG_GONE_REV_BST,
2279 0xFF,
2280 0x80, 1);
2281
David Keitel80668952012-07-27 14:25:49 -07002282 break;
2283 case SMBB_DC_CHGPTH_SUBTYPE:
2284 break;
2285 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002286 case SMBBP_BOOST_SUBTYPE:
David Keitel6dc4ed42013-05-17 11:08:58 -07002287 init_data = of_get_regulator_init_data(chip->dev,
2288 spmi_resource->of_node);
2289 if (!init_data) {
2290 pr_err("unable to allocate memory\n");
2291 return -ENOMEM;
2292 }
2293
2294 if (init_data->constraints.name) {
2295 if (of_get_property(chip->dev->of_node,
2296 "boost-parent-supply", NULL))
2297 init_data->supply_regulator = "boost-parent";
2298
2299 rdesc = &(chip->boost_vreg.rdesc);
2300 rdesc->owner = THIS_MODULE;
2301 rdesc->type = REGULATOR_VOLTAGE;
2302 rdesc->ops = &qpnp_chg_boost_reg_ops;
2303 rdesc->name = init_data->constraints.name;
2304
2305 init_data->constraints.valid_ops_mask
2306 |= REGULATOR_CHANGE_STATUS
2307 | REGULATOR_CHANGE_VOLTAGE;
2308
2309 chip->boost_vreg.rdev = regulator_register(rdesc,
2310 chip->dev, init_data, chip,
2311 spmi_resource->of_node);
2312 if (IS_ERR(chip->boost_vreg.rdev)) {
2313 rc = PTR_ERR(chip->boost_vreg.rdev);
2314 if (rc != -EPROBE_DEFER)
2315 pr_err("boost reg failed, rc=%d\n", rc);
2316 return rc;
2317 }
2318 }
David Keitel80668952012-07-27 14:25:49 -07002319 break;
2320 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002321 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002322 case SMBCL_MISC_SUBTYPE:
David Keitel52d685e2013-05-02 11:59:05 -07002323 if (subtype == SMBB_MISC_SUBTYPE)
2324 chip->type = SMBB;
2325 else if (subtype == SMBBP_MISC_SUBTYPE)
2326 chip->type = SMBBP;
2327 else if (subtype == SMBCL_MISC_SUBTYPE)
2328 chip->type = SMBCL;
2329
David Keitel80668952012-07-27 14:25:49 -07002330 pr_debug("Setting BOOT_DONE\n");
2331 rc = qpnp_chg_masked_write(chip,
2332 chip->misc_base + CHGR_MISC_BOOT_DONE,
2333 CHGR_BOOT_DONE, CHGR_BOOT_DONE, 1);
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002334 rc = qpnp_chg_read(chip, &reg,
2335 chip->misc_base + MISC_REVISION2, 1);
2336 if (rc) {
2337 pr_err("failed to read revision register rc=%d\n", rc);
2338 return rc;
2339 }
David Keitel80668952012-07-27 14:25:49 -07002340
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002341 chip->revision = reg;
David Keitel80668952012-07-27 14:25:49 -07002342 break;
2343 default:
2344 pr_err("Invalid peripheral subtype\n");
2345 }
2346 return rc;
2347}
2348
David Keitel112ba9c2013-04-12 18:40:43 -07002349#define OF_PROP_READ(chip, prop, qpnp_dt_property, retval, optional) \
2350do { \
2351 if (retval) \
2352 break; \
2353 \
2354 retval = of_property_read_u32(chip->spmi->dev.of_node, \
2355 "qcom," qpnp_dt_property, \
2356 &chip->prop); \
2357 \
2358 if ((retval == -EINVAL) && optional) \
2359 retval = 0; \
2360 else if (retval) \
2361 pr_err("Error reading " #qpnp_dt_property \
2362 " property rc = %d\n", rc); \
2363} while (0)
2364
2365static int
2366qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
2367{
2368 int rc = 0;
David Keitel796882d2013-05-14 18:01:11 -07002369 const char *bpd;
David Keitel112ba9c2013-04-12 18:40:43 -07002370
2371 OF_PROP_READ(chip, max_voltage_mv, "vddmax-mv", rc, 0);
2372 OF_PROP_READ(chip, min_voltage_mv, "vinmin-mv", rc, 0);
2373 OF_PROP_READ(chip, safe_voltage_mv, "vddsafe-mv", rc, 0);
2374 OF_PROP_READ(chip, resume_delta_mv, "vbatdet-delta-mv", rc, 0);
2375 OF_PROP_READ(chip, safe_current, "ibatsafe-ma", rc, 0);
2376 OF_PROP_READ(chip, max_bat_chg_current, "ibatmax-ma", rc, 0);
2377 if (rc)
2378 pr_err("failed to read required dt parameters %d\n", rc);
2379
2380 OF_PROP_READ(chip, term_current, "ibatterm-ma", rc, 1);
2381 OF_PROP_READ(chip, maxinput_dc_ma, "maxinput-dc-ma", rc, 1);
2382 OF_PROP_READ(chip, maxinput_usb_ma, "maxinput-usb-ma", rc, 1);
2383 OF_PROP_READ(chip, warm_bat_decidegc, "warm-bat-decidegc", rc, 1);
2384 OF_PROP_READ(chip, cool_bat_decidegc, "cool-bat-decidegc", rc, 1);
David Keitela4b7b592013-04-11 18:34:35 -07002385 OF_PROP_READ(chip, tchg_mins, "tchg-mins", rc, 1);
David Keitel112ba9c2013-04-12 18:40:43 -07002386 if (rc)
2387 return rc;
2388
David Keitel796882d2013-05-14 18:01:11 -07002389 rc = of_property_read_string(chip->spmi->dev.of_node,
2390 "qcom,bpd-detection", &bpd);
2391 if (rc) {
2392 pr_debug("no bpd-detection specified, ignored\n");
2393 } else {
2394 chip->bpd_detection = get_bpd(bpd);
2395 if (chip->bpd_detection < 0) {
2396 pr_err("failed to determine bpd schema %d\n", rc);
2397 return rc;
2398 }
2399 }
2400
David Keitel112ba9c2013-04-12 18:40:43 -07002401 /* Look up JEITA compliance parameters if cool and warm temp provided */
2402 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2403 rc = qpnp_adc_tm_is_ready();
2404 if (rc) {
2405 pr_err("tm not ready %d\n", rc);
2406 return rc;
2407 }
2408
2409 OF_PROP_READ(chip, warm_bat_chg_ma, "ibatmax-warm-ma", rc, 1);
2410 OF_PROP_READ(chip, cool_bat_chg_ma, "ibatmax-cool-ma", rc, 1);
2411 OF_PROP_READ(chip, warm_bat_mv, "warm-bat-mv", rc, 1);
2412 OF_PROP_READ(chip, cool_bat_mv, "cool-bat-mv", rc, 1);
2413 if (rc)
2414 return rc;
2415 }
2416
2417 /* Get the charging-disabled property */
2418 chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
2419 "qcom,charging-disabled");
2420
David Keitel8b68d2d2013-05-14 23:36:51 -07002421 /* Get the duty-cycle-100p property */
2422 chip->duty_cycle_100p = of_property_read_bool(
2423 chip->spmi->dev.of_node,
2424 "qcom,duty-cycle-100p");
2425 if (chip->duty_cycle_100p) {
2426 rc = qpnp_buck_set_100_duty_cycle_enable(chip, 1);
2427 if (rc) {
2428 pr_err("failed to enable duty cycle %d\n", rc);
2429 return rc;
2430 }
2431 }
2432
David Keitel112ba9c2013-04-12 18:40:43 -07002433 /* Get the fake-batt-values property */
2434 chip->use_default_batt_values =
2435 of_property_read_bool(chip->spmi->dev.of_node,
2436 "qcom,use-default-batt-values");
2437
2438 /* Disable charging when faking battery values */
2439 if (chip->use_default_batt_values)
2440 chip->charging_disabled = true;
2441
2442 of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
2443 &(chip->thermal_levels));
2444
2445 if (chip->thermal_levels > sizeof(int)) {
2446 chip->thermal_mitigation = kzalloc(
2447 chip->thermal_levels,
2448 GFP_KERNEL);
2449
2450 if (chip->thermal_mitigation == NULL) {
2451 pr_err("thermal mitigation kzalloc() failed.\n");
2452 return rc;
2453 }
2454
2455 chip->thermal_levels /= sizeof(int);
2456 rc = of_property_read_u32_array(chip->spmi->dev.of_node,
2457 "qcom,thermal-mitigation",
2458 chip->thermal_mitigation, chip->thermal_levels);
2459 if (rc) {
2460 pr_err("qcom,thermal-mitigation missing in dt\n");
2461 return rc;
2462 }
2463 }
2464
2465 return rc;
2466}
2467
David Keitel80668952012-07-27 14:25:49 -07002468static int __devinit
2469qpnp_charger_probe(struct spmi_device *spmi)
2470{
2471 u8 subtype;
2472 struct qpnp_chg_chip *chip;
2473 struct resource *resource;
2474 struct spmi_resource *spmi_resource;
2475 int rc = 0;
2476
2477 chip = kzalloc(sizeof *chip, GFP_KERNEL);
2478 if (chip == NULL) {
2479 pr_err("kzalloc() failed.\n");
2480 return -ENOMEM;
2481 }
2482
David Keitel80668952012-07-27 14:25:49 -07002483 chip->dev = &(spmi->dev);
2484 chip->spmi = spmi;
2485
2486 chip->usb_psy = power_supply_get_by_name("usb");
2487 if (!chip->usb_psy) {
2488 pr_err("usb supply not found deferring probe\n");
2489 rc = -EPROBE_DEFER;
2490 goto fail_chg_enable;
2491 }
2492
David Keitel112ba9c2013-04-12 18:40:43 -07002493 /* Get all device tree properties */
2494 rc = qpnp_charger_read_dt_props(chip);
2495 if (rc)
David Keitel80668952012-07-27 14:25:49 -07002496 goto fail_chg_enable;
David Keitel3dd5e0f2012-12-12 18:12:36 -08002497
David Keitel80668952012-07-27 14:25:49 -07002498 spmi_for_each_container_dev(spmi_resource, spmi) {
2499 if (!spmi_resource) {
2500 pr_err("qpnp_chg: spmi resource absent\n");
2501 rc = -ENXIO;
2502 goto fail_chg_enable;
2503 }
2504
2505 resource = spmi_get_resource(spmi, spmi_resource,
2506 IORESOURCE_MEM, 0);
2507 if (!(resource && resource->start)) {
2508 pr_err("node %s IO resource absent!\n",
2509 spmi->dev.of_node->full_name);
2510 rc = -ENXIO;
2511 goto fail_chg_enable;
2512 }
2513
2514 rc = qpnp_chg_read(chip, &subtype,
2515 resource->start + REG_OFFSET_PERP_SUBTYPE, 1);
2516 if (rc) {
2517 pr_err("Peripheral subtype read failed rc=%d\n", rc);
2518 goto fail_chg_enable;
2519 }
2520
2521 switch (subtype) {
2522 case SMBB_CHGR_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002523 case SMBBP_CHGR_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002524 case SMBCL_CHGR_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002525 chip->chgr_base = resource->start;
2526 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2527 if (rc) {
2528 pr_err("Failed to init subtype 0x%x rc=%d\n",
2529 subtype, rc);
2530 goto fail_chg_enable;
2531 }
2532 break;
2533 case SMBB_BUCK_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002534 case SMBBP_BUCK_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002535 case SMBCL_BUCK_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002536 chip->buck_base = resource->start;
2537 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2538 if (rc) {
2539 pr_err("Failed to init subtype 0x%x rc=%d\n",
2540 subtype, rc);
2541 goto fail_chg_enable;
2542 }
David Keitel344c6972013-04-09 19:28:21 -07002543
2544 rc = qpnp_chg_masked_write(chip,
2545 chip->buck_base + SEC_ACCESS,
2546 0xFF,
2547 0xA5, 1);
2548
2549 rc = qpnp_chg_masked_write(chip,
2550 chip->buck_base + BUCK_VCHG_OV,
2551 0xff,
2552 0x00, 1);
2553
2554 rc = qpnp_chg_masked_write(chip,
2555 chip->buck_base + SEC_ACCESS,
2556 0xFF,
2557 0xA5, 1);
2558
2559 rc = qpnp_chg_masked_write(chip,
2560 chip->buck_base + BUCK_TEST_SMBC_MODES,
2561 0xFF,
2562 0x80, 1);
2563
David Keitel80668952012-07-27 14:25:49 -07002564 break;
2565 case SMBB_BAT_IF_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002566 case SMBBP_BAT_IF_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002567 case SMBCL_BAT_IF_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002568 chip->bat_if_base = resource->start;
2569 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2570 if (rc) {
2571 pr_err("Failed to init subtype 0x%x rc=%d\n",
2572 subtype, rc);
2573 goto fail_chg_enable;
2574 }
2575 break;
2576 case SMBB_USB_CHGPTH_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002577 case SMBBP_USB_CHGPTH_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002578 case SMBCL_USB_CHGPTH_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002579 chip->usb_chgpth_base = resource->start;
2580 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2581 if (rc) {
David Keitel6dc4ed42013-05-17 11:08:58 -07002582 if (rc != -EPROBE_DEFER)
2583 pr_err("Failed to init subtype 0x%x rc=%d\n",
David Keitel80668952012-07-27 14:25:49 -07002584 subtype, rc);
2585 goto fail_chg_enable;
2586 }
2587 break;
2588 case SMBB_DC_CHGPTH_SUBTYPE:
2589 chip->dc_chgpth_base = resource->start;
2590 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2591 if (rc) {
2592 pr_err("Failed to init subtype 0x%x rc=%d\n",
2593 subtype, rc);
2594 goto fail_chg_enable;
2595 }
2596 break;
2597 case SMBB_BOOST_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002598 case SMBBP_BOOST_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002599 chip->boost_base = resource->start;
2600 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2601 if (rc) {
David Keitel6dc4ed42013-05-17 11:08:58 -07002602 if (rc != -EPROBE_DEFER)
2603 pr_err("Failed to init subtype 0x%x rc=%d\n",
David Keitel80668952012-07-27 14:25:49 -07002604 subtype, rc);
2605 goto fail_chg_enable;
2606 }
2607 break;
2608 case SMBB_MISC_SUBTYPE:
David Keitelf2170cc2013-02-20 17:49:03 -08002609 case SMBBP_MISC_SUBTYPE:
David Keitel46c9f7b2013-04-02 19:54:12 -07002610 case SMBCL_MISC_SUBTYPE:
David Keitel80668952012-07-27 14:25:49 -07002611 chip->misc_base = resource->start;
2612 rc = qpnp_chg_hwinit(chip, subtype, spmi_resource);
2613 if (rc) {
2614 pr_err("Failed to init subtype=0x%x rc=%d\n",
2615 subtype, rc);
2616 goto fail_chg_enable;
2617 }
2618 break;
2619 default:
2620 pr_err("Invalid peripheral subtype=0x%x\n", subtype);
2621 rc = -EINVAL;
2622 goto fail_chg_enable;
2623 }
2624 }
2625 dev_set_drvdata(&spmi->dev, chip);
2626 device_init_wakeup(&spmi->dev, 1);
2627
David Keitelf2170cc2013-02-20 17:49:03 -08002628 if (chip->bat_if_base) {
2629 rc = qpnp_vadc_is_ready();
2630 if (rc)
2631 goto fail_chg_enable;
David Keitel80668952012-07-27 14:25:49 -07002632
David Keitelf2170cc2013-02-20 17:49:03 -08002633 chip->batt_psy.name = "battery";
2634 chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
2635 chip->batt_psy.properties = msm_batt_power_props;
2636 chip->batt_psy.num_properties =
2637 ARRAY_SIZE(msm_batt_power_props);
2638 chip->batt_psy.get_property = qpnp_batt_power_get_property;
2639 chip->batt_psy.set_property = qpnp_batt_power_set_property;
2640 chip->batt_psy.property_is_writeable =
2641 qpnp_batt_property_is_writeable;
2642 chip->batt_psy.external_power_changed =
David Keitel80668952012-07-27 14:25:49 -07002643 qpnp_batt_external_power_changed;
Xiaozhe Shi890fbf42013-05-02 16:42:53 -07002644 chip->batt_psy.supplied_to = pm_batt_supplied_to;
2645 chip->batt_psy.num_supplicants =
2646 ARRAY_SIZE(pm_batt_supplied_to);
David Keitel80668952012-07-27 14:25:49 -07002647
David Keitelf2170cc2013-02-20 17:49:03 -08002648 rc = power_supply_register(chip->dev, &chip->batt_psy);
2649 if (rc < 0) {
2650 pr_err("batt failed to register rc = %d\n", rc);
2651 goto fail_chg_enable;
2652 }
David Keitel79f4c932013-04-03 16:08:39 -07002653 INIT_WORK(&chip->adc_measure_work,
2654 qpnp_bat_if_adc_measure_work);
David Keitelc7093b02013-02-14 12:50:04 -08002655 }
2656
David Keitel9fd07382013-05-02 15:37:44 -07002657 wake_lock_init(&chip->eoc_wake_lock,
2658 WAKE_LOCK_SUSPEND, "qpnp-chg-eoc-lock");
2659 INIT_DELAYED_WORK(&chip->eoc_work, qpnp_eoc_work);
David Keitel5910eea2013-05-02 15:32:25 -07002660 INIT_DELAYED_WORK(&chip->arb_stop_work, qpnp_arb_stop_work);
2661
David Keitelf2170cc2013-02-20 17:49:03 -08002662 if (chip->dc_chgpth_base) {
2663 chip->dc_psy.name = "qpnp-dc";
2664 chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
2665 chip->dc_psy.supplied_to = pm_power_supplied_to;
2666 chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
2667 chip->dc_psy.properties = pm_power_props_mains;
2668 chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
2669 chip->dc_psy.get_property = qpnp_power_get_property_mains;
2670
2671 rc = power_supply_register(chip->dev, &chip->dc_psy);
2672 if (rc < 0) {
2673 pr_err("power_supply_register dc failed rc=%d\n", rc);
2674 goto unregister_batt;
2675 }
David Keitel80668952012-07-27 14:25:49 -07002676 }
2677
Sridhar Parasuramae183bd2012-12-21 09:28:46 -08002678 /* Turn on appropriate workaround flags */
2679 qpnp_chg_setup_flags(chip);
2680
David Keitelf2170cc2013-02-20 17:49:03 -08002681 if (chip->maxinput_dc_ma && chip->dc_chgpth_base) {
David Keitel22ed2232013-01-28 11:04:07 -08002682 rc = qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
2683 if (rc) {
2684 pr_err("Error setting idcmax property %d\n", rc);
David Keitelf2170cc2013-02-20 17:49:03 -08002685 goto unregister_batt;
David Keitel22ed2232013-01-28 11:04:07 -08002686 }
2687 }
2688
David Keitel0c1a4532013-03-21 16:39:06 -07002689 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc) {
2690 chip->adc_param.low_temp = chip->cool_bat_decidegc;
2691 chip->adc_param.high_temp = chip->warm_bat_decidegc;
David Keitel454ee842013-03-08 16:19:11 -08002692 chip->adc_param.timer_interval = ADC_MEAS2_INTERVAL_1S;
2693 chip->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
2694 chip->adc_param.btm_ctx = chip;
2695 chip->adc_param.threshold_notification =
2696 qpnp_chg_adc_notification;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -08002697 chip->adc_param.channel = LR_MUX1_BATT_THERM;
David Keitel0c1a4532013-03-21 16:39:06 -07002698
2699 if (get_prop_batt_present(chip)) {
2700 rc = qpnp_adc_tm_channel_measure(&chip->adc_param);
2701 if (rc) {
2702 pr_err("request ADC error %d\n", rc);
2703 goto fail_chg_enable;
2704 }
David Keitel454ee842013-03-08 16:19:11 -08002705 }
2706 }
2707
David Keitel03ee6b52012-10-22 12:25:19 -07002708 qpnp_chg_charge_en(chip, !chip->charging_disabled);
David Keitelb1ddb742012-11-06 19:05:51 -08002709 qpnp_chg_force_run_on_batt(chip, chip->charging_disabled);
David Keitelbf359042012-10-19 16:54:58 -07002710
David Keitel0f35be42013-04-16 11:10:40 -07002711 rc = qpnp_chg_request_irqs(chip);
2712 if (rc) {
2713 pr_err("failed to request interrupts %d\n", rc);
2714 goto unregister_batt;
2715 }
2716
David Keitel9fd07382013-05-02 15:37:44 -07002717 qpnp_chg_usb_usbin_valid_irq_handler(USBIN_VALID_IRQ, chip);
2718 power_supply_set_present(chip->usb_psy,
2719 qpnp_chg_is_usb_chg_plugged_in(chip));
2720
David Keitel3c62b472013-05-06 15:38:11 -07002721 /* Set USB psy online to avoid userspace from shutting down if battery
2722 * capacity is at zero and no chargers online. */
2723 if (qpnp_chg_is_usb_chg_plugged_in(chip))
2724 power_supply_set_online(chip->usb_psy, 1);
2725
David Keitel796882d2013-05-14 18:01:11 -07002726 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 -08002727 chip->charging_disabled,
David Keitel796882d2013-05-14 18:01:11 -07002728 chip->bpd_detection,
Abhijeet Dharmapurikar2d996b12013-01-03 17:48:02 -08002729 qpnp_chg_is_usb_chg_plugged_in(chip),
2730 qpnp_chg_is_dc_chg_plugged_in(chip),
2731 get_prop_batt_present(chip),
2732 get_prop_batt_health(chip));
David Keitel80668952012-07-27 14:25:49 -07002733 return 0;
2734
David Keitelc7093b02013-02-14 12:50:04 -08002735unregister_batt:
David Keitelf2170cc2013-02-20 17:49:03 -08002736 if (chip->bat_if_base)
2737 power_supply_unregister(&chip->batt_psy);
David Keitel80668952012-07-27 14:25:49 -07002738fail_chg_enable:
David Keitelbe208252013-01-31 14:49:25 -08002739 kfree(chip->thermal_mitigation);
David Keitel80668952012-07-27 14:25:49 -07002740 kfree(chip);
2741 dev_set_drvdata(&spmi->dev, NULL);
2742 return rc;
2743}
2744
2745static int __devexit
2746qpnp_charger_remove(struct spmi_device *spmi)
2747{
2748 struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
David Keitel0c1a4532013-03-21 16:39:06 -07002749 if (chip->cool_bat_decidegc && chip->warm_bat_decidegc
2750 && chip->batt_present) {
2751 qpnp_adc_tm_disable_chan_meas(&chip->adc_param);
2752 }
David Keitel79f4c932013-04-03 16:08:39 -07002753 cancel_work_sync(&chip->adc_measure_work);
David Keitel9fd07382013-05-02 15:37:44 -07002754 cancel_delayed_work_sync(&chip->eoc_work);
David Keitel79f4c932013-04-03 16:08:39 -07002755
David Keitel6dc4ed42013-05-17 11:08:58 -07002756 if (chip->otg_vreg.rdev)
2757 regulator_unregister(chip->otg_vreg.rdev);
2758
2759 if (chip->boost_vreg.rdev)
2760 regulator_unregister(chip->boost_vreg.rdev);
2761
David Keitel80668952012-07-27 14:25:49 -07002762 dev_set_drvdata(&spmi->dev, NULL);
2763 kfree(chip);
2764
2765 return 0;
2766}
2767
David Keitel85ae4342013-04-16 11:46:00 -07002768static int qpnp_chg_resume(struct device *dev)
2769{
2770 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2771 int rc = 0;
2772
2773 rc = qpnp_chg_masked_write(chip,
2774 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2775 VREF_BATT_THERM_FORCE_ON,
2776 VREF_BATT_THERM_FORCE_ON, 1);
2777 if (rc)
2778 pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
2779
2780 return rc;
2781}
2782
2783static int qpnp_chg_suspend(struct device *dev)
2784{
2785 struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
2786 int rc = 0;
2787
2788 rc = qpnp_chg_masked_write(chip,
2789 chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
2790 VREF_BATT_THERM_FORCE_ON,
2791 VREF_BAT_THM_ENABLED_FSM, 1);
2792 if (rc)
2793 pr_debug("failed to enable FSM ctrl VREF_BAT_THM rc=%d\n", rc);
2794
2795 return rc;
2796}
2797
David Keitel723d5012013-05-03 13:17:27 -07002798static const struct dev_pm_ops qpnp_chg_pm_ops = {
David Keitel85ae4342013-04-16 11:46:00 -07002799 .resume = qpnp_chg_resume,
2800 .suspend = qpnp_chg_suspend,
2801};
2802
David Keitel80668952012-07-27 14:25:49 -07002803static struct spmi_driver qpnp_charger_driver = {
2804 .probe = qpnp_charger_probe,
2805 .remove = __devexit_p(qpnp_charger_remove),
2806 .driver = {
David Keitel723d5012013-05-03 13:17:27 -07002807 .name = QPNP_CHARGER_DEV_NAME,
2808 .owner = THIS_MODULE,
2809 .of_match_table = qpnp_charger_match_table,
2810 .pm = &qpnp_chg_pm_ops,
David Keitel80668952012-07-27 14:25:49 -07002811 },
2812};
2813
2814/**
2815 * qpnp_chg_init() - register spmi driver for qpnp-chg
2816 */
2817int __init
2818qpnp_chg_init(void)
2819{
2820 return spmi_driver_register(&qpnp_charger_driver);
2821}
2822module_init(qpnp_chg_init);
2823
2824static void __exit
2825qpnp_chg_exit(void)
2826{
2827 spmi_driver_unregister(&qpnp_charger_driver);
2828}
2829module_exit(qpnp_chg_exit);
2830
2831
2832MODULE_DESCRIPTION("QPNP charger driver");
2833MODULE_LICENSE("GPL v2");
2834MODULE_ALIAS("platform:" QPNP_CHARGER_DEV_NAME);