]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/power/battery-charger-gauge-comm.c
3603f2a55498656b5cd098f7a79b84f381e92dc0
[sojka/nv-tegra/linux-3.10.git] / drivers / power / battery-charger-gauge-comm.c
1 /*
2  * battery-charger-gauge-comm.c -- Communication between battery charger and
3  *      battery gauge driver.
4  *
5  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
6  *
7  * Author: Laxman Dewangan <ldewangan@nvidia.com>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation version 2.
12  *
13  * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
14  * whether express or implied; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307, USA
22  */
23
24 #include <linux/alarmtimer.h>
25 #include <linux/module.h>
26 #include <linux/err.h>
27 #include <linux/export.h>
28 #include <linux/workqueue.h>
29 #include <linux/delay.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
32 #include <linux/mutex.h>
33 #include <linux/thermal.h>
34 #include <linux/list.h>
35 #include <linux/rtc.h>
36 #include <linux/time.h>
37 #include <linux/timer.h>
38 #include <linux/power/battery-charger-gauge-comm.h>
39 #include <linux/power/reset/system-pmic.h>
40 #include <linux/wakelock.h>
41 #include <linux/iio/consumer.h>
42 #include <linux/iio/types.h>
43 #include <linux/iio/iio.h>
44
45 #define JETI_TEMP_COLD          0
46 #define JETI_TEMP_COOL          10
47 #define JETI_TEMP_WARM          45
48 #define JETI_TEMP_HOT           60
49
50 #define MAX_STR_PRINT           50
51
52 static DEFINE_MUTEX(charger_gauge_list_mutex);
53 static LIST_HEAD(charger_list);
54 static LIST_HEAD(gauge_list);
55
56 struct battery_charger_dev {
57         int                             cell_id;
58         char                            *tz_name;
59         struct device                   *parent_dev;
60         struct battery_charging_ops     *ops;
61         struct list_head                list;
62         void                            *drv_data;
63         struct delayed_work             restart_charging_wq;
64         struct delayed_work             poll_temp_monitor_wq;
65         int                             polling_time_sec;
66         struct thermal_zone_device      *battery_tz;
67         bool                            start_monitoring;
68         struct wake_lock                charger_wake_lock;
69         bool                            locked;
70         struct rtc_device               *rtc;
71         bool                            enable_thermal_monitor;
72 };
73
74 struct battery_gauge_dev {
75         int                             cell_id;
76         char                            *tz_name;
77         struct device                   *parent_dev;
78         struct battery_gauge_ops        *ops;
79         struct list_head                list;
80         void                            *drv_data;
81         struct thermal_zone_device      *battery_tz;
82         int                             battery_voltage;
83         int                             battery_capacity;
84         int                             battery_snapshot_voltage;
85         int                             battery_snapshot_capacity;
86         const char                      *bat_curr_channel_name;
87         struct iio_channel              *bat_current_iio_channel;
88 };
89
90 struct battery_gauge_dev *bg_temp;
91
92 static void battery_charger_restart_charging_wq(struct work_struct *work)
93 {
94         struct battery_charger_dev *bc_dev;
95
96         bc_dev = container_of(work, struct battery_charger_dev,
97                                         restart_charging_wq.work);
98         if (!bc_dev->ops->restart_charging) {
99                 dev_err(bc_dev->parent_dev,
100                                 "No callback for restart charging\n");
101                 return;
102         }
103         bc_dev->ops->restart_charging(bc_dev);
104 }
105
106 static void battery_charger_thermal_monitor_wq(struct work_struct *work)
107 {
108         struct battery_charger_dev *bc_dev;
109         struct device *dev;
110         long temperature;
111         bool charger_enable_state;
112         bool charger_current_half;
113         int battery_thersold_voltage;
114         int ret;
115
116         bc_dev = container_of(work, struct battery_charger_dev,
117                                         poll_temp_monitor_wq.work);
118         if (!bc_dev->tz_name)
119                 return;
120
121         dev = bc_dev->parent_dev;
122         if (!bc_dev->battery_tz) {
123                 bc_dev->battery_tz = thermal_zone_device_find_by_name(
124                                         bc_dev->tz_name);
125
126                 if (!bc_dev->battery_tz) {
127                         dev_info(dev,
128                             "Battery thermal zone %s is not registered yet\n",
129                                 bc_dev->tz_name);
130                         schedule_delayed_work(&bc_dev->poll_temp_monitor_wq,
131                             msecs_to_jiffies(bc_dev->polling_time_sec * HZ));
132                         return;
133                 }
134         }
135
136         ret = thermal_zone_get_temp(bc_dev->battery_tz, &temperature);
137         if (ret < 0) {
138                 dev_err(dev, "Temperature read failed: %d\n ", ret);
139                 goto exit;
140         }
141         temperature = temperature / 1000;
142
143         charger_enable_state = true;
144         charger_current_half = false;
145         battery_thersold_voltage = 4250;
146
147         if (temperature <= JETI_TEMP_COLD || temperature >= JETI_TEMP_HOT) {
148                 charger_enable_state = false;
149         } else if (temperature <= JETI_TEMP_COOL ||
150                                 temperature >= JETI_TEMP_WARM) {
151                 charger_current_half = true;
152                 battery_thersold_voltage = 4100;
153         }
154
155         if (bc_dev->ops->thermal_configure)
156                 bc_dev->ops->thermal_configure(bc_dev, temperature,
157                         charger_enable_state, charger_current_half,
158                         battery_thersold_voltage);
159
160 exit:
161         if (bc_dev->start_monitoring)
162                 schedule_delayed_work(&bc_dev->poll_temp_monitor_wq,
163                         msecs_to_jiffies(bc_dev->polling_time_sec * HZ));
164         return;
165 }
166
167 int battery_charger_set_current_broadcast(struct battery_charger_dev *bc_dev)
168 {
169         struct battery_gauge_dev *bg_dev;
170         int ret = 0;
171
172         if (!bc_dev) {
173                 return -EINVAL;
174         }
175
176         mutex_lock(&charger_gauge_list_mutex);
177
178         list_for_each_entry(bg_dev, &gauge_list, list) {
179                 if (bg_dev->cell_id != bc_dev->cell_id)
180                         continue;
181                 if (bg_dev->ops && bg_dev->ops->set_current_broadcast)
182                         ret = bg_dev->ops->set_current_broadcast(bg_dev);
183         }
184
185         mutex_unlock(&charger_gauge_list_mutex);
186         return ret;
187 }
188 EXPORT_SYMBOL_GPL(battery_charger_set_current_broadcast);
189
190 int battery_charger_thermal_start_monitoring(
191         struct battery_charger_dev *bc_dev)
192 {
193         if (!bc_dev || !bc_dev->polling_time_sec || !bc_dev->tz_name)
194                 return -EINVAL;
195
196         bc_dev->start_monitoring = true;
197         schedule_delayed_work(&bc_dev->poll_temp_monitor_wq,
198                         msecs_to_jiffies(bc_dev->polling_time_sec * HZ));
199         return 0;
200 }
201 EXPORT_SYMBOL_GPL(battery_charger_thermal_start_monitoring);
202
203 int battery_charger_thermal_stop_monitoring(
204         struct battery_charger_dev *bc_dev)
205 {
206         if (!bc_dev || !bc_dev->polling_time_sec || !bc_dev->tz_name)
207                 return -EINVAL;
208
209         bc_dev->start_monitoring = false;
210         cancel_delayed_work(&bc_dev->poll_temp_monitor_wq);
211         return 0;
212 }
213 EXPORT_SYMBOL_GPL(battery_charger_thermal_stop_monitoring);
214
215 int battery_charger_acquire_wake_lock(struct battery_charger_dev *bc_dev)
216 {
217         if (!bc_dev->locked) {
218                 wake_lock(&bc_dev->charger_wake_lock);
219                 bc_dev->locked = true;
220         }
221         return 0;
222 }
223 EXPORT_SYMBOL_GPL(battery_charger_acquire_wake_lock);
224
225 int battery_charger_release_wake_lock(struct battery_charger_dev *bc_dev)
226 {
227         if (bc_dev->locked) {
228                 wake_unlock(&bc_dev->charger_wake_lock);
229                 bc_dev->locked = false;
230         }
231         return 0;
232 }
233 EXPORT_SYMBOL_GPL(battery_charger_release_wake_lock);
234
235 int battery_charging_restart(struct battery_charger_dev *bc_dev, int after_sec)
236 {
237         if (!bc_dev->ops->restart_charging) {
238                 dev_err(bc_dev->parent_dev,
239                         "No callback for restart charging\n");
240                 return -EINVAL;
241         }
242         schedule_delayed_work(&bc_dev->restart_charging_wq,
243                         msecs_to_jiffies(after_sec * HZ));
244         return 0;
245 }
246 EXPORT_SYMBOL_GPL(battery_charging_restart);
247
248 static ssize_t battery_show_snapshot_voltage(struct device *dev,
249                                 struct device_attribute *attr,
250                                 char *buf)
251 {
252         struct battery_gauge_dev *bg_dev = bg_temp;
253
254         return snprintf(buf, MAX_STR_PRINT, "%d\n",
255                                 bg_dev->battery_snapshot_voltage);
256 }
257
258 static ssize_t battery_show_snapshot_capacity(struct device *dev,
259                                 struct device_attribute *attr,
260                                 char *buf)
261 {
262         struct battery_gauge_dev *bg_dev = bg_temp;
263
264         return snprintf(buf, MAX_STR_PRINT, "%d\n",
265                                 bg_dev->battery_snapshot_capacity);
266 }
267
268 static ssize_t battery_show_max_capacity(struct device *dev,
269                                 struct device_attribute *attr,
270                                 char *buf)
271 {
272         struct iio_channel *channel;
273         int val, ret;
274
275         channel = iio_channel_get(dev, "batt_id");
276         if (IS_ERR(channel)) {
277                 dev_err(dev,
278                         "%s: Failed to get channel batt_id, %ld\n",
279                         __func__, PTR_ERR(channel));
280                         return 0;
281         }
282
283         ret = iio_read_channel_raw(channel, &val);
284         if (ret < 0) {
285                 dev_err(dev,
286                         "%s: Failed to read channel, %d\n",
287                         __func__, ret);
288                         return 0;
289         }
290
291         return snprintf(buf, MAX_STR_PRINT, "%d\n", val);
292 }
293
294 static DEVICE_ATTR(battery_snapshot_voltage, S_IRUGO,
295                 battery_show_snapshot_voltage, NULL);
296
297 static DEVICE_ATTR(battery_snapshot_capacity, S_IRUGO,
298                 battery_show_snapshot_capacity, NULL);
299
300 static DEVICE_ATTR(battery_max_capacity, S_IRUGO,
301                 battery_show_max_capacity, NULL);
302
303 static struct attribute *battery_snapshot_attributes[] = {
304         &dev_attr_battery_snapshot_voltage.attr,
305         &dev_attr_battery_snapshot_capacity.attr,
306         &dev_attr_battery_max_capacity.attr,
307         NULL
308 };
309
310 static const struct attribute_group battery_snapshot_attr_group = {
311         .attrs = battery_snapshot_attributes,
312 };
313
314 int battery_gauge_record_voltage_value(struct battery_gauge_dev *bg_dev,
315                                                         int voltage)
316 {
317         if (!bg_dev)
318                 return -EINVAL;
319
320         bg_dev->battery_voltage = voltage;
321
322         return 0;
323 }
324 EXPORT_SYMBOL_GPL(battery_gauge_record_voltage_value);
325
326 int battery_gauge_record_capacity_value(struct battery_gauge_dev *bg_dev,
327                                                         int capacity)
328 {
329         if (!bg_dev)
330                 return -EINVAL;
331
332         bg_dev->battery_capacity = capacity;
333
334         return 0;
335 }
336 EXPORT_SYMBOL_GPL(battery_gauge_record_capacity_value);
337
338 int battery_gauge_record_snapshot_values(struct battery_gauge_dev *bg_dev,
339                                                 int interval)
340 {
341         msleep(interval);
342         if (!bg_dev)
343                 return -EINVAL;
344
345         bg_dev->battery_snapshot_voltage = bg_dev->battery_voltage;
346         bg_dev->battery_snapshot_capacity = bg_dev->battery_capacity;
347
348         return 0;
349 }
350 EXPORT_SYMBOL_GPL(battery_gauge_record_snapshot_values);
351
352 int battery_gauge_report_battery_soc(struct battery_gauge_dev *bg_dev,
353                                         int battery_soc)
354 {
355         struct battery_charger_dev *node;
356         int ret = 0;
357
358         if (!bg_dev)
359                 return -EINVAL;
360
361         if (battery_soc < 90 || battery_soc > 100)
362                 return -EINVAL;
363
364         mutex_lock(&charger_gauge_list_mutex);
365
366         list_for_each_entry(node, &charger_list, list) {
367                 if (node->cell_id != bg_dev->cell_id)
368                         continue;
369                 if (node->ops && node->ops->input_voltage_configure)
370                         ret = node->ops->input_voltage_configure(node,
371                                 battery_soc);
372         }
373
374         mutex_unlock(&charger_gauge_list_mutex);
375         return ret;
376 }
377 EXPORT_SYMBOL_GPL(battery_gauge_report_battery_soc);
378
379 int battery_gauge_get_scaled_soc(struct battery_gauge_dev *bg_dev,
380         int actual_soc_semi, int thresod_soc)
381 {
382         int thresod_soc_semi = thresod_soc * 100;
383
384         if (actual_soc_semi >= 10000)
385                 return 100;
386
387         if (actual_soc_semi <= thresod_soc_semi)
388                 return 0;
389
390         return (actual_soc_semi - thresod_soc_semi) / (100 - thresod_soc);
391 }
392 EXPORT_SYMBOL_GPL(battery_gauge_get_scaled_soc);
393
394 int battery_gauge_get_adjusted_soc(struct battery_gauge_dev *bg_dev,
395         int min_soc, int max_soc, int actual_soc_semi)
396 {
397         int min_soc_semi = min_soc * 100;
398         int max_soc_semi = max_soc * 100;
399
400         if (actual_soc_semi >= max_soc_semi)
401                 return 100;
402
403         if (actual_soc_semi <= min_soc_semi)
404                 return 0;
405
406         return (actual_soc_semi - min_soc_semi + 50) / (max_soc - min_soc);
407 }
408 EXPORT_SYMBOL_GPL(battery_gauge_get_adjusted_soc);
409
410 void battery_charging_restart_cancel(struct battery_charger_dev *bc_dev)
411 {
412         if (!bc_dev->ops->restart_charging) {
413                 dev_err(bc_dev->parent_dev,
414                         "No callback for restart charging\n");
415                 return;
416         }
417         cancel_delayed_work(&bc_dev->restart_charging_wq);
418 }
419 EXPORT_SYMBOL_GPL(battery_charging_restart_cancel);
420
421 int battery_charging_wakeup(struct battery_charger_dev *bc_dev, int after_sec)
422 {
423         int ret;
424         unsigned long now;
425         struct rtc_wkalrm alm;
426         int alarm_time = after_sec;
427
428         if (!alarm_time)
429                 return 0;
430
431         bc_dev->rtc = alarmtimer_get_rtcdev();
432         if (!bc_dev->rtc) {
433                 dev_err(bc_dev->parent_dev, "No RTC device found\n");
434                 return -ENODEV;
435         }
436
437         alm.enabled = true;
438         ret = rtc_read_time(bc_dev->rtc, &alm.time);
439         if (ret < 0) {
440                 dev_err(bc_dev->parent_dev, "RTC read time failed %d\n", ret);
441                 return ret;
442         }
443         rtc_tm_to_time(&alm.time, &now);
444
445         rtc_time_to_tm(now + alarm_time, &alm.time);
446         ret = rtc_set_alarm(bc_dev->rtc, &alm);
447         if (ret < 0) {
448                 dev_err(bc_dev->parent_dev, "RTC set alarm failed %d\n", ret);
449                 alm.enabled = false;
450                 return ret;
451         }
452         alm.enabled = false;
453         return 0;
454 }
455 EXPORT_SYMBOL_GPL(battery_charging_wakeup);
456
457 int battery_charging_system_reset_after(struct battery_charger_dev *bc_dev,
458         int after_sec)
459 {
460         struct system_pmic_rtc_data rtc_data;
461         int ret;
462
463         dev_info(bc_dev->parent_dev, "Setting system on after %d sec\n",
464                 after_sec);
465         battery_charging_wakeup(bc_dev, after_sec);
466         rtc_data.power_on_after_sec = after_sec;
467
468         ret = system_pmic_set_power_on_event(SYSTEM_PMIC_RTC_ALARM, &rtc_data);
469         if (ret < 0)
470                 dev_err(bc_dev->parent_dev,
471                         "Setting power on event failed: %d\n", ret);
472         return ret;
473 }
474 EXPORT_SYMBOL_GPL(battery_charging_system_reset_after);
475
476 int battery_charging_system_power_on_usb_event(
477         struct battery_charger_dev *bc_dev)
478 {
479         int ret;
480
481         dev_info(bc_dev->parent_dev,
482                 "Setting system on with USB connect/disconnect\n");
483
484         ret = system_pmic_set_power_on_event(SYSTEM_PMIC_USB_VBUS_INSERTION,
485                 NULL);
486         if (ret < 0)
487                 dev_err(bc_dev->parent_dev,
488                         "Setting power on event failed: %d\n", ret);
489         return ret;
490 }
491 EXPORT_SYMBOL_GPL(battery_charging_system_power_on_usb_event);
492
493 struct battery_charger_dev *battery_charger_register(struct device *dev,
494         struct battery_charger_info *bci, void *drv_data)
495 {
496         struct battery_charger_dev *bc_dev;
497
498         dev_info(dev, "Registering battery charger driver\n");
499
500         if (!dev || !bci) {
501                 dev_err(dev, "Invalid parameters\n");
502                 return ERR_PTR(-EINVAL);
503         }
504
505         bc_dev = kzalloc(sizeof(*bc_dev), GFP_KERNEL);
506         if (!bc_dev) {
507                 dev_err(dev, "Memory alloc for bc_dev failed\n");
508                 return ERR_PTR(-ENOMEM);
509         }
510
511         mutex_lock(&charger_gauge_list_mutex);
512
513         INIT_LIST_HEAD(&bc_dev->list);
514         bc_dev->cell_id = bci->cell_id;
515         bc_dev->ops = bci->bc_ops;
516         bc_dev->parent_dev = dev;
517         bc_dev->drv_data = drv_data;
518
519         /* Thermal monitoring */
520         if (bci->tz_name) {
521                 bc_dev->tz_name = kstrdup(bci->tz_name, GFP_KERNEL);
522                 bc_dev->polling_time_sec = bci->polling_time_sec;
523                 bc_dev->enable_thermal_monitor = true;
524                 INIT_DELAYED_WORK(&bc_dev->poll_temp_monitor_wq,
525                                 battery_charger_thermal_monitor_wq);
526         }
527
528         INIT_DELAYED_WORK(&bc_dev->restart_charging_wq,
529                         battery_charger_restart_charging_wq);
530
531         wake_lock_init(&bc_dev->charger_wake_lock, WAKE_LOCK_SUSPEND,
532                                                 "charger-suspend-lock");
533         list_add(&bc_dev->list, &charger_list);
534         mutex_unlock(&charger_gauge_list_mutex);
535         return bc_dev;
536 }
537 EXPORT_SYMBOL_GPL(battery_charger_register);
538
539 void battery_charger_unregister(struct battery_charger_dev *bc_dev)
540 {
541         mutex_lock(&charger_gauge_list_mutex);
542         list_del(&bc_dev->list);
543         if (bc_dev->polling_time_sec)
544                 cancel_delayed_work(&bc_dev->poll_temp_monitor_wq);
545         cancel_delayed_work(&bc_dev->restart_charging_wq);
546         wake_lock_destroy(&bc_dev->charger_wake_lock);
547         mutex_unlock(&charger_gauge_list_mutex);
548         kfree(bc_dev);
549 }
550 EXPORT_SYMBOL_GPL(battery_charger_unregister);
551
552 int battery_gauge_get_battery_temperature(struct battery_gauge_dev *bg_dev,
553         int *temp)
554 {
555         int ret;
556         long temperature;
557
558         if (!bg_dev || !bg_dev->tz_name)
559                 return -EINVAL;
560
561         if (!bg_dev->battery_tz)
562                 bg_dev->battery_tz =
563                         thermal_zone_device_find_by_name(bg_dev->tz_name);
564
565         if (!bg_dev->battery_tz) {
566                 dev_info(bg_dev->parent_dev,
567                         "Battery thermal zone %s is not registered yet\n",
568                         bg_dev->tz_name);
569                 return -ENODEV;
570         }
571
572         ret = thermal_zone_get_temp(bg_dev->battery_tz, &temperature);
573         if (ret < 0)
574                 return ret;
575
576         *temp = temperature / 1000;
577         return 0;
578 }
579 EXPORT_SYMBOL_GPL(battery_gauge_get_battery_temperature);
580
581 int battery_gauge_get_battery_current(struct battery_gauge_dev *bg_dev,
582         int *current_ma)
583 {
584         int ret;
585
586         if (!bg_dev || !bg_dev->bat_curr_channel_name)
587                 return -EINVAL;
588
589         if (!bg_dev->bat_current_iio_channel)
590                 bg_dev->bat_current_iio_channel =
591                         iio_channel_get(bg_dev->parent_dev,
592                                         bg_dev->bat_curr_channel_name);
593         if (!bg_dev->bat_current_iio_channel || IS_ERR(bg_dev->bat_current_iio_channel)) {
594                 dev_info(bg_dev->parent_dev,
595                         "Battery IIO current channel %s not registered yet\n",
596                         bg_dev->bat_curr_channel_name);
597                 bg_dev->bat_current_iio_channel = NULL;
598                 return -ENODEV;
599         }
600
601         ret = iio_read_channel_processed(bg_dev->bat_current_iio_channel,
602                         current_ma);
603         if (ret < 0) {
604                 dev_err(bg_dev->parent_dev, " The channel read failed: %d\n", ret);
605                 return ret;
606         }
607         return 0;
608 }
609 EXPORT_SYMBOL_GPL(battery_gauge_get_battery_current);
610
611 struct battery_gauge_dev *battery_gauge_register(struct device *dev,
612         struct battery_gauge_info *bgi, void *drv_data)
613 {
614         struct battery_gauge_dev *bg_dev;
615         int ret;
616
617         dev_info(dev, "Registering battery gauge driver\n");
618
619         if (!dev || !bgi) {
620                 dev_err(dev, "Invalid parameters\n");
621                 return ERR_PTR(-EINVAL);
622         }
623
624         bg_dev = kzalloc(sizeof(*bg_dev), GFP_KERNEL);
625         if (!bg_dev) {
626                 dev_err(dev, "Memory alloc for bg_dev failed\n");
627                 return ERR_PTR(-ENOMEM);
628         }
629
630         ret = sysfs_create_group(&dev->kobj, &battery_snapshot_attr_group);
631         if (ret < 0)
632                 dev_info(dev, "Could not create battery snapshot sysfs group\n");
633
634         mutex_lock(&charger_gauge_list_mutex);
635
636         INIT_LIST_HEAD(&bg_dev->list);
637         bg_dev->cell_id = bgi->cell_id;
638         bg_dev->ops = bgi->bg_ops;
639         bg_dev->parent_dev = dev;
640         bg_dev->drv_data = drv_data;
641         bg_dev->tz_name = NULL;
642
643         if (bgi->current_channel_name)
644                 bg_dev->bat_curr_channel_name = bgi->current_channel_name;
645
646         if (bgi->tz_name) {
647                 bg_dev->tz_name = kstrdup(bgi->tz_name, GFP_KERNEL);
648                 bg_dev->battery_tz = thermal_zone_device_find_by_name(
649                         bg_dev->tz_name);
650                 if (!bg_dev->battery_tz)
651                         dev_info(dev,
652                         "Battery thermal zone %s is not registered yet\n",
653                         bg_dev->tz_name);
654         }
655
656         list_add(&bg_dev->list, &gauge_list);
657         mutex_unlock(&charger_gauge_list_mutex);
658         bg_temp = bg_dev;
659
660         return bg_dev;
661 }
662 EXPORT_SYMBOL_GPL(battery_gauge_register);
663
664 void battery_gauge_unregister(struct battery_gauge_dev *bg_dev)
665 {
666         mutex_lock(&charger_gauge_list_mutex);
667         list_del(&bg_dev->list);
668         mutex_unlock(&charger_gauge_list_mutex);
669         kfree(bg_dev);
670 }
671 EXPORT_SYMBOL_GPL(battery_gauge_unregister);
672
673 int battery_charging_status_update(struct battery_charger_dev *bc_dev,
674         enum battery_charger_status status)
675 {
676         struct battery_gauge_dev *node;
677         int ret = -EINVAL;
678
679         if (!bc_dev) {
680                 dev_err(bc_dev->parent_dev, "Invalid parameters\n");
681                 return -EINVAL;
682         }
683
684         mutex_lock(&charger_gauge_list_mutex);
685
686         list_for_each_entry(node, &gauge_list, list) {
687                 if (node->cell_id != bc_dev->cell_id)
688                         continue;
689                 if (node->ops && node->ops->update_battery_status)
690                         ret = node->ops->update_battery_status(node, status);
691         }
692
693         mutex_unlock(&charger_gauge_list_mutex);
694         return ret;
695 }
696 EXPORT_SYMBOL_GPL(battery_charging_status_update);
697
698 void *battery_charger_get_drvdata(struct battery_charger_dev *bc_dev)
699 {
700         if (bc_dev)
701                 return bc_dev->drv_data;
702         return NULL;
703 }
704 EXPORT_SYMBOL_GPL(battery_charger_get_drvdata);
705
706 void battery_charger_set_drvdata(struct battery_charger_dev *bc_dev, void *data)
707 {
708         if (bc_dev)
709                 bc_dev->drv_data = data;
710 }
711 EXPORT_SYMBOL_GPL(battery_charger_set_drvdata);
712
713 void *battery_gauge_get_drvdata(struct battery_gauge_dev *bg_dev)
714 {
715         if (bg_dev)
716                 return bg_dev->drv_data;
717         return NULL;
718 }
719 EXPORT_SYMBOL_GPL(battery_gauge_get_drvdata);
720
721 void battery_gauge_set_drvdata(struct battery_gauge_dev *bg_dev, void *data)
722 {
723         if (bg_dev)
724                 bg_dev->drv_data = data;
725 }
726 EXPORT_SYMBOL_GPL(battery_gauge_set_drvdata);