3 * Samsung Mobile Fuel Gauge Driver
5 * Copyright (C) 2012 Samsung Electronics
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/battery/sec_fuelgauge.h>
14 #include <linux/of_gpio.h>
15 int sec_fg_dt_init(struct device_node *np,
17 sec_battery_platform_data_t *pdata);
18 static struct device_attribute sec_fg_attrs[] = {
24 static enum power_supply_property sec_fuelgauge_props[] = {
25 POWER_SUPPLY_PROP_STATUS,
26 POWER_SUPPLY_PROP_VOLTAGE_NOW,
27 POWER_SUPPLY_PROP_VOLTAGE_AVG,
28 POWER_SUPPLY_PROP_CURRENT_NOW,
29 POWER_SUPPLY_PROP_CURRENT_AVG,
30 POWER_SUPPLY_PROP_CHARGE_FULL,
31 POWER_SUPPLY_PROP_PRESENT,
32 POWER_SUPPLY_PROP_ENERGY_NOW,
33 POWER_SUPPLY_PROP_CAPACITY,
34 POWER_SUPPLY_PROP_TEMP,
35 POWER_SUPPLY_PROP_TEMP_AMBIENT,
37 #ifdef CONFIG_FUELGAUGE_SPRD4SAMSUNG27X3
42 #define dev_dbg(dev, format, arg...) pr_info(format, ##arg)
43 #define dev_err(dev, format, arg...) pr_info(format, ##arg)
44 #define dev_info(dev, format, arg...) pr_info(format, ##arg)
47 /* capacity is 0.1% unit */
48 static void sec_fg_get_scaled_capacity(
49 struct sec_fuelgauge_info *fuelgauge,
50 union power_supply_propval *val)
52 val->intval = (val->intval < fuelgauge->pdata->capacity_min) ?
53 0 : ((val->intval - fuelgauge->pdata->capacity_min) * 1000 /
54 (fuelgauge->capacity_max - fuelgauge->pdata->capacity_min));
56 dev_dbg(&fuelgauge->client->dev,
57 "%s: scaled capacity (%d.%d)\n",
58 __func__, val->intval/10, val->intval%10);
61 /* capacity is integer */
62 static void sec_fg_get_atomic_capacity(
63 struct sec_fuelgauge_info *fuelgauge,
64 union power_supply_propval *val)
66 if (fuelgauge->pdata->capacity_calculation_type &
67 SEC_FUELGAUGE_CAPACITY_TYPE_ATOMIC) {
68 if (fuelgauge->capacity_old < val->intval)
69 val->intval = fuelgauge->capacity_old + 1;
70 else if (fuelgauge->capacity_old > val->intval)
71 val->intval = fuelgauge->capacity_old - 1;
74 /* keep SOC stable in abnormal status */
75 if (fuelgauge->pdata->capacity_calculation_type &
76 SEC_FUELGAUGE_CAPACITY_TYPE_SKIP_ABNORMAL) {
77 if ((fuelgauge->is_charging &&
78 fuelgauge->capacity_old > val->intval) ||
79 (!fuelgauge->is_charging &&
80 fuelgauge->capacity_old < val->intval)) {
81 dev_err(&fuelgauge->client->dev,
82 "%s: abnormal capacity (old %d : new %d)\n",
83 __func__, fuelgauge->capacity_old, val->intval);
84 val->intval = fuelgauge->capacity_old;
88 /* updated old capacity */
89 fuelgauge->capacity_old = val->intval;
92 static int sec_fg_get_property(struct power_supply *psy,
93 enum power_supply_property psp,
94 union power_supply_propval *val)
96 struct sec_fuelgauge_info *fuelgauge =
97 container_of(psy, struct sec_fuelgauge_info, psy_fg);
98 int soc_type = val->intval;
101 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
102 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
103 case POWER_SUPPLY_PROP_CURRENT_NOW:
104 case POWER_SUPPLY_PROP_CURRENT_AVG:
105 case POWER_SUPPLY_PROP_ENERGY_NOW:
106 case POWER_SUPPLY_PROP_CAPACITY:
107 case POWER_SUPPLY_PROP_TEMP:
108 case POWER_SUPPLY_PROP_TEMP_AMBIENT:
109 case POWER_SUPPLY_PROP_PRESENT:
110 if (!sec_hal_fg_get_property(fuelgauge_variable, psp, val))
112 if (psp == POWER_SUPPLY_PROP_CAPACITY) {
113 if (soc_type == SEC_FUELGAUGE_CAPACITY_TYPE_RAW)
116 if (fuelgauge->pdata->capacity_calculation_type &
117 (SEC_FUELGAUGE_CAPACITY_TYPE_SCALE |
118 SEC_FUELGAUGE_CAPACITY_TYPE_DYNAMIC_SCALE))
119 sec_fg_get_scaled_capacity(fuelgauge, val);
121 /* capacity should be between 0% and 100%
124 if (val->intval > 1000)
129 /* get only integer part */
132 /* check whether doing the wake_unlock */
133 if ((val->intval > fuelgauge->pdata->fuel_alert_soc) &&
134 fuelgauge->is_fuel_alerted) {
135 wake_unlock(&fuelgauge->fuel_alert_wake_lock);
136 sec_hal_fg_fuelalert_init(fuelgauge_variable,
137 fuelgauge->pdata->fuel_alert_soc);
140 /* (Only for atomic capacity)
141 * In initial time, capacity_old is 0.
142 * and in resume from sleep,
143 * capacity_old is too different from actual soc.
144 * should update capacity_old
145 * by val->intval in booting or resume.
147 if (fuelgauge->initial_update_of_soc) {
148 /* updated old capacity */
149 fuelgauge->capacity_old = val->intval;
150 fuelgauge->initial_update_of_soc = false;
154 if (fuelgauge->pdata->capacity_calculation_type &
155 (SEC_FUELGAUGE_CAPACITY_TYPE_ATOMIC |
156 SEC_FUELGAUGE_CAPACITY_TYPE_SKIP_ABNORMAL))
157 sec_fg_get_atomic_capacity(fuelgauge, val);
160 case POWER_SUPPLY_PROP_STATUS:
164 case POWER_SUPPLY_PROP_CHARGE_FULL:
174 static int sec_fg_calculate_dynamic_scale(
175 struct sec_fuelgauge_info *fuelgauge)
177 union power_supply_propval raw_soc_val;
179 raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW;
180 if (!sec_hal_fg_get_property(fuelgauge_variable,
181 POWER_SUPPLY_PROP_CAPACITY,
184 raw_soc_val.intval /= 10;
186 if (raw_soc_val.intval <
187 fuelgauge->pdata->capacity_max -
188 fuelgauge->pdata->capacity_max_margin) {
189 fuelgauge->capacity_max =
190 fuelgauge->pdata->capacity_max -
191 fuelgauge->pdata->capacity_max_margin;
192 dev_dbg(&fuelgauge->client->dev, "%s: capacity_max (%d)",
193 __func__, fuelgauge->capacity_max);
195 fuelgauge->capacity_max =
196 (raw_soc_val.intval >
197 fuelgauge->pdata->capacity_max +
198 fuelgauge->pdata->capacity_max_margin) ?
199 (fuelgauge->pdata->capacity_max +
200 fuelgauge->pdata->capacity_max_margin) :
202 dev_dbg(&fuelgauge->client->dev, "%s: raw soc (%d)",
203 __func__, fuelgauge->capacity_max);
206 fuelgauge->capacity_max =
207 (fuelgauge->capacity_max * 99 / 100);
209 dev_info(&fuelgauge->client->dev, "%s: %d is used for capacity_max\n",
210 __func__, fuelgauge->capacity_max);
212 return fuelgauge->capacity_max;
215 static int sec_fg_set_property(struct power_supply *psy,
216 enum power_supply_property psp,
217 const union power_supply_propval *val)
219 struct sec_fuelgauge_info *fuelgauge =
220 container_of(psy, struct sec_fuelgauge_info, psy_fg);
223 case POWER_SUPPLY_PROP_STATUS:
224 if (val->intval == POWER_SUPPLY_STATUS_FULL)
225 sec_hal_fg_full_charged(fuelgauge_variable);
227 case POWER_SUPPLY_PROP_CHARGE_FULL:
228 if (val->intval == POWER_SUPPLY_TYPE_BATTERY) {
229 if (fuelgauge->pdata->capacity_calculation_type &
230 SEC_FUELGAUGE_CAPACITY_TYPE_DYNAMIC_SCALE)
231 sec_fg_calculate_dynamic_scale(fuelgauge);
234 case POWER_SUPPLY_PROP_ONLINE:
235 fuelgauge->cable_type = val->intval;
236 if (val->intval == POWER_SUPPLY_TYPE_BATTERY)
237 fuelgauge->is_charging = false;
239 fuelgauge->is_charging = true;
241 case POWER_SUPPLY_PROP_CAPACITY:
242 if (val->intval == SEC_FUELGAUGE_CAPACITY_TYPE_RESET) {
243 if (!sec_hal_fg_reset(fuelgauge_variable))
248 case POWER_SUPPLY_PROP_TEMP:
249 case POWER_SUPPLY_PROP_TEMP_AMBIENT:
250 if (!sec_hal_fg_set_property(fuelgauge_variable, psp, val))
259 static void sec_fg_isr_work(struct work_struct *work)
261 struct sec_fuelgauge_info *fuelgauge =
262 container_of(work, struct sec_fuelgauge_info, isr_work.work);
264 /* process for fuel gauge chip */
265 sec_hal_fg_fuelalert_process(fuelgauge, fuelgauge->is_fuel_alerted);
267 /* process for others */
268 if (fuelgauge->pdata->fuelalert_process != NULL)
269 fuelgauge->pdata->fuelalert_process(fuelgauge->is_fuel_alerted);
272 static irqreturn_t sec_fg_irq_thread(int irq, void *irq_data)
274 struct sec_fuelgauge_info *fuelgauge = irq_data;
277 if (fuelgauge->pdata->fuel_alert_soc >= 0) {
279 sec_hal_fg_is_fuelalerted(fuelgauge_variable);
281 dev_info(&fuelgauge->client->dev,
282 "%s: Fuel-alert %salerted!\n",
283 __func__, fuel_alerted ? "" : "NOT ");
285 if (fuel_alerted == fuelgauge->is_fuel_alerted) {
286 if (!fuelgauge->pdata->repeated_fuelalert) {
287 dev_dbg(&fuelgauge->client->dev,
288 "%s: Fuel-alert Repeated (%d)\n",
289 __func__, fuelgauge->is_fuel_alerted);
295 wake_lock(&fuelgauge->fuel_alert_wake_lock);
297 wake_unlock(&fuelgauge->fuel_alert_wake_lock);
299 schedule_delayed_work(&fuelgauge->isr_work, 0);
301 fuelgauge->is_fuel_alerted = fuel_alerted;
307 static int sec_fg_create_attrs(struct device *dev)
311 for (i = 0; i < ARRAY_SIZE(sec_fg_attrs); i++) {
312 rc = device_create_file(dev, &sec_fg_attrs[i]);
314 goto create_attrs_failed;
316 goto create_attrs_succeed;
319 dev_err(dev, "%s: failed (%d)\n", __func__, rc);
321 device_remove_file(dev, &sec_fg_attrs[i]);
322 create_attrs_succeed:
326 ssize_t sec_fg_show_attrs(struct device *dev,
327 struct device_attribute *attr, char *buf)
329 const ptrdiff_t offset = attr - sec_fg_attrs;
336 // i = sec_hal_fg_show_attrs(dev, offset, buf);
346 ssize_t sec_fg_store_attrs(struct device *dev,
347 struct device_attribute *attr,
348 const char *buf, size_t count)
350 const ptrdiff_t offset = attr - sec_fg_attrs;
356 // ret = sec_hal_fg_store_attrs(dev, offset, buf, count);
365 #if defined(CONFIG_FUELGAUGE_MFD) || defined(CONFIG_FUELGAUGE_SPRD4SAMSUNG27X3)
366 static int sec_fuelgauge_probe(struct platform_device *pdev)
368 struct sec_fuelgauge_info *fuelgauge;
369 #ifndef CONFIG_FUELGAUGE_SPRD4SAMSUNG27X3
370 sec_fuelgauge_dev_t *mfd_dev = dev_get_drvdata(pdev->dev.parent);
371 sec_fuelgauge_pdata_t *pdata = dev_get_platdata(mfd_dev->dev);
373 sec_battery_platform_data_t *pdata = dev_get_platdata(&pdev->dev);
376 bool fuelalert_init_ret = false;
377 union power_supply_propval raw_soc_val;
380 "%s: SEC Fuelgauge Driver Loading\n", __func__);
382 fuelgauge = kzalloc(sizeof(*fuelgauge), GFP_KERNEL);
386 platform_set_drvdata(pdev, fuelgauge);
387 #ifndef CONFIG_FUELGAUGE_SPRD4SAMSUNG27X3
388 fuelgauge->client = mfd_dev->i2c;
389 fuelgauge->pdata = pdata->fuelgauge_data;
391 fuelgauge->pdata = pdata;
394 mutex_init(&fuelgauge->fg_lock);
396 if (pdev->dev.of_node) {
397 pdata = devm_kzalloc(&pdev->dev,
398 sizeof(sec_battery_platform_data_t),
401 dev_err(&pdev->dev, "Failed to allocate memory\n");
406 fuelgauge->pdata = pdata;
408 if (sec_fg_dt_init(pdev->dev.of_node, &pdev->dev, fuelgauge->pdata))
410 "%s: Failed to get fuel_int\n", __func__);
414 fuelgauge->psy_fg.name = "sec-fuelgauge";
415 fuelgauge->psy_fg.type = POWER_SUPPLY_TYPE_UNKNOWN;
416 fuelgauge->psy_fg.get_property = sec_fg_get_property;
417 fuelgauge->psy_fg.set_property = sec_fg_set_property;
418 fuelgauge->psy_fg.properties = sec_fuelgauge_props;
419 fuelgauge->psy_fg.num_properties =
420 ARRAY_SIZE(sec_fuelgauge_props);
421 fuelgauge->capacity_max = fuelgauge->pdata->capacity_max;
422 raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW;
423 sec_hal_fg_get_property(fuelgauge,
424 POWER_SUPPLY_PROP_CAPACITY, &raw_soc_val);
425 raw_soc_val.intval /= 10;
426 if(raw_soc_val.intval > fuelgauge->pdata->capacity_max)
427 sec_fg_calculate_dynamic_scale(fuelgauge);
429 if (!fuelgauge->pdata->fg_gpio_init()) {
431 "%s: Failed to Initialize GPIO\n", __func__);
435 if (!sec_hal_fg_init(fuelgauge)) {
437 "%s: Failed to Initialize Fuelgauge\n", __func__);
441 ret = power_supply_register(&pdev->dev, &fuelgauge->psy_fg);
444 "%s: Failed to Register psy_fg\n", __func__);
448 fuelgauge->is_fuel_alerted = false;
449 if (fuelgauge->pdata->fuel_alert_soc >= 0) {
451 sec_hal_fg_fuelalert_init(fuelgauge,
452 fuelgauge->pdata->fuel_alert_soc);
453 if (fuelalert_init_ret)
454 wake_lock_init(&fuelgauge->fuel_alert_wake_lock,
455 WAKE_LOCK_SUSPEND, "fuel_alerted");
458 "%s: Failed to Initialize Fuel-alert\n",
463 #ifndef CONFIG_FUELGAUGE_SPRD4SAMSUNG27X3
464 if (fuelgauge->pdata->fg_irq) {
465 INIT_DELAYED_WORK_DEFERRABLE(
466 &fuelgauge->isr_work, sec_fg_isr_work);
468 fuelgauge->fg_irq = gpio_to_irq(fuelgauge->pdata->fg_irq);
470 ret = request_threaded_irq(fuelgauge->fg_irq,
471 NULL, sec_fg_irq_thread,
472 fuelgauge->pdata->fg_irq_attr,
473 "fuelgauge-irq", fuelgauge);
476 "%s: Failed to Reqeust IRQ\n", __func__);
477 goto err_supply_unreg;
480 ret = enable_irq_wake(fuelgauge->pdata->fg_irq);
483 "%s: Failed to Enable Wakeup Source(%d)\n",
487 fuelgauge->initial_update_of_soc = true;
489 ret = sec_fg_create_attrs(fuelgauge->psy_fg.dev);
492 "%s : Failed to create_attrs\n", __func__);
497 "%s: SEC Fuelgauge Driver Loaded\n", __func__);
501 if (fuelgauge->pdata->fg_irq)
502 free_irq(fuelgauge->pdata->fg_irq, fuelgauge);
503 if (fuelalert_init_ret)
504 wake_lock_destroy(&fuelgauge->fuel_alert_wake_lock);
506 power_supply_unregister(&fuelgauge->psy_fg);
508 mutex_destroy(&fuelgauge->fg_lock);
514 static int sec_fuelgauge_remove(struct platform_device *pdev)
519 static int sec_fuelgauge_suspend(struct device *dev)
521 struct sec_fuelgauge_info *fuelgauge = dev_get_drvdata(dev);
523 if (!sec_hal_fg_suspend(fuelgauge))
525 "%s: Failed to Suspend Fuelgauge\n", __func__);
530 static int sec_fuelgauge_resume(struct device *dev)
532 struct sec_fuelgauge_info *fuelgauge = dev_get_drvdata(dev);
534 if (!sec_hal_fg_resume(fuelgauge))
536 "%s: Failed to Resume Fuelgauge\n", __func__);
538 if (fuelgauge->pdata->capacity_calculation_type &
539 SEC_FUELGAUGE_CAPACITY_TYPE_ATOMIC)
540 fuelgauge->initial_update_of_soc = true;
545 static void sec_fuelgauge_shutdown(struct device *dev)
549 static const struct dev_pm_ops sec_fuelgauge_pm_ops = {
550 .suspend = sec_fuelgauge_suspend,
551 .resume = sec_fuelgauge_resume,
555 static struct of_device_id sec_fuelgauge_dt_ids[] = {
556 { .compatible = "samsung,sec-fuelgauge" },
559 MODULE_DEVICE_TABLE(of, sec_fuelgauge_dt_ids);
560 #endif /* CONFIG_OF */
562 static struct platform_driver sec_fuelgauge_driver = {
564 .name = "sec-fuelgauge",
565 .pm = &sec_fuelgauge_pm_ops,
566 .shutdown = sec_fuelgauge_shutdown,
568 .of_match_table = sec_fuelgauge_dt_ids,
571 .probe = sec_fuelgauge_probe,
572 .remove = sec_fuelgauge_remove,
575 static int __init sec_fuelgauge_init(void)
577 pr_info("[%s] start !!!!! \n", __func__);
578 return platform_driver_register(&sec_fuelgauge_driver);
581 static void __exit sec_fuelgauge_exit(void)
583 platform_driver_unregister(&sec_fuelgauge_driver);
587 static int sec_fuelgauge_probe(struct i2c_client *client,
588 const struct i2c_device_id *id)
590 struct sec_fuelgauge_info *fuelgauge;
591 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
593 bool fuelalert_init_ret = false;
594 union power_supply_propval raw_soc_val;
596 dev_dbg(&client->dev,
597 "%s: SEC Fuelgauge Driver Loading\n", __func__);
599 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
602 fuelgauge = kzalloc(sizeof(*fuelgauge), GFP_KERNEL);
606 mutex_init(&fuelgauge->fg_lock);
608 fuelgauge->client = client;
609 fuelgauge->pdata = client->dev.platform_data;
611 i2c_set_clientdata(client, fuelgauge);
613 fuelgauge->psy_fg.name = "sec-fuelgauge";
614 fuelgauge->psy_fg.type = POWER_SUPPLY_TYPE_UNKNOWN;
615 fuelgauge->psy_fg.get_property = sec_fg_get_property;
616 fuelgauge->psy_fg.set_property = sec_fg_set_property;
617 fuelgauge->psy_fg.properties = sec_fuelgauge_props;
618 fuelgauge->psy_fg.num_properties =
619 ARRAY_SIZE(sec_fuelgauge_props);
620 fuelgauge->capacity_max = fuelgauge->pdata->capacity_max;
621 raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW;
622 sec_hal_fg_get_property(fuelgauge->client,
623 POWER_SUPPLY_PROP_CAPACITY, &raw_soc_val);
624 raw_soc_val.intval /= 10;
625 if(raw_soc_val.intval > fuelgauge->pdata->capacity_max)
626 sec_fg_calculate_dynamic_scale(fuelgauge);
628 if (!fuelgauge->pdata->fg_gpio_init()) {
629 dev_err(&client->dev,
630 "%s: Failed to Initialize GPIO\n", __func__);
634 if (!sec_hal_fg_init(fuelgauge->client)) {
635 dev_err(&client->dev,
636 "%s: Failed to Initialize Fuelgauge\n", __func__);
640 ret = power_supply_register(&client->dev, &fuelgauge->psy_fg);
642 dev_err(&client->dev,
643 "%s: Failed to Register psy_fg\n", __func__);
647 fuelgauge->is_fuel_alerted = false;
648 if (fuelgauge->pdata->fuel_alert_soc >= 0) {
650 sec_hal_fg_fuelalert_init(fuelgauge->client,
651 fuelgauge->pdata->fuel_alert_soc);
652 if (fuelalert_init_ret)
653 wake_lock_init(&fuelgauge->fuel_alert_wake_lock,
654 WAKE_LOCK_SUSPEND, "fuel_alerted");
656 dev_err(&client->dev,
657 "%s: Failed to Initialize Fuel-alert\n",
663 if (fuelgauge->pdata->fg_irq) {
664 INIT_DELAYED_WORK(&fuelgauge->isr_work, sec_fg_isr_work);
666 ret = request_threaded_irq(fuelgauge->pdata->fg_irq,
667 NULL, sec_fg_irq_thread,
668 fuelgauge->pdata->fg_irq_attr,
669 "fuelgauge-irq", fuelgauge);
671 dev_err(&client->dev,
672 "%s: Failed to Reqeust IRQ\n", __func__);
673 goto err_supply_unreg;
676 ret = enable_irq_wake(fuelgauge->pdata->fg_irq);
678 dev_err(&client->dev,
679 "%s: Failed to Enable Wakeup Source(%d)\n",
683 fuelgauge->initial_update_of_soc = true;
685 ret = sec_fg_create_attrs(fuelgauge->psy_fg.dev);
687 dev_err(&client->dev,
688 "%s : Failed to create_attrs\n", __func__);
692 dev_dbg(&client->dev,
693 "%s: SEC Fuelgauge Driver Loaded\n", __func__);
697 if (fuelgauge->pdata->fg_irq)
698 free_irq(fuelgauge->pdata->fg_irq, fuelgauge);
700 power_supply_unregister(&fuelgauge->psy_fg);
702 mutex_destroy(&fuelgauge->fg_lock);
708 static int sec_fuelgauge_remove(struct i2c_client *client)
710 struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
712 if (fuelgauge->pdata->fuel_alert_soc >= 0)
713 wake_lock_destroy(&fuelgauge->fuel_alert_wake_lock);
718 static int sec_fuelgauge_suspend(struct device *dev)
720 struct i2c_client *client =
721 container_of(dev, struct i2c_client, dev);
723 if (!sec_hal_fg_suspend(client))
724 dev_err(dev, "%s: Failed to Suspend Fuelgauge\n", __func__);
729 static int sec_fuelgauge_resume(struct device *dev)
731 struct i2c_client *client =
732 container_of(dev, struct i2c_client, dev);
733 struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
735 if (!sec_hal_fg_resume(client))
736 dev_err(dev, "%s: Failed to Resume Fuelgauge\n", __func__);
738 if (fuelgauge->pdata->capacity_calculation_type &
739 SEC_FUELGAUGE_CAPACITY_TYPE_ATOMIC)
740 fuelgauge->initial_update_of_soc = true;
745 static void sec_fuelgauge_shutdown(struct device *dev)
749 static const struct i2c_device_id sec_fuelgauge_id[] = {
750 {"sec-fuelgauge", 0},
754 MODULE_DEVICE_TABLE(i2c, sec_fuelgauge_id);
756 static const struct dev_pm_ops sec_fuelgauge_pm_ops = {
757 .suspend = sec_fuelgauge_suspend,
758 .resume = sec_fuelgauge_resume,
761 static struct i2c_driver sec_fuelgauge_driver = {
763 .name = "sec-fuelgauge",
764 .owner = THIS_MODULE,
765 .pm = &sec_fuelgauge_pm_ops,
766 .shutdown = sec_fuelgauge_shutdown,
768 .probe = sec_fuelgauge_probe,
769 .remove = sec_fuelgauge_remove,
770 .id_table = sec_fuelgauge_id,
773 static int __init sec_fuelgauge_init(void)
775 return i2c_add_driver(&sec_fuelgauge_driver);
778 static void __exit sec_fuelgauge_exit(void)
780 i2c_del_driver(&sec_fuelgauge_driver);
784 module_init(sec_fuelgauge_init);
785 module_exit(sec_fuelgauge_exit);
787 MODULE_DESCRIPTION("Samsung Fuel Gauge Driver");
788 MODULE_AUTHOR("Samsung Electronics");
789 MODULE_LICENSE("GPL");