blob: b07efdf84a32fe77cef21525ebc05f532ab52773 [file] [log] [blame]
Harry Yang4b7db0f2017-11-27 10:50:44 -08001/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/debugfs.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/regmap.h>
19#include <linux/power_supply.h>
20#include <linux/of.h>
21#include <linux/of_irq.h>
22#include <linux/log2.h>
23#include <linux/qpnp/qpnp-revid.h>
24#include <linux/regulator/driver.h>
25#include <linux/regulator/of_regulator.h>
26#include <linux/regulator/machine.h>
27#include <linux/pmic-voter.h>
28#include "smb5-reg.h"
29#include "smb5-lib.h"
30
Ashay Jaiswala9e10912018-02-02 14:03:35 +053031static struct smb_params smb5_pmi632_params = {
32 .fcc = {
33 .name = "fast charge current",
34 .reg = CHGR_FAST_CHARGE_CURRENT_CFG_REG,
35 .min_u = 0,
36 .max_u = 3000000,
37 .step_u = 50000,
38 },
39 .fv = {
40 .name = "float voltage",
41 .reg = CHGR_FLOAT_VOLTAGE_CFG_REG,
42 .min_u = 3600000,
43 .max_u = 4800000,
44 .step_u = 10000,
45 },
46 .usb_icl = {
47 .name = "usb input current limit",
48 .reg = USBIN_CURRENT_LIMIT_CFG_REG,
49 .min_u = 0,
50 .max_u = 3000000,
51 .step_u = 50000,
52 },
53 .icl_stat = {
54 .name = "input current limit status",
55 .reg = AICL_ICL_STATUS_REG,
56 .min_u = 0,
57 .max_u = 3000000,
58 .step_u = 50000,
59 },
60 .otg_cl = {
61 .name = "usb otg current limit",
62 .reg = DCDC_OTG_CURRENT_LIMIT_CFG_REG,
63 .min_u = 500000,
64 .max_u = 1000000,
65 .step_u = 250000,
66 },
67 .jeita_cc_comp_hot = {
68 .name = "jeita fcc reduction",
69 .reg = JEITA_CCCOMP_CFG_HOT_REG,
70 .min_u = 0,
71 .max_u = 1575000,
72 .step_u = 25000,
73 },
74 .jeita_cc_comp_cold = {
75 .name = "jeita fcc reduction",
76 .reg = JEITA_CCCOMP_CFG_COLD_REG,
77 .min_u = 0,
78 .max_u = 1575000,
79 .step_u = 25000,
80 },
81 .freq_switcher = {
82 .name = "switching frequency",
83 .reg = DCDC_FSW_SEL_REG,
84 .min_u = 600,
85 .max_u = 1200,
86 .step_u = 400,
87 .set_proc = smblib_set_chg_freq,
88 },
89};
90
91static struct smb_params smb5_pmi855_params = {
Harry Yang4b7db0f2017-11-27 10:50:44 -080092 .fcc = {
93 .name = "fast charge current",
94 .reg = CHGR_FAST_CHARGE_CURRENT_CFG_REG,
95 .min_u = 0,
96 .max_u = 8000000,
97 .step_u = 25000,
98 },
99 .fv = {
100 .name = "float voltage",
101 .reg = CHGR_FLOAT_VOLTAGE_CFG_REG,
102 .min_u = 3600000,
103 .max_u = 4790000,
104 .step_u = 10000,
105 },
106 .usb_icl = {
107 .name = "usb input current limit",
108 .reg = USBIN_CURRENT_LIMIT_CFG_REG,
109 .min_u = 0,
110 .max_u = 5000000,
111 .step_u = 50000,
112 },
113 .icl_stat = {
114 .name = "input current limit status",
115 .reg = AICL_ICL_STATUS_REG,
116 .min_u = 0,
117 .max_u = 5000000,
118 .step_u = 50000,
119 },
120 .otg_cl = {
121 .name = "usb otg current limit",
122 .reg = DCDC_OTG_CURRENT_LIMIT_CFG_REG,
123 .min_u = 500000,
124 .max_u = 3000000,
125 .step_u = 500000,
126 },
127 .jeita_cc_comp_hot = {
128 .name = "jeita fcc reduction",
129 .reg = JEITA_CCCOMP_CFG_HOT_REG,
130 .min_u = 0,
131 .max_u = 8000000,
132 .step_u = 25000,
133 .set_proc = NULL,
134 },
135 .jeita_cc_comp_cold = {
136 .name = "jeita fcc reduction",
137 .reg = JEITA_CCCOMP_CFG_COLD_REG,
138 .min_u = 0,
139 .max_u = 8000000,
140 .step_u = 25000,
141 .set_proc = NULL,
142 },
143 .freq_switcher = {
144 .name = "switching frequency",
145 .reg = DCDC_FSW_SEL_REG,
146 .min_u = 1200,
147 .max_u = 2400,
148 .step_u = 400,
149 .set_proc = NULL,
150 },
151};
152
153struct smb_dt_props {
154 int usb_icl_ua;
155 struct device_node *revid_dev_node;
156 enum float_options float_option;
157 int chg_inhibit_thr_mv;
158 bool no_battery;
159 bool hvdcp_disable;
160 bool auto_recharge_soc;
161 int wd_bark_time;
162 int batt_profile_fcc_ua;
163 int batt_profile_fv_uv;
164};
165
166struct smb5 {
167 struct smb_charger chg;
168 struct dentry *dfs_root;
169 struct smb_dt_props dt;
170};
171
172static int __debug_mask;
173module_param_named(
174 debug_mask, __debug_mask, int, 0600
175);
176
177static int __weak_chg_icl_ua = 500000;
178module_param_named(
179 weak_chg_icl_ua, __weak_chg_icl_ua, int, 0600
180);
181
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530182#define PMI632_MAX_ICL_UA 3000000
183static int smb5_chg_config_init(struct smb5 *chip)
184{
185 struct smb_charger *chg = &chip->chg;
186 struct pmic_revid_data *pmic_rev_id;
187 struct device_node *revid_dev_node;
188 int rc = 0;
189
190 revid_dev_node = of_parse_phandle(chip->chg.dev->of_node,
191 "qcom,pmic-revid", 0);
192 if (!revid_dev_node) {
193 pr_err("Missing qcom,pmic-revid property\n");
194 return -EINVAL;
195 }
196
197 pmic_rev_id = get_revid_data(revid_dev_node);
198 if (IS_ERR_OR_NULL(pmic_rev_id)) {
199 /*
200 * the revid peripheral must be registered, any failure
201 * here only indicates that the rev-id module has not
202 * probed yet.
203 */
204 rc = -EPROBE_DEFER;
205 goto out;
206 }
207
208 switch (pmic_rev_id->pmic_subtype) {
209 case PM855B_SUBTYPE:
210 chip->chg.smb_version = PM855B_SUBTYPE;
211 chg->param = smb5_pmi855_params;
212 chg->name = "pm855b_charger";
213 break;
214 case PMI632_SUBTYPE:
215 chip->chg.smb_version = PMI632_SUBTYPE;
216 chg->param = smb5_pmi632_params;
217 chg->use_extcon = true;
218 chg->name = "pmi632_charger";
219 chg->hw_max_icl_ua =
220 (chip->dt.usb_icl_ua > 0) ? chip->dt.usb_icl_ua
221 : PMI632_MAX_ICL_UA;
222 chg->chg_freq.freq_5V = 600;
223 chg->chg_freq.freq_6V_8V = 800;
224 chg->chg_freq.freq_9V = 1050;
225 chg->chg_freq.freq_removal = 1050;
226 chg->chg_freq.freq_below_otg_threshold = 800;
227 chg->chg_freq.freq_above_otg_threshold = 800;
228 break;
229 default:
230 pr_err("PMIC subtype %d not supported\n",
231 pmic_rev_id->pmic_subtype);
232 rc = -EINVAL;
233 }
234
235out:
236 of_node_put(revid_dev_node);
237 return rc;
238}
239
Harry Yang4b7db0f2017-11-27 10:50:44 -0800240#define MICRO_1P5A 1500000
241#define MICRO_P1A 100000
242#define OTG_DEFAULT_DEGLITCH_TIME_MS 50
243#define MIN_WD_BARK_TIME 16
244#define DEFAULT_WD_BARK_TIME 64
245#define BITE_WDOG_TIMEOUT_8S 0x3
246#define BARK_WDOG_TIMEOUT_MASK GENMASK(3, 2)
247#define BARK_WDOG_TIMEOUT_SHIFT 2
248static int smb5_parse_dt(struct smb5 *chip)
249{
250 struct smb_charger *chg = &chip->chg;
251 struct device_node *node = chg->dev->of_node;
252 int rc, byte_len;
253
254 if (!node) {
255 pr_err("device tree node missing\n");
256 return -EINVAL;
257 }
258
259 chg->step_chg_enabled = of_property_read_bool(node,
260 "qcom,step-charging-enable");
261
262 chg->sw_jeita_enabled = of_property_read_bool(node,
263 "qcom,sw-jeita-enable");
264
265 rc = of_property_read_u32(node, "qcom,wd-bark-time-secs",
266 &chip->dt.wd_bark_time);
267 if (rc < 0 || chip->dt.wd_bark_time < MIN_WD_BARK_TIME)
268 chip->dt.wd_bark_time = DEFAULT_WD_BARK_TIME;
269
270 chip->dt.no_battery = of_property_read_bool(node,
271 "qcom,batteryless-platform");
272
273 rc = of_property_read_u32(node,
274 "qcom,fcc-max-ua", &chip->dt.batt_profile_fcc_ua);
275 if (rc < 0)
276 chip->dt.batt_profile_fcc_ua = -EINVAL;
277
278 rc = of_property_read_u32(node,
279 "qcom,fv-max-uv", &chip->dt.batt_profile_fv_uv);
280 if (rc < 0)
281 chip->dt.batt_profile_fv_uv = -EINVAL;
282
283 rc = of_property_read_u32(node,
284 "qcom,usb-icl-ua", &chip->dt.usb_icl_ua);
285 if (rc < 0)
286 chip->dt.usb_icl_ua = -EINVAL;
287
288 rc = of_property_read_u32(node,
289 "qcom,otg-cl-ua", &chg->otg_cl_ua);
290 if (rc < 0)
291 chg->otg_cl_ua = MICRO_1P5A;
292
293 if (of_find_property(node, "qcom,thermal-mitigation", &byte_len)) {
294 chg->thermal_mitigation = devm_kzalloc(chg->dev, byte_len,
295 GFP_KERNEL);
296
297 if (chg->thermal_mitigation == NULL)
298 return -ENOMEM;
299
300 chg->thermal_levels = byte_len / sizeof(u32);
301 rc = of_property_read_u32_array(node,
302 "qcom,thermal-mitigation",
303 chg->thermal_mitigation,
304 chg->thermal_levels);
305 if (rc < 0) {
306 dev_err(chg->dev,
307 "Couldn't read threm limits rc = %d\n", rc);
308 return rc;
309 }
310 }
311
312 rc = of_property_read_u32(node, "qcom,float-option",
313 &chip->dt.float_option);
314 if (!rc && (chip->dt.float_option < 0 || chip->dt.float_option > 4)) {
315 pr_err("qcom,float-option is out of range [0, 4]\n");
316 return -EINVAL;
317 }
318
319 chip->dt.hvdcp_disable = of_property_read_bool(node,
320 "qcom,hvdcp-disable");
321
322
323 rc = of_property_read_u32(node, "qcom,chg-inhibit-threshold-mv",
324 &chip->dt.chg_inhibit_thr_mv);
325 if (!rc && (chip->dt.chg_inhibit_thr_mv < 0 ||
326 chip->dt.chg_inhibit_thr_mv > 300)) {
327 pr_err("qcom,chg-inhibit-threshold-mv is incorrect\n");
328 return -EINVAL;
329 }
330
331 chip->dt.auto_recharge_soc = of_property_read_bool(node,
332 "qcom,auto-recharge-soc");
333
Harry Yang4b7db0f2017-11-27 10:50:44 -0800334 chg->dcp_icl_ua = chip->dt.usb_icl_ua;
335
336 chg->suspend_input_on_debug_batt = of_property_read_bool(node,
337 "qcom,suspend-input-on-debug-batt");
338
339 rc = of_property_read_u32(node, "qcom,otg-deglitch-time-ms",
340 &chg->otg_delay_ms);
341 if (rc < 0)
342 chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS;
343
344 return 0;
345}
346
347/************************
348 * USB PSY REGISTRATION *
349 ************************/
350static enum power_supply_property smb5_usb_props[] = {
351 POWER_SUPPLY_PROP_PRESENT,
352 POWER_SUPPLY_PROP_ONLINE,
353 POWER_SUPPLY_PROP_PD_CURRENT_MAX,
354 POWER_SUPPLY_PROP_CURRENT_MAX,
355 POWER_SUPPLY_PROP_TYPE,
356 POWER_SUPPLY_PROP_TYPEC_MODE,
357 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE,
358 POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION,
359 POWER_SUPPLY_PROP_PD_ALLOWED,
360 POWER_SUPPLY_PROP_PD_ACTIVE,
361 POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
362 POWER_SUPPLY_PROP_INPUT_CURRENT_NOW,
363 POWER_SUPPLY_PROP_BOOST_CURRENT,
364 POWER_SUPPLY_PROP_PE_START,
365 POWER_SUPPLY_PROP_CTM_CURRENT_MAX,
366 POWER_SUPPLY_PROP_HW_CURRENT_MAX,
367 POWER_SUPPLY_PROP_REAL_TYPE,
368 POWER_SUPPLY_PROP_PR_SWAP,
369 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX,
370 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN,
371 POWER_SUPPLY_PROP_SDP_CURRENT_MAX,
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530372 POWER_SUPPLY_PROP_CONNECTOR_TYPE,
Ashay Jaiswal1f71b412017-10-31 14:33:27 +0530373 POWER_SUPPLY_PROP_VOLTAGE_MAX,
Harry Yang4b7db0f2017-11-27 10:50:44 -0800374};
375
376static int smb5_usb_get_prop(struct power_supply *psy,
377 enum power_supply_property psp,
378 union power_supply_propval *val)
379{
380 struct smb5 *chip = power_supply_get_drvdata(psy);
381 struct smb_charger *chg = &chip->chg;
382 int rc = 0;
383
384 switch (psp) {
385 case POWER_SUPPLY_PROP_PRESENT:
386 rc = smblib_get_prop_usb_present(chg, val);
387 break;
388 case POWER_SUPPLY_PROP_ONLINE:
389 rc = smblib_get_prop_usb_online(chg, val);
390 if (!val->intval)
391 break;
392
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530393 if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) ||
394 (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB))
395 && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB))
Harry Yang4b7db0f2017-11-27 10:50:44 -0800396 val->intval = 0;
397 else
398 val->intval = 1;
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530399
Harry Yang4b7db0f2017-11-27 10:50:44 -0800400 if (chg->real_charger_type == POWER_SUPPLY_TYPE_UNKNOWN)
401 val->intval = 0;
402 break;
403 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
404 rc = smblib_get_prop_usb_voltage_max(chg, val);
405 break;
406 case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
407 val->intval = get_client_vote(chg->usb_icl_votable, PD_VOTER);
408 break;
409 case POWER_SUPPLY_PROP_CURRENT_MAX:
410 rc = smblib_get_prop_input_current_settled(chg, val);
411 break;
412 case POWER_SUPPLY_PROP_TYPE:
413 val->intval = POWER_SUPPLY_TYPE_USB_PD;
414 break;
415 case POWER_SUPPLY_PROP_REAL_TYPE:
416 val->intval = chg->real_charger_type;
417 break;
418 case POWER_SUPPLY_PROP_TYPEC_MODE:
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530419 if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
Harry Yang4b7db0f2017-11-27 10:50:44 -0800420 val->intval = POWER_SUPPLY_TYPEC_NONE;
421 else
422 val->intval = chg->typec_mode;
423 break;
424 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530425 if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
Harry Yang4b7db0f2017-11-27 10:50:44 -0800426 val->intval = POWER_SUPPLY_TYPEC_PR_NONE;
427 else
428 rc = smblib_get_prop_typec_power_role(chg, val);
429 break;
430 case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION:
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530431 if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
Harry Yang4b7db0f2017-11-27 10:50:44 -0800432 val->intval = 0;
433 else
434 rc = smblib_get_prop_typec_cc_orientation(chg, val);
435 break;
436 case POWER_SUPPLY_PROP_PD_ALLOWED:
437 rc = smblib_get_prop_pd_allowed(chg, val);
438 break;
439 case POWER_SUPPLY_PROP_PD_ACTIVE:
440 val->intval = chg->pd_active;
441 break;
442 case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
443 rc = smblib_get_prop_input_current_settled(chg, val);
444 break;
445 case POWER_SUPPLY_PROP_BOOST_CURRENT:
446 val->intval = chg->boost_current_ua;
447 break;
448 case POWER_SUPPLY_PROP_PD_IN_HARD_RESET:
449 rc = smblib_get_prop_pd_in_hard_reset(chg, val);
450 break;
451 case POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED:
452 val->intval = chg->system_suspend_supported;
453 break;
454 case POWER_SUPPLY_PROP_PE_START:
455 rc = smblib_get_pe_start(chg, val);
456 break;
457 case POWER_SUPPLY_PROP_CTM_CURRENT_MAX:
458 val->intval = get_client_vote(chg->usb_icl_votable, CTM_VOTER);
459 break;
460 case POWER_SUPPLY_PROP_HW_CURRENT_MAX:
461 rc = smblib_get_charge_current(chg, &val->intval);
462 break;
463 case POWER_SUPPLY_PROP_PR_SWAP:
464 rc = smblib_get_prop_pr_swap_in_progress(chg, val);
465 break;
466 case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX:
467 val->intval = chg->voltage_max_uv;
468 break;
469 case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN:
470 val->intval = chg->voltage_min_uv;
471 break;
472 case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
473 val->intval = get_client_vote(chg->usb_icl_votable,
474 USB_PSY_VOTER);
475 break;
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530476 case POWER_SUPPLY_PROP_CONNECTOR_TYPE:
477 val->intval = chg->connector_type;
478 break;
Harry Yang4b7db0f2017-11-27 10:50:44 -0800479 default:
480 pr_err("get prop %d is not supported in usb\n", psp);
481 rc = -EINVAL;
482 break;
483 }
484
485 if (rc < 0) {
486 pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
487 return -ENODATA;
488 }
489
490 return 0;
491}
492
493static int smb5_usb_set_prop(struct power_supply *psy,
494 enum power_supply_property psp,
495 const union power_supply_propval *val)
496{
497 struct smb5 *chip = power_supply_get_drvdata(psy);
498 struct smb_charger *chg = &chip->chg;
499 int rc = 0;
500
501 mutex_lock(&chg->lock);
502 if (!chg->typec_present) {
503 rc = -EINVAL;
504 goto unlock;
505 }
506
507 switch (psp) {
508 case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
509 rc = smblib_set_prop_pd_current_max(chg, val);
510 break;
511 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
512 rc = smblib_set_prop_typec_power_role(chg, val);
513 break;
514 case POWER_SUPPLY_PROP_PD_ACTIVE:
515 rc = smblib_set_prop_pd_active(chg, val);
516 break;
517 case POWER_SUPPLY_PROP_PD_IN_HARD_RESET:
518 rc = smblib_set_prop_pd_in_hard_reset(chg, val);
519 break;
520 case POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED:
521 chg->system_suspend_supported = val->intval;
522 break;
523 case POWER_SUPPLY_PROP_BOOST_CURRENT:
524 rc = smblib_set_prop_boost_current(chg, val);
525 break;
526 case POWER_SUPPLY_PROP_CTM_CURRENT_MAX:
527 rc = vote(chg->usb_icl_votable, CTM_VOTER,
528 val->intval >= 0, val->intval);
529 break;
530 case POWER_SUPPLY_PROP_PR_SWAP:
531 rc = smblib_set_prop_pr_swap_in_progress(chg, val);
532 break;
533 case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX:
534 rc = smblib_set_prop_pd_voltage_max(chg, val);
535 break;
536 case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN:
537 rc = smblib_set_prop_pd_voltage_min(chg, val);
538 break;
539 case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
540 rc = smblib_set_prop_sdp_current_max(chg, val);
541 break;
542 default:
543 pr_err("set prop %d is not supported\n", psp);
544 rc = -EINVAL;
545 break;
546 }
547
548unlock:
549 mutex_unlock(&chg->lock);
550 return rc;
551}
552
553static int smb5_usb_prop_is_writeable(struct power_supply *psy,
554 enum power_supply_property psp)
555{
556 switch (psp) {
557 case POWER_SUPPLY_PROP_CTM_CURRENT_MAX:
558 return 1;
559 default:
560 break;
561 }
562
563 return 0;
564}
565
566static const struct power_supply_desc usb_psy_desc = {
567 .name = "usb",
568 .type = POWER_SUPPLY_TYPE_USB_PD,
569 .properties = smb5_usb_props,
570 .num_properties = ARRAY_SIZE(smb5_usb_props),
571 .get_property = smb5_usb_get_prop,
572 .set_property = smb5_usb_set_prop,
573 .property_is_writeable = smb5_usb_prop_is_writeable,
574};
575
576static int smb5_init_usb_psy(struct smb5 *chip)
577{
578 struct power_supply_config usb_cfg = {};
579 struct smb_charger *chg = &chip->chg;
580
581 usb_cfg.drv_data = chip;
582 usb_cfg.of_node = chg->dev->of_node;
583 chg->usb_psy = devm_power_supply_register(chg->dev,
584 &usb_psy_desc,
585 &usb_cfg);
586 if (IS_ERR(chg->usb_psy)) {
587 pr_err("Couldn't register USB power supply\n");
588 return PTR_ERR(chg->usb_psy);
589 }
590
591 return 0;
592}
593
594/********************************
595 * USB PC_PORT PSY REGISTRATION *
596 ********************************/
597static enum power_supply_property smb5_usb_port_props[] = {
598 POWER_SUPPLY_PROP_TYPE,
599 POWER_SUPPLY_PROP_ONLINE,
600 POWER_SUPPLY_PROP_VOLTAGE_MAX,
601 POWER_SUPPLY_PROP_CURRENT_MAX,
602};
603
604static int smb5_usb_port_get_prop(struct power_supply *psy,
605 enum power_supply_property psp,
606 union power_supply_propval *val)
607{
608 struct smb5 *chip = power_supply_get_drvdata(psy);
609 struct smb_charger *chg = &chip->chg;
610 int rc = 0;
611
612 switch (psp) {
613 case POWER_SUPPLY_PROP_TYPE:
614 val->intval = POWER_SUPPLY_TYPE_USB;
615 break;
616 case POWER_SUPPLY_PROP_ONLINE:
617 rc = smblib_get_prop_usb_online(chg, val);
618 if (!val->intval)
619 break;
620
Ashay Jaiswala9e10912018-02-02 14:03:35 +0530621 if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) ||
622 (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB))
623 && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB))
Harry Yang4b7db0f2017-11-27 10:50:44 -0800624 val->intval = 1;
625 else
626 val->intval = 0;
627 break;
628 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
629 val->intval = 5000000;
630 break;
631 case POWER_SUPPLY_PROP_CURRENT_MAX:
632 rc = smblib_get_prop_input_current_settled(chg, val);
633 break;
634 default:
635 pr_err_ratelimited("Get prop %d is not supported in pc_port\n",
636 psp);
637 return -EINVAL;
638 }
639
640 if (rc < 0) {
641 pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
642 return -ENODATA;
643 }
644
645 return 0;
646}
647
648static int smb5_usb_port_set_prop(struct power_supply *psy,
649 enum power_supply_property psp,
650 const union power_supply_propval *val)
651{
652 int rc = 0;
653
654 switch (psp) {
655 default:
656 pr_err_ratelimited("Set prop %d is not supported in pc_port\n",
657 psp);
658 rc = -EINVAL;
659 break;
660 }
661
662 return rc;
663}
664
665static const struct power_supply_desc usb_port_psy_desc = {
666 .name = "pc_port",
667 .type = POWER_SUPPLY_TYPE_USB,
668 .properties = smb5_usb_port_props,
669 .num_properties = ARRAY_SIZE(smb5_usb_port_props),
670 .get_property = smb5_usb_port_get_prop,
671 .set_property = smb5_usb_port_set_prop,
672};
673
674static int smb5_init_usb_port_psy(struct smb5 *chip)
675{
676 struct power_supply_config usb_port_cfg = {};
677 struct smb_charger *chg = &chip->chg;
678
679 usb_port_cfg.drv_data = chip;
680 usb_port_cfg.of_node = chg->dev->of_node;
681 chg->usb_port_psy = devm_power_supply_register(chg->dev,
682 &usb_port_psy_desc,
683 &usb_port_cfg);
684 if (IS_ERR(chg->usb_port_psy)) {
685 pr_err("Couldn't register USB pc_port power supply\n");
686 return PTR_ERR(chg->usb_port_psy);
687 }
688
689 return 0;
690}
691
692/*****************************
693 * USB MAIN PSY REGISTRATION *
694 *****************************/
695
696static enum power_supply_property smb5_usb_main_props[] = {
697 POWER_SUPPLY_PROP_VOLTAGE_MAX,
698 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
699 POWER_SUPPLY_PROP_TYPE,
700 POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
701 POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
702 POWER_SUPPLY_PROP_FCC_DELTA,
703 POWER_SUPPLY_PROP_CURRENT_MAX,
704};
705
706static int smb5_usb_main_get_prop(struct power_supply *psy,
707 enum power_supply_property psp,
708 union power_supply_propval *val)
709{
710 struct smb5 *chip = power_supply_get_drvdata(psy);
711 struct smb_charger *chg = &chip->chg;
712 int rc = 0;
713
714 switch (psp) {
715 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
716 rc = smblib_get_charge_param(chg, &chg->param.fv, &val->intval);
717 break;
718 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
719 rc = smblib_get_charge_param(chg, &chg->param.fcc,
720 &val->intval);
721 break;
722 case POWER_SUPPLY_PROP_TYPE:
723 val->intval = POWER_SUPPLY_TYPE_MAIN;
724 break;
725 case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
726 rc = smblib_get_prop_input_current_settled(chg, val);
727 break;
728 case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED:
729 rc = smblib_get_prop_input_voltage_settled(chg, val);
730 break;
731 case POWER_SUPPLY_PROP_FCC_DELTA:
732 rc = smblib_get_prop_fcc_delta(chg, val);
733 break;
734 case POWER_SUPPLY_PROP_CURRENT_MAX:
735 rc = smblib_get_icl_current(chg, &val->intval);
736 break;
737 default:
738 pr_debug("get prop %d is not supported in usb-main\n", psp);
739 rc = -EINVAL;
740 break;
741 }
742 if (rc < 0) {
743 pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
744 return -ENODATA;
745 }
746
747 return 0;
748}
749
750static int smb5_usb_main_set_prop(struct power_supply *psy,
751 enum power_supply_property psp,
752 const union power_supply_propval *val)
753{
754 struct smb5 *chip = power_supply_get_drvdata(psy);
755 struct smb_charger *chg = &chip->chg;
756 int rc = 0;
757
758 switch (psp) {
759 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
760 rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval);
761 break;
762 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
763 rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval);
764 break;
765 case POWER_SUPPLY_PROP_CURRENT_MAX:
766 rc = smblib_set_icl_current(chg, val->intval);
767 break;
768 default:
769 pr_err("set prop %d is not supported\n", psp);
770 rc = -EINVAL;
771 break;
772 }
773
774 return rc;
775}
776
777static const struct power_supply_desc usb_main_psy_desc = {
778 .name = "main",
779 .type = POWER_SUPPLY_TYPE_MAIN,
780 .properties = smb5_usb_main_props,
781 .num_properties = ARRAY_SIZE(smb5_usb_main_props),
782 .get_property = smb5_usb_main_get_prop,
783 .set_property = smb5_usb_main_set_prop,
784};
785
786static int smb5_init_usb_main_psy(struct smb5 *chip)
787{
788 struct power_supply_config usb_main_cfg = {};
789 struct smb_charger *chg = &chip->chg;
790
791 usb_main_cfg.drv_data = chip;
792 usb_main_cfg.of_node = chg->dev->of_node;
793 chg->usb_main_psy = devm_power_supply_register(chg->dev,
794 &usb_main_psy_desc,
795 &usb_main_cfg);
796 if (IS_ERR(chg->usb_main_psy)) {
797 pr_err("Couldn't register USB main power supply\n");
798 return PTR_ERR(chg->usb_main_psy);
799 }
800
801 return 0;
802}
803
804/*************************
805 * DC PSY REGISTRATION *
806 *************************/
807
808static enum power_supply_property smb5_dc_props[] = {
809 POWER_SUPPLY_PROP_INPUT_SUSPEND,
810 POWER_SUPPLY_PROP_PRESENT,
811 POWER_SUPPLY_PROP_ONLINE,
812 POWER_SUPPLY_PROP_REAL_TYPE,
813};
814
815static int smb5_dc_get_prop(struct power_supply *psy,
816 enum power_supply_property psp,
817 union power_supply_propval *val)
818{
819 struct smb5 *chip = power_supply_get_drvdata(psy);
820 struct smb_charger *chg = &chip->chg;
821 int rc = 0;
822
823 switch (psp) {
824 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
825 val->intval = get_effective_result(chg->dc_suspend_votable);
826 break;
827 case POWER_SUPPLY_PROP_PRESENT:
828 rc = smblib_get_prop_dc_present(chg, val);
829 break;
830 case POWER_SUPPLY_PROP_ONLINE:
831 rc = smblib_get_prop_dc_online(chg, val);
832 break;
833 case POWER_SUPPLY_PROP_REAL_TYPE:
834 val->intval = POWER_SUPPLY_TYPE_WIPOWER;
835 break;
836 default:
837 return -EINVAL;
838 }
839 if (rc < 0) {
840 pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
841 return -ENODATA;
842 }
843 return 0;
844}
845
846static int smb5_dc_set_prop(struct power_supply *psy,
847 enum power_supply_property psp,
848 const union power_supply_propval *val)
849{
850 struct smb5 *chip = power_supply_get_drvdata(psy);
851 struct smb_charger *chg = &chip->chg;
852 int rc = 0;
853
854 switch (psp) {
855 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
856 rc = vote(chg->dc_suspend_votable, WBC_VOTER,
857 (bool)val->intval, 0);
858 break;
859 default:
860 return -EINVAL;
861 }
862
863 return rc;
864}
865
866static int smb5_dc_prop_is_writeable(struct power_supply *psy,
867 enum power_supply_property psp)
868{
869 int rc;
870
871 switch (psp) {
872 default:
873 rc = 0;
874 break;
875 }
876
877 return rc;
878}
879
880static const struct power_supply_desc dc_psy_desc = {
881 .name = "dc",
882 .type = POWER_SUPPLY_TYPE_WIRELESS,
883 .properties = smb5_dc_props,
884 .num_properties = ARRAY_SIZE(smb5_dc_props),
885 .get_property = smb5_dc_get_prop,
886 .set_property = smb5_dc_set_prop,
887 .property_is_writeable = smb5_dc_prop_is_writeable,
888};
889
890static int smb5_init_dc_psy(struct smb5 *chip)
891{
892 struct power_supply_config dc_cfg = {};
893 struct smb_charger *chg = &chip->chg;
894
895 dc_cfg.drv_data = chip;
896 dc_cfg.of_node = chg->dev->of_node;
897 chg->dc_psy = devm_power_supply_register(chg->dev,
898 &dc_psy_desc,
899 &dc_cfg);
900 if (IS_ERR(chg->dc_psy)) {
901 pr_err("Couldn't register USB power supply\n");
902 return PTR_ERR(chg->dc_psy);
903 }
904
905 return 0;
906}
907
908/*************************
909 * BATT PSY REGISTRATION *
910 *************************/
911static enum power_supply_property smb5_batt_props[] = {
912 POWER_SUPPLY_PROP_INPUT_SUSPEND,
913 POWER_SUPPLY_PROP_STATUS,
914 POWER_SUPPLY_PROP_HEALTH,
915 POWER_SUPPLY_PROP_PRESENT,
916 POWER_SUPPLY_PROP_CHARGE_TYPE,
917 POWER_SUPPLY_PROP_CAPACITY,
918 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED,
919 POWER_SUPPLY_PROP_VOLTAGE_NOW,
920 POWER_SUPPLY_PROP_VOLTAGE_MAX,
921 POWER_SUPPLY_PROP_CURRENT_NOW,
922 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
923 POWER_SUPPLY_PROP_TEMP,
924 POWER_SUPPLY_PROP_TECHNOLOGY,
925 POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED,
926 POWER_SUPPLY_PROP_SW_JEITA_ENABLED,
927 POWER_SUPPLY_PROP_CHARGE_DONE,
928 POWER_SUPPLY_PROP_PARALLEL_DISABLE,
929 POWER_SUPPLY_PROP_SET_SHIP_MODE,
930 POWER_SUPPLY_PROP_DIE_HEALTH,
931 POWER_SUPPLY_PROP_RERUN_AICL,
932 POWER_SUPPLY_PROP_DP_DM,
933 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
934 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
935 POWER_SUPPLY_PROP_CHARGE_COUNTER,
936};
937
938static int smb5_batt_get_prop(struct power_supply *psy,
939 enum power_supply_property psp,
940 union power_supply_propval *val)
941{
942 struct smb_charger *chg = power_supply_get_drvdata(psy);
943 int rc = 0;
944
945 switch (psp) {
946 case POWER_SUPPLY_PROP_STATUS:
947 rc = smblib_get_prop_batt_status(chg, val);
948 break;
949 case POWER_SUPPLY_PROP_HEALTH:
950 rc = smblib_get_prop_batt_health(chg, val);
951 break;
952 case POWER_SUPPLY_PROP_PRESENT:
953 rc = smblib_get_prop_batt_present(chg, val);
954 break;
955 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
956 rc = smblib_get_prop_input_suspend(chg, val);
957 break;
958 case POWER_SUPPLY_PROP_CHARGE_TYPE:
959 rc = smblib_get_prop_batt_charge_type(chg, val);
960 break;
961 case POWER_SUPPLY_PROP_CAPACITY:
962 rc = smblib_get_prop_batt_capacity(chg, val);
963 break;
964 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
965 rc = smblib_get_prop_system_temp_level(chg, val);
966 break;
967 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
968 rc = smblib_get_prop_system_temp_level_max(chg, val);
969 break;
970 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
971 rc = smblib_get_prop_input_current_limited(chg, val);
972 break;
973 case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
974 val->intval = chg->step_chg_enabled;
975 break;
976 case POWER_SUPPLY_PROP_SW_JEITA_ENABLED:
977 val->intval = chg->sw_jeita_enabled;
978 break;
979 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
980 rc = smblib_get_prop_batt_voltage_now(chg, val);
981 break;
982 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
983 val->intval = get_client_vote(chg->fv_votable,
984 BATT_PROFILE_VOTER);
985 break;
986 case POWER_SUPPLY_PROP_CURRENT_NOW:
987 rc = smblib_get_prop_batt_current_now(chg, val);
988 break;
989 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
990 val->intval = get_client_vote(chg->fcc_votable,
991 BATT_PROFILE_VOTER);
992 break;
993 case POWER_SUPPLY_PROP_TEMP:
994 rc = smblib_get_prop_batt_temp(chg, val);
995 break;
996 case POWER_SUPPLY_PROP_TECHNOLOGY:
997 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
998 break;
999 case POWER_SUPPLY_PROP_CHARGE_DONE:
1000 rc = smblib_get_prop_batt_charge_done(chg, val);
1001 break;
1002 case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
1003 val->intval = get_client_vote(chg->pl_disable_votable,
1004 USER_VOTER);
1005 break;
1006 case POWER_SUPPLY_PROP_SET_SHIP_MODE:
1007 /* Not in ship mode as long as device is active */
1008 val->intval = 0;
1009 break;
1010 case POWER_SUPPLY_PROP_DIE_HEALTH:
1011 if (chg->die_health == -EINVAL)
1012 rc = smblib_get_prop_die_health(chg, val);
1013 else
1014 val->intval = chg->die_health;
1015 break;
1016 case POWER_SUPPLY_PROP_DP_DM:
1017 val->intval = chg->pulse_cnt;
1018 break;
1019 case POWER_SUPPLY_PROP_RERUN_AICL:
1020 val->intval = 0;
1021 break;
1022 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
1023 rc = smblib_get_prop_batt_charge_counter(chg, val);
1024 break;
1025 default:
1026 pr_err("batt power supply prop %d not supported\n", psp);
1027 return -EINVAL;
1028 }
1029
1030 if (rc < 0) {
1031 pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
1032 return -ENODATA;
1033 }
1034
1035 return 0;
1036}
1037
1038static int smb5_batt_set_prop(struct power_supply *psy,
1039 enum power_supply_property prop,
1040 const union power_supply_propval *val)
1041{
1042 int rc = 0;
1043 struct smb_charger *chg = power_supply_get_drvdata(psy);
1044
1045 switch (prop) {
1046 case POWER_SUPPLY_PROP_STATUS:
1047 rc = smblib_set_prop_batt_status(chg, val);
1048 break;
1049 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
1050 rc = smblib_set_prop_input_suspend(chg, val);
1051 break;
1052 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
1053 rc = smblib_set_prop_system_temp_level(chg, val);
1054 break;
1055 case POWER_SUPPLY_PROP_CAPACITY:
1056 rc = smblib_set_prop_batt_capacity(chg, val);
1057 break;
1058 case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
1059 vote(chg->pl_disable_votable, USER_VOTER, (bool)val->intval, 0);
1060 break;
1061 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
1062 chg->batt_profile_fv_uv = val->intval;
1063 vote(chg->fv_votable, BATT_PROFILE_VOTER, true, val->intval);
1064 break;
1065 case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
1066 chg->step_chg_enabled = !!val->intval;
1067 break;
1068 case POWER_SUPPLY_PROP_SW_JEITA_ENABLED:
1069 if (chg->sw_jeita_enabled != (!!val->intval)) {
1070 rc = smblib_disable_hw_jeita(chg, !!val->intval);
1071 if (rc == 0)
1072 chg->sw_jeita_enabled = !!val->intval;
1073 }
1074 break;
1075 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1076 chg->batt_profile_fcc_ua = val->intval;
1077 vote(chg->fcc_votable, BATT_PROFILE_VOTER, true, val->intval);
1078 break;
1079 case POWER_SUPPLY_PROP_SET_SHIP_MODE:
1080 /* Not in ship mode as long as the device is active */
1081 if (!val->intval)
1082 break;
1083 if (chg->pl.psy)
1084 power_supply_set_property(chg->pl.psy,
1085 POWER_SUPPLY_PROP_SET_SHIP_MODE, val);
1086 rc = smblib_set_prop_ship_mode(chg, val);
1087 break;
1088 case POWER_SUPPLY_PROP_RERUN_AICL:
1089 rc = smblib_rerun_aicl(chg);
1090 break;
1091 case POWER_SUPPLY_PROP_DP_DM:
1092 rc = smblib_dp_dm(chg, val->intval);
1093 break;
1094 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
1095 rc = smblib_set_prop_input_current_limited(chg, val);
1096 break;
1097 case POWER_SUPPLY_PROP_DIE_HEALTH:
1098 chg->die_health = val->intval;
1099 power_supply_changed(chg->batt_psy);
1100 break;
1101 default:
1102 rc = -EINVAL;
1103 }
1104
1105 return rc;
1106}
1107
1108static int smb5_batt_prop_is_writeable(struct power_supply *psy,
1109 enum power_supply_property psp)
1110{
1111 switch (psp) {
1112 case POWER_SUPPLY_PROP_STATUS:
1113 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
1114 case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
1115 case POWER_SUPPLY_PROP_CAPACITY:
1116 case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
1117 case POWER_SUPPLY_PROP_DP_DM:
1118 case POWER_SUPPLY_PROP_RERUN_AICL:
1119 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
1120 case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
1121 case POWER_SUPPLY_PROP_SW_JEITA_ENABLED:
1122 case POWER_SUPPLY_PROP_DIE_HEALTH:
1123 return 1;
1124 default:
1125 break;
1126 }
1127
1128 return 0;
1129}
1130
1131static const struct power_supply_desc batt_psy_desc = {
1132 .name = "battery",
1133 .type = POWER_SUPPLY_TYPE_BATTERY,
1134 .properties = smb5_batt_props,
1135 .num_properties = ARRAY_SIZE(smb5_batt_props),
1136 .get_property = smb5_batt_get_prop,
1137 .set_property = smb5_batt_set_prop,
1138 .property_is_writeable = smb5_batt_prop_is_writeable,
1139};
1140
1141static int smb5_init_batt_psy(struct smb5 *chip)
1142{
1143 struct power_supply_config batt_cfg = {};
1144 struct smb_charger *chg = &chip->chg;
1145 int rc = 0;
1146
1147 batt_cfg.drv_data = chg;
1148 batt_cfg.of_node = chg->dev->of_node;
1149 chg->batt_psy = devm_power_supply_register(chg->dev,
1150 &batt_psy_desc,
1151 &batt_cfg);
1152 if (IS_ERR(chg->batt_psy)) {
1153 pr_err("Couldn't register battery power supply\n");
1154 return PTR_ERR(chg->batt_psy);
1155 }
1156
1157 return rc;
1158}
1159
1160/******************************
1161 * VBUS REGULATOR REGISTRATION *
1162 ******************************/
1163
1164static struct regulator_ops smb5_vbus_reg_ops = {
1165 .enable = smblib_vbus_regulator_enable,
1166 .disable = smblib_vbus_regulator_disable,
1167 .is_enabled = smblib_vbus_regulator_is_enabled,
1168};
1169
1170static int smb5_init_vbus_regulator(struct smb5 *chip)
1171{
1172 struct smb_charger *chg = &chip->chg;
1173 struct regulator_config cfg = {};
1174 int rc = 0;
1175
1176 chg->vbus_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vbus_vreg),
1177 GFP_KERNEL);
1178 if (!chg->vbus_vreg)
1179 return -ENOMEM;
1180
1181 cfg.dev = chg->dev;
1182 cfg.driver_data = chip;
1183
1184 chg->vbus_vreg->rdesc.owner = THIS_MODULE;
1185 chg->vbus_vreg->rdesc.type = REGULATOR_VOLTAGE;
1186 chg->vbus_vreg->rdesc.ops = &smb5_vbus_reg_ops;
1187 chg->vbus_vreg->rdesc.of_match = "qcom,smb5-vbus";
1188 chg->vbus_vreg->rdesc.name = "qcom,smb5-vbus";
1189
1190 chg->vbus_vreg->rdev = devm_regulator_register(chg->dev,
1191 &chg->vbus_vreg->rdesc, &cfg);
1192 if (IS_ERR(chg->vbus_vreg->rdev)) {
1193 rc = PTR_ERR(chg->vbus_vreg->rdev);
1194 chg->vbus_vreg->rdev = NULL;
1195 if (rc != -EPROBE_DEFER)
1196 pr_err("Couldn't register VBUS regulator rc=%d\n", rc);
1197 }
1198
1199 return rc;
1200}
1201
1202/******************************
1203 * VCONN REGULATOR REGISTRATION *
1204 ******************************/
1205
1206static struct regulator_ops smb5_vconn_reg_ops = {
1207 .enable = smblib_vconn_regulator_enable,
1208 .disable = smblib_vconn_regulator_disable,
1209 .is_enabled = smblib_vconn_regulator_is_enabled,
1210};
1211
1212static int smb5_init_vconn_regulator(struct smb5 *chip)
1213{
1214 struct smb_charger *chg = &chip->chg;
1215 struct regulator_config cfg = {};
1216 int rc = 0;
1217
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301218 if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
Harry Yang4b7db0f2017-11-27 10:50:44 -08001219 return 0;
1220
1221 chg->vconn_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vconn_vreg),
1222 GFP_KERNEL);
1223 if (!chg->vconn_vreg)
1224 return -ENOMEM;
1225
1226 cfg.dev = chg->dev;
1227 cfg.driver_data = chip;
1228
1229 chg->vconn_vreg->rdesc.owner = THIS_MODULE;
1230 chg->vconn_vreg->rdesc.type = REGULATOR_VOLTAGE;
1231 chg->vconn_vreg->rdesc.ops = &smb5_vconn_reg_ops;
1232 chg->vconn_vreg->rdesc.of_match = "qcom,smb5-vconn";
1233 chg->vconn_vreg->rdesc.name = "qcom,smb5-vconn";
1234
1235 chg->vconn_vreg->rdev = devm_regulator_register(chg->dev,
1236 &chg->vconn_vreg->rdesc, &cfg);
1237 if (IS_ERR(chg->vconn_vreg->rdev)) {
1238 rc = PTR_ERR(chg->vconn_vreg->rdev);
1239 chg->vconn_vreg->rdev = NULL;
1240 if (rc != -EPROBE_DEFER)
1241 pr_err("Couldn't register VCONN regulator rc=%d\n", rc);
1242 }
1243
1244 return rc;
1245}
1246
1247/***************************
1248 * HARDWARE INITIALIZATION *
1249 ***************************/
1250static int smb5_configure_typec(struct smb_charger *chg)
1251{
1252 int rc;
1253
1254 rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_1_REG,
1255 TYPEC_CCOUT_DETACH_INT_EN_BIT |
1256 TYPEC_CCOUT_ATTACH_INT_EN_BIT);
1257 if (rc < 0) {
1258 dev_err(chg->dev,
1259 "Couldn't configure Type-C interrupts rc=%d\n", rc);
1260 return rc;
1261 }
1262
1263 rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG,
Harry Yang4b7db0f2017-11-27 10:50:44 -08001264 TYPEC_WATER_DETECTION_INT_EN_BIT);
1265 if (rc < 0) {
1266 dev_err(chg->dev,
1267 "Couldn't configure Type-C interrupts rc=%d\n", rc);
1268 return rc;
1269 }
1270
1271 /* configure VCONN for software control */
1272 rc = smblib_masked_write(chg, TYPE_C_VCONN_CONTROL_REG,
1273 VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT,
1274 VCONN_EN_SRC_BIT);
1275 if (rc < 0) {
1276 dev_err(chg->dev,
1277 "Couldn't configure VCONN for SW control rc=%d\n", rc);
1278 return rc;
1279 }
1280
1281 return rc;
1282}
1283
1284static int smb5_configure_micro_usb(struct smb_charger *chg)
1285{
1286 int rc;
1287
1288 /* configure micro USB mode */
1289 rc = smblib_masked_write(chg, TYPEC_U_USB_CFG_REG,
1290 EN_MICRO_USB_MODE_BIT, EN_MICRO_USB_MODE_BIT);
1291 if (rc < 0) {
1292 dev_err(chg->dev, "Couldn't enable micro USB mode rc=%d\n", rc);
1293 return rc;
1294 }
1295
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301296 rc = smblib_masked_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG,
1297 MICRO_USB_STATE_CHANGE_INT_EN_BIT,
1298 MICRO_USB_STATE_CHANGE_INT_EN_BIT);
1299 if (rc < 0) {
1300 dev_err(chg->dev,
1301 "Couldn't configure Type-C interrupts rc=%d\n", rc);
1302 return rc;
1303 }
1304
Harry Yang4b7db0f2017-11-27 10:50:44 -08001305 return rc;
1306}
1307
1308static int smb5_init_hw(struct smb5 *chip)
1309{
1310 struct smb_charger *chg = &chip->chg;
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301311 int rc, type = 0;
1312 u8 val = 0;
Harry Yang4b7db0f2017-11-27 10:50:44 -08001313
1314 if (chip->dt.no_battery)
1315 chg->fake_capacity = 50;
1316
1317 if (chip->dt.batt_profile_fcc_ua < 0)
1318 smblib_get_charge_param(chg, &chg->param.fcc,
1319 &chg->batt_profile_fcc_ua);
1320
1321 if (chip->dt.batt_profile_fv_uv < 0)
1322 smblib_get_charge_param(chg, &chg->param.fv,
1323 &chg->batt_profile_fv_uv);
1324
1325 smblib_get_charge_param(chg, &chg->param.usb_icl,
1326 &chg->default_icl_ua);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301327
1328 /* Use SW based VBUS control, disable HW autonomous mode */
1329 /* TODO: auth can be enabled through vote based on APSD flow */
1330 rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
1331 HVDCP_AUTH_ALG_EN_CFG_BIT | HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT,
1332 HVDCP_AUTH_ALG_EN_CFG_BIT);
1333 if (rc < 0) {
1334 dev_err(chg->dev, "Couldn't configure HVDCP rc=%d\n", rc);
1335 return rc;
1336 }
1337
1338 /*
1339 * PMI632 can have the connector type defined by a dedicated register
1340 * TYPEC_MICRO_USB_MODE_REG or by a common TYPEC_U_USB_CFG_REG.
1341 */
1342 if (chg->smb_version == PMI632_SUBTYPE) {
1343 rc = smblib_read(chg, TYPEC_MICRO_USB_MODE_REG, &val);
1344 if (rc < 0) {
1345 dev_err(chg->dev, "Couldn't read USB mode rc=%d\n", rc);
1346 return rc;
1347 }
1348 type = !!(val & MICRO_USB_MODE_ONLY_BIT);
1349 }
1350
1351 /*
1352 * If TYPEC_MICRO_USB_MODE_REG is not set and for all non-PMI632
1353 * check the connector type using TYPEC_U_USB_CFG_REG.
1354 */
1355 if (!type) {
1356 rc = smblib_read(chg, TYPEC_U_USB_CFG_REG, &val);
1357 if (rc < 0) {
1358 dev_err(chg->dev, "Couldn't read U_USB config rc=%d\n",
1359 rc);
1360 return rc;
1361 }
1362
1363 type = !!(val & EN_MICRO_USB_MODE_BIT);
1364 }
1365
1366 chg->connector_type = type ? POWER_SUPPLY_CONNECTOR_MICRO_USB
1367 : POWER_SUPPLY_CONNECTOR_TYPEC;
1368 pr_debug("Connector type=%s\n", type ? "Micro USB" : "TypeC");
1369
1370 smblib_rerun_apsd_if_required(chg);
Harry Yang4b7db0f2017-11-27 10:50:44 -08001371
1372 /* vote 0mA on usb_icl for non battery platforms */
1373 vote(chg->usb_icl_votable,
1374 DEFAULT_VOTER, chip->dt.no_battery, 0);
1375 vote(chg->dc_suspend_votable,
1376 DEFAULT_VOTER, chip->dt.no_battery, 0);
1377 vote(chg->fcc_votable, HW_LIMIT_VOTER,
1378 chip->dt.batt_profile_fcc_ua > 0, chip->dt.batt_profile_fcc_ua);
1379 vote(chg->fv_votable, HW_LIMIT_VOTER,
1380 chip->dt.batt_profile_fv_uv > 0, chip->dt.batt_profile_fv_uv);
1381 vote(chg->fcc_votable,
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301382 BATT_PROFILE_VOTER, chg->batt_profile_fcc_ua > 0,
1383 chg->batt_profile_fcc_ua);
Harry Yang4b7db0f2017-11-27 10:50:44 -08001384 vote(chg->fv_votable,
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301385 BATT_PROFILE_VOTER, chg->batt_profile_fv_uv > 0,
1386 chg->batt_profile_fv_uv);
Harry Yang4b7db0f2017-11-27 10:50:44 -08001387 vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER,
1388 true, 0);
1389 vote(chg->pd_disallowed_votable_indirect, APSD_VOTER,
1390 true, 0);
1391 vote(chg->pd_disallowed_votable_indirect, MICRO_USB_VOTER,
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301392 chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB, 0);
1393
1394 /* Some h/w limit maximum supported ICL */
1395 vote(chg->usb_icl_votable, HW_LIMIT_VOTER,
1396 chg->hw_max_icl_ua > 0, chg->hw_max_icl_ua);
Harry Yang4b7db0f2017-11-27 10:50:44 -08001397
1398 /*
1399 * AICL configuration:
1400 * start from min and AICL ADC disable
1401 */
1402 rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
1403 USBIN_AICL_ADC_EN_BIT, 0);
1404 if (rc < 0) {
1405 dev_err(chg->dev, "Couldn't configure AICL rc=%d\n", rc);
1406 return rc;
1407 }
1408
1409 /* enable the charging path */
1410 rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0);
1411 if (rc < 0) {
1412 dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
1413 return rc;
1414 }
1415
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301416 if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
Harry Yang4b7db0f2017-11-27 10:50:44 -08001417 rc = smb5_configure_micro_usb(chg);
1418 else
1419 rc = smb5_configure_typec(chg);
1420 if (rc < 0) {
1421 dev_err(chg->dev,
1422 "Couldn't configure TypeC/micro-USB mode rc=%d\n", rc);
1423 return rc;
1424 }
1425
1426 /* configure VBUS for software control */
1427 rc = smblib_masked_write(chg, DCDC_OTG_CFG_REG, OTG_EN_SRC_CFG_BIT, 0);
1428 if (rc < 0) {
1429 dev_err(chg->dev,
1430 "Couldn't configure VBUS for SW control rc=%d\n", rc);
1431 return rc;
1432 }
1433
1434 val = (ilog2(chip->dt.wd_bark_time / 16) << BARK_WDOG_TIMEOUT_SHIFT)
1435 & BARK_WDOG_TIMEOUT_MASK;
1436 val |= BITE_WDOG_TIMEOUT_8S;
1437 rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG,
1438 BITE_WDOG_DISABLE_CHARGING_CFG_BIT |
1439 BARK_WDOG_TIMEOUT_MASK | BITE_WDOG_TIMEOUT_MASK,
1440 val);
1441 if (rc < 0) {
1442 pr_err("Couldn't configue WD config rc=%d\n", rc);
1443 return rc;
1444 }
1445
1446 /* enable WD BARK and enable it on plugin */
1447 rc = smblib_masked_write(chg, WD_CFG_REG,
1448 WATCHDOG_TRIGGER_AFP_EN_BIT |
1449 WDOG_TIMER_EN_ON_PLUGIN_BIT |
1450 BARK_WDOG_INT_EN_BIT,
1451 WDOG_TIMER_EN_ON_PLUGIN_BIT |
1452 BARK_WDOG_INT_EN_BIT);
1453 if (rc < 0) {
1454 pr_err("Couldn't configue WD config rc=%d\n", rc);
1455 return rc;
1456 }
1457
1458 /* configure float charger options */
1459 switch (chip->dt.float_option) {
1460 case FLOAT_DCP:
1461 rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
1462 FLOAT_OPTIONS_MASK, 0);
1463 break;
1464 case FLOAT_SDP:
1465 rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
1466 FLOAT_OPTIONS_MASK, FORCE_FLOAT_SDP_CFG_BIT);
1467 break;
1468 case DISABLE_CHARGING:
1469 rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
1470 FLOAT_OPTIONS_MASK, FLOAT_DIS_CHGING_CFG_BIT);
1471 break;
1472 case SUSPEND_INPUT:
1473 rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
1474 FLOAT_OPTIONS_MASK, SUSPEND_FLOAT_CFG_BIT);
1475 break;
1476 default:
1477 rc = 0;
1478 break;
1479 }
1480
1481 if (rc < 0) {
1482 dev_err(chg->dev, "Couldn't configure float charger options rc=%d\n",
1483 rc);
1484 return rc;
1485 }
1486
1487 rc = smblib_read(chg, USBIN_OPTIONS_2_CFG_REG, &chg->float_cfg);
1488 if (rc < 0) {
1489 dev_err(chg->dev, "Couldn't read float charger options rc=%d\n",
1490 rc);
1491 return rc;
1492 }
1493
1494 switch (chip->dt.chg_inhibit_thr_mv) {
1495 case 50:
1496 rc = smblib_masked_write(chg, CHARGE_INHIBIT_THRESHOLD_CFG_REG,
1497 CHARGE_INHIBIT_THRESHOLD_MASK,
1498 INHIBIT_ANALOG_VFLT_MINUS_50MV);
1499 break;
1500 case 100:
1501 rc = smblib_masked_write(chg, CHARGE_INHIBIT_THRESHOLD_CFG_REG,
1502 CHARGE_INHIBIT_THRESHOLD_MASK,
1503 INHIBIT_ANALOG_VFLT_MINUS_100MV);
1504 break;
1505 case 200:
1506 rc = smblib_masked_write(chg, CHARGE_INHIBIT_THRESHOLD_CFG_REG,
1507 CHARGE_INHIBIT_THRESHOLD_MASK,
1508 INHIBIT_ANALOG_VFLT_MINUS_200MV);
1509 break;
1510 case 300:
1511 rc = smblib_masked_write(chg, CHARGE_INHIBIT_THRESHOLD_CFG_REG,
1512 CHARGE_INHIBIT_THRESHOLD_MASK,
1513 INHIBIT_ANALOG_VFLT_MINUS_300MV);
1514 break;
1515 case 0:
1516 rc = smblib_masked_write(chg, CHGR_CFG2_REG,
1517 CHARGER_INHIBIT_BIT, 0);
1518 default:
1519 break;
1520 }
1521
1522 if (rc < 0) {
1523 dev_err(chg->dev, "Couldn't configure charge inhibit threshold rc=%d\n",
1524 rc);
1525 return rc;
1526 }
1527
1528 rc = smblib_masked_write(chg, CHGR_CFG2_REG,
1529 SOC_BASED_RECHG_BIT,
1530 chip->dt.auto_recharge_soc ? SOC_BASED_RECHG_BIT : 0);
1531 if (rc < 0) {
1532 dev_err(chg->dev, "Couldn't configure FG_UPDATE_CFG2_SEL_REG rc=%d\n",
1533 rc);
1534 return rc;
1535 }
1536
1537 if (chg->sw_jeita_enabled) {
1538 rc = smblib_disable_hw_jeita(chg, true);
1539 if (rc < 0) {
1540 dev_err(chg->dev, "Couldn't set hw jeita rc=%d\n", rc);
1541 return rc;
1542 }
1543 }
1544
1545 return rc;
1546}
1547
1548static int smb5_post_init(struct smb5 *chip)
1549{
1550 struct smb_charger *chg = &chip->chg;
1551 union power_supply_propval pval;
1552 int rc;
1553
1554 /*
1555 * In case the usb path is suspended, we would have missed disabling
1556 * the icl change interrupt because the interrupt could have been
1557 * not requested
1558 */
1559 rerun_election(chg->usb_icl_votable);
1560
1561 /* configure power role for dual-role */
1562 pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
1563 rc = smblib_set_prop_typec_power_role(chg, &pval);
1564 if (rc < 0) {
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301565 dev_err(chg->dev, "Couldn't configure DRP role rc=%d\n",
1566 rc);
Harry Yang4b7db0f2017-11-27 10:50:44 -08001567 return rc;
1568 }
1569
1570 rerun_election(chg->usb_irq_enable_votable);
1571
1572 return 0;
1573}
1574
1575/****************************
1576 * DETERMINE INITIAL STATUS *
1577 ****************************/
1578
1579static int smb5_determine_initial_status(struct smb5 *chip)
1580{
1581 struct smb_irq_data irq_data = {chip, "determine-initial-status"};
1582 struct smb_charger *chg = &chip->chg;
1583
1584 if (chg->bms_psy)
1585 smblib_suspend_on_debug_battery(chg);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301586
Harry Yang4b7db0f2017-11-27 10:50:44 -08001587 usb_plugin_irq_handler(0, &irq_data);
1588 typec_state_change_irq_handler(0, &irq_data);
1589 usb_source_change_irq_handler(0, &irq_data);
1590 chg_state_change_irq_handler(0, &irq_data);
1591 icl_change_irq_handler(0, &irq_data);
1592 batt_temp_changed_irq_handler(0, &irq_data);
1593 wdog_bark_irq_handler(0, &irq_data);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301594 typec_or_rid_detection_change_irq_handler(0, &irq_data);
Harry Yang4b7db0f2017-11-27 10:50:44 -08001595
1596 return 0;
1597}
1598
1599/**************************
1600 * INTERRUPT REGISTRATION *
1601 **************************/
1602
1603static struct smb_irq_info smb5_irqs[] = {
1604 /* CHARGER IRQs */
1605 [CHGR_ERROR_IRQ] = {
1606 .name = "chgr-error",
1607 .handler = default_irq_handler,
1608 },
1609 [CHG_STATE_CHANGE_IRQ] = {
1610 .name = "chg-state-change",
1611 .handler = chg_state_change_irq_handler,
1612 },
1613 [STEP_CHG_STATE_CHANGE_IRQ] = {
1614 .name = "step-chg-state-change",
1615 .handler = default_irq_handler,
1616 },
1617 [STEP_CHG_SOC_UPDATE_FAIL_IRQ] = {
1618 .name = "step-chg-soc-update-fail",
1619 .handler = default_irq_handler,
1620 },
1621 [STEP_CHG_SOC_UPDATE_REQ_IRQ] = {
1622 .name = "step-chg-soc-update-req",
1623 .handler = default_irq_handler,
1624 },
1625 [FG_FVCAL_QUALIFIED_IRQ] = {
1626 .name = "fg-fvcal-qualified",
1627 .handler = default_irq_handler,
1628 },
1629 [VPH_ALARM_IRQ] = {
1630 .name = "vph-alarm",
1631 .handler = default_irq_handler,
1632 },
1633 [VPH_DROP_PRECHG_IRQ] = {
1634 .name = "vph-drop-prechg",
1635 .handler = default_irq_handler,
1636 },
1637 /* DCDC IRQs */
1638 [OTG_FAIL_IRQ] = {
1639 .name = "otg-fail",
1640 .handler = default_irq_handler,
1641 },
1642 [OTG_OC_DISABLE_SW_IRQ] = {
1643 .name = "otg-oc-disable-sw",
1644 .handler = default_irq_handler,
1645 },
1646 [OTG_OC_HICCUP_IRQ] = {
1647 .name = "otg-oc-hiccup",
1648 .handler = default_irq_handler,
1649 },
1650 [BSM_ACTIVE_IRQ] = {
1651 .name = "bsm-active",
1652 .handler = default_irq_handler,
1653 },
1654 [HIGH_DUTY_CYCLE_IRQ] = {
1655 .name = "high-duty-cycle",
1656 .handler = high_duty_cycle_irq_handler,
1657 },
1658 [INPUT_CURRENT_LIMITING_IRQ] = {
1659 .name = "input-current-limiting",
1660 .handler = default_irq_handler,
1661 },
1662 [CONCURRENT_MODE_DISABLE_IRQ] = {
1663 .name = "concurrent-mode-disable",
1664 .handler = default_irq_handler,
1665 },
1666 [SWITCHER_POWER_OK_IRQ] = {
1667 .name = "switcher-power-ok",
1668 .handler = switcher_power_ok_irq_handler,
1669 },
1670 /* BATTERY IRQs */
1671 [BAT_TEMP_IRQ] = {
1672 .name = "bat-temp",
1673 .handler = batt_temp_changed_irq_handler,
1674 },
1675 [ALL_CHNL_CONV_DONE_IRQ] = {
1676 .name = "all-chnl-conv-done",
1677 .handler = default_irq_handler,
1678 },
1679 [BAT_OV_IRQ] = {
1680 .name = "bat-ov",
1681 .handler = batt_psy_changed_irq_handler,
1682 },
1683 [BAT_LOW_IRQ] = {
1684 .name = "bat-low",
1685 .handler = batt_psy_changed_irq_handler,
1686 },
1687 [BAT_THERM_OR_ID_MISSING_IRQ] = {
1688 .name = "bat-therm-or-id-missing",
1689 .handler = batt_psy_changed_irq_handler,
1690 },
1691 [BAT_TERMINAL_MISSING_IRQ] = {
1692 .name = "bat-terminal-missing",
1693 .handler = batt_psy_changed_irq_handler,
1694 },
1695 [BUCK_OC_IRQ] = {
1696 .name = "buck-oc",
1697 .handler = default_irq_handler,
1698 },
1699 [VPH_OV_IRQ] = {
1700 .name = "vph-ov",
1701 .handler = default_irq_handler,
1702 },
1703 /* USB INPUT IRQs */
1704 [USBIN_COLLAPSE_IRQ] = {
1705 .name = "usbin-collapse",
1706 .handler = default_irq_handler,
1707 },
1708 [USBIN_VASHDN_IRQ] = {
1709 .name = "usbin-vashdn",
1710 .handler = default_irq_handler,
1711 },
1712 [USBIN_UV_IRQ] = {
1713 .name = "usbin-uv",
1714 .handler = usbin_uv_irq_handler,
1715 },
1716 [USBIN_OV_IRQ] = {
1717 .name = "usbin-ov",
1718 .handler = default_irq_handler,
1719 },
1720 [USBIN_PLUGIN_IRQ] = {
1721 .name = "usbin-plugin",
1722 .handler = usb_plugin_irq_handler,
1723 },
1724 [USBIN_REVI_CHANGE_IRQ] = {
1725 .name = "usbin-revi-change",
1726 .handler = default_irq_handler,
1727 },
1728 [USBIN_SRC_CHANGE_IRQ] = {
1729 .name = "usbin-src-change",
1730 .handler = usb_source_change_irq_handler,
1731 },
1732 [USBIN_ICL_CHANGE_IRQ] = {
1733 .name = "usbin-icl-change",
1734 .handler = icl_change_irq_handler,
1735 },
1736 /* DC INPUT IRQs */
1737 [DCIN_VASHDN_IRQ] = {
1738 .name = "dcin-vashdn",
1739 .handler = default_irq_handler,
1740 },
1741 [DCIN_UV_IRQ] = {
1742 .name = "dcin-uv",
1743 .handler = default_irq_handler,
1744 },
1745 [DCIN_OV_IRQ] = {
1746 .name = "dcin-ov",
1747 .handler = default_irq_handler,
1748 },
1749 [DCIN_PLUGIN_IRQ] = {
1750 .name = "dcin-plugin",
1751 .handler = dc_plugin_irq_handler,
1752 .wake = true,
1753 },
1754 [DCIN_REVI_IRQ] = {
1755 .name = "dcin-revi",
1756 .handler = default_irq_handler,
1757 },
1758 [DCIN_PON_IRQ] = {
1759 .name = "dcin-pon",
1760 .handler = default_irq_handler,
1761 },
1762 [DCIN_EN_IRQ] = {
1763 .name = "dcin-en",
1764 .handler = default_irq_handler,
1765 },
1766 /* TYPEC IRQs */
1767 [TYPEC_OR_RID_DETECTION_CHANGE_IRQ] = {
1768 .name = "typec-or-rid-detect-change",
Ashay Jaiswala9e10912018-02-02 14:03:35 +05301769 .handler = typec_or_rid_detection_change_irq_handler,
Harry Yang4b7db0f2017-11-27 10:50:44 -08001770 },
1771 [TYPEC_VPD_DETECT_IRQ] = {
1772 .name = "typec-vpd-detect",
1773 .handler = default_irq_handler,
1774 },
1775 [TYPEC_CC_STATE_CHANGE_IRQ] = {
1776 .name = "typec-cc-state-change",
1777 .handler = typec_state_change_irq_handler,
1778 },
1779 [TYPEC_VCONN_OC_IRQ] = {
1780 .name = "typec-vconn-oc",
1781 .handler = default_irq_handler,
1782 },
1783 [TYPEC_VBUS_CHANGE_IRQ] = {
1784 .name = "typec-vbus-change",
1785 .handler = default_irq_handler,
1786 },
1787 [TYPEC_ATTACH_DETACH_IRQ] = {
1788 .name = "typec-attach-detach",
1789 .handler = default_irq_handler,
1790 },
1791 [TYPEC_LEGACY_CABLE_DETECT_IRQ] = {
1792 .name = "typec-legacy-cable-detect",
1793 .handler = default_irq_handler,
1794 },
1795 [TYPEC_TRY_SNK_SRC_DETECT_IRQ] = {
1796 .name = "typec-try-snk-src-detect",
1797 .handler = default_irq_handler,
1798 },
1799 /* MISCELLANEOUS IRQs */
1800 [WDOG_SNARL_IRQ] = {
1801 .name = "wdog-snarl",
1802 .handler = NULL,
1803 },
1804 [WDOG_BARK_IRQ] = {
1805 .name = "wdog-bark",
1806 .handler = wdog_bark_irq_handler,
1807 },
1808 [AICL_FAIL_IRQ] = {
1809 .name = "aicl-fail",
1810 .handler = default_irq_handler,
1811 },
1812 [AICL_DONE_IRQ] = {
1813 .name = "aicl-done",
1814 .handler = default_irq_handler,
1815 },
1816 [SMB_EN_IRQ] = {
1817 .name = "smb-en",
1818 .handler = default_irq_handler,
1819 },
1820 [IMP_TRIGGER_IRQ] = {
1821 .name = "imp-trigger",
1822 .handler = default_irq_handler,
1823 },
1824 [TEMP_CHANGE_IRQ] = {
1825 .name = "temp-change",
1826 .handler = default_irq_handler,
1827 },
1828 [TEMP_CHANGE_SMB_IRQ] = {
1829 .name = "temp-change-smb",
1830 .handler = default_irq_handler,
1831 },
1832};
1833
1834static int smb5_get_irq_index_byname(const char *irq_name)
1835{
1836 int i;
1837
1838 for (i = 0; i < ARRAY_SIZE(smb5_irqs); i++) {
1839 if (strcmp(smb5_irqs[i].name, irq_name) == 0)
1840 return i;
1841 }
1842
1843 return -ENOENT;
1844}
1845
1846static int smb5_request_interrupt(struct smb5 *chip,
1847 struct device_node *node, const char *irq_name)
1848{
1849 struct smb_charger *chg = &chip->chg;
1850 int rc, irq, irq_index;
1851 struct smb_irq_data *irq_data;
1852
1853 irq = of_irq_get_byname(node, irq_name);
1854 if (irq < 0) {
1855 pr_err("Couldn't get irq %s byname\n", irq_name);
1856 return irq;
1857 }
1858
1859 irq_index = smb5_get_irq_index_byname(irq_name);
1860 if (irq_index < 0) {
1861 pr_err("%s is not a defined irq\n", irq_name);
1862 return irq_index;
1863 }
1864
1865 if (!smb5_irqs[irq_index].handler)
1866 return 0;
1867
1868 irq_data = devm_kzalloc(chg->dev, sizeof(*irq_data), GFP_KERNEL);
1869 if (!irq_data)
1870 return -ENOMEM;
1871
1872 irq_data->parent_data = chip;
1873 irq_data->name = irq_name;
1874 irq_data->storm_data = smb5_irqs[irq_index].storm_data;
1875 mutex_init(&irq_data->storm_data.storm_lock);
1876
1877 rc = devm_request_threaded_irq(chg->dev, irq, NULL,
1878 smb5_irqs[irq_index].handler,
1879 IRQF_ONESHOT, irq_name, irq_data);
1880 if (rc < 0) {
1881 pr_err("Couldn't request irq %d\n", irq);
1882 return rc;
1883 }
1884
1885 smb5_irqs[irq_index].irq = irq;
1886 smb5_irqs[irq_index].irq_data = irq_data;
1887 if (smb5_irqs[irq_index].wake)
1888 enable_irq_wake(irq);
1889
1890 return rc;
1891}
1892
1893static int smb5_request_interrupts(struct smb5 *chip)
1894{
1895 struct smb_charger *chg = &chip->chg;
1896 struct device_node *node = chg->dev->of_node;
1897 struct device_node *child;
1898 int rc = 0;
1899 const char *name;
1900 struct property *prop;
1901
1902 for_each_available_child_of_node(node, child) {
1903 of_property_for_each_string(child, "interrupt-names",
1904 prop, name) {
1905 rc = smb5_request_interrupt(chip, child, name);
1906 if (rc < 0)
1907 return rc;
1908 }
1909 }
1910 if (chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq)
1911 chg->usb_icl_change_irq_enabled = true;
1912
1913 return rc;
1914}
1915
1916static void smb5_free_interrupts(struct smb_charger *chg)
1917{
1918 int i;
1919
1920 for (i = 0; i < ARRAY_SIZE(smb5_irqs); i++) {
1921 if (smb5_irqs[i].irq > 0) {
1922 if (smb5_irqs[i].wake)
1923 disable_irq_wake(smb5_irqs[i].irq);
1924
1925 devm_free_irq(chg->dev, smb5_irqs[i].irq,
1926 smb5_irqs[i].irq_data);
1927 }
1928 }
1929}
1930
1931static void smb5_disable_interrupts(struct smb_charger *chg)
1932{
1933 int i;
1934
1935 for (i = 0; i < ARRAY_SIZE(smb5_irqs); i++) {
1936 if (smb5_irqs[i].irq > 0)
1937 disable_irq(smb5_irqs[i].irq);
1938 }
1939}
1940
1941#if defined(CONFIG_DEBUG_FS)
1942
1943static int force_batt_psy_update_write(void *data, u64 val)
1944{
1945 struct smb_charger *chg = data;
1946
1947 power_supply_changed(chg->batt_psy);
1948 return 0;
1949}
1950DEFINE_SIMPLE_ATTRIBUTE(force_batt_psy_update_ops, NULL,
1951 force_batt_psy_update_write, "0x%02llx\n");
1952
1953static int force_usb_psy_update_write(void *data, u64 val)
1954{
1955 struct smb_charger *chg = data;
1956
1957 power_supply_changed(chg->usb_psy);
1958 return 0;
1959}
1960DEFINE_SIMPLE_ATTRIBUTE(force_usb_psy_update_ops, NULL,
1961 force_usb_psy_update_write, "0x%02llx\n");
1962
1963static int force_dc_psy_update_write(void *data, u64 val)
1964{
1965 struct smb_charger *chg = data;
1966
1967 power_supply_changed(chg->dc_psy);
1968 return 0;
1969}
1970DEFINE_SIMPLE_ATTRIBUTE(force_dc_psy_update_ops, NULL,
1971 force_dc_psy_update_write, "0x%02llx\n");
1972
1973static void smb5_create_debugfs(struct smb5 *chip)
1974{
1975 struct dentry *file;
1976
1977 chip->dfs_root = debugfs_create_dir("charger", NULL);
1978 if (IS_ERR_OR_NULL(chip->dfs_root)) {
1979 pr_err("Couldn't create charger debugfs rc=%ld\n",
1980 (long)chip->dfs_root);
1981 return;
1982 }
1983
1984 file = debugfs_create_file("force_batt_psy_update", 0600,
1985 chip->dfs_root, chip, &force_batt_psy_update_ops);
1986 if (IS_ERR_OR_NULL(file))
1987 pr_err("Couldn't create force_batt_psy_update file rc=%ld\n",
1988 (long)file);
1989
1990 file = debugfs_create_file("force_usb_psy_update", 0600,
1991 chip->dfs_root, chip, &force_usb_psy_update_ops);
1992 if (IS_ERR_OR_NULL(file))
1993 pr_err("Couldn't create force_usb_psy_update file rc=%ld\n",
1994 (long)file);
1995
1996 file = debugfs_create_file("force_dc_psy_update", 0600,
1997 chip->dfs_root, chip, &force_dc_psy_update_ops);
1998 if (IS_ERR_OR_NULL(file))
1999 pr_err("Couldn't create force_dc_psy_update file rc=%ld\n",
2000 (long)file);
2001}
2002
2003#else
2004
2005static void smb5_create_debugfs(struct smb5 *chip)
2006{}
2007
2008#endif
2009
2010static int smb5_show_charger_status(struct smb5 *chip)
2011{
2012 struct smb_charger *chg = &chip->chg;
2013 union power_supply_propval val;
2014 int usb_present, batt_present, batt_health, batt_charge_type;
2015 int rc;
2016
2017 rc = smblib_get_prop_usb_present(chg, &val);
2018 if (rc < 0) {
2019 pr_err("Couldn't get usb present rc=%d\n", rc);
2020 return rc;
2021 }
2022 usb_present = val.intval;
2023
2024 rc = smblib_get_prop_batt_present(chg, &val);
2025 if (rc < 0) {
2026 pr_err("Couldn't get batt present rc=%d\n", rc);
2027 return rc;
2028 }
2029 batt_present = val.intval;
2030
2031 rc = smblib_get_prop_batt_health(chg, &val);
2032 if (rc < 0) {
2033 pr_err("Couldn't get batt health rc=%d\n", rc);
2034 val.intval = POWER_SUPPLY_HEALTH_UNKNOWN;
2035 }
2036 batt_health = val.intval;
2037
2038 rc = smblib_get_prop_batt_charge_type(chg, &val);
2039 if (rc < 0) {
2040 pr_err("Couldn't get batt charge type rc=%d\n", rc);
2041 return rc;
2042 }
2043 batt_charge_type = val.intval;
2044
2045 pr_info("SMB5 status - usb:present=%d type=%d batt:present = %d health = %d charge = %d\n",
2046 usb_present, chg->real_charger_type,
2047 batt_present, batt_health, batt_charge_type);
2048 return rc;
2049}
2050
2051static int smb5_probe(struct platform_device *pdev)
2052{
2053 struct smb5 *chip;
2054 struct smb_charger *chg;
2055 int rc = 0;
2056
2057 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
2058 if (!chip)
2059 return -ENOMEM;
2060
2061 chg = &chip->chg;
2062 chg->dev = &pdev->dev;
Harry Yang4b7db0f2017-11-27 10:50:44 -08002063 chg->debug_mask = &__debug_mask;
2064 chg->weak_chg_icl_ua = &__weak_chg_icl_ua;
2065 chg->mode = PARALLEL_MASTER;
2066 chg->irq_info = smb5_irqs;
2067 chg->die_health = -EINVAL;
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302068 chg->otg_present = false;
Harry Yang4b7db0f2017-11-27 10:50:44 -08002069
2070 chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
2071 if (!chg->regmap) {
2072 pr_err("parent regmap is missing\n");
2073 return -EINVAL;
2074 }
2075
2076 rc = smb5_parse_dt(chip);
2077 if (rc < 0) {
2078 pr_err("Couldn't parse device tree rc=%d\n", rc);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302079 return rc;
2080 }
2081
2082 rc = smb5_chg_config_init(chip);
2083 if (rc < 0) {
2084 if (rc != -EPROBE_DEFER)
2085 pr_err("Couldn't setup chg_config rc=%d\n", rc);
2086 return rc;
Harry Yang4b7db0f2017-11-27 10:50:44 -08002087 }
2088
2089 rc = smblib_init(chg);
2090 if (rc < 0) {
2091 pr_err("Smblib_init failed rc=%d\n", rc);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302092 return rc;
Harry Yang4b7db0f2017-11-27 10:50:44 -08002093 }
2094
2095 /* set driver data before resources request it */
2096 platform_set_drvdata(pdev, chip);
2097
2098 rc = smb5_init_vbus_regulator(chip);
2099 if (rc < 0) {
2100 pr_err("Couldn't initialize vbus regulator rc=%d\n",
2101 rc);
2102 goto cleanup;
2103 }
2104
2105 rc = smb5_init_vconn_regulator(chip);
2106 if (rc < 0) {
2107 pr_err("Couldn't initialize vconn regulator rc=%d\n",
2108 rc);
2109 goto cleanup;
2110 }
2111
2112 /* extcon registration */
2113 chg->extcon = devm_extcon_dev_allocate(chg->dev, smblib_extcon_cable);
2114 if (IS_ERR(chg->extcon)) {
2115 rc = PTR_ERR(chg->extcon);
2116 dev_err(chg->dev, "failed to allocate extcon device rc=%d\n",
2117 rc);
2118 goto cleanup;
2119 }
2120
2121 rc = devm_extcon_dev_register(chg->dev, chg->extcon);
2122 if (rc < 0) {
2123 dev_err(chg->dev, "failed to register extcon device rc=%d\n",
2124 rc);
2125 goto cleanup;
2126 }
2127
2128 rc = smb5_init_hw(chip);
2129 if (rc < 0) {
2130 pr_err("Couldn't initialize hardware rc=%d\n", rc);
2131 goto cleanup;
2132 }
2133
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302134 if (chg->smb_version == PM855B_SUBTYPE) {
2135 rc = smb5_init_dc_psy(chip);
2136 if (rc < 0) {
2137 pr_err("Couldn't initialize dc psy rc=%d\n", rc);
2138 goto cleanup;
2139 }
Harry Yang4b7db0f2017-11-27 10:50:44 -08002140 }
2141
2142 rc = smb5_init_usb_psy(chip);
2143 if (rc < 0) {
2144 pr_err("Couldn't initialize usb psy rc=%d\n", rc);
2145 goto cleanup;
2146 }
2147
2148 rc = smb5_init_usb_main_psy(chip);
2149 if (rc < 0) {
2150 pr_err("Couldn't initialize usb main psy rc=%d\n", rc);
2151 goto cleanup;
2152 }
2153
2154 rc = smb5_init_usb_port_psy(chip);
2155 if (rc < 0) {
2156 pr_err("Couldn't initialize usb pc_port psy rc=%d\n", rc);
2157 goto cleanup;
2158 }
2159
2160 rc = smb5_init_batt_psy(chip);
2161 if (rc < 0) {
2162 pr_err("Couldn't initialize batt psy rc=%d\n", rc);
2163 goto cleanup;
2164 }
2165
2166 rc = smb5_determine_initial_status(chip);
2167 if (rc < 0) {
2168 pr_err("Couldn't determine initial status rc=%d\n",
2169 rc);
2170 goto cleanup;
2171 }
2172
2173 rc = smb5_request_interrupts(chip);
2174 if (rc < 0) {
2175 pr_err("Couldn't request interrupts rc=%d\n", rc);
2176 goto cleanup;
2177 }
2178
2179 rc = smb5_post_init(chip);
2180 if (rc < 0) {
2181 pr_err("Failed in post init rc=%d\n", rc);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302182 goto free_irq;
Harry Yang4b7db0f2017-11-27 10:50:44 -08002183 }
2184
2185 smb5_create_debugfs(chip);
2186
2187 rc = smb5_show_charger_status(chip);
2188 if (rc < 0) {
2189 pr_err("Failed in getting charger status rc=%d\n", rc);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302190 goto free_irq;
Harry Yang4b7db0f2017-11-27 10:50:44 -08002191 }
2192
2193 device_init_wakeup(chg->dev, true);
2194
2195 pr_info("QPNP SMB5 probed successfully\n");
2196
2197 return rc;
2198
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302199free_irq:
Harry Yang4b7db0f2017-11-27 10:50:44 -08002200 smb5_free_interrupts(chg);
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302201cleanup:
Harry Yang4b7db0f2017-11-27 10:50:44 -08002202 smblib_deinit(chg);
2203 platform_set_drvdata(pdev, NULL);
2204
2205 return rc;
2206}
2207
2208static int smb5_remove(struct platform_device *pdev)
2209{
2210 struct smb5 *chip = platform_get_drvdata(pdev);
2211 struct smb_charger *chg = &chip->chg;
2212
2213 smb5_free_interrupts(chg);
2214 smblib_deinit(chg);
2215 platform_set_drvdata(pdev, NULL);
2216 return 0;
2217}
2218
2219static void smb5_shutdown(struct platform_device *pdev)
2220{
2221 struct smb5 *chip = platform_get_drvdata(pdev);
2222 struct smb_charger *chg = &chip->chg;
2223
2224 /* disable all interrupts */
2225 smb5_disable_interrupts(chg);
2226
2227 /* configure power role for UFP */
Ashay Jaiswala9e10912018-02-02 14:03:35 +05302228 if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC)
Harry Yang4b7db0f2017-11-27 10:50:44 -08002229 smblib_masked_write(chg, TYPE_C_MODE_CFG_REG,
2230 TYPEC_POWER_ROLE_CMD_MASK, EN_SNK_ONLY_BIT);
2231
2232 /* force HVDCP to 5V */
2233 smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
2234 HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT, 0);
2235 smblib_write(chg, CMD_HVDCP_2_REG, FORCE_5V_BIT);
2236
2237 /* force enable APSD */
2238 smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
2239 BC1P2_SRC_DETECT_BIT, BC1P2_SRC_DETECT_BIT);
2240}
2241
2242static const struct of_device_id match_table[] = {
2243 { .compatible = "qcom,qpnp-smb5", },
2244 { },
2245};
2246
2247static struct platform_driver smb5_driver = {
2248 .driver = {
2249 .name = "qcom,qpnp-smb5",
2250 .owner = THIS_MODULE,
2251 .of_match_table = match_table,
2252 },
2253 .probe = smb5_probe,
2254 .remove = smb5_remove,
2255 .shutdown = smb5_shutdown,
2256};
2257module_platform_driver(smb5_driver);
2258
2259MODULE_DESCRIPTION("QPNP SMB5 Charger Driver");
2260MODULE_LICENSE("GPL v2");