summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2015-03-10 15:19:49 +0000
committerNick Dyer <nick.dyer@itdev.co.uk>2015-05-01 14:57:54 +0100
commit8c3f7d9d66ccd405c7ba818c49fe7ca82e254372 (patch)
tree7c89bfe34b36318a5471032be154326e3a698ea7
parentd9a9f129fb1a4680605dad434216f8792327ee58 (diff)
downloadolio-linux-3.10-8c3f7d9d66ccd405c7ba818c49fe7ca82e254372.tar.xz
olio-linux-3.10-8c3f7d9d66ccd405c7ba818c49fe7ca82e254372.zip
Input: atmel_mxt_ts - add suspend modes
-rw-r--r--Documentation/devicetree/bindings/input/atmel,maxtouch.txt5
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c99
-rw-r--r--include/dt-bindings/input/atmel_mxt_ts.h22
-rw-r--r--include/linux/platform_data/atmel_mxt_ts.h (renamed from include/linux/i2c/atmel_mxt_ts.h)8
4 files changed, 107 insertions, 27 deletions
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index a20561aa991..e879f6d1d2c 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -22,6 +22,11 @@ Optional properties for main touchpad device:
experiment to determine which bit corresponds to which input. Use
KEY_RESERVED for unused padding values.
+- atmel,suspend-mode: Select method used to suspend:
+ MXT_SUSPEND_DEEP_SLEEP - use T7 to suspend the device into deep sleep
+ MXT_SUSPEND_TOUCH_CTRL - use T9.CTRL to turn off touch processing
+ Definitions are in <dt-bindings/input/atmel_mxt_ts.h>.
+
- atmel,reset-gpio: Configure RESET GPIO. Required for regulator support.
- atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4987f7a650b..4d93a2a37bd 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -20,7 +20,7 @@
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
-#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/platform_data/atmel_mxt_ts.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -103,6 +103,7 @@ struct t7_config {
#define MXT_POWER_CFG_DEEPSLEEP 1
/* MXT_TOUCH_MULTI_T9 field */
+#define MXT_TOUCH_CTRL 0
#define MXT_T9_ORIENT 9
#define MXT_T9_RANGE 18
@@ -279,7 +280,6 @@ struct mxt_data {
u8 stylus_aux_pressure;
u8 stylus_aux_peak;
bool use_retrigen_workaround;
- bool use_regulator;
struct regulator *reg_vdd;
struct regulator *reg_avdd;
char *fw_name;
@@ -864,6 +864,20 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg)
data->t6_status = status;
}
+static int mxt_write_object(struct mxt_data *data,
+ u8 type, u8 offset, u8 val)
+{
+ struct mxt_object *object;
+ u16 reg;
+
+ object = mxt_get_object(data, type);
+ if (!object || offset >= mxt_obj_size(object))
+ return -EINVAL;
+
+ reg = object->start_address;
+ return mxt_write_reg(data->client, reg + offset, val);
+}
+
static void mxt_input_button(struct mxt_data *data, u8 *message)
{
struct input_dev *input = data->input_dev;
@@ -2153,6 +2167,11 @@ static void mxt_regulator_enable(struct mxt_data *data)
if (error)
return;
+ /*
+ * According to maXTouch power sequencing specification, RESET line
+ * must be kept low until some time after regulators come up to
+ * voltage
+ */
msleep(MXT_REGULATOR_DELAY);
gpio_set_value(data->pdata->gpio_reset, 1);
msleep(MXT_CHG_DELAY);
@@ -2174,18 +2193,14 @@ static void mxt_regulator_disable(struct mxt_data *data)
regulator_disable(data->reg_avdd);
}
-static void mxt_probe_regulators(struct mxt_data *data)
+static int mxt_probe_regulators(struct mxt_data *data)
{
struct device *dev = &data->client->dev;
int error;
- /*
- * According to maXTouch power sequencing specification, RESET line
- * must be kept low until some time after regulators come up to
- * voltage
- */
if (!gpio_is_valid(data->pdata->gpio_reset)) {
dev_dbg(dev, "Must have reset GPIO to use regulator support\n");
+ error = -EINVAL;
goto fail;
}
@@ -2203,18 +2218,17 @@ static void mxt_probe_regulators(struct mxt_data *data)
goto fail_release;
}
- data->use_regulator = true;
mxt_regulator_enable(data);
dev_dbg(dev, "Initialised regulators\n");
- return;
+ return 0;
fail_release:
regulator_put(data->reg_vdd);
fail:
data->reg_vdd = NULL;
data->reg_avdd = NULL;
- data->use_regulator = false;
+ return error;
}
static int mxt_read_t9_resolution(struct mxt_data *data)
@@ -2899,10 +2913,12 @@ static int mxt_load_fw(struct device *dev)
goto release_firmware;
if (data->suspended) {
- if (data->use_regulator)
+ if (data->pdata->suspend_mode == MXT_SUSPEND_REGULATOR)
mxt_regulator_enable(data);
- enable_irq(data->irq);
+ if (data->pdata->suspend_mode == MXT_SUSPEND_DEEP_SLEEP)
+ enable_irq(data->irq);
+
data->suspended = false;
}
@@ -3066,6 +3082,7 @@ static ssize_t mxt_update_cfg_store(struct device *dev,
const char *buf, size_t count)
{
struct mxt_data *data = dev_get_drvdata(dev);
+ const struct mxt_platform_data *pdata = data->pdata;
const struct firmware *cfg;
int ret;
@@ -3091,10 +3108,10 @@ static ssize_t mxt_update_cfg_store(struct device *dev,
mxt_free_input_device(data);
if (data->suspended) {
- if (data->use_regulator) {
+ if (pdata->suspend_mode == MXT_SUSPEND_REGULATOR) {
enable_irq(data->irq);
mxt_regulator_enable(data);
- } else {
+ } else if (pdata->suspend_mode == MXT_SUSPEND_DEEP_SLEEP) {
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
mxt_acquire_irq(data);
}
@@ -3276,13 +3293,24 @@ static void mxt_start(struct mxt_data *data)
if (!data->suspended || data->in_bootloader)
return;
- if (data->use_regulator) {
- enable_irq(data->irq);
+ switch (data->pdata->suspend_mode) {
+ case MXT_SUSPEND_TOUCH_CTRL:
+ mxt_soft_reset(data);
+
+ /* Touch enable */
+ mxt_write_object(data,
+ MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
+ break;
+ case MXT_SUSPEND_REGULATOR:
+ enable_irq(data->irq);
mxt_regulator_enable(data);
- } else {
+ break;
+
+ case MXT_SUSPEND_DEEP_SLEEP:
+ default:
/*
- * Discard any messages still in message buffer
+ * Discard any touch messages still in message buffer
* from before chip went to sleep
*/
mxt_process_messages_until_invalid(data);
@@ -3293,6 +3321,7 @@ static void mxt_start(struct mxt_data *data)
mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
mxt_acquire_irq(data);
+ break;
}
data->suspended = false;
@@ -3303,14 +3332,29 @@ static void mxt_stop(struct mxt_data *data)
if (data->suspended || data->in_bootloader || data->updating_config)
return;
- disable_irq(data->irq);
+ switch (data->pdata->suspend_mode) {
+ case MXT_SUSPEND_TOUCH_CTRL:
+ /* Touch disable */
+ mxt_write_object(data,
+ MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
+ break;
- if (data->use_regulator)
+ case MXT_SUSPEND_REGULATOR:
+ disable_irq(data->irq);
mxt_regulator_disable(data);
- else
+ mxt_reset_slots(data);
+ break;
+
+ case MXT_SUSPEND_DEEP_SLEEP:
+ default:
+ disable_irq(data->irq);
+
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
- mxt_reset_slots(data);
+ mxt_reset_slots(data);
+ break;
+ }
+
data->suspended = true;
}
@@ -3376,6 +3420,9 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
pdata->t19_keymap = keymap;
}
+ of_property_read_u32(client->dev.of_node, "atmel,suspend-mode",
+ &pdata->suspend_mode);
+
return pdata;
}
#else
@@ -3438,7 +3485,11 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
goto err_free_mem;
}
- mxt_probe_regulators(data);
+ if (pdata->suspend_mode == MXT_SUSPEND_REGULATOR) {
+ error = mxt_probe_regulators(data);
+ if (error)
+ goto err_free_irq;
+ }
disable_irq(data->irq);
diff --git a/include/dt-bindings/input/atmel_mxt_ts.h b/include/dt-bindings/input/atmel_mxt_ts.h
new file mode 100644
index 00000000000..c7637925da5
--- /dev/null
+++ b/include/dt-bindings/input/atmel_mxt_ts.h
@@ -0,0 +1,22 @@
+/*
+ * Atmel maXTouch Touchscreen driver
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ * Author: Nick Dyer <nick.dyer@itdev.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_ATMEL_MXT_TS_H
+#define __DT_BINDINGS_ATMEL_MXT_TS_H
+
+enum mxt_suspend_mode {
+ MXT_SUSPEND_DEEP_SLEEP = 0,
+ MXT_SUSPEND_TOUCH_CTRL = 1,
+ MXT_SUSPEND_REGULATOR = 2,
+};
+
+#endif /* __DT_BINDINGS_ATMEL_MXT_TS_H */
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/platform_data/atmel_mxt_ts.h
index bc74c3f4c86..be6fa95a661 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/platform_data/atmel_mxt_ts.h
@@ -10,16 +10,18 @@
* option) any later version.
*/
-#ifndef __LINUX_ATMEL_MXT_TS_H
-#define __LINUX_ATMEL_MXT_TS_H
+#ifndef __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H
+#define __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H
#include <linux/types.h>
+#include <dt-bindings/input/atmel_mxt_ts.h>
/* The platform data for the Atmel maXTouch touchscreen driver */
struct mxt_platform_data {
unsigned long irqflags;
u8 t19_num_keys;
const unsigned int *t19_keymap;
+ enum mxt_suspend_mode suspend_mode;
int t15_num_keys;
const unsigned int *t15_keymap;
unsigned long gpio_reset;
@@ -27,4 +29,4 @@ struct mxt_platform_data {
const char *input_name;
};
-#endif /* __LINUX_ATMEL_MXT_TS_H */
+#endif /* __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H */