diff options
-rw-r--r-- | drivers/input/touchscreen/wm97xx-core.c | 39 | ||||
-rw-r--r-- | include/linux/wm97xx.h | 3 |
2 files changed, 42 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index fec07c28281a..e9c7ea46b6e3 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -262,6 +262,23 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir, | |||
262 | EXPORT_SYMBOL_GPL(wm97xx_config_gpio); | 262 | EXPORT_SYMBOL_GPL(wm97xx_config_gpio); |
263 | 263 | ||
264 | /* | 264 | /* |
265 | * Configure the WM97XX_PRP value to use while system is suspended. | ||
266 | * If a value other than 0 is set then WM97xx pen detection will be | ||
267 | * left enabled in the configured mode while the system is in suspend, | ||
268 | * the device has users and suspend has not been disabled via the | ||
269 | * wakeup sysfs entries. | ||
270 | * | ||
271 | * @wm: WM97xx device to configure | ||
272 | * @mode: WM97XX_PRP value to configure while suspended | ||
273 | */ | ||
274 | void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode) | ||
275 | { | ||
276 | wm->suspend_mode = mode; | ||
277 | device_init_wakeup(&wm->input_dev->dev, mode != 0); | ||
278 | } | ||
279 | EXPORT_SYMBOL_GPL(wm97xx_set_suspend_mode); | ||
280 | |||
281 | /* | ||
265 | * Handle a pen down interrupt. | 282 | * Handle a pen down interrupt. |
266 | */ | 283 | */ |
267 | static void wm97xx_pen_irq_worker(struct work_struct *work) | 284 | static void wm97xx_pen_irq_worker(struct work_struct *work) |
@@ -689,10 +706,32 @@ static int wm97xx_remove(struct device *dev) | |||
689 | static int wm97xx_suspend(struct device *dev, pm_message_t state) | 706 | static int wm97xx_suspend(struct device *dev, pm_message_t state) |
690 | { | 707 | { |
691 | struct wm97xx *wm = dev_get_drvdata(dev); | 708 | struct wm97xx *wm = dev_get_drvdata(dev); |
709 | u16 reg; | ||
710 | int suspend_mode; | ||
711 | |||
712 | if (device_may_wakeup(&wm->input_dev->dev)) | ||
713 | suspend_mode = wm->suspend_mode; | ||
714 | else | ||
715 | suspend_mode = 0; | ||
692 | 716 | ||
693 | if (wm->input_dev->users) | 717 | if (wm->input_dev->users) |
694 | cancel_delayed_work_sync(&wm->ts_reader); | 718 | cancel_delayed_work_sync(&wm->ts_reader); |
695 | 719 | ||
720 | /* Power down the digitiser (bypassing the cache for resume) */ | ||
721 | reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2); | ||
722 | reg &= ~WM97XX_PRP_DET_DIG; | ||
723 | if (wm->input_dev->users) | ||
724 | reg |= suspend_mode; | ||
725 | wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg); | ||
726 | |||
727 | /* WM9713 has an additional power bit - turn it off if there | ||
728 | * are no users or if suspend mode is zero. */ | ||
729 | if (wm->id == WM9713_ID2 && | ||
730 | (!wm->input_dev->users || !suspend_mode)) { | ||
731 | reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000; | ||
732 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg); | ||
733 | } | ||
734 | |||
696 | return 0; | 735 | return 0; |
697 | } | 736 | } |
698 | 737 | ||
diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h index ed01c7df54a3..4d13732e9cf0 100644 --- a/include/linux/wm97xx.h +++ b/include/linux/wm97xx.h | |||
@@ -282,6 +282,7 @@ struct wm97xx { | |||
282 | unsigned pen_is_down:1; /* Pen is down */ | 282 | unsigned pen_is_down:1; /* Pen is down */ |
283 | unsigned aux_waiting:1; /* aux measurement waiting */ | 283 | unsigned aux_waiting:1; /* aux measurement waiting */ |
284 | unsigned pen_probably_down:1; /* used in polling mode */ | 284 | unsigned pen_probably_down:1; /* used in polling mode */ |
285 | u16 suspend_mode; /* PRP in suspend mode */ | ||
285 | }; | 286 | }; |
286 | 287 | ||
287 | /* | 288 | /* |
@@ -297,6 +298,8 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, | |||
297 | enum wm97xx_gpio_sticky sticky, | 298 | enum wm97xx_gpio_sticky sticky, |
298 | enum wm97xx_gpio_wake wake); | 299 | enum wm97xx_gpio_wake wake); |
299 | 300 | ||
301 | void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode); | ||
302 | |||
300 | /* codec AC97 IO access */ | 303 | /* codec AC97 IO access */ |
301 | int wm97xx_reg_read(struct wm97xx *wm, u16 reg); | 304 | int wm97xx_reg_read(struct wm97xx *wm, u16 reg); |
302 | void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val); | 305 | void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val); |