Skip to content

Commit 18ab69c

Browse files
jlabundydtor
authored andcommitted
Input: iqs269a - do not poll during suspend or resume
Polling the device while it transitions from automatic to manual power mode switching may keep the device from actually finishing the transition. The process appears to time out depending on the polling rate and the device's core clock frequency. This is ultimately unnecessary in the first place; instead it is sufficient to write the desired mode during initialization, then disable automatic switching at suspend. This eliminates the need to ensure the device is prepared for a manual change and removes the 'suspend_mode' variable. Similarly, polling the device while it transitions from one mode to another under manual control may time out as well. This added step does not appear to be necessary either, so drop it. Fixes: 04e4986 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy <[email protected]> Reviewed-by: Mattijs Korpershoek <[email protected]> Link: https://lore.kernel.org/r/Y7Rs+eEXlRw4Vq57@nixie71 Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 3689abf commit 18ab69c

File tree

1 file changed

+31
-87
lines changed

1 file changed

+31
-87
lines changed

drivers/input/misc/iqs269a.c

Lines changed: 31 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,6 @@
148148
#define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000)
149149
#define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150)
150150

151-
#define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US
152-
#define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US
153-
154151
#define iqs269_irq_wait() usleep_range(200, 250)
155152

156153
enum iqs269_local_cap_size {
@@ -295,7 +292,6 @@ struct iqs269_private {
295292
struct input_dev *keypad;
296293
struct input_dev *slider[IQS269_NUM_SL];
297294
unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
298-
unsigned int suspend_mode;
299295
unsigned int delay_mult;
300296
unsigned int ch_num;
301297
bool hall_enable;
@@ -767,17 +763,6 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
767763
iqs269->hall_enable = device_property_present(&client->dev,
768764
"azoteq,hall-enable");
769765

770-
if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
771-
&val)) {
772-
if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
773-
dev_err(&client->dev, "Invalid suspend mode: %u\n",
774-
val);
775-
return -EINVAL;
776-
}
777-
778-
iqs269->suspend_mode = val;
779-
}
780-
781766
error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
782767
sizeof(*sys_reg));
783768
if (error)
@@ -1005,6 +990,17 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
1005990
general &= ~IQS269_SYS_SETTINGS_DIS_AUTO;
1006991
general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK;
1007992

993+
if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
994+
&val)) {
995+
if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
996+
dev_err(&client->dev, "Invalid suspend mode: %u\n",
997+
val);
998+
return -EINVAL;
999+
}
1000+
1001+
general |= (val << IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
1002+
}
1003+
10081004
if (!device_property_read_u32(&client->dev, "azoteq,ulp-update",
10091005
&val)) {
10101006
if (val > IQS269_SYS_SETTINGS_ULP_UPDATE_MAX) {
@@ -1687,59 +1683,30 @@ static int iqs269_probe(struct i2c_client *client)
16871683
return error;
16881684
}
16891685

1686+
static u16 iqs269_general_get(struct iqs269_private *iqs269)
1687+
{
1688+
u16 general = be16_to_cpu(iqs269->sys_reg.general);
1689+
1690+
general &= ~IQS269_SYS_SETTINGS_REDO_ATI;
1691+
general &= ~IQS269_SYS_SETTINGS_ACK_RESET;
1692+
1693+
return general | IQS269_SYS_SETTINGS_DIS_AUTO;
1694+
}
1695+
16901696
static int iqs269_suspend(struct device *dev)
16911697
{
16921698
struct iqs269_private *iqs269 = dev_get_drvdata(dev);
16931699
struct i2c_client *client = iqs269->client;
1694-
unsigned int val;
16951700
int error;
1701+
u16 general = iqs269_general_get(iqs269);
16961702

1697-
if (!iqs269->suspend_mode)
1703+
if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK))
16981704
return 0;
16991705

17001706
disable_irq(client->irq);
17011707

1702-
/*
1703-
* Automatic power mode switching must be disabled before the device is
1704-
* forced into any particular power mode. In this case, the device will
1705-
* transition into normal-power mode.
1706-
*/
1707-
error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
1708-
IQS269_SYS_SETTINGS_DIS_AUTO, ~0);
1709-
if (error)
1710-
goto err_irq;
1711-
1712-
/*
1713-
* The following check ensures the device has completed its transition
1714-
* into normal-power mode before a manual mode switch is performed.
1715-
*/
1716-
error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
1717-
!(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
1718-
IQS269_PWR_MODE_POLL_SLEEP_US,
1719-
IQS269_PWR_MODE_POLL_TIMEOUT_US);
1720-
if (error)
1721-
goto err_irq;
1722-
1723-
error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
1724-
IQS269_SYS_SETTINGS_PWR_MODE_MASK,
1725-
iqs269->suspend_mode <<
1726-
IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
1727-
if (error)
1728-
goto err_irq;
1729-
1730-
/*
1731-
* This last check ensures the device has completed its transition into
1732-
* the desired power mode to prevent any spurious interrupts from being
1733-
* triggered after iqs269_suspend has already returned.
1734-
*/
1735-
error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
1736-
(val & IQS269_SYS_FLAGS_PWR_MODE_MASK)
1737-
== (iqs269->suspend_mode <<
1738-
IQS269_SYS_FLAGS_PWR_MODE_SHIFT),
1739-
IQS269_PWR_MODE_POLL_SLEEP_US,
1740-
IQS269_PWR_MODE_POLL_TIMEOUT_US);
1708+
error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, general);
17411709

1742-
err_irq:
17431710
iqs269_irq_wait();
17441711
enable_irq(client->irq);
17451712

@@ -1750,43 +1717,20 @@ static int iqs269_resume(struct device *dev)
17501717
{
17511718
struct iqs269_private *iqs269 = dev_get_drvdata(dev);
17521719
struct i2c_client *client = iqs269->client;
1753-
unsigned int val;
17541720
int error;
1721+
u16 general = iqs269_general_get(iqs269);
17551722

1756-
if (!iqs269->suspend_mode)
1723+
if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK))
17571724
return 0;
17581725

17591726
disable_irq(client->irq);
17601727

1761-
error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
1762-
IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0);
1763-
if (error)
1764-
goto err_irq;
1765-
1766-
/*
1767-
* This check ensures the device has returned to normal-power mode
1768-
* before automatic power mode switching is re-enabled.
1769-
*/
1770-
error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
1771-
!(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
1772-
IQS269_PWR_MODE_POLL_SLEEP_US,
1773-
IQS269_PWR_MODE_POLL_TIMEOUT_US);
1774-
if (error)
1775-
goto err_irq;
1776-
1777-
error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
1778-
IQS269_SYS_SETTINGS_DIS_AUTO, 0);
1779-
if (error)
1780-
goto err_irq;
1781-
1782-
/*
1783-
* This step reports any events that may have been "swallowed" as a
1784-
* result of polling PWR_MODE (which automatically acknowledges any
1785-
* pending interrupts).
1786-
*/
1787-
error = iqs269_report(iqs269);
1728+
error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS,
1729+
general & ~IQS269_SYS_SETTINGS_PWR_MODE_MASK);
1730+
if (!error)
1731+
error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS,
1732+
general & ~IQS269_SYS_SETTINGS_DIS_AUTO);
17881733

1789-
err_irq:
17901734
iqs269_irq_wait();
17911735
enable_irq(client->irq);
17921736

0 commit comments

Comments
 (0)