Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34d27853 authored by Mark Brown's avatar Mark Brown Committed by Dmitry Torokhov
Browse files

Input: wm97xx-core - support use as a wakeup source



The WM97xx touch screen controllers can be used to generate a wakeup
event when the system is suspended. Provide a new core API call
wm97xx_set_suspend_mode() allowing machine drivers to enable this. If no
suspend_mode is provided then the touch panel will be powered down when
the system is suspended.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent db7c10e7
Loading
Loading
Loading
Loading
+39 −0
Original line number Original line Diff line number Diff line
@@ -261,6 +261,23 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir,
}
}
EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
EXPORT_SYMBOL_GPL(wm97xx_config_gpio);


/*
 * Configure the WM97XX_PRP value to use while system is suspended.
 * If a value other than 0 is set then WM97xx pen detection will be
 * left enabled in the configured mode while the system is in suspend,
 * the device has users and suspend has not been disabled via the
 * wakeup sysfs entries.
 *
 * @wm:   WM97xx device to configure
 * @mode: WM97XX_PRP value to configure while suspended
 */
void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode)
{
	wm->suspend_mode = mode;
	device_init_wakeup(&wm->input_dev->dev, mode != 0);
}
EXPORT_SYMBOL_GPL(wm97xx_set_suspend_mode);

/*
/*
 * Handle a pen down interrupt.
 * Handle a pen down interrupt.
 */
 */
@@ -689,10 +706,32 @@ static int wm97xx_remove(struct device *dev)
static int wm97xx_suspend(struct device *dev, pm_message_t state)
static int wm97xx_suspend(struct device *dev, pm_message_t state)
{
{
	struct wm97xx *wm = dev_get_drvdata(dev);
	struct wm97xx *wm = dev_get_drvdata(dev);
	u16 reg;
	int suspend_mode;

	if (device_may_wakeup(&wm->input_dev->dev))
		suspend_mode = wm->suspend_mode;
	else
		suspend_mode = 0;


	if (wm->input_dev->users)
	if (wm->input_dev->users)
		cancel_delayed_work_sync(&wm->ts_reader);
		cancel_delayed_work_sync(&wm->ts_reader);


	/* Power down the digitiser (bypassing the cache for resume) */
	reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2);
	reg &= ~WM97XX_PRP_DET_DIG;
	if (wm->input_dev->users)
		reg |= suspend_mode;
	wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg);

	/* WM9713 has an additional power bit - turn it off if there
	 * are no users or if suspend mode is zero. */
	if (wm->id == WM9713_ID2 &&
	    (!wm->input_dev->users || !suspend_mode)) {
		reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000;
		wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
	}

	return 0;
	return 0;
}
}


+3 −0
Original line number Original line Diff line number Diff line
@@ -282,6 +282,7 @@ struct wm97xx {
	unsigned pen_is_down:1;		/* Pen is down */
	unsigned pen_is_down:1;		/* Pen is down */
	unsigned aux_waiting:1;		/* aux measurement waiting */
	unsigned aux_waiting:1;		/* aux measurement waiting */
	unsigned pen_probably_down:1;	/* used in polling mode */
	unsigned pen_probably_down:1;	/* used in polling mode */
	u16 suspend_mode;               /* PRP in suspend mode */
};
};


/*
/*
@@ -297,6 +298,8 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio,
				     enum wm97xx_gpio_sticky sticky,
				     enum wm97xx_gpio_sticky sticky,
				     enum wm97xx_gpio_wake wake);
				     enum wm97xx_gpio_wake wake);


void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode);

/* codec AC97 IO access */
/* codec AC97 IO access */
int wm97xx_reg_read(struct wm97xx *wm, u16 reg);
int wm97xx_reg_read(struct wm97xx *wm, u16 reg);
void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val);
void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val);