summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (from parent 1: 1ffed10)
raw | patch | inline | side by side (from parent 1: 1ffed10)
author | Patil, Rachna <rachna@ti.com> | |
Wed, 1 Feb 2012 05:36:37 +0000 (11:06 +0530) | ||
committer | Patil, Rachna <rachna@ti.com> | |
Wed, 22 Feb 2012 07:25:30 +0000 (12:55 +0530) |
This patch adds support for suspend/resume feature in
touchscreen.
Since touchscreen is in wakeup domain, it can be used
to resume the system.
Signed-off-by: Patil, Rachna <rachna@ti.com>
touchscreen.
Since touchscreen is in wakeup domain, it can be used
to resume the system.
Signed-off-by: Patil, Rachna <rachna@ti.com>
drivers/input/touchscreen/ti_tscadc.c | patch | blob | history |
index e3b57755936c2b032a772ad3aa4b074285b6c6ba..9b34b82072799945e61b2a2cdc2bf6e6b1a33d52 100644 (file)
#include <linux/io.h>
#include <linux/input/ti_tscadc.h>
#include <linux/delay.h>
+#include <linux/pm_runtime.h>
#define TSCADC_REG_IRQEOI 0x020
#define TSCADC_REG_RAWIRQSTATUS 0x024
#define TSCADC_REG_IRQSTATUS 0x028
#define TSCADC_REG_IRQENABLE 0x02C
+#define TSCADC_REG_IRQCLR 0x030
#define TSCADC_REG_IRQWAKEUP 0x034
#define TSCADC_REG_CTRL 0x040
#define TSCADC_REG_ADCFSM 0x044
/* Register Bitfields */
#define TSCADC_IRQWKUP_ENB BIT(0)
+#define TSCADC_IRQWKUP_DISABLE 0x00
#define TSCADC_STPENB_STEPENB 0x7FFF
#define TSCADC_IRQENB_FIFO0THRES BIT(2)
#define TSCADC_IRQENB_FIFO1THRES BIT(5)
#define TSCADC_IRQENB_PENUP BIT(9)
+#define TSCADC_IRQENB_HW_PEN BIT(0)
#define TSCADC_STEPCONFIG_MODE_HWSYNC 0x2
#define TSCADC_STEPCONFIG_2SAMPLES_AVG (1 << 4)
#define TSCADC_STEPCONFIG_XPP BIT(5)
int wires;
int analog_input;
int x_plate_resistance;
- struct clk *tsc_ick;
int irq;
void __iomem *tsc_base;
+ unsigned int ctrl;
};
static unsigned int tscadc_readl(struct tscadc *ts, unsigned int reg)
}
irqclr |= TSCADC_IRQENB_PENUP;
}
+ irqclr |= TSCADC_IRQENB_HW_PEN;
tscadc_writel(ts_dev, TSCADC_REG_IRQSTATUS, irqclr);
goto err_unmap_regs;
}
- ts_dev->tsc_ick = clk_get(&pdev->dev, "adc_tsc_ick");
- if (IS_ERR(ts_dev->tsc_ick)) {
- dev_err(&pdev->dev, "failed to get TSC ick\n");
- goto err_free_irq;
- }
- clk_enable(ts_dev->tsc_ick);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
clk = clk_get(&pdev->dev, "adc_tsc_fck");
if (IS_ERR(clk)) {
clk_value = clk_value - 1;
tscadc_writel(ts_dev, TSCADC_REG_CLKDIV, clk_value);
- /* Enable wake-up of the SoC using touchscreen */
- tscadc_writel(ts_dev, TSCADC_REG_IRQWAKEUP, TSCADC_IRQWKUP_ENB);
-
ts_dev->wires = pdata->wires;
ts_dev->analog_input = pdata->analog_input;
ts_dev->x_plate_resistance = pdata->x_plate_resistance;
break;
}
tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
+ ts_dev->ctrl = ctrl;
/* Set register bits for Idel Config Mode */
tsc_idle_config(ts_dev);
if (err)
goto err_fail;
+ device_init_wakeup(&pdev->dev, true);
platform_set_drvdata(pdev, ts_dev);
return 0;
err_fail:
- clk_disable(ts_dev->tsc_ick);
- clk_put(ts_dev->tsc_ick);
+ pm_runtime_disable(&pdev->dev);
err_free_irq:
free_irq(ts_dev->irq, ts_dev);
err_unmap_regs:
iounmap(ts_dev->tsc_base);
release_mem_region(res->start, resource_size(res));
- clk_disable(ts_dev->tsc_ick);
- clk_put(ts_dev->tsc_ick);
+ pm_runtime_disable(&pdev->dev);
kfree(ts_dev);
+ device_init_wakeup(&pdev->dev, 0);
platform_set_drvdata(pdev, NULL);
return 0;
}
static int tscadc_suspend(struct platform_device *pdev, pm_message_t state)
{
struct tscadc *ts_dev = platform_get_drvdata(pdev);
- unsigned int status;
+ unsigned int idle;
+
+ if (device_may_wakeup(&pdev->dev)) {
+ idle = tscadc_readl(ts_dev, TSCADC_REG_IRQENABLE);
+ tscadc_writel(ts_dev, TSCADC_REG_IRQENABLE,
+ (idle | TSCADC_IRQENB_HW_PEN));
+ tscadc_writel(ts_dev, TSCADC_REG_IRQWAKEUP, TSCADC_IRQWKUP_ENB);
+ }
- status = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
- status &= ~(TSCADC_CNTRLREG_TSCSSENB);
- tscadc_writel(ts_dev, TSCADC_REG_CTRL, status);
+ /* module disable */
+ idle = 0;
+ idle = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
+ idle &= ~(TSCADC_CNTRLREG_TSCSSENB);
+ tscadc_writel(ts_dev, TSCADC_REG_CTRL, idle);
- clk_disable(ts_dev->tsc_ick);
- clk_put(ts_dev->tsc_ick);
+ pm_runtime_put_sync(&pdev->dev);
return 0;
static int tscadc_resume(struct platform_device *pdev)
{
struct tscadc *ts_dev = platform_get_drvdata(pdev);
- unsigned int status;
+ unsigned int restore;
- clk_enable(ts_dev->tsc_ick);
+ pm_runtime_get_sync(&pdev->dev);
- status = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
+ if (device_may_wakeup(&pdev->dev)) {
+ tscadc_writel(ts_dev, TSCADC_REG_IRQWAKEUP,
+ TSCADC_IRQWKUP_DISABLE);
+ tscadc_writel(ts_dev, TSCADC_REG_IRQCLR, TSCADC_IRQENB_HW_PEN);
+ }
+
+ /* context restore */
+ tscadc_writel(ts_dev, TSCADC_REG_CTRL, ts_dev->ctrl);
+ tsc_idle_config(ts_dev);
+ tsc_step_config(ts_dev);
+ tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 6);
+ restore = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
tscadc_writel(ts_dev, TSCADC_REG_CTRL,
- (status | TSCADC_CNTRLREG_TSCSSENB));
+ (restore | TSCADC_CNTRLREG_TSCSSENB));
return 0;
}