diff options
| author | Jee Su Chang <w20740@motorola.com> | 2014-05-04 14:14:55 -0500 |
|---|---|---|
| committer | Jee Su Chang <w20740@motorola.com> | 2014-05-04 14:14:55 -0500 |
| commit | d9e15ffe03f3be4a7de2e320798728830c1f3057 (patch) | |
| tree | 48a43e096fe2c2c902f9f1a8359aed846a4c4101 /drivers/misc/c55_ctrl.c | |
| parent | 82e085f9dd609b78b8ce8bed440a62a643c99df0 (diff) | |
| download | olio-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.c | 50 |
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); |