summaryrefslogtreecommitdiff
path: root/drivers/edp
diff options
context:
space:
mode:
authorKerwin Wan <kerwinw@nvidia.com>2013-12-05 23:13:13 +0800
committerJuha Tukkinen <jtukkinen@nvidia.com>2013-12-31 04:37:17 -0800
commit138b68226845b781e82710f65d96a3d927d9847c (patch)
tree3ac7f5c463101cd53f75cdad3b78d6a760621b39 /drivers/edp
parent146c45645d8b0b198a4837f10f43d386ef542ae2 (diff)
edp: add DT support for sysedp battery monitor
Bug 1391872 Change-Id: I31bbe2b2fe18c8fd46b8d70980639511e21c9dd2 Signed-off-by: Kerwin Wan <kerwinw@nvidia.com> Reviewed-on: http://git-master/r/338795 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Timo Alho <talho@nvidia.com> Tested-by: Timo Alho <talho@nvidia.com> Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers/edp')
-rw-r--r--drivers/edp/sysedp_batmon_calc.c206
1 files changed, 203 insertions, 3 deletions
diff --git a/drivers/edp/sysedp_batmon_calc.c b/drivers/edp/sysedp_batmon_calc.c
index 50829e8e1fa1..0f5db1196e4d 100644
--- a/drivers/edp/sysedp_batmon_calc.c
+++ b/drivers/edp/sysedp_batmon_calc.c
@@ -23,6 +23,7 @@
#include <linux/workqueue.h>
#include <linux/suspend.h>
#include <linux/debugfs.h>
+#include <linux/of.h>
#include "sysedp_internal.h"
#define UPDATE_INTERVAL 60000
@@ -274,17 +275,210 @@ static int init_ocv_reader(void)
return 0;
}
+static void of_batmon_calc_get_pdata(struct platform_device *pdev,
+ struct sysedp_batmon_calc_platform_data **pdata)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct sysedp_batmon_calc_platform_data *obj_ptr;
+ u32 *u32_ptr;
+ const char *c_ptr;
+ const void *ptr;
+ u32 lenp, val;
+ int n;
+ int ret;
+ int i;
+
+ obj_ptr = devm_kzalloc(&pdev->dev,
+ sizeof(struct sysedp_batmon_calc_platform_data), GFP_KERNEL);
+ if (!obj_ptr)
+ return;
+
+ ptr = of_get_property(np, "power_supply", &lenp);
+ if (!ptr) {
+ dev_err(&pdev->dev, "Fail to get power_supply\n");
+ return;
+ } else {
+ obj_ptr->power_supply = devm_kzalloc(&pdev->dev,
+ sizeof(char) * lenp, GFP_KERNEL);
+ if (!obj_ptr->power_supply)
+ return;
+ ret = of_property_read_string(np, "power_supply", &c_ptr);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to read power_supply\n");
+ return;
+ }
+ strncpy(obj_ptr->power_supply, c_ptr, lenp);
+ }
+
+ ret = of_property_read_u32(np, "r_const", &val);
+ if (ret)
+ dev_info(&pdev->dev, "Fail to read r_const\n");
+ else
+ obj_ptr->r_const = val;
+
+ ret = of_property_read_u32(np, "vsys_min", &val);
+ if (ret)
+ dev_info(&pdev->dev, "Fail to read vsys_min\n");
+ else
+ obj_ptr->vsys_min = val;
+
+ ret = of_property_read_u32(np, "update_interval", &val);
+ if (!ret)
+ obj_ptr->update_interval = val;
+
+ ptr = of_get_property(np, "ocv_lut", &lenp);
+ if (ptr) {
+ n = lenp / sizeof(u32);
+ if (!n || (n % 2) != 0)
+ return;
+ obj_ptr->ocv_lut = devm_kzalloc(&pdev->dev,
+ sizeof(struct sysedp_batmon_ocv_lut) * n / 2,
+ GFP_KERNEL);
+ if (!obj_ptr->ocv_lut)
+ return;
+ u32_ptr = kzalloc(sizeof(u32) * n, GFP_KERNEL);
+ if (!u32_ptr)
+ return;
+ ret = of_property_read_u32_array(np, "ocv_lut", u32_ptr, n);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to read ocv_lut\n");
+ kfree(u32_ptr);
+ return;
+ }
+ for (i = 0; i < n / 2; ++i) {
+ obj_ptr->ocv_lut[i].capacity = u32_ptr[2 * i];
+ obj_ptr->ocv_lut[i].ocv = u32_ptr[2 * i + 1];
+ }
+ kfree(u32_ptr);
+ }
+
+ ptr = of_get_property(np, "ibat_lut", &lenp);
+ if (!ptr) {
+ dev_err(&pdev->dev, "Fail to get ibat_lut\n");
+ return;
+ }
+ n = lenp / sizeof(u32);
+ if (!n || (n % 2) != 0)
+ return;
+ obj_ptr->ibat_lut = devm_kzalloc(&pdev->dev,
+ sizeof(struct sysedp_batmon_ibat_lut) * n / 2, GFP_KERNEL);
+ if (!obj_ptr->ibat_lut)
+ return;
+ u32_ptr = kzalloc(sizeof(u32) * n, GFP_KERNEL);
+ if (!u32_ptr)
+ return;
+ ret = of_property_read_u32_array(np, "ibat_lut", u32_ptr, n);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to read ibat_lut\n");
+ kfree(u32_ptr);
+ return;
+ }
+ for (i = 0; i < n / 2; ++i) {
+ obj_ptr->ibat_lut[i].temp = (s32)u32_ptr[2 * i];
+ obj_ptr->ibat_lut[i].ibat = u32_ptr[2 * i + 1];
+ }
+ kfree(u32_ptr);
+
+ obj_ptr->rbat_lut = devm_kzalloc(&pdev->dev,
+ sizeof(struct sysedp_batmon_rbat_lut), GFP_KERNEL);
+ if (!obj_ptr->rbat_lut)
+ return;
+
+ ptr = of_get_property(np, "rbat_data", &lenp);
+ if (!ptr) {
+ dev_err(&pdev->dev, "Fail to get rbat_data\n");
+ return;
+ }
+ n = lenp / sizeof(u32);
+ if (!n)
+ return;
+ obj_ptr->rbat_lut->data = devm_kzalloc(&pdev->dev,
+ sizeof(int) * n, GFP_KERNEL);
+ if (!obj_ptr->rbat_lut->data)
+ return;
+ u32_ptr = kzalloc(sizeof(u32) * n, GFP_KERNEL);
+ if (!u32_ptr)
+ return;
+ ret = of_property_read_u32_array(np, "rbat_data", u32_ptr, n);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to read rbat_data\n");
+ kfree(u32_ptr);
+ return;
+ }
+ for (i = 0; i < n; ++i)
+ obj_ptr->rbat_lut->data[i] = u32_ptr[i];
+ kfree(u32_ptr);
+ obj_ptr->rbat_lut->data_size = n;
+
+ ptr = of_get_property(np, "temp_axis", &lenp);
+ if (!ptr) {
+ dev_err(&pdev->dev, "Fail to get temp_axis\n");
+ return;
+ }
+ n = lenp / sizeof(u32);
+ if (!n)
+ return;
+ obj_ptr->rbat_lut->temp_axis = devm_kzalloc(&pdev->dev,
+ sizeof(int) * n, GFP_KERNEL);
+ if (!obj_ptr->rbat_lut->temp_axis)
+ return;
+ u32_ptr = kzalloc(sizeof(u32) * n, GFP_KERNEL);
+ if (!u32_ptr)
+ return;
+ ret = of_property_read_u32_array(np, "temp_axis", u32_ptr, n);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to read temp_axis\n");
+ kfree(u32_ptr);
+ return;
+ }
+ for (i = 0; i < n; ++i)
+ obj_ptr->rbat_lut->temp_axis[i] = (s32)u32_ptr[i];
+ kfree(u32_ptr);
+ obj_ptr->rbat_lut->temp_size = n;
+
+ ptr = of_get_property(np, "capacity_axis", &lenp);
+ if (!ptr) {
+ dev_err(&pdev->dev, "Fail to get capacity_axis\n");
+ return;
+ }
+ n = lenp / sizeof(u32);
+ if (!n)
+ return;
+ obj_ptr->rbat_lut->capacity_axis = devm_kzalloc(&pdev->dev,
+ sizeof(int) * n, GFP_KERNEL);
+ if (!obj_ptr->rbat_lut->capacity_axis)
+ return;
+ u32_ptr = kzalloc(sizeof(u32) * n, GFP_KERNEL);
+ if (!u32_ptr)
+ return;
+ ret = of_property_read_u32_array(np, "capacity_axis", u32_ptr, n);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to read capacity_axis\n");
+ kfree(u32_ptr);
+ return;
+ }
+ for (i = 0; i < n; ++i)
+ obj_ptr->rbat_lut->capacity_axis[i] = u32_ptr[i];
+ kfree(u32_ptr);
+ obj_ptr->rbat_lut->capacity_size = n;
+
+ *pdata = obj_ptr;
+ return;
+}
+
static int batmon_probe(struct platform_device *pdev)
{
int i;
struct sysedp_batmon_rbat_lut *rbat;
- pdata = pdev->dev.platform_data;
+ if (pdev->dev.of_node)
+ of_batmon_calc_get_pdata(pdev, &pdata);
+ else
+ pdata = pdev->dev.platform_data;
if (!pdata)
return -EINVAL;
-
/* validate pdata->rbat_lut table */
rbat = pdata->rbat_lut;
if (!rbat)
@@ -312,6 +506,11 @@ static int batmon_probe(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id batmon_calc_of_match[] = {
+ { .compatible = "sysedp_batmon_calc", },
+};
+MODULE_DEVICE_TABLE(of, batmon_calc_of_match);
+
static struct platform_driver batmon_driver = {
.probe = batmon_probe,
.shutdown = batmon_shutdown,
@@ -319,7 +518,8 @@ static struct platform_driver batmon_driver = {
.resume = batmon_resume,
.driver = {
.name = "sysedp_batmon_calc",
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .of_match_table = batmon_calc_of_match,
}
};