blob: f5eb9bde7af2a5f2811c1cbe13a3e2ace03dd354 [file] [log] [blame]
Nicholas Troast96886052016-02-25 15:42:17 -08001/* Copyright (c) 2016 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/device.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <linux/power_supply.h>
18#include <linux/interrupt.h>
19#include <linux/of.h>
20#include <linux/of_irq.h>
21#include <linux/regulator/driver.h>
22#include <linux/regulator/of_regulator.h>
23#include <linux/regulator/machine.h>
24#include "smb-reg.h"
25#include "smb-lib.h"
26#include "pmic-voter.h"
27
28#define SMB2_DEFAULT_FCC_UA 1000000
29#define SMB2_DEFAULT_ICL_UA 1500000
30
31static struct smb_params v1_params = {
32 .fcc = {
33 .name = "fast charge current",
34 .reg = FAST_CHARGE_CURRENT_CFG_REG,
35 .min_u = 0,
36 .max_u = 4500000,
37 .step_u = 25000,
38 },
39 .fv = {
40 .name = "float voltage",
41 .reg = FLOAT_VOLTAGE_CFG_REG,
42 .min_u = 2500000,
43 .max_u = 5000000,
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 = 6000000,
51 .step_u = 25000,
52 },
53 .dc_icl = {
54 .name = "dc input current limit",
55 .reg = DCIN_CURRENT_LIMIT_CFG_REG,
56 .min_u = 0,
57 .max_u = 6000000,
58 .step_u = 25000,
59 },
60};
61
62struct smb_dt_props {
63 bool suspend_input;
64 int fcc_ua;
65 int usb_icl_ua;
66 int dc_icl_ua;
67 int fv_uv;
68};
69
70struct smb2 {
71 struct smb_charger chg;
72 struct smb_dt_props dt;
73 bool bad_part;
74};
75
76static int __debug_mask;
77module_param_named(
78 debug_mask, __debug_mask, int, 0600
79);
80
81static int smb2_parse_dt(struct smb2 *chip)
82{
83 struct smb_charger *chg = &chip->chg;
84 struct device_node *node = chg->dev->of_node;
85 int rc;
86
87 if (!node) {
88 pr_err("device tree node missing\n");
89 return -EINVAL;
90 }
91
92 chip->dt.suspend_input = of_property_read_bool(node,
93 "qcom,suspend-input");
94
95 rc = of_property_read_u32(node,
96 "qcom,fcc-max-ua", &chip->dt.fcc_ua);
97 if (rc < 0)
98 chip->dt.fcc_ua = SMB2_DEFAULT_FCC_UA;
99
100 rc = of_property_read_u32(node,
101 "qcom,usb-icl-ua", &chip->dt.usb_icl_ua);
102 if (rc < 0)
103 chip->dt.usb_icl_ua = SMB2_DEFAULT_ICL_UA;
104
105 rc = of_property_read_u32(node,
106 "qcom,dc-icl-ua", &chip->dt.dc_icl_ua);
107 if (rc < 0)
108 chip->dt.dc_icl_ua = SMB2_DEFAULT_ICL_UA;
109
110 return 0;
111}
112
113/************************
114 * USB PSY REGISTRATION *
115 ************************/
116
117static enum power_supply_property smb2_usb_props[] = {
118 POWER_SUPPLY_PROP_PRESENT,
119 POWER_SUPPLY_PROP_ONLINE,
120 POWER_SUPPLY_PROP_VOLTAGE_MIN,
121 POWER_SUPPLY_PROP_VOLTAGE_MAX,
122 POWER_SUPPLY_PROP_VOLTAGE_NOW,
123 POWER_SUPPLY_PROP_CURRENT_MAX,
124 POWER_SUPPLY_PROP_TYPE,
125 POWER_SUPPLY_PROP_TYPEC_MODE,
126 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE,
127 POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION,
128 POWER_SUPPLY_PROP_PD_ALLOWED,
129 POWER_SUPPLY_PROP_PD_ACTIVE,
130};
131
132static int smb2_usb_get_prop(struct power_supply *psy,
133 enum power_supply_property psp,
134 union power_supply_propval *val)
135{
136 struct smb2 *chip = power_supply_get_drvdata(psy);
137 struct smb_charger *chg = &chip->chg;
138 int rc = 0;
139
140 switch (psp) {
141 case POWER_SUPPLY_PROP_PRESENT:
142 if (chip->bad_part)
143 val->intval = 1;
144 else
145 rc = smblib_get_prop_usb_present(chg, val);
146 break;
147 case POWER_SUPPLY_PROP_ONLINE:
148 rc = smblib_get_prop_usb_online(chg, val);
149 break;
150 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
151 val->intval = chg->voltage_min_uv;
152 break;
153 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
154 val->intval = chg->voltage_max_uv;
155 break;
156 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
157 rc = smblib_get_prop_usb_voltage_now(chg, val);
158 break;
159 case POWER_SUPPLY_PROP_CURRENT_MAX:
160 rc = smblib_get_prop_usb_current_max(chg, val);
161 break;
162 case POWER_SUPPLY_PROP_TYPE:
163 if (chip->bad_part)
164 val->intval = POWER_SUPPLY_TYPE_USB;
165 else
166 val->intval = chg->usb_psy_desc.type;
167 break;
168 case POWER_SUPPLY_PROP_TYPEC_MODE:
169 if (chip->bad_part)
170 val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
171 else
172 rc = smblib_get_prop_typec_mode(chg, val);
173 break;
174 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
175 rc = smblib_get_prop_typec_power_role(chg, val);
176 break;
177 case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION:
178 rc = smblib_get_prop_typec_cc_orientation(chg, val);
179 break;
180 case POWER_SUPPLY_PROP_PD_ALLOWED:
181 rc = smblib_get_prop_pd_allowed(chg, val);
182 break;
183 case POWER_SUPPLY_PROP_PD_ACTIVE:
184 val->intval = chg->pd_active;
185 break;
186 default:
187 pr_err("get prop %d is not supported\n", psp);
188 rc = -EINVAL;
189 break;
190 }
191 return rc;
192}
193
194static int smb2_usb_set_prop(struct power_supply *psy,
195 enum power_supply_property psp,
196 const union power_supply_propval *val)
197{
198 struct smb2 *chip = power_supply_get_drvdata(psy);
199 struct smb_charger *chg = &chip->chg;
200 int rc = 0;
201
202 switch (psp) {
203 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
204 rc = smblib_set_prop_usb_voltage_min(chg, val);
205 break;
206 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
207 rc = smblib_set_prop_usb_voltage_max(chg, val);
208 break;
209 case POWER_SUPPLY_PROP_CURRENT_MAX:
210 rc = smblib_set_prop_usb_current_max(chg, val);
211 break;
Jack Pham9696e252016-05-23 11:15:15 -0700212 case POWER_SUPPLY_PROP_TYPE:
213 if (chg->pd_active && val->intval == POWER_SUPPLY_TYPE_USB_PD) {
214 chg->usb_psy_desc.type = val->intval;
215 } else {
216 pr_err("set type %d not allowed\n", val->intval);
217 rc = -EINVAL;
218 }
219 break;
Nicholas Troast96886052016-02-25 15:42:17 -0800220 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
221 rc = smblib_set_prop_typec_power_role(chg, val);
222 break;
223 case POWER_SUPPLY_PROP_PD_ACTIVE:
224 rc = smblib_set_prop_pd_active(chg, val);
225 break;
226 default:
227 pr_err("set prop %d is not supported\n", psp);
228 rc = -EINVAL;
229 break;
230 }
231
232 return rc;
233}
234
235static int smb2_usb_prop_is_writeable(struct power_supply *psy,
236 enum power_supply_property psp)
237{
238 switch (psp) {
239 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
240 return 1;
241 default:
242 break;
243 }
244
245 return 0;
246}
247
248static int smb2_init_usb_psy(struct smb2 *chip)
249{
250 struct power_supply_config usb_cfg = {};
251 struct smb_charger *chg = &chip->chg;
252
253 chg->usb_psy_desc.name = "usb";
254 chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;
255 chg->usb_psy_desc.properties = smb2_usb_props;
256 chg->usb_psy_desc.num_properties = ARRAY_SIZE(smb2_usb_props);
257 chg->usb_psy_desc.get_property = smb2_usb_get_prop;
258 chg->usb_psy_desc.set_property = smb2_usb_set_prop;
259 chg->usb_psy_desc.property_is_writeable = smb2_usb_prop_is_writeable;
260
261 usb_cfg.drv_data = chip;
262 usb_cfg.of_node = chg->dev->of_node;
263 chg->usb_psy = devm_power_supply_register(chg->dev,
264 &chg->usb_psy_desc,
265 &usb_cfg);
266 if (IS_ERR(chg->usb_psy)) {
267 pr_err("Couldn't register USB power supply\n");
268 return PTR_ERR(chg->usb_psy);
269 }
270
271 return 0;
272}
273
274/*************************
275 * BATT PSY REGISTRATION *
276 *************************/
277
278static enum power_supply_property smb2_batt_props[] = {
279 POWER_SUPPLY_PROP_INPUT_SUSPEND,
280 POWER_SUPPLY_PROP_STATUS,
281 POWER_SUPPLY_PROP_HEALTH,
282 POWER_SUPPLY_PROP_PRESENT,
283 POWER_SUPPLY_PROP_CHARGE_TYPE,
284 POWER_SUPPLY_PROP_CAPACITY,
285};
286
287static int smb2_batt_get_prop(struct power_supply *psy,
288 enum power_supply_property psp,
289 union power_supply_propval *val)
290{
291 struct smb_charger *chg = power_supply_get_drvdata(psy);
292
293 switch (psp) {
294 case POWER_SUPPLY_PROP_STATUS:
295 smblib_get_prop_batt_status(chg, val);
296 break;
297 case POWER_SUPPLY_PROP_HEALTH:
298 smblib_get_prop_batt_health(chg, val);
299 break;
300 case POWER_SUPPLY_PROP_PRESENT:
301 smblib_get_prop_batt_present(chg, val);
302 break;
303 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
304 smblib_get_prop_input_suspend(chg, val);
305 break;
306 case POWER_SUPPLY_PROP_CHARGE_TYPE:
307 smblib_get_prop_batt_charge_type(chg, val);
308 break;
309 case POWER_SUPPLY_PROP_CAPACITY:
310 smblib_get_prop_batt_capacity(chg, val);
311 break;
312 default:
313 pr_err("batt power supply prop %d not supported\n",
314 psp);
315 return -EINVAL;
316 }
317
318 return 0;
319}
320
321static int smb2_batt_set_prop(struct power_supply *psy,
322 enum power_supply_property prop,
323 const union power_supply_propval *val)
324{
325 struct smb_charger *chg = power_supply_get_drvdata(psy);
326
327 switch (prop) {
328 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
329 smblib_set_prop_input_suspend(chg, val);
330 break;
331 default:
332 return -EINVAL;
333 }
334
335 return 0;
336}
337
338static int smb2_batt_prop_is_writeable(struct power_supply *psy,
339 enum power_supply_property psp)
340{
341 switch (psp) {
342 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
343 return 1;
344 default:
345 break;
346 }
347
348 return 0;
349}
350
351static const struct power_supply_desc batt_psy_desc = {
352 .name = "battery",
353 .type = POWER_SUPPLY_TYPE_BATTERY,
354 .properties = smb2_batt_props,
355 .num_properties = ARRAY_SIZE(smb2_batt_props),
356 .get_property = smb2_batt_get_prop,
357 .set_property = smb2_batt_set_prop,
358 .property_is_writeable = smb2_batt_prop_is_writeable,
359};
360
361static int smb2_init_batt_psy(struct smb2 *chip)
362{
363 struct power_supply_config batt_cfg = {};
364 struct smb_charger *chg = &chip->chg;
365 int rc = 0;
366
367 batt_cfg.drv_data = chg;
368 batt_cfg.of_node = chg->dev->of_node;
369 chg->batt_psy = devm_power_supply_register(chg->dev,
370 &batt_psy_desc,
371 &batt_cfg);
372 if (IS_ERR(chg->batt_psy)) {
373 pr_err("Couldn't register battery power supply\n");
374 return PTR_ERR(chg->batt_psy);
375 }
376
377 return rc;
378}
379
380/******************************
381 * VBUS REGULATOR REGISTRATION *
382 ******************************/
383
384struct regulator_ops smb2_vbus_reg_ops = {
385 .enable = smblib_vbus_regulator_enable,
386 .disable = smblib_vbus_regulator_disable,
387 .is_enabled = smblib_vbus_regulator_is_enabled,
388};
389
390static int smb2_init_vbus_regulator(struct smb2 *chip)
391{
392 struct smb_charger *chg = &chip->chg;
393 struct regulator_config cfg = {};
394 int rc = 0;
395
396 chg->vbus_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vbus_vreg),
397 GFP_KERNEL);
398 if (!chg->vbus_vreg)
399 return -ENOMEM;
400
401 cfg.dev = chg->dev;
402 cfg.driver_data = chip;
403
404 chg->vbus_vreg->rdesc.owner = THIS_MODULE;
405 chg->vbus_vreg->rdesc.type = REGULATOR_VOLTAGE;
406 chg->vbus_vreg->rdesc.ops = &smb2_vbus_reg_ops;
407 chg->vbus_vreg->rdesc.of_match = "qcom,smb2-vbus";
408 chg->vbus_vreg->rdesc.name = "qcom,smb2-vbus";
409
410 chg->vbus_vreg->rdev = devm_regulator_register(chg->dev,
411 &chg->vbus_vreg->rdesc, &cfg);
412 if (IS_ERR(chg->vbus_vreg->rdev)) {
413 rc = PTR_ERR(chg->vbus_vreg->rdev);
414 chg->vbus_vreg->rdev = NULL;
415 if (rc != -EPROBE_DEFER)
416 pr_err("Couldn't register VBUS regualtor rc=%d\n", rc);
417 }
418
419 return rc;
420}
421
422/******************************
423 * VCONN REGULATOR REGISTRATION *
424 ******************************/
425
426struct regulator_ops smb2_vconn_reg_ops = {
427 .enable = smblib_vconn_regulator_enable,
428 .disable = smblib_vconn_regulator_disable,
429 .is_enabled = smblib_vconn_regulator_is_enabled,
430};
431
432static int smb2_init_vconn_regulator(struct smb2 *chip)
433{
434 struct smb_charger *chg = &chip->chg;
435 struct regulator_config cfg = {};
436 int rc = 0;
437
438 chg->vconn_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vconn_vreg),
439 GFP_KERNEL);
440 if (!chg->vconn_vreg)
441 return -ENOMEM;
442
443 cfg.dev = chg->dev;
444 cfg.driver_data = chip;
445
446 chg->vconn_vreg->rdesc.owner = THIS_MODULE;
447 chg->vconn_vreg->rdesc.type = REGULATOR_VOLTAGE;
448 chg->vconn_vreg->rdesc.ops = &smb2_vconn_reg_ops;
449 chg->vconn_vreg->rdesc.of_match = "qcom,smb2-vconn";
450 chg->vconn_vreg->rdesc.name = "qcom,smb2-vconn";
451
452 chg->vconn_vreg->rdev = devm_regulator_register(chg->dev,
453 &chg->vconn_vreg->rdesc, &cfg);
454 if (IS_ERR(chg->vconn_vreg->rdev)) {
455 rc = PTR_ERR(chg->vconn_vreg->rdev);
456 chg->vconn_vreg->rdev = NULL;
457 if (rc != -EPROBE_DEFER)
458 pr_err("Couldn't register VCONN regualtor rc=%d\n", rc);
459 }
460
461 return rc;
462}
463
464/***************************
465 * HARDWARE INITIALIZATION *
466 ***************************/
467
468static int smb2_init_hw(struct smb2 *chip)
469{
470 struct smb_charger *chg = &chip->chg;
471 int rc;
472
473 /* votes must be cast before configuring software control */
474 vote(chg->usb_suspend_votable,
475 DEFAULT_VOTER, chip->dt.suspend_input, 0);
476 vote(chg->dc_suspend_votable,
477 DEFAULT_VOTER, chip->dt.suspend_input, 0);
478 vote(chg->fcc_votable,
479 DEFAULT_VOTER, true, chip->dt.fcc_ua);
480 vote(chg->usb_icl_votable,
481 DEFAULT_VOTER, true, chip->dt.usb_icl_ua);
482 vote(chg->dc_icl_votable,
483 DEFAULT_VOTER, true, chip->dt.dc_icl_ua);
484
485 /* configure charge enable for software control; active high */
486 rc = smblib_masked_write(chg, CHGR_CFG2_REG,
487 CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
488 if (rc < 0) {
489 dev_err(chg->dev,
490 "Couldn't configure charge enable source rc=%d\n", rc);
491 return rc;
492 }
493
494 /* enable the charging path */
495 rc = smblib_enable_charging(chg, true);
496 if (rc < 0) {
497 dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
498 return rc;
499 }
500
501 /*
502 * trigger the usb-typec-change interrupt only when the CC state
503 * changes, or there was a VBUS error
504 */
505 rc = smblib_write(chg, TYPE_C_INTRPT_ENB_REG,
506 TYPEC_CCSTATE_CHANGE_INT_EN_BIT
507 | TYPEC_VBUS_ERROR_INT_EN_BIT);
508 if (rc < 0) {
509 dev_err(chg->dev,
510 "Couldn't configure Type-C interrupts rc=%d\n", rc);
511 return rc;
512 }
513
514 /* configure VCONN for software control */
515 rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
516 VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT,
517 VCONN_EN_SRC_BIT);
518 if (rc < 0) {
519 dev_err(chg->dev,
520 "Couldn't configure VCONN for SW control rc=%d\n", rc);
521 return rc;
522 }
523
524 /* configure VBUS for software control */
525 rc = smblib_masked_write(chg, OTG_CFG_REG, OTG_EN_SRC_CFG_BIT, 0);
526 if (rc < 0) {
527 dev_err(chg->dev,
528 "Couldn't configure VBUS for SW control rc=%d\n", rc);
529 return rc;
530 }
531
532 /* configure power role for dual-role */
533 rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
534 TYPEC_POWER_ROLE_CMD_MASK, 0);
535 if (rc < 0) {
536 dev_err(chg->dev,
537 "Couldn't configure power role for DRP rc=%d\n", rc);
538 return rc;
539 }
540
Nicholas Troast4ea53ba2016-05-20 16:15:36 -0700541 /* disable Type-C factory mode */
542 rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
543 FACTORY_MODE_DETECTION_EN_BIT, 0);
544 if (rc < 0) {
545 dev_err(chg->dev,
546 "Couldn't disable Type-C factory mode rc=%d\n", rc);
547 return rc;
548 }
549
Nicholas Troast96886052016-02-25 15:42:17 -0800550 return rc;
551}
552
553/****************************
554 * DETERMINE INITIAL STATUS *
555 ****************************/
556
557static int smb2_determine_initial_status(struct smb2 *chip)
558{
559 struct smb_irq_data irq_data = {chip, "determine-initial-status"};
560
561 smblib_handle_usb_plugin(0, &irq_data);
562 smblib_handle_usb_typec_change(0, &irq_data);
563 smblib_handle_usb_source_change(0, &irq_data);
564
565 return 0;
566}
567
568/**************************
569 * INTERRUPT REGISTRATION *
570 **************************/
571
572struct smb2_irq_info {
573 const char *name;
574 const irq_handler_t handler;
575};
576
577static const struct smb2_irq_info smb2_irqs[] = {
578/* CHARGER IRQs */
579 { "chg-error", smblib_handle_debug },
580 { "chg-state-change", smblib_handle_debug },
581 { "step-chg-state-change", smblib_handle_debug },
582 { "step-chg-soc-update-fail", smblib_handle_debug },
583 { "step-chg-soc-update-request", smblib_handle_debug },
584/* OTG IRQs */
585 { "otg-fail", smblib_handle_debug },
586 { "otg-overcurrent", smblib_handle_debug },
587 { "otg-oc-dis-sw-sts", smblib_handle_debug },
588 { "testmode-change-detect", smblib_handle_debug },
589/* BATTERY IRQs */
590 { "bat-temp", smblib_handle_batt_psy_changed },
591 { "bat-ocp", smblib_handle_batt_psy_changed },
592 { "bat-ov", smblib_handle_batt_psy_changed },
593 { "bat-low", smblib_handle_batt_psy_changed },
594 { "bat-therm-or-id-missing", smblib_handle_batt_psy_changed },
595 { "bat-terminal-missing", smblib_handle_batt_psy_changed },
596/* USB INPUT IRQs */
597 { "usbin-collapse", smblib_handle_debug },
598 { "usbin-lt-3p6v", smblib_handle_debug },
599 { "usbin-uv", smblib_handle_debug },
600 { "usbin-ov", smblib_handle_debug },
601 { "usbin-plugin", smblib_handle_usb_plugin },
602 { "usbin-src-change", smblib_handle_usb_source_change },
603 { "usbin-icl-change", smblib_handle_debug },
604 { "type-c-change", smblib_handle_usb_typec_change },
605/* DC INPUT IRQs */
606 { "dcin-collapse", smblib_handle_debug },
607 { "dcin-lt-3p6v", smblib_handle_debug },
608 { "dcin-uv", smblib_handle_debug },
609 { "dcin-ov", smblib_handle_debug },
610 { "dcin-plugin", smblib_handle_debug },
611 { "div2-en-dg", smblib_handle_debug },
612 { "dcin-icl-change", smblib_handle_debug },
613/* MISCELLANEOUS IRQs */
614 { "wdog-snarl", smblib_handle_debug },
615 { "wdog-bark", smblib_handle_debug },
616 { "aicl-fail", smblib_handle_debug },
617 { "aicl-done", smblib_handle_debug },
618 { "high-duty-cycle", smblib_handle_debug },
619 { "input-current-limiting", smblib_handle_debug },
620 { "temperature-change", smblib_handle_debug },
621 { "switcher-power-ok", smblib_handle_debug },
622};
623
624static int smb2_get_irq_index_byname(const char *irq_name)
625{
626 int i;
627
628 for (i = 0; i < ARRAY_SIZE(smb2_irqs); i++) {
629 if (strcmp(smb2_irqs[i].name, irq_name) == 0)
630 return i;
631 }
632
633 return -ENOENT;
634}
635
636static int smb2_request_interrupt(struct smb2 *chip,
637 struct device_node *node, const char *irq_name)
638{
639 struct smb_charger *chg = &chip->chg;
640 int rc, irq, irq_index;
641 struct smb_irq_data *irq_data;
642
643 irq = of_irq_get_byname(node, irq_name);
644 if (irq < 0) {
645 pr_err("Couldn't get irq %s byname\n", irq_name);
646 return irq;
647 }
648
649 irq_index = smb2_get_irq_index_byname(irq_name);
650 if (irq_index < 0) {
651 pr_err("%s is not a defined irq\n", irq_name);
652 return irq_index;
653 }
654
655 irq_data = devm_kzalloc(chg->dev, sizeof(*irq_data), GFP_KERNEL);
656 if (!irq_data)
657 return -ENOMEM;
658
659 irq_data->parent_data = chip;
660 irq_data->name = irq_name;
661
662 rc = devm_request_threaded_irq(chg->dev, irq, NULL,
663 smb2_irqs[irq_index].handler,
664 IRQF_ONESHOT, irq_name, irq_data);
665 if (rc < 0) {
666 pr_err("Couldn't request irq %d\n", irq);
667 return rc;
668 }
669
670 return rc;
671}
672
673static int smb2_request_interrupts(struct smb2 *chip)
674{
675 struct smb_charger *chg = &chip->chg;
676 struct device_node *node = chg->dev->of_node;
677 struct device_node *child;
678 int rc = 0;
679 const char *name;
680 struct property *prop;
681
682 for_each_available_child_of_node(node, child) {
683 of_property_for_each_string(child, "interrupt-names",
684 prop, name) {
685 rc = smb2_request_interrupt(chip, child, name);
686 if (rc < 0)
687 return rc;
688 }
689 }
690
691 return rc;
692}
693
694/*********
695 * PROBE *
696 *********/
697
698static int smb2_probe(struct platform_device *pdev)
699{
700 struct smb2 *chip;
701 struct smb_charger *chg;
702 int rc = 0;
703 u8 stat;
704
705 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
706 if (!chip)
707 return -ENOMEM;
708
709 chg = &chip->chg;
710 chg->dev = &pdev->dev;
711 chg->param = v1_params;
712 chg->debug_mask = &__debug_mask;
713
714 chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
715 if (!chg->regmap) {
716 pr_err("parent regmap is missing\n");
717 return -EINVAL;
718 }
719
720 smblib_init(chg);
721
722 rc = smb2_parse_dt(chip);
723 if (rc < 0) {
724 pr_err("Couldn't parse device tree rc=%d\n", rc);
725 goto cleanup;
726 }
727
728 /* set driver data before resources request it */
729 platform_set_drvdata(pdev, chip);
730
731 rc = smb2_init_vbus_regulator(chip);
732 if (rc < 0) {
733 pr_err("Couldn't initialize vbus regulator rc=%d\n",
734 rc);
735 goto cleanup;
736 }
737
738 rc = smb2_init_vconn_regulator(chip);
739 if (rc < 0) {
740 pr_err("Couldn't initialize vconn regulator rc=%d\n",
741 rc);
742 goto cleanup;
743 }
744
745 rc = smb2_init_usb_psy(chip);
746 if (rc < 0) {
747 pr_err("Couldn't initialize usb psy rc=%d\n", rc);
748 goto cleanup;
749 }
750
751 rc = smblib_read(chg, SHDN_CMD_REG, &stat);
752 if (rc < 0) {
753 pr_err("Couldn't read MISC_SHDN_CMD_REG rc=%d\n", rc);
754 return rc;
755 }
756
757 if (stat) {
758 pr_err("bad charger part; faking USB insertion\n");
759 chip->bad_part = true;
760 power_supply_changed(chg->usb_psy);
761 return 0;
762 }
763
764 rc = smb2_init_batt_psy(chip);
765 if (rc < 0) {
766 pr_err("Couldn't initialize batt psy rc=%d\n", rc);
767 goto cleanup;
768 }
769
770 rc = smb2_init_hw(chip);
771 if (rc < 0) {
772 pr_err("Couldn't initialize hardware rc=%d\n", rc);
773 goto cleanup;
774 }
775
776 rc = smb2_determine_initial_status(chip);
777 if (rc < 0) {
778 pr_err("Couldn't determine initial status rc=%d\n",
779 rc);
780 goto cleanup;
781 }
782
783 rc = smb2_request_interrupts(chip);
784 if (rc < 0) {
785 pr_err("Couldn't request interrupts rc=%d\n", rc);
786 goto cleanup;
787 }
788
789 pr_info("QPNP SMB2 probed successfully\n");
790 return rc;
791
792cleanup:
793 if (chg->usb_psy)
794 power_supply_unregister(chg->usb_psy);
795 if (chg->batt_psy)
796 power_supply_unregister(chg->batt_psy);
797 if (chg->vconn_vreg && chg->vconn_vreg->rdev)
798 regulator_unregister(chg->vconn_vreg->rdev);
799 if (chg->vbus_vreg && chg->vbus_vreg->rdev)
800 regulator_unregister(chg->vbus_vreg->rdev);
801 platform_set_drvdata(pdev, NULL);
802 return rc;
803}
804
805static int smb2_remove(struct platform_device *pdev)
806{
807 struct smb2 *chip = platform_get_drvdata(pdev);
808 struct smb_charger *chg = &chip->chg;
809
810 power_supply_unregister(chg->batt_psy);
811 power_supply_unregister(chg->usb_psy);
812 regulator_unregister(chg->vconn_vreg->rdev);
813 regulator_unregister(chg->vbus_vreg->rdev);
814
815 platform_set_drvdata(pdev, NULL);
816 return 0;
817}
818
819static const struct of_device_id match_table[] = {
820 { .compatible = "qcom,qpnp-smb2", },
821 { },
822};
823
824static struct platform_driver smb2_driver = {
825 .driver = {
826 .name = "qcom,qpnp-smb2",
827 .owner = THIS_MODULE,
828 .of_match_table = match_table,
829 },
830 .probe = smb2_probe,
831 .remove = smb2_remove,
832};
833module_platform_driver(smb2_driver);
834
835MODULE_DESCRIPTION("QPNP SMB2 Charger Driver");
836MODULE_LICENSE("GPL v2");