3 * SiliconMitus SM5414 Charger Driver
5 * Copyright (C) 2013 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.
20 #include <linux/battery/sec_charger.h>
21 #include <linux/seq_file.h>
22 #include <linux/debugfs.h>
23 #include <linux/seq_file.h>
24 #include <linux/gpio.h>
25 #include <linux/gpio-pxa.h>
26 #include <linux/of_device.h>
27 #include <linux/of_gpio.h>
28 #include <linux/of_irq.h>
30 static int charger_health = POWER_SUPPLY_HEALTH_GOOD;
32 static int SM5414_i2c_write(struct i2c_client *client,
36 ret = i2c_smbus_write_i2c_block_data(client, reg, 1, buf);
38 dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
43 static int SM5414_i2c_read(struct i2c_client *client,
47 ret = i2c_smbus_read_i2c_block_data(client, reg, 1, buf);
49 dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
55 static void SM5414_test_read(struct i2c_client *client)
61 for (addr = SM5414_INTMASK1; addr <= SM5414_CHGCTRL5; addr++) {
62 SM5414_i2c_read(client, addr, &data);
63 dev_info(&client->dev,
64 "SM5414 addr : 0x%02x data : 0x%02x\n", addr, data);
69 static void SM5414_read_regs(struct i2c_client *client, char *str)
74 //0x00~02 are R/C (read and clear)
75 for (addr = SM5414_INTMASK1; addr <= SM5414_CHGCTRL5; addr++) {
76 SM5414_i2c_read(client, addr, &data);
77 sprintf(str+strlen(str), "0x%x, ", data);
81 static int SM5414_get_battery_present(struct i2c_client *client)
85 SM5414_i2c_read(client, SM5414_INT2, &data);
87 pr_info("%s: SM5414_INT2 (0x%02x)\n", __func__, data);
89 data = ((data & SM5414_INT2_NOBAT) >> 6);
94 static int SM5414_get_charging_status(struct i2c_client *client)
96 int status = POWER_SUPPLY_STATUS_UNKNOWN;
97 struct sec_charger_info *charger = i2c_get_clientdata(client);
100 union power_supply_propval value;
102 SM5414_i2c_read(client, SM5414_INT2, &int2);
103 SM5414_i2c_read(client, SM5414_CTRL, &chg_en);
105 if((int2 & SM5414_INT2_DONE) || (int2 & SM5414_INT2_TOPOFF)) {
106 psy_do_property("sec-fuelgauge", get,
107 POWER_SUPPLY_PROP_CAPACITY, value);
108 if ((value.intval > 94) &&
109 (charger->cable_type != POWER_SUPPLY_TYPE_BATTERY)) {
110 status = POWER_SUPPLY_STATUS_FULL;
111 charger->is_fullcharged = true;
112 dev_info(&client->dev,
113 "%s : Power Supply Full\n", __func__);
115 } else if (chg_en & CHARGE_EN) {
116 nCHG = gpio_get_value(charger->pdata->chg_gpio_en);
117 if ((nCHG) || (charger_health != POWER_SUPPLY_HEALTH_GOOD))
118 status = POWER_SUPPLY_STATUS_DISCHARGING;
120 status = POWER_SUPPLY_STATUS_CHARGING;
122 status = POWER_SUPPLY_STATUS_DISCHARGING;
128 int sec_get_charging_health(struct i2c_client *client)
130 static int health = POWER_SUPPLY_HEALTH_GOOD;
131 struct sec_charger_info *charger = i2c_get_clientdata(client);
135 SM5414_i2c_read(client, SM5414_INT1, &int1);
137 dev_info(&client->dev,
138 "%s : SM5414_INT1 : 0x%02x\n", __func__, int1);
140 #if defined(CONFIG_MACH_PIKEAYOUNG2DTV) || defined(CONFIG_MACH_PIKEAJ1)
141 /* VF check by adc detection */
142 if (!sec_vf_adc_check())
143 return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
146 if (int1 & SM5414_INT1_VBUSOVP) {
147 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
148 charger_health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
149 } else if (int1 & SM5414_INT1_VBUSUVLO) {
151 if (charger->cable_type != POWER_SUPPLY_TYPE_BATTERY) {
152 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
153 charger_health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
155 } else if (int1 & SM5414_INT1_VBUSINOK) {
156 health = POWER_SUPPLY_HEALTH_GOOD;
157 charger_health = POWER_SUPPLY_HEALTH_GOOD;
163 static u8 SM5414_set_float_voltage_data(
164 struct i2c_client *client, int float_voltage)
168 SM5414_i2c_read(client, SM5414_CHGCTRL3, &data);
172 if (float_voltage < 4100)
173 float_voltage = 4100;
174 else if (float_voltage > 4475)
175 float_voltage = 4475;
177 float_reg = (float_voltage - 4100) / 25;
178 data |= (float_reg << 4);
180 SM5414_i2c_write(client, SM5414_CHGCTRL3, &data);
182 SM5414_i2c_read(client, SM5414_CHGCTRL3, &data);
183 dev_dbg(&client->dev,
184 "%s : SM5414_CHGCTRL3 (float) : 0x%02x\n", __func__, data);
189 static u8 SM5414_set_input_current_limit_data(
190 struct i2c_client *client, int input_current)
192 u8 set_reg, curr_reg = 0;
194 struct sec_charger_info *charger = i2c_get_clientdata(client);
196 if(input_current < 100)
198 else if (input_current >= 2050)
199 input_current = 2050;
201 set_reg = (input_current - 100) / 50;
203 curr_reg = ((input_current % 100) >= 50) ? 1 : 0;
205 chg_en = gpio_get_value(charger->pdata->chg_gpio_en);
208 SM5414_i2c_write(client, SM5414_VBUSCTRL, &set_reg);
210 while (set_reg >= curr_reg) {
211 SM5414_i2c_write(client, SM5414_VBUSCTRL, &curr_reg);
217 SM5414_i2c_read(client, SM5414_VBUSCTRL, &curr_reg);
218 dev_dbg(&client->dev,
219 "%s : SM5414_VBUSCTRL (Input limit) : 0x%02x\n",
225 static u8 SM5414_set_topoff_current_limit_data(
226 struct i2c_client *client, int topoff_current)
231 SM5414_i2c_read(client, SM5414_CHGCTRL4, &data);
235 if(topoff_current < 100)
236 topoff_current = 100;
237 else if (topoff_current > 650)
238 topoff_current = 650;
240 topoff_reg = (topoff_current - 100) / 50;
241 data = data | (topoff_reg<<3);
243 SM5414_i2c_write(client, SM5414_CHGCTRL4, &data);
245 SM5414_i2c_read(client, SM5414_CHGCTRL4, &data);
246 dev_dbg(&client->dev,
247 "%s : SM5414_CHGCTRL4 (Top-off limit) : 0x%02x\n",
253 static u8 SM5414_set_fast_charging_current_data(
254 struct i2c_client *client, int fast_charging_current)
258 if(fast_charging_current < 100)
259 fast_charging_current = 100;
260 else if (fast_charging_current > 2500)
261 fast_charging_current = 2500;
263 data = (fast_charging_current - 100) / 50;
265 SM5414_i2c_write(client, SM5414_CHGCTRL2, &data);
266 SM5414_i2c_read(client, SM5414_CHGCTRL2, &data);
268 dev_dbg(&client->dev,
269 "%s : SM5414_CHGCTRL2 (fast) : 0x%02x\n", __func__, data);
274 static u8 SM5414_set_toggle_charger(struct i2c_client *client, int enable)
279 SM5414_i2c_read(client, SM5414_CTRL, &chg_en);
283 chg_en &= ~CHARGE_EN;
285 SM5414_i2c_write(client, SM5414_CTRL, &chg_en);
287 dev_info(&client->dev, "%s: SM5414 Charger toggled!! \n", __func__);
289 SM5414_i2c_read(client, SM5414_CTRL, &chg_en);
290 dev_info(&client->dev,
291 "%s : chg_en value(07h register): 0x%02x\n", __func__, chg_en);
293 SM5414_i2c_read(client, SM5414_CHGCTRL2, &data);
294 dev_info(&client->dev,
295 "%s : SM5414_CHGCTRL2 value: 0x%02x", __func__, data);
300 static void SM5414_charger_function_control(
301 struct i2c_client *client)
303 struct sec_charger_info *charger = i2c_get_clientdata(client);
304 union power_supply_propval value;
307 if (charger->charging_current < 0) {
308 dev_info(&client->dev,
309 "%s : OTG is activated. Ignore command!\n", __func__);
313 if (charger->cable_type == POWER_SUPPLY_TYPE_BATTERY) {
314 /* Disable Charger */
315 dev_info(&client->dev,
316 "%s : Disable Charger, Battery Supply!\n", __func__);
317 // nCHG_EN is logic low so set 1 to disable charger
318 charger->is_fullcharged = false;
319 gpio_direction_output((charger->pdata->chg_gpio_en), 1);
321 psy_do_property("sec-fuelgauge", get,
322 POWER_SUPPLY_PROP_CAPACITY, value);
323 if (value.intval > 0) {
324 SM5414_i2c_read(client, SM5414_CTRL, &suspend_en);
326 /* Suspend enable for register reset */
328 SM5414_i2c_write(client, SM5414_CTRL, &suspend_en);
331 SM5414_i2c_write(client, SM5414_CTRL, &suspend_en);
334 dev_info(&client->dev, "%s : float voltage (%dmV)\n",
335 __func__, charger->pdata->chg_float_voltage);
337 /* Set float voltage */
338 SM5414_set_float_voltage_data(
339 client, charger->pdata->chg_float_voltage);
341 dev_info(&client->dev, "%s : topoff current (%dmA)\n",
342 __func__, charger->pdata->charging_current[
343 charger->cable_type].full_check_current_1st);
344 SM5414_set_topoff_current_limit_data(
345 client, charger->pdata->charging_current[
346 charger->cable_type].full_check_current_1st);
348 SM5414_set_input_current_limit_data(client, 100);
349 // nCHG_EN is logic low so set 0 to enable charger
350 gpio_direction_output((charger->pdata->chg_gpio_en), 0);
353 /* Young2 DTV event charging set */
354 if (charger->pdata->siop_level == CALL_EVENT_SIOP) {
355 charger->charging_current = CALL_EVENT_CURRENT;
356 charger->input_current_limit = CALL_EVENT_CURRENT;
357 } else if (charger->pdata->siop_level == HIGH_TEMP_SIOP) {
358 charger->charging_current = HIGH_TEMP_CURRENT;
359 charger->input_current_limit = HIGH_TEMP_CURRENT;
361 charger->charging_current =
362 charger->pdata->charging_current
363 [charger->cable_type].fast_charging_current;
364 charger->input_current_limit =
365 charger->pdata->charging_current
366 [charger->cable_type].input_current_limit;
369 /* Input current limit */
370 dev_info(&client->dev, "%s : input current (%dmA)\n",
371 __func__, charger->input_current_limit);
373 SM5414_set_input_current_limit_data(
374 client, charger->input_current_limit);
376 /* Set fast charge current */
377 dev_info(&client->dev, "%s : fast charging current (%dmA), siop_level=%d\n",
378 __func__, charger->charging_current, charger->pdata->siop_level);
379 SM5414_set_fast_charging_current_data(
380 client, charger->charging_current);
382 dev_info(&client->dev,
383 "%s : Enable Charger!\n", __func__);
387 static void SM5414_charger_otg_control(
388 struct i2c_client *client)
390 struct sec_charger_info *charger = i2c_get_clientdata(client);
392 //turn on/off ENBOOST
393 if (charger->cable_type ==
394 POWER_SUPPLY_TYPE_BATTERY) {
395 dev_info(&client->dev, "%s : turn off OTG\n", __func__);
397 SM5414_i2c_read(client, SM5414_CTRL, &data);
399 SM5414_i2c_write(client, SM5414_CTRL, &data);
401 dev_info(&client->dev, "%s : turn on OTG\n", __func__);
403 SM5414_i2c_read(client, SM5414_CTRL, &data);
405 SM5414_i2c_write(client, SM5414_CTRL, &data);
409 static int SM5414_debugfs_show(struct seq_file *s, void *data)
411 struct sec_charger_info *charger = s->private;
415 seq_printf(s, "SM CHARGER IC :\n");
416 seq_printf(s, "==================\n");
417 for (reg = SM5414_INTMASK1; reg <= SM5414_CHGCTRL5; reg++) {
418 SM5414_i2c_read(charger->client, reg, ®_data);
419 seq_printf(s, "0x%02x:\t0x%02x\n", reg, reg_data);
426 static int SM5414_debugfs_open(struct inode *inode, struct file *file)
428 return single_open(file, SM5414_debugfs_show, inode->i_private);
431 static const struct file_operations SM5414_debugfs_fops = {
432 .open = SM5414_debugfs_open,
435 .release = single_release,
438 bool sec_hal_chg_init(struct i2c_client *client)
443 struct sec_charger_info *charger = i2c_get_clientdata(client);
445 dev_info(&client->dev, "%s: SM5414 Charger init (Starting)!! \n", __func__);
446 charger->is_fullcharged = false;
448 SM5414_i2c_read(client, SM5414_CTRL, &chg_en);
450 SM5414_i2c_write(client, SM5414_CTRL, &chg_en);
452 SM5414_i2c_read(client, SM5414_CTRL, &chg_en);
453 dev_info(&client->dev,
454 "%s : chg_en value(07h register): 0x%02x\n", __func__, chg_en);
456 SM5414_i2c_read(client, SM5414_INT1, &int1);
457 dev_info(&client->dev,
458 "%s : SM5414_INT1 : 0x%02x\n", __func__, int1);
461 SM5414_i2c_write(client, SM5414_INTMASK1, ®_data);
464 SM5414_i2c_write(client, SM5414_INTMASK2, ®_data);
466 SM5414_i2c_read(client, SM5414_CHGCTRL1, ®_data);
467 reg_data &= ~SM5414_CHGCTRL1_AUTOSTOP;
468 SM5414_i2c_write(client, SM5414_CHGCTRL1, ®_data);
470 (void) debugfs_create_file("SM5414_regs",
471 S_IRUGO, NULL, (void *)charger, &SM5414_debugfs_fops);
476 bool sec_hal_chg_suspend(struct i2c_client *client)
478 dev_info(&client->dev,
479 "%s: CHARGER - SM5414(suspend mode)!!\n", __func__);
484 bool sec_hal_chg_resume(struct i2c_client *client)
486 dev_info(&client->dev,
487 "%s: CHARGER - SM5414(resume mode)!!\n", __func__);
492 bool sec_hal_chg_shutdown(struct i2c_client *client)
494 struct sec_charger_info *charger = i2c_get_clientdata(client);
495 dev_info(&client->dev,
496 "%s: CHARGER - SM5414(suspend)!!\n", __func__);
497 SM5414_set_toggle_charger(client, 1);
498 gpio_direction_output((charger->pdata->chg_gpio_en), 0);
501 bool sec_hal_chg_get_property(struct i2c_client *client,
502 enum power_supply_property psp,
503 union power_supply_propval *val)
505 struct sec_charger_info *charger = i2c_get_clientdata(client);
508 case POWER_SUPPLY_PROP_ONLINE:
510 case POWER_SUPPLY_PROP_STATUS:
511 if (charger->is_fullcharged)
512 val->intval = POWER_SUPPLY_STATUS_FULL;
514 val->intval = SM5414_get_charging_status(client);
516 case POWER_SUPPLY_PROP_HEALTH:
517 val->intval = charger_health;
519 case POWER_SUPPLY_PROP_CHARGE_TYPE:
520 val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
522 // Have to mention the issue about POWER_SUPPLY_PROP_CHARGE_NOW to Marvel
523 case POWER_SUPPLY_PROP_CHARGE_NOW:
524 case POWER_SUPPLY_PROP_CURRENT_MAX:
525 case POWER_SUPPLY_PROP_CURRENT_AVG:
526 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
527 case POWER_SUPPLY_PROP_CURRENT_NOW:
528 if (charger->charging_current) {
529 SM5414_i2c_read(client, SM5414_VBUSCTRL, &data);
531 val->intval = (100 + (data * 50));
532 if (val->intval < 2050)
533 val->intval = (100 + (data * 50));
534 /*dev_dbg(&client->dev,
535 "%s 1: set-current(%dmA), current now(%dmA)\n",
536 __func__, charger->charging_current, val->intval);*/
539 /*dev_dbg(&client->dev,
540 "%s 2: set-current(%dmA), current now(%dmA)\n",
541 __func__, charger->charging_current, val->intval);*/
544 case POWER_SUPPLY_PROP_PRESENT:
545 val->intval = SM5414_get_battery_present(client);
547 case POWER_SUPPLY_PROP_POWER_STATUS:
548 val->intval = POWER_SUPPLY_PWR_RDY_UNKNOWN;
556 bool sec_hal_chg_set_property(struct i2c_client *client,
557 enum power_supply_property psp,
558 const union power_supply_propval *val)
560 struct sec_charger_info *charger = i2c_get_clientdata(client);
562 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
563 charger->pdata->siop_level = val->intval;
564 /* val->intval : type */
565 case POWER_SUPPLY_PROP_ONLINE:
566 if (charger->charging_current < 0)
567 SM5414_charger_otg_control(client);
568 else if (charger->charging_current > 0)
569 SM5414_charger_function_control(client);
571 SM5414_charger_function_control(client);
572 SM5414_charger_otg_control(client);
574 dev_dbg(&client->dev, "%s: PROP_ONLINE \n", __func__);
576 /* val->intval : charging current */
577 case POWER_SUPPLY_PROP_CURRENT_NOW:
578 dev_dbg(&client->dev, "%s: PROP_CURRENT_NOW \n", __func__);
580 #ifdef CONFIG_CHARGER_SM5414
581 case POWER_SUPPLY_PROP_HEALTH:
582 charger_health = val->intval;
592 ssize_t sec_hal_chg_show_attrs(struct device *dev,
593 const ptrdiff_t offset, char *buf)
595 struct power_supply *psy = dev_get_drvdata(dev);
596 struct sec_charger_info *chg =
597 container_of(psy, struct sec_charger_info, psy_chg);
605 i += scnprintf(buf + i, PAGE_SIZE - i, "%x\n",
609 str = kzalloc(sizeof(char)*1024, GFP_KERNEL);
613 SM5414_read_regs(chg->client, str);
614 i += scnprintf(buf + i, PAGE_SIZE - i, "%s\n",
627 ssize_t sec_hal_chg_store_attrs(struct device *dev,
628 const ptrdiff_t offset,
629 const char *buf, size_t count)
631 struct power_supply *psy = dev_get_drvdata(dev);
632 struct sec_charger_info *chg =
633 container_of(psy, struct sec_charger_info, psy_chg);
640 if (sscanf(buf, "%x\n", &x) == 1) {
642 SM5414_i2c_read(chg->client,
643 chg->reg_addr, &data);
644 chg->reg_data = data;
645 dev_dbg(dev, "%s: (read) addr = 0x%x, data = 0x%x\n",
646 __func__, chg->reg_addr, chg->reg_data);
651 if (sscanf(buf, "%x\n", &x) == 1) {
653 dev_dbg(dev, "%s: (write) addr = 0x%x, data = 0x%x\n",
654 __func__, chg->reg_addr, data);
655 SM5414_i2c_write(chg->client,
656 chg->reg_addr, &data);