summaryrefslogtreecommitdiff
path: root/drivers/edp
diff options
context:
space:
mode:
authorSivaram Nair <sivaramn@nvidia.com>2013-07-23 13:19:14 +0300
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:39:38 -0700
commit1a1446550de4a78e486170475a06ab706bcb345f (patch)
treed8ee5f7fe5c86b8ced8d93ec3ac9fae1c0a5ed20 /drivers/edp
parent7a1e35c1b3ccb17b88c6eddb076ca0a93da158ae (diff)
EDP: tegra: add psy emulator mode
Add an emulator mode to the psy depletion client so that we can emulate different depletion states. This mode requires the board to specify a valid { capacity, OCV } lut. Bug 1293353 Change-Id: Ie4f83ee70cec3575ee42a8edea4524d0a33da0fb Signed-off-by: Sivaram Nair <sivaramn@nvidia.com> Reviewed-on: http://git-master/r/255648 (cherry picked from commit db1d75dc8dfaec9d0c906413d9b1eaf1df9c1e64) Reviewed-on: http://git-master/r/256830 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers/edp')
-rw-r--r--drivers/edp/psy_depletion.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/drivers/edp/psy_depletion.c b/drivers/edp/psy_depletion.c
index 5c26caa2fb1e..11ba4fc22b64 100644
--- a/drivers/edp/psy_depletion.c
+++ b/drivers/edp/psy_depletion.c
@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/debugfs.h>
#include <linux/edp.h>
#include <linux/edpdev.h>
#include <linux/kernel.h>
@@ -31,6 +32,8 @@ struct depl_driver {
struct delayed_work work;
struct edp_manager *manager;
struct power_supply *psy;
+ bool emulator_mode;
+ int capacity;
int (*get_ocv)(struct depl_driver *drv, unsigned int capacity);
};
@@ -39,6 +42,8 @@ static int depl_psy_get_property(struct depl_driver *drv,
{
union power_supply_propval pv;
+ if (!drv->psy)
+ return -ENODEV;
if (drv->psy->get_property(drv->psy, psp, &pv))
return -EFAULT;
if (val)
@@ -58,6 +63,8 @@ static int depl_psy_ocv_from_chip(struct depl_driver *drv,
static int depl_psy_capacity(struct depl_driver *drv)
{
int val;
+ if (drv->emulator_mode)
+ return drv->capacity;
if (depl_psy_get_property(drv, POWER_SUPPLY_PROP_CAPACITY, &val))
return 0;
return val;
@@ -176,6 +183,9 @@ static unsigned int depl_calc(struct depl_driver *drv)
s64 depl;
capacity = depl_psy_capacity(drv);
+ if (capacity >= 100)
+ return 0;
+
ocv = drv->get_ocv(drv, capacity);
rbat = depl_rbat(drv, capacity);
@@ -251,17 +261,53 @@ static int depl_resume(struct platform_device *pdev)
static int depl_init_ocv_reader(struct depl_driver *drv)
{
- if (drv->pdata->ocv_lut)
- drv->get_ocv = depl_psy_ocv_from_lut;
- else if (!depl_psy_get_property(drv,
- POWER_SUPPLY_PROP_VOLTAGE_OCV, NULL))
+ if (!depl_psy_get_property(drv, POWER_SUPPLY_PROP_VOLTAGE_OCV, NULL))
drv->get_ocv = depl_psy_ocv_from_chip;
+ else if (drv->pdata->ocv_lut)
+ drv->get_ocv = depl_psy_ocv_from_lut;
else
return -ENODEV;
return 0;
}
+#ifdef CONFIG_DEBUG_FS
+static int capacity_set(void *data, u64 val)
+{
+ struct depl_driver *drv = data;
+
+ drv->capacity = clamp_t(int, val, 0, 100);
+ flush_delayed_work_sync(&drv->work);
+
+ return 0;
+}
+
+static int capacity_get(void *data, u64 *val)
+{
+ struct depl_driver *drv = data;
+ *val = drv->capacity;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(capacity_fops, capacity_get, capacity_set, "%lld\n");
+
+static void init_debug(struct depl_driver *drv)
+{
+ struct dentry *d;
+
+ if (!drv->client.dentry) {
+ WARN_ON(1);
+ return;
+ }
+
+ d = debugfs_create_file("capacity", S_IRUGO | S_IWUSR,
+ drv->client.dentry, drv, &capacity_fops);
+ WARN_ON(IS_ERR_OR_NULL(d));
+}
+#else
+static inline void init_debug(struct depl_driver *drv) {}
+#endif
+
static int depl_probe(struct platform_device *pdev)
{
struct depl_driver *drv;
@@ -285,8 +331,12 @@ static int depl_probe(struct platform_device *pdev)
drv->pdata = pdev->dev.platform_data;
drv->manager = m;
drv->psy = power_supply_get_by_name(drv->pdata->power_supply);
- if (!drv->psy)
- goto fail;
+ if (!drv->psy) {
+ if (!drv->pdata->ocv_lut)
+ goto fail;
+ drv->capacity = 100;
+ drv->emulator_mode = true;
+ }
r = depl_init_ocv_reader(drv);
if (r)
@@ -311,6 +361,10 @@ static int depl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drv);
INIT_DEFERRABLE_WORK(&drv->work, depl_update);
schedule_delayed_work(&drv->work, 0);
+
+ if (drv->emulator_mode)
+ init_debug(drv);
+
return 0;
fail: