power: battery-gauge:read battery temp from FG
Venkat Reddy Talla [Wed, 8 Jan 2014 07:09:58 +0000 (12:09 +0530)]
 add support to read battery temperature using Fuel
 gauge driver.

Change-Id: I2f82c8f70f032ea811fd16077f3c647d66344e70
Signed-off-by: Venkat Reddy Talla <vreddytalla@nvidia.com>
Reviewed-on: http://git-master/r/353145
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

drivers/power/battery-charger-gauge-comm.c
include/linux/power/battery-charger-gauge-comm.h

index 3df6f4e..dfe941d 100644 (file)
@@ -2,7 +2,7 @@
  * battery-charger-gauge-comm.c -- Communication between battery charger and
  *     battery gauge driver.
  *
- * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
  *
  * Author: Laxman Dewangan <ldewangan@nvidia.com>
  *
@@ -65,6 +65,7 @@ struct battery_charger_dev {
        struct wake_lock                charger_wake_lock;
        bool                            locked;
        struct rtc_device               *rtc;
+       bool                            enable_thermal_monitor;
 };
 
 struct battery_gauge_dev {
@@ -100,6 +101,7 @@ static void battery_charger_restart_charging_wq(struct work_struct *work)
 static void battery_charger_thermal_monitor_wq(struct work_struct *work)
 {
        struct battery_charger_dev *bc_dev;
+       struct battery_gauge_dev *node;
        struct device *dev;
        long temperature;
        bool charger_enable_state;
@@ -111,25 +113,49 @@ static void battery_charger_thermal_monitor_wq(struct work_struct *work)
                                        poll_temp_monitor_wq.work);
        dev = bc_dev->parent_dev;
 
-       if (!bc_dev->battery_tz)
-               bc_dev->battery_tz =
+       if (bc_dev->enable_thermal_monitor) {
+               mutex_lock(&charger_gauge_list_mutex);
+
+               list_for_each_entry(node, &gauge_list, list) {
+                       if (node->cell_id != bc_dev->cell_id)
+                               continue;
+                       if (node->ops && node->ops->get_battery_temp) {
+                               ret = node->ops->get_battery_temp();
+                               if (ret < 0) {
+                                       dev_err(dev,
+                                       "Temperature read failed: %d\n ",
+                                       ret);
+                                       mutex_unlock(&charger_gauge_list_mutex);
+                                       goto exit;
+                               }
+                               temperature = ret;
+                       }
+               }
+               mutex_unlock(&charger_gauge_list_mutex);
+       } else {
+               if (!bc_dev->battery_tz)
+                       bc_dev->battery_tz =
                        thermal_zone_device_find_by_name(bc_dev->tz_name);
 
-       if (!bc_dev->battery_tz) {
-               dev_info(dev, "Battery thermal zone %s is not registered yet\n",
-                                       bc_dev->tz_name);
-               schedule_delayed_work(&bc_dev->poll_temp_monitor_wq,
+               if (!bc_dev->battery_tz) {
+                       dev_info(dev,
+                       "Battery thermal zone %s is not registered yet\n",
+                       bc_dev->tz_name);
+                       schedule_delayed_work(&bc_dev->poll_temp_monitor_wq,
                        msecs_to_jiffies(bc_dev->polling_time_sec * HZ));
-               return;
+                       return;
+               }
+
+               ret = thermal_zone_get_temp(bc_dev->battery_tz,
+                               &temperature);
+               if (ret < 0) {
+                       dev_err(dev, "Temperature read failed: %d\n ",
+                               ret);
+                       goto exit;
+               }
+               temperature = temperature / 1000;
        }
 
-       ret = thermal_zone_get_temp(bc_dev->battery_tz, &temperature);
-       if (ret < 0) {
-               dev_err(dev, "Temperature read failed: %d\n ", ret);
-               goto exit;
-       }
-
-       temperature = temperature / 1000;
        charger_enable_state = true;
        charger_current_half = false;
        battery_thersold_voltage = 4250;
@@ -420,7 +446,13 @@ struct battery_charger_dev *battery_charger_register(struct device *dev,
        bc_dev->drv_data = drv_data;
 
        /* Thermal monitoring */
-       if (!bc_dev->tz_name) {
+       if (bci->enable_thermal_monitor) {
+               bc_dev->polling_time_sec = bci->polling_time_sec;
+               bc_dev->enable_thermal_monitor =
+                       bci->enable_thermal_monitor;
+               INIT_DELAYED_WORK(&bc_dev->poll_temp_monitor_wq,
+                               battery_charger_thermal_monitor_wq);
+       } else if (!bc_dev->tz_name) {
                bc_dev->polling_time_sec = bci->polling_time_sec;
                strcpy(bc_dev->tz_name, bci->tz_name ? : "");
                bc_dev->battery_tz = thermal_zone_device_find_by_name(
index 3988f82..be857d8 100644 (file)
@@ -2,7 +2,7 @@
  * battery-charger-gauge-comm.h -- Communication APIS between battery charger
  *             and battery gauge driver.
  *
- * Copyright (c) 2013, NVIDIA Corporation.
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
  *
  * Author: Laxman Dewangan <ldewangan@nvidia.com>
  *
@@ -37,6 +37,7 @@ struct battery_gauge_ops {
        int (*update_battery_status)(struct battery_gauge_dev *bg_device,
                                enum battery_charger_status status);
        int (*set_current_broadcast) (struct battery_gauge_dev *bg_device);
+       int (*get_battery_temp)(void);
 };
 
 struct battery_charging_ops {
@@ -51,6 +52,7 @@ struct battery_charger_info {
        const char *tz_name;
        int cell_id;
        int polling_time_sec;
+       bool enable_thermal_monitor;
        struct battery_charging_ops *bc_ops;
 };