3 * SiliconMitus SM5701 Charger Driver
5 * Copyright (C) 2014 SiliconMitus
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/module.h>
19 #include <linux/moduleparam.h>
20 #include <linux/bug.h>
21 #include <linux/delay.h>
22 #include <linux/err.h>
23 #include <linux/gpio.h>
24 #include <linux/slab.h>
25 #include <linux/platform_device.h>
26 #include <linux/i2c.h>
27 #include <linux/mfd/sm5701_core.h>
28 #include <linux/battery/sec_charger.h>
29 #include <linux/interrupt.h>
30 #include <linux/irq.h>
32 #include <linux/seq_file.h>
33 #include <linux/debugfs.h>
34 #include <linux/seq_file.h>
36 #include <linux/gpio-pxa.h>
37 #include <linux/of_device.h>
38 #include <linux/of_gpio.h>
39 #include <linux/of_irq.h>
41 extern int sec_chg_dt_init(struct device_node *np,
43 sec_battery_platform_data_t *pdata);
44 extern led_state_charger;
46 static enum power_supply_property sec_charger_props[] = {
47 POWER_SUPPLY_PROP_STATUS,
48 POWER_SUPPLY_PROP_CHARGE_TYPE,
49 POWER_SUPPLY_PROP_HEALTH,
50 POWER_SUPPLY_PROP_PRESENT,
51 POWER_SUPPLY_PROP_ONLINE,
52 POWER_SUPPLY_PROP_VOLTAGE_MAX,
53 POWER_SUPPLY_PROP_CURRENT_MAX,
54 POWER_SUPPLY_PROP_CURRENT_AVG,
55 POWER_SUPPLY_PROP_CURRENT_NOW,
58 static void SM5701_charger_initialize(struct SM5701_charger_data *charger);
60 static int SM5701_get_battery_present(struct SM5701_charger_data *charger)
64 SM5701_reg_read(charger->SM5701->i2c, SM5701_STATUS1, &data);
66 pr_info("%s: SM5701_STATUS1 (0x%02x)\n", __func__, data);
68 data = ((data & SM5701_STATUS1_NOBAT) >> SM5701_STATUS1_NOBAT_SHIFT);
73 static int SM5701_get_charging_status(struct SM5701_charger_data *charger)
75 int status = POWER_SUPPLY_STATUS_UNKNOWN;
77 u8 stat2, chg_en, cln;
79 SM5701_reg_read(charger->SM5701->i2c, SM5701_STATUS2, &stat2);
80 pr_info("%s : SM5701_STATUS2 : 0x%02x\n", __func__, stat2);
82 // Clear interrupt register 2
83 SM5701_reg_read(charger->SM5701->i2c, SM5701_INT2, &cln);
85 SM5701_reg_read(charger->SM5701->i2c, SM5701_CNTL, &chg_en);
86 chg_en &= SM5701_CNTL_OPERATIONMODE;
88 nCHG = gpio_get_value(charger->pdata->chg_gpio_en);
90 if((stat2 & SM5701_STATUS2_DONE) || (stat2 & SM5701_STATUS2_TOPOFF)) {
91 status = POWER_SUPPLY_STATUS_FULL;
92 charger->is_fullcharged = true;
93 pr_info("%s : Status, Power Supply Full \n", __func__);
96 status = POWER_SUPPLY_STATUS_DISCHARGING;
98 status = POWER_SUPPLY_STATUS_CHARGING;
104 static int SM5701_get_charging_health(struct SM5701_charger_data *charger)
106 static int health = POWER_SUPPLY_HEALTH_GOOD;
109 SM5701_reg_read(charger->SM5701->i2c, SM5701_STATUS1, &stat1);
111 // Clear interrupt register 1
112 SM5701_reg_read(charger->SM5701->i2c, SM5701_INT1, &cln);
114 pr_info("%s : Health, SM5701_STATUS1 : 0x%02x\n", __func__, stat1);
116 if (stat1 & SM5701_STATUS1_VBUSOVP) {
117 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
118 } else if (stat1 & SM5701_STATUS1_VBUSUVLO) {
119 if (charger->cable_type != POWER_SUPPLY_TYPE_BATTERY) {
120 health = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
122 } else if (stat1 & SM5701_INT1_VBUSOK) {
123 health = POWER_SUPPLY_HEALTH_GOOD;
129 static u8 SM5701_set_batreg_voltage(
130 struct SM5701_charger_data *charger, int batreg_voltage)
134 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL3, &data);
136 data &= ~BATREG_MASK;
138 if (charger->dev_id < 3) {
139 if ((batreg_voltage*10) < 40125)
141 else if ((batreg_voltage*10) > 44000)
142 batreg_voltage = 4400;
144 data = ((batreg_voltage*10 - 40125) / 125);
146 if (batreg_voltage <= 3725)
148 else if (batreg_voltage >= 4400)
150 else if (batreg_voltage <= 4300)
151 data = (batreg_voltage - 3725) / 25;
153 data = (batreg_voltage - 4300) * 10 / 125 + 23;
156 SM5701_reg_write(charger->SM5701->i2c, SM5701_CHGCNTL3, data);
158 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL3, &data);
159 pr_info("%s : SM5701_CHGCNTL3 (Battery regulation voltage) : 0x%02x\n",
165 static u8 SM5701_set_vbuslimit_current(
166 struct SM5701_charger_data *charger, int input_current)
168 u8 data = 0, temp = 0;
169 SM5701_reg_read(charger->SM5701->i2c, SM5701_VBUSCNTL, &data);
170 data &= ~SM5701_VBUSCNTL_VBUSLIMIT;
172 if (input_current >= 1200)
173 input_current = 1200;
175 if (charger->voltage_max != 4200) {
176 if (charger->cable_type != POWER_SUPPLY_TYPE_BATTERY) {
177 data &= ~SM5701_VBUSCNTL_VBUSLIMIT;
178 SM5701_reg_write(charger->SM5701->i2c, SM5701_VBUSCNTL, data);
179 pr_info("%s : SM5701_VBUSCNTL (Input current limit) : 0x%02x\n",
183 if(input_current <= 100)
184 data &= ~SM5701_VBUSCNTL_VBUSLIMIT;
185 else if(input_current <= 500)
188 temp = (input_current/100)-5;
194 SM5701_reg_write(charger->SM5701->i2c, SM5701_VBUSCNTL, data);
196 SM5701_reg_read(charger->SM5701->i2c, SM5701_VBUSCNTL, &data);
197 pr_info("%s : SM5701_VBUSCNTL (Input current limit) : 0x%02x\n",
203 static u8 SM5701_set_topoff(
204 struct SM5701_charger_data *charger, int topoff_current)
208 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL1, &data);
210 data &= ~SM5701_CHGCNTL1_TOPOFF;
212 if(topoff_current < 100)
213 topoff_current = 100;
214 else if (topoff_current > 475)
215 topoff_current = 475;
217 data |= (topoff_current - 100) / 25;
219 SM5701_reg_write(charger->SM5701->i2c, SM5701_CHGCNTL1, data);
221 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL1, &data);
222 pr_info("%s : SM5701_CHGCNTL1 (Top-off current threshold) : 0x%02x\n",
228 static u8 SM5701_set_fastchg_current(
229 struct SM5701_charger_data *charger, int fast_charging_current)
233 if(fast_charging_current < 100)
234 fast_charging_current = 100;
235 else if (fast_charging_current > 1600)
236 fast_charging_current = 1600;
238 data = (fast_charging_current - 100) / 25;
240 SM5701_reg_write(charger->SM5701->i2c, SM5701_CHGCNTL2, data);
242 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL2, &data);
243 pr_info("%s : SM5701_CHGCNTL2 (fastchg current) : 0x%02x\n",
249 static int SM5701_get_charging_current(
250 struct SM5701_charger_data *charger)
255 if (charger->charging_current) {
256 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL2, &data);
257 data &= SM5701_CHGCNTL2_FASTCHG;
258 charger->charging_curr_step = 25;
259 get_current = (100 + (data * charger->charging_curr_step));
260 if (get_current <= 1600)
261 get_current = (100 + (data * charger->charging_curr_step));
266 get_current = (100 + (data * charger->charging_curr_step));
268 pr_debug("%s : Charging current : %dmA\n", __func__, get_current);
272 static u8 SM5701_toggle_charger(struct SM5701_charger_data *charger, int enable)
274 u8 chg_en = 0, mask = 0;
276 SM5701_reg_read(charger->SM5701->i2c, SM5701_CNTL, &chg_en);
278 mask = charger->dev_id < 3 ? OP_MODE_CHG_ON : OP_MODE_CHG_ON_REV3;
281 if ((led_state_charger == LED_DISABLE) || (charger->dev_id != 4)) {
285 SM5701_reg_write(charger->SM5701->i2c, SM5701_CNTL, chg_en);
286 gpio_direction_output((charger->pdata->chg_gpio_en), !enable);
288 pr_info("%s: SM5701 Charger toggled!! \n", __func__);
290 SM5701_reg_read(charger->SM5701->i2c, SM5701_CNTL, &chg_en);
291 pr_info("%s : CNTL register (0x09) : 0x%02x\n", __func__, chg_en);
294 SM5701_set_operationmode(SM5701_OPERATIONMODE_FLASH_ON);
295 pr_info("%s: SM5701 Charger toggled!! - flash on!! \n", __func__);
296 gpio_direction_output((charger->pdata->chg_gpio_en), !enable);
302 static void SM5701_isr_work(struct work_struct *work)
304 union power_supply_propval val, value;
305 struct SM5701_charger_data *charger =
306 container_of(work, struct SM5701_charger_data, isr_work.work);;
309 u8 cln = 0, topoff_data = 0, status = 0;
311 psy_do_property("battery", get,
312 POWER_SUPPLY_PROP_CHARGE_NOW, val);
313 if (val.intval == SEC_BATTERY_CHARGING_1ST)
314 full_check_type = charger->pdata->full_check_type;
316 full_check_type = charger->pdata->full_check_type_2nd;
318 if (full_check_type == SEC_BATTERY_FULLCHARGED_CHGINT) {
319 val.intval = SM5701_get_charging_status(charger);
321 switch (val.intval) {
322 case POWER_SUPPLY_STATUS_FULL:
323 pr_err("%s: Interrupted by Full\n", __func__);
324 psy_do_property("battery", set,
325 POWER_SUPPLY_PROP_STATUS, val);
330 pr_info("=============================================================\n");
331 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL1, &topoff_data);
332 pr_info("%s : SM5701_CHGCNTL1 (Top-off current threshold) : 0x%02x\n",__func__, topoff_data);
333 SM5701_reg_read(charger->SM5701->i2c, SM5701_STATUS2, &status);
334 pr_info("%s: STATUS2 : %d\n", __func__, status); //SM : test
335 pr_info("=============================================================\n");
337 if (charger->pdata->ovp_uvlo_check_type ==
338 SEC_BATTERY_OVP_UVLO_CHGINT) {
339 val.intval = SM5701_get_charging_health(charger);
341 switch (val.intval) {
342 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
343 /* case POWER_SUPPLY_HEALTH_UNDERVOLTAGE: */
344 pr_info("%s: Interrupted by OVP/UVLO\n", __func__);
345 psy_do_property("battery", set,
346 POWER_SUPPLY_PROP_HEALTH, val);
348 case POWER_SUPPLY_HEALTH_UNDERVOLTAGE:
349 /* case POWER_SUPPLY_HEALTH_UNDERVOLTAGE: */
350 psy_do_property("battery", get,
351 POWER_SUPPLY_PROP_ONLINE, value);
353 if (value.intval != POWER_SUPPLY_TYPE_BATTERY) {
354 pr_info("%s: Interrupted by OVP/UVLO\n", __func__);
355 psy_do_property("battery", set,
356 POWER_SUPPLY_PROP_HEALTH, val);
359 case POWER_SUPPLY_HEALTH_GOOD:
360 pr_err("%s: Interrupted but Good\n", __func__);
361 psy_do_property("battery", set,
362 POWER_SUPPLY_PROP_HEALTH, val);
365 pr_err("%s: Invalid Charger Health\n", __func__);
370 val.intval = SM5701_get_battery_present(charger);
371 pr_info("%s: battery status : %d\n", __func__, val.intval);
373 psy_do_property("battery", set,
374 POWER_SUPPLY_PROP_PRESENT, val);
377 static irqreturn_t SM5701_irq_thread(int irq, void *irq_data)
379 struct SM5701_charger_data *charger = irq_data;
380 pr_info("*** %s ***\n", __func__);
381 // Temporary delay of the interrupt to prevent MUIC interrupt running after it
382 schedule_delayed_work(&charger->isr_work, HZ * 0.25);
386 static int SM5701_debugfs_show(struct seq_file *s, void *data)
388 struct SM5701_charger_data *charger = s->private;
392 seq_printf(s, "SM5701 CHARGER IC :\n");
393 seq_printf(s, "===================\n");
394 for (reg = SM5701_INTMASK1; reg <= SM5701_FLEDCNTL6; reg++) {
395 SM5701_reg_read(charger->SM5701->i2c, reg, ®_data);
396 seq_printf(s, "0x%02x:\t0x%02x\n", reg, reg_data);
403 static int SM5701_debugfs_open(struct inode *inode, struct file *file)
405 return single_open(file, SM5701_debugfs_show, inode->i_private);
408 static const struct file_operations SM5701_debugfs_fops = {
409 .open = SM5701_debugfs_open,
412 .release = single_release,
415 static void SM5701_charger_initialize(struct SM5701_charger_data *charger)
417 u8 reg_data = 0, status1 = 0;
419 SM5701_reg_read(charger->SM5701->i2c,
420 SM5701_DEVICE_ID, &charger->dev_id);
421 pr_info("%s: SM5701 Charger init, CHIP REV : %2d !! \n",
422 __func__, charger->dev_id);
423 charger->is_fullcharged = false;
425 SM5701_reg_read(charger->SM5701->i2c, SM5701_VBUSCNTL, ®_data);
426 reg_data &= ~SM5701_VBUSCNTL_AICLEN;
427 SM5701_reg_write(charger->SM5701->i2c, SM5701_VBUSCNTL, reg_data);
429 SM5701_reg_read(charger->SM5701->i2c, SM5701_STATUS1, &status1);
430 pr_info("%s : SM5701_STATUS1 : 0x%02x\n", __func__, status1);
432 /* NOBAT, Enable OVP, UVLO, VBUSOK interrupts */
434 SM5701_reg_write(charger->SM5701->i2c, SM5701_INTMASK1, reg_data);
436 /* Mask CHGON, FASTTMROFFM */
438 SM5701_reg_write(charger->SM5701->i2c, SM5701_INTMASK2, reg_data);
440 /* Set OVPSEL to 6.35V
441 SM5701_reg_read(charger->SM5701->i2c, SM5701_CNTL, ®_data);
443 SM5701_reg_write(charger->SM5701->i2c, SM5701_CNTL, reg_data);
446 /* Operating Frequency in PWM BUCK mode : 2.4KHz */
447 SM5701_reg_read(charger->SM5701->i2c, SM5701_CNTL, ®_data);
449 reg_data |= (FREQ_24 | 0x4);
450 SM5701_reg_write(charger->SM5701->i2c, SM5701_CNTL, reg_data);
452 /* Disable AUTOSTOP */
453 SM5701_reg_read(charger->SM5701->i2c, SM5701_CHGCNTL1, ®_data);
454 reg_data &= ~SM5701_CHGCNTL1_AUTOSTOP;
455 SM5701_reg_write(charger->SM5701->i2c, SM5701_CHGCNTL1, reg_data);
457 (void) debugfs_create_file("SM5701_regs",
458 S_IRUGO, NULL, (void *)charger, &SM5701_debugfs_fops);
460 SM5701_test_read(charger->SM5701->i2c);
463 static int sec_chg_get_property(struct power_supply *psy,
464 enum power_supply_property psp,
465 union power_supply_propval *val)
467 struct SM5701_charger_data *charger =
468 container_of(psy, struct SM5701_charger_data, psy_chg);
471 case POWER_SUPPLY_PROP_ONLINE:
472 printk("[%s] got val->intval:%d\n",__func__, val->intval);
474 case POWER_SUPPLY_PROP_STATUS:
475 if (charger->is_fullcharged)
476 val->intval = POWER_SUPPLY_STATUS_FULL;
478 val->intval = SM5701_get_charging_status(charger);
480 case POWER_SUPPLY_PROP_HEALTH:
481 val->intval = SM5701_get_charging_health(charger);
483 case POWER_SUPPLY_PROP_PRESENT:
484 val->intval = SM5701_get_battery_present(charger);
486 case POWER_SUPPLY_PROP_CURRENT_MAX:
487 val->intval = charger->charging_current_max;
489 case POWER_SUPPLY_PROP_CURRENT_AVG:
490 val->intval = charger->charging_current;
492 case POWER_SUPPLY_PROP_CHARGE_NOW:
494 case POWER_SUPPLY_PROP_CURRENT_NOW:
495 val->intval = SM5701_get_charging_current(charger);
497 case POWER_SUPPLY_PROP_CHARGE_TYPE:
498 if (!charger->is_charging)
499 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
500 else if (charger->aicl_on)
502 val->intval = POWER_SUPPLY_CHARGE_TYPE_SLOW;
503 pr_info("%s: slow-charging mode\n", __func__);
506 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
508 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
516 static int sec_chg_set_property(struct power_supply *psy,
517 enum power_supply_property psp,
518 const union power_supply_propval *val)
520 struct SM5701_charger_data *charger =
521 container_of(psy, struct SM5701_charger_data, psy_chg);
522 union power_supply_propval value;
523 int charging_current;
524 // int set_charging_current, set_charging_current_max;
525 // const int usb_charging_current = charger->pdata->charging_current[
526 // POWER_SUPPLY_TYPE_USB].fast_charging_current;
527 u8 topoff_data = 0, stauts = 0;
530 case POWER_SUPPLY_PROP_STATUS:
531 charger->status = val->intval;
533 case POWER_SUPPLY_PROP_ONLINE:
534 charger->cable_type = val->intval;
535 psy_do_property("battery", get,
536 POWER_SUPPLY_PROP_HEALTH, value);
537 if (val->intval == POWER_SUPPLY_TYPE_BATTERY) {
538 /* Disable Charger */
539 charger->is_charging = false;
540 charger->nchgen = true;
541 charger->aicl_on = false;
542 pr_info("%s : Disable Charger, Battery Supply!\n", __func__);
543 // nCHG_EN is logic low so set 1 to disable charger
544 charger->is_fullcharged = false;
545 } else if(val->intval == POWER_SUPPLY_TYPE_OTG){
546 charger->is_charging = false;
547 charger->nchgen = true;
548 charger->aicl_on = false;
549 charger->is_fullcharged = false;
550 charger->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
551 SM5701_set_bstout(SM5701_BSTOUT_5P0);
552 SM5701_set_operationmode(SM5701_OPERATIONMODE_OTG_ON_FLASH_ON);
553 SM5701_test_read(charger->SM5701->i2c);
556 charger->is_charging = true;
557 charger->nchgen = false;
558 charger->charging_current_max =
559 charger->pdata->charging_current
560 [charger->cable_type].input_current_limit;
561 charger->charging_current =
562 charger->pdata->charging_current
563 [charger->cable_type].fast_charging_current;
566 SM5701_operation_mode_function_control();
567 pr_info("%s : STATUS OF CHARGER ON(0)/OFF(1): %d\n", __func__, charger->nchgen);
568 SM5701_toggle_charger(charger, charger->is_charging);
570 /* if battery full, only disable charging */
571 if ((charger->status == POWER_SUPPLY_STATUS_CHARGING) ||
572 (charger->status == POWER_SUPPLY_STATUS_DISCHARGING) ||
573 (charger->status == POWER_SUPPLY_STATUS_FULL) ||
574 (value.intval == POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) ||
575 (value.intval == POWER_SUPPLY_HEALTH_OVERHEATLIMIT)) {
577 /* Set float voltage */
578 pr_info("%s : float voltage (%dmV)\n",
579 __func__, charger->pdata->chg_float_voltage);
580 if (charger->pdata->chg_float_voltage > charger->voltage_max) {
581 SM5701_set_batreg_voltage(
582 charger, charger->voltage_max);
583 pr_info("%s : set float voltage to voltage_max (%dmV)\n",
584 __func__, charger->voltage_max);
586 SM5701_set_batreg_voltage(
587 charger, charger->pdata->chg_float_voltage);
590 /* if battery is removed, put vbus current limit to minimum */
591 if ((value.intval == POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) ||
592 (value.intval == POWER_SUPPLY_HEALTH_OVERHEATLIMIT))
593 SM5701_set_vbuslimit_current(charger, 100);
595 /* Set input current limit */
596 pr_info("%s : vbus current limit (%dmA)\n",
597 __func__, charger->pdata->charging_current
598 [charger->cable_type].input_current_limit);
600 SM5701_set_vbuslimit_current(
601 charger, charger->pdata->charging_current
602 [charger->cable_type].input_current_limit);
605 /* Set topoff current */
606 pr_info("%s : topoff current (%dmA)\n",
607 __func__, charger->pdata->charging_current[
608 charger->cable_type].full_check_current_1st);
609 if (charger->voltage_max == 4200)
610 SM5701_set_topoff(charger, 100);
613 charger, charger->pdata->charging_current[
614 charger->cable_type].full_check_current_1st);
616 /* Set fast charge current */
617 pr_info("%s : fast charging current (%dmA), siop_level=%d\n",
618 __func__, charger->charging_current, charger->siop_level);
620 charger->charging_current * charger->siop_level / 100;
621 SM5701_set_fastchg_current(
622 charger, charging_current);
625 /* val->intval : float voltage */
626 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
627 charger->voltage_max = val->intval;
628 SM5701_set_batreg_voltage(
629 charger, charger->voltage_max);
630 pr_info("POWER_SUPPLY_PROP_VOLTAGE_MAX[%d]\n", charger->voltage_max);
631 if (charger->voltage_max == 4200)
632 SM5701_set_topoff(charger, 100);
633 else if (charger->voltage_max == 4350)
634 SM5701_set_topoff(charger, charger->pdata->charging_current[
635 charger->cable_type].full_check_current_1st);
637 /* val->intval : input charging current */
638 case POWER_SUPPLY_PROP_CURRENT_MAX:
639 charger->charging_current_max = val->intval;
641 /* val->intval : charging current */
642 case POWER_SUPPLY_PROP_CURRENT_AVG:
643 charger->charging_current = val->intval;
645 case POWER_SUPPLY_PROP_CURRENT_NOW:
646 SM5701_set_fastchg_current(charger,
648 SM5701_set_vbuslimit_current(charger,
651 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
652 charger->siop_level = val->intval;
653 /* Set fast charge current */
654 pr_info("%s : fast charging current (%dmA), siop_level=%d\n",
655 __func__, charger->charging_current, charger->siop_level);
657 charger->charging_current * charger->siop_level / 100;
658 SM5701_set_fastchg_current(
659 charger, charging_current);
668 static struct of_device_id SM5701_charger_match_table[] = {
669 { .compatible = "sm,sm5701-charger",},
673 #define SM5701_charger_match_table NULL
674 #endif /* CONFIG_OF */
676 static int SM5701_charger_probe(struct platform_device *pdev)
678 struct SM5701_dev *iodev = dev_get_drvdata(pdev->dev.parent);
679 struct SM5701_platform_data *pdata = dev_get_platdata(iodev->dev);
680 struct SM5701_charger_data *charger;
683 pr_info("%s: SM5701 Charger Probe Start\n", __func__);
685 charger = kzalloc(sizeof(*charger), GFP_KERNEL);
689 if (pdev->dev.parent->of_node) {
690 pdev->dev.of_node = of_find_compatible_node(
691 of_node_get(pdev->dev.parent->of_node), NULL,
692 SM5701_charger_match_table[0].compatible);
695 charger->SM5701 = iodev;
696 charger->SM5701->dev = &pdev->dev;
698 if (pdev->dev.of_node) {
699 charger->pdata = devm_kzalloc(&pdev->dev, sizeof(*(charger->pdata)),
701 if (!charger->pdata) {
702 dev_err(&pdev->dev, "Failed to allocate memory\n");
704 goto err_parse_dt_nomem;
706 ret = sec_chg_dt_init(pdev->dev.of_node, &pdev->dev, charger->pdata);
710 charger->pdata = pdata->charger_data;
712 charger->voltage_max = charger->pdata->chg_float_voltage;
714 platform_set_drvdata(pdev, charger);
716 if (charger->pdata->charger_name == NULL)
717 charger->pdata->charger_name = "sec-charger";
719 charger->psy_chg.name = charger->pdata->charger_name;
720 charger->psy_chg.type = POWER_SUPPLY_TYPE_UNKNOWN;
721 charger->psy_chg.get_property = sec_chg_get_property;
722 charger->psy_chg.set_property = sec_chg_set_property;
723 charger->psy_chg.properties = sec_charger_props;
724 charger->psy_chg.num_properties = ARRAY_SIZE(sec_charger_props);
726 charger->siop_level = 100;
727 SM5701_charger_initialize(charger);
729 charger->input_curr_limit_step = 500;
730 charger->charging_curr_step= 25;
731 ret = power_supply_register(&pdev->dev, &charger->psy_chg);
733 pr_err("%s: Failed to Register psy_chg\n", __func__);
734 goto err_power_supply_register;
737 SM5701_set_charger_data(charger);
738 if (charger->pdata->chg_irq) {
739 INIT_DELAYED_WORK(&charger->isr_work, SM5701_isr_work);
741 ret = request_threaded_irq(charger->pdata->chg_irq,
742 NULL, SM5701_irq_thread,
743 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
744 /* charger->pdata->chg_irq_attr, */
745 "charger-irq", charger);
748 "%s: Failed to Reqeust IRQ\n", __func__);
749 goto err_request_irq;
752 ret = enable_irq_wake(charger->pdata->chg_irq);
755 "%s: Failed to Enable Wakeup Source(%d)\n",
758 pr_info("%s: SM5701 Charger Probe Loaded\n", __func__);
762 power_supply_unregister(&charger->psy_chg);
763 err_power_supply_register:
764 pr_info("%s: err_power_supply_register error \n", __func__);
766 pr_info("%s: err_parse_dt error \n", __func__);
768 pr_info("%s: err_parse_dt_nomem error \n", __func__);
773 static int SM5701_charger_remove(struct platform_device *pdev)
775 struct SM5701_charger_data *charger =
776 platform_get_drvdata(pdev);
777 power_supply_unregister(&charger->psy_chg);
783 bool SM5701_charger_suspend(struct SM5701_charger_data *charger)
785 pr_info("%s: CHARGER - SM5701(suspend mode)!!\n", __func__);
789 bool SM5701_charger_resume(struct SM5701_charger_data *charger)
791 pr_info("%s: CHARGER - SM5701(resume mode)!!\n", __func__);
795 static void SM5701_charger_shutdown(struct device *dev)
797 struct SM5701_charger_data *charger =
798 dev_get_drvdata(dev);
800 pr_info("%s: SM5701 Charger driver shutdown\n", __func__);
801 if (!charger->SM5701->i2c) {
802 pr_err("%s: no SM5701 i2c client\n", __func__);
807 static const struct platform_device_id SM5701_charger_id[] = {
808 { "sm5701-charger", 0},
811 MODULE_DEVICE_TABLE(platform, SM5701_charger_id);
813 static struct platform_driver SM5701_charger_driver = {
815 .name = "sm5701-charger",
816 .owner = THIS_MODULE,
817 .of_match_table = SM5701_charger_match_table,
818 .shutdown = SM5701_charger_shutdown,
820 .probe = SM5701_charger_probe,
821 .remove = SM5701_charger_remove,
822 .id_table = SM5701_charger_id,
825 static int __init SM5701_charger_init(void)
827 pr_info("%s\n", __func__);
828 return platform_driver_register(&SM5701_charger_driver);
831 subsys_initcall(SM5701_charger_init);
833 static void __exit SM5701_charger_exit(void)
835 platform_driver_unregister(&SM5701_charger_driver);
838 module_exit(SM5701_charger_exit);
840 MODULE_DESCRIPTION("SILICONMITUS SM5701 Charger Driver");
841 MODULE_AUTHOR("Samsung Electronics");
842 MODULE_LICENSE("GPL");
843 MODULE_ALIAS("platform:SM5701_charger");