diff options
| author | Nick Dyer <nick.dyer@itdev.co.uk> | 2015-03-10 15:19:49 +0000 |
|---|---|---|
| committer | Nick Dyer <nick.dyer@itdev.co.uk> | 2015-05-01 14:57:54 +0100 |
| commit | 8c3f7d9d66ccd405c7ba818c49fe7ca82e254372 (patch) | |
| tree | 7c89bfe34b36318a5471032be154326e3a698ea7 | |
| parent | d9a9f129fb1a4680605dad434216f8792327ee58 (diff) | |
| download | olio-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.txt | 5 | ||||
| -rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 99 | ||||
| -rw-r--r-- | include/dt-bindings/input/atmel_mxt_ts.h | 22 | ||||
| -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 */ |