summaryrefslogtreecommitdiff
path: root/drivers/misc/c55_ctrl.c
diff options
context:
space:
mode:
authorJee Su Chang <w20740@motorola.com>2014-05-04 14:14:55 -0500
committerJee Su Chang <w20740@motorola.com>2014-05-04 14:14:55 -0500
commitd9e15ffe03f3be4a7de2e320798728830c1f3057 (patch)
tree48a43e096fe2c2c902f9f1a8359aed846a4c4101 /drivers/misc/c55_ctrl.c
parent82e085f9dd609b78b8ce8bed440a62a643c99df0 (diff)
downloadolio-linux-3.10-d9e15ffe03f3be4a7de2e320798728830c1f3057.tar.xz
olio-linux-3.10-d9e15ffe03f3be4a7de2e320798728830c1f3057.zip
IKXCLOCK-1029 c55: optimize gpio pins during when c55 is off
Change-Id: I1d046bd680ff4aaa0de13a4cb162cf946a17e38f
Diffstat (limited to 'drivers/misc/c55_ctrl.c')
-rw-r--r--drivers/misc/c55_ctrl.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/misc/c55_ctrl.c b/drivers/misc/c55_ctrl.c
index 31dbd6cde57..507732514cb 100644
--- a/drivers/misc/c55_ctrl.c
+++ b/drivers/misc/c55_ctrl.c
@@ -38,10 +38,17 @@ struct c55_ctrl_data {
struct wake_lock wake_lock;
struct regulator *reg_vddc;
struct regulator *reg_vddldo;
+ struct pinctrl *pctrl;
+ struct pinctrl_state *states[C55_MODE_MAX];
int c55_mode;
struct mutex ctrl_mutex; /* mutex to handle critical area */
};
+const char *c55_pin_state_labels[C55_MODE_MAX] = {
+ "off",
+ "on"
+};
+
#define NUM_GPIOS 2
const char *gpio_labels[NUM_GPIOS] = {
@@ -156,6 +163,8 @@ static ssize_t c55_ctrl_enable(struct device *dev,
mutex_lock(&cdata->ctrl_mutex);
if (mode == C55_ON) {
+ pinctrl_select_state(cdata->pctrl, cdata->states[C55_ON]);
+
gpio_set_value(cdata->ap_c55_int_gpio, 1);
if (m4sensorhub_reg_write_1byte
@@ -190,6 +199,8 @@ static ssize_t c55_ctrl_enable(struct device *dev,
* for current drain reasons */
gpio_set_value(cdata->ap_c55_int_gpio, 0);
+ pinctrl_select_state(cdata->pctrl, cdata->states[C55_OFF]);
+
/* Unlock wake lock in case it is active */
wake_unlock(&cdata->wake_lock);
}
@@ -205,6 +216,38 @@ static ssize_t c55_ctrl_enable(struct device *dev,
static DEVICE_ATTR(enable, S_IWUSR | S_IWGRP, NULL, c55_ctrl_enable);
+static int c55_ctrl_pin_setup(struct device *dev, struct c55_ctrl_data *cdata)
+{
+ int i, ret = 0;
+
+ cdata->pctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(cdata->pctrl)) {
+ ret = PTR_ERR(cdata->pctrl);
+ dev_dbg(dev, "no pinctrl handle\n");
+ }
+
+ for (i = 0; !ret && (i < C55_MODE_MAX); i++) {
+ cdata->states[i] = pinctrl_lookup_state(cdata->pctrl,
+ c55_pin_state_labels[i]);
+ if (IS_ERR(cdata->states[i])) {
+ ret = PTR_ERR(cdata->states[i]);
+ dev_dbg(dev, "no %s pinctrl state\n",
+ c55_pin_state_labels[i]);
+ }
+ }
+
+ if (!ret) {
+ ret = pinctrl_select_state(cdata->pctrl,
+ cdata->states[C55_OFF]);
+ if (ret)
+ dev_dbg(dev, "failed to activate %s pinctrl state\n",
+ c55_pin_state_labels[C55_OFF]);
+ }
+
+ return ret;
+}
+
+
static int c55_ctrl_probe(struct platform_device *pdev)
{
struct c55_ctrl_data *cdata;
@@ -223,6 +266,13 @@ static int c55_ctrl_probe(struct platform_device *pdev)
mutex_init(&cdata->ctrl_mutex);
+ ret = c55_ctrl_pin_setup(&pdev->dev, cdata);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: c55_ctrl_pin_setup failed.\n",
+ __func__);
+ return ret;
+ }
+
cdata->c55_ap_int_gpio = -1;
cdata->ap_c55_int_gpio = -1;
ret = c55_ctrl_gpio_setup(cdata, &pdev->dev);