power: charger-gauge: abstract charger to/from gauge communication
Laxman Dewangan [Tue, 25 Jun 2013 13:53:48 +0000 (18:53 +0530)]
It is require to communicate from charger driver to battery
gauge driver and vice versa. This communication is needed for
different status transfer between battery gauge and charger
driver.

Add common file where battery charger and gauge driver register
them self through their callbacks and call common APIs to update/get
their status.

This way the communication from battery charger to battery gauge
driver is completely abstracted and no need to provide callback
through platform data.

bug 1231506

Change-Id: I99af16fda9777a2d1d4c439486f6ff2d1ec8d681
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/237849
(Cherrypicked commit 8f5298e9f737b7852547d8ac446f3d16a9b183df)

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Change-Id: I8633462e520471e8266df0b0aacfe85167004078
Reviewed-on: http://git-master/r/241969

drivers/power/Kconfig
drivers/power/Makefile
drivers/power/battery-charger-gauge-comm.c [new file with mode: 0644]
include/linux/power/battery-charger-gauge-comm.h [new file with mode: 0644]

index 571f758..4e6fe58 100644 (file)
@@ -485,4 +485,7 @@ config TEGRA_BPC_MGMT
          This driver reduces cpu frequency/voltage on gpio event from the
          battery current monitor device.
 
+config BATTERY_CHARGER_GAUGE_COMM
+       bool
+
 source "drivers/power/avs/Kconfig"
index 2c4f375..55c7891 100644 (file)
@@ -70,3 +70,4 @@ obj-$(CONFIG_MAX8907C_CHARGER)        += max8907c-charger.o
 obj-$(CONFIG_CHARGER_EXTCON_MAX77660)  += max77660-charger-extcon.o
 CFLAGS_tegra_bpc_mgmt.o                = -Werror
 obj-$(CONFIG_TEGRA_BPC_MGMT)   += tegra_bpc_mgmt.o
+obj-$(CONFIG_BATTERY_CHARGER_GAUGE_COMM) += battery-charger-gauge-comm.o
diff --git a/drivers/power/battery-charger-gauge-comm.c b/drivers/power/battery-charger-gauge-comm.c
new file mode 100644 (file)
index 0000000..9c05812
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * battery-charger-gauge-comm.c -- Communication between battery charger and
+ *     battery gauge driver.
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/pm.h>
+#include <linux/extcon.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max77660/max77660-core.h>
+#include <linux/workqueue.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/power_supply.h>
+#include <linux/power/battery-charger-gauge-comm.h>
+
+static DEFINE_MUTEX(charger_gauge_list_mutex);
+static LIST_HEAD(charger_list);
+static LIST_HEAD(gauge_list);
+
+struct battery_charger_dev {
+       int                             cell_id;
+       struct device                   *parent_dev;
+       struct battery_charging_ops     *ops;
+       struct list_head                list;
+       void                            *drv_data;
+};
+
+struct battery_gauge_dev {
+       int                             cell_id;
+       struct device                   *parent_dev;
+       struct battery_gauge_ops        *ops;
+       struct list_head                list;
+       void                            *drv_data;
+};
+
+struct battery_charger_dev *battery_charger_register(struct device *dev,
+       struct battery_charger_info *bci)
+{
+       struct battery_charger_dev *bc_dev;
+
+       dev_info(dev, "Registering battery charger driver\n");
+
+       if (!dev || !bci) {
+               dev_err(dev, "Invalid parameters\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       bc_dev = kzalloc(sizeof(*bc_dev), GFP_KERNEL);
+       if (!bc_dev) {
+               dev_err(dev, "Memory alloc for bc_dev failed\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       mutex_lock(&charger_gauge_list_mutex);
+
+       INIT_LIST_HEAD(&bc_dev->list);
+       bc_dev->cell_id = bci->cell_id;
+       bc_dev->ops = bci->bc_ops;
+       bc_dev->parent_dev = dev;
+       list_add(&bc_dev->list, &charger_list);
+       mutex_unlock(&charger_gauge_list_mutex);
+       return bc_dev;
+}
+EXPORT_SYMBOL_GPL(battery_charger_register);
+
+void battery_charger_unregister(struct battery_charger_dev *bc_dev)
+{
+       mutex_lock(&charger_gauge_list_mutex);
+       list_del(&bc_dev->list);
+       mutex_unlock(&charger_gauge_list_mutex);
+       kfree(bc_dev);
+}
+EXPORT_SYMBOL_GPL(battery_charger_unregister);
+
+struct battery_gauge_dev *battery_gauge_register(struct device *dev,
+       struct battery_gauge_info *bgi)
+{
+       struct battery_gauge_dev *bg_dev;
+
+       dev_info(dev, "Registering battery gauge driver\n");
+
+       if (!dev || !bgi) {
+               dev_err(dev, "Invalid parameters\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       bg_dev = kzalloc(sizeof(*bg_dev), GFP_KERNEL);
+       if (!bg_dev) {
+               dev_err(dev, "Memory alloc for bg_dev failed\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       mutex_lock(&charger_gauge_list_mutex);
+
+       INIT_LIST_HEAD(&bg_dev->list);
+       bg_dev->cell_id = bgi->cell_id;
+       bg_dev->ops = bgi->bg_ops;
+       bg_dev->parent_dev = dev;
+       list_add(&bg_dev->list, &gauge_list);
+       mutex_unlock(&charger_gauge_list_mutex);
+       return bg_dev;
+}
+EXPORT_SYMBOL_GPL(battery_gauge_register);
+
+void battery_gauge_unregister(struct battery_gauge_dev *bg_dev)
+{
+       mutex_lock(&charger_gauge_list_mutex);
+       list_del(&bg_dev->list);
+       mutex_unlock(&charger_gauge_list_mutex);
+       kfree(bg_dev);
+}
+EXPORT_SYMBOL_GPL(battery_gauge_unregister);
+
+int battery_charging_status_update(struct battery_charger_dev *bc_dev,
+       enum battery_charger_status status)
+{
+       struct battery_gauge_dev *node;
+       int ret = -EINVAL;
+
+       if (!bc_dev) {
+               dev_err(bc_dev->parent_dev, "Invalid parameters\n");
+               return -EINVAL;
+       }
+
+       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->update_battery_status)
+                       ret = node->ops->update_battery_status(node, status);
+       }
+
+       mutex_unlock(&charger_gauge_list_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(battery_charging_status_update);
+
+void *battery_charger_get_drvdata(struct battery_charger_dev *bc_dev)
+{
+       if (bc_dev)
+               return bc_dev->drv_data;
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(battery_charger_get_drvdata);
+
+void battery_charger_set_drvdata(struct battery_charger_dev *bc_dev, void *data)
+{
+       if (bc_dev)
+               bc_dev->drv_data = data;
+}
+EXPORT_SYMBOL_GPL(battery_charger_set_drvdata);
+
+void *battery_gauge_get_drvdata(struct battery_gauge_dev *bg_dev)
+{
+       if (bg_dev)
+               return bg_dev->drv_data;
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(battery_gauge_get_drvdata);
+
+void battery_gauge_set_drvdata(struct battery_gauge_dev *bg_dev, void *data)
+{
+       if (bg_dev)
+               bg_dev->drv_data = data;
+}
+EXPORT_SYMBOL_GPL(battery_gauge_set_drvdata);
+
diff --git a/include/linux/power/battery-charger-gauge-comm.h b/include/linux/power/battery-charger-gauge-comm.h
new file mode 100644 (file)
index 0000000..288a8f3
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * battery-charger-gauge-comm.h -- Communication APIS between battery charger
+ *             and battery gauge driver.
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#ifndef TEGRA_CHARGER_CORE_H
+#define TEGRA_CHARGER_CORE_H
+
+enum battery_charger_status {
+       BATTERY_DISCHARGING,
+       BATTERY_CHARGING,
+       BATTERY_CHARGING_DONE,
+};
+
+struct battery_gauge_dev;
+struct battery_charger_dev;
+
+struct battery_gauge_ops {
+       int (*update_battery_status)(struct battery_gauge_dev *bg_device,
+                               enum battery_charger_status status);
+};
+
+struct battery_charging_ops {
+       int (*get_charging_status)(struct battery_charger_dev *bc_dev);
+};
+
+struct battery_charger_info {
+       int cell_id;
+       struct battery_charging_ops *bc_ops;
+};
+
+struct battery_gauge_info {
+       int cell_id;
+       struct battery_gauge_ops *bg_ops;
+};
+
+struct battery_charger_dev *battery_charger_register(struct device *dev,
+               struct battery_charger_info *bci);
+void battery_charger_unregister(struct battery_charger_dev *bc_dev);
+
+struct battery_gauge_dev *battery_gauge_register(struct device *dev,
+               struct battery_gauge_info *bgi);
+void battery_gauge_unregister(struct battery_gauge_dev *bg_dev);
+
+int battery_charging_status_update(struct battery_charger_dev *bc_dev,
+               enum battery_charger_status status);
+
+void *battery_charger_get_drvdata(struct battery_charger_dev *bc_dev);
+void battery_charger_set_drvdata(struct battery_charger_dev *bc_dev,
+                       void *data);
+void *battery_gauge_get_drvdata(struct battery_gauge_dev *bg_dev);
+void battery_gauge_set_drvdata(struct battery_gauge_dev *bg_dev, void *data);
+#endif