summaryrefslogtreecommitdiff
path: root/drivers/edp
diff options
context:
space:
mode:
authorTimo Alho <talho@nvidia.com>2013-11-26 20:07:18 +0200
committerTerje Bergstrom <tbergstrom@nvidia.com>2014-04-10 05:21:02 -0700
commit7cb44192bfc117c1642e2b8af67cacff8a5304be (patch)
tree6d172af0b9daa5a9eadd70cb856894e67fe241a1 /drivers/edp
parentfee2e9af4a3ae76534df8e929f66e2b3138da888 (diff)
EDP: add userspace knob to update ESR value
This patch adds a sysfs entry /sys/power/sysedp/batmon/esr. This allows an user space process to update the current ESR value seen by the sysedp_batmon_calc component. sysedp_batmon_calc will compute the ratio between internal table based ESR estimate and value set from user space. This ratio will be then used to scale all future table based ESR estimations. Bug 1400509 Change-Id: Ia409826f793afef4e4c8d1e42010ff31e529f827 Signed-off-by: Timo Alho <talho@nvidia.com> Reviewed-on: http://git-master/r/337378 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Sivaram Nair <sivaramn@nvidia.com> Reviewed-by: Steve Rogers <srogers@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/edp')
-rw-r--r--drivers/edp/sysedp_batmon_calc.c118
-rw-r--r--drivers/edp/sysedp_internal.h1
-rw-r--r--drivers/edp/sysedp_sysfs.c4
3 files changed, 117 insertions, 6 deletions
diff --git a/drivers/edp/sysedp_batmon_calc.c b/drivers/edp/sysedp_batmon_calc.c
index feb961eb7142..c0625853bd68 100644
--- a/drivers/edp/sysedp_batmon_calc.c
+++ b/drivers/edp/sysedp_batmon_calc.c
@@ -31,9 +31,14 @@
static struct sysedp_batmon_calc_platform_data *pdata;
static struct delayed_work work;
static struct power_supply *psy;
-static int esr;
+
int (*get_ocv)(unsigned int capacity);
+static struct kobject batmon_kobj;
+
+/* ratio between user-space ESR setting and look-up-table based ESR value */
+static int user_esr_ratio = 100;
+
static int psy_get_property(enum power_supply_property psp, int *val)
{
union power_supply_propval pv;
@@ -152,7 +157,7 @@ static int psy_ocv_from_lut(unsigned int capacity)
q->ocv);
}
-static int calc_esr(int capacity, int temp)
+static int lookup_esr(int capacity, int temp)
{
struct sysedp_batmon_rbat_lut *lut = pdata->rbat_lut;
int ret = pdata->r_const;
@@ -162,6 +167,14 @@ static int calc_esr(int capacity, int temp)
return ret;
}
+static int calc_esr(int capacity, int temp)
+{
+ int esr;
+ esr = lookup_esr(capacity, temp);
+ esr = esr * user_esr_ratio / 100;
+ return esr;
+}
+
/* calculate maximum allowed current (in mA) limited by equivalent
* series resistance (esr) */
static s64 calc_ibat_esr(s64 ocv, s64 esr)
@@ -203,8 +216,7 @@ static s64 calc_pbat(s64 ocv, s64 ibat, s64 esr)
static unsigned int calc_avail_budget(void)
{
- unsigned int capacity;
- int temp;
+ int esr, capacity, temp;
s64 ocv;
s64 ibat_esr;
s64 ibat;
@@ -552,6 +564,102 @@ static void of_batmon_calc_get_pdata(struct platform_device *pdev,
return;
}
+struct batmon_attribute {
+ struct attribute attr;
+ ssize_t (*show)(char *buf);
+ ssize_t (*store)(const char *buf, size_t count);
+};
+
+static ssize_t esr_show(char *s)
+{
+ int capacity, temp, esr;
+
+ capacity = psy_capacity();
+ temp = psy_temp();
+ esr = calc_esr(capacity, temp);
+ esr /= 1000; /* to mOhm */
+
+ return sprintf(s, "%d\n", esr);
+}
+
+static ssize_t esr_store(const char *s, size_t count)
+{
+ int mohm, capacity, temp;
+ int lut_esr;
+ int n;
+
+ n = sscanf(s, "%d %d %d", &mohm, &capacity, &temp);
+ if (n != 1 && n != 3)
+ return -EINVAL;
+ if (mohm <= 0)
+ return -EINVAL;
+
+ if (n != 3) {
+ capacity = psy_capacity();
+ temp = psy_temp();
+ } else {
+ if (capacity < 0 || capacity > 100)
+ return -EINVAL;
+ }
+
+ lut_esr = lookup_esr(capacity, temp);
+ if (!lut_esr)
+ return -EINVAL;
+
+ user_esr_ratio = DIV_ROUND_CLOSEST(100 * 1000 * mohm, lut_esr);
+
+ cancel_delayed_work_sync(&work);
+ schedule_delayed_work(&work, 0);
+
+ return count;
+}
+
+static struct batmon_attribute attr_esr =
+ __ATTR(esr, 0660, esr_show, esr_store);
+
+static struct attribute *batmon_attrs[] = {
+ &attr_esr.attr,
+ NULL
+};
+
+static ssize_t batmon_attr_show(struct kobject *kobj,
+ struct attribute *_attr, char *buf)
+{
+ ssize_t r = -EINVAL;
+ struct batmon_attribute *attr;
+ attr = container_of(_attr, struct batmon_attribute, attr);
+ if (attr && attr->show)
+ r = attr->show(buf);
+ return r;
+}
+
+static ssize_t batmon_attr_store(struct kobject *kobj, struct attribute *_attr,
+ const char *buf, size_t count)
+{
+ ssize_t r = -EINVAL;
+ struct batmon_attribute *attr;
+ attr = container_of(_attr, struct batmon_attribute, attr);
+ if (attr && attr->store)
+ r = attr->store(buf, count);
+ return r;
+}
+
+static const struct sysfs_ops batmon_sysfs_ops = {
+ .show = batmon_attr_show,
+ .store = batmon_attr_store,
+};
+
+static struct kobj_type ktype_batmon = {
+ .sysfs_ops = &batmon_sysfs_ops,
+ .default_attrs = batmon_attrs,
+};
+
+static int init_sysfs(void)
+{
+ return kobject_init_and_add(&batmon_kobj, &ktype_batmon,
+ &sysedp_kobj, "batmon");
+}
+
static int batmon_probe(struct platform_device *pdev)
{
int i;
@@ -586,6 +694,8 @@ static int batmon_probe(struct platform_device *pdev)
if (init_ocv_reader())
return -EFAULT;
+ init_sysfs();
+
INIT_DEFERRABLE_WORK(&work, batmon_update);
schedule_delayed_work(&work, 0);
diff --git a/drivers/edp/sysedp_internal.h b/drivers/edp/sysedp_internal.h
index cb725ac1d3c3..5f9e4dffb318 100644
--- a/drivers/edp/sysedp_internal.h
+++ b/drivers/edp/sysedp_internal.h
@@ -29,6 +29,7 @@ extern unsigned int avail_budget;
extern unsigned int consumer_sum;
extern struct list_head registered_consumers;
extern struct mutex sysedp_lock;
+extern struct kobject sysedp_kobj;
static inline unsigned int _cur_level(struct sysedp_consumer *c)
{
diff --git a/drivers/edp/sysedp_sysfs.c b/drivers/edp/sysedp_sysfs.c
index 21e536bdb271..d0be34ca602a 100644
--- a/drivers/edp/sysedp_sysfs.c
+++ b/drivers/edp/sysedp_sysfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -23,7 +23,7 @@
#include <trace/events/sysedp.h>
#include "sysedp_internal.h"
-static struct kobject sysedp_kobj;
+struct kobject sysedp_kobj;
static struct kset *consumers_kset;
struct sysedp_consumer_attribute {