diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-09-03 10:01:44 -0700 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-09-03 10:01:44 -0700 |
| commit | 01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba (patch) | |
| tree | 85f506cf9fce3d8fd47cf624dd8698472bffc13f /drivers/input/touchscreen | |
| parent | e51e38494a8ecc18650efb0c840600637891de2c (diff) | |
| parent | 58f1eae48e5372200553de07b5ecc7574803ee91 (diff) | |
| download | linux-01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba.tar.gz linux-01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba.tar.bz2 linux-01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba.zip | |
Merge branch 'next' into for-linus
Prepare first round of input updates for 4.3 merge window.
Diffstat (limited to 'drivers/input/touchscreen')
28 files changed, 1115 insertions, 469 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index aa2b5f21b89b..059edeb7f04a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,9 +11,9 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN -config OF_TOUCHSCREEN +config TOUCHSCREEN_PROPERTIES def_tristate INPUT - depends on INPUT && OF + depends on INPUT config TOUCHSCREEN_88PM860X tristate "Marvell 88PM860x touchscreen" @@ -118,7 +118,7 @@ config TOUCHSCREEN_ATMEL_MXT config TOUCHSCREEN_AUO_PIXCIR tristate "AUO in-cell touchscreen using Pixcir ICs" depends on I2C - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST help Say Y here if you have a AUO display with in-cell touchscreen using Pixcir ICs. @@ -142,7 +142,7 @@ config TOUCHSCREEN_BU21013 config TOUCHSCREEN_CHIPONE_ICN8318 tristate "chipone icn8318 touchscreen controller" - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST depends on I2C depends on OF help @@ -156,7 +156,7 @@ config TOUCHSCREEN_CHIPONE_ICN8318 config TOUCHSCREEN_CY8CTMG110 tristate "cy8ctmg110 touchscreen" depends on I2C - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST help Say Y here if you have a cy8ctmg110 capacitive touchscreen on an AAVA device. @@ -915,10 +915,11 @@ config TOUCHSCREEN_TSC_SERIO module will be called tsc40. config TOUCHSCREEN_TSC2005 - tristate "TSC2005 based touchscreens" - depends on SPI_MASTER - help - Say Y here if you have a TSC2005 based touchscreen. + tristate "TSC2005 based touchscreens" + depends on SPI_MASTER + select REGMAP_SPI + help + Say Y here if you have a TSC2005 based touchscreen. If unsure, say N. @@ -992,8 +993,9 @@ config TOUCHSCREEN_SUN4I config TOUCHSCREEN_SUR40 tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" - depends on USB + depends on USB && MEDIA_USB_SUPPORT && HAS_DMA select INPUT_POLLDEV + select VIDEOBUF2_DMA_SG help Say Y here if you want support for the Samsung SUR40 touchscreen (also known as Microsoft Surface 2.0 or Microsoft PixelSense). @@ -1028,7 +1030,7 @@ config TOUCHSCREEN_TPS6507X config TOUCHSCREEN_ZFORCE tristate "Neonode zForce infrared touchscreens" depends on I2C - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST help Say Y here if you have a touchscreen using the zforce infraread technology from Neonode. diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index fa3d33bac7fc..c85aae23e7f8 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -6,7 +6,7 @@ wm97xx-ts-y := wm97xx-core.o -obj-$(CONFIG_OF_TOUCHSCREEN) += of_touchscreen.o +obj-$(CONFIG_TOUCHSCREEN_PROPERTIES) += of_touchscreen.o obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c index dcf390771549..d66962c5b1c2 100644 --- a/drivers/input/touchscreen/ad7879-i2c.c +++ b/drivers/input/touchscreen/ad7879-i2c.c @@ -94,7 +94,6 @@ MODULE_DEVICE_TABLE(i2c, ad7879_id); static struct i2c_driver ad7879_i2c_driver = { .driver = { .name = "ad7879", - .owner = THIS_MODULE, .pm = &ad7879_pm_ops, }, .probe = ad7879_i2c_probe, diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index e4eb8a6c658f..0f5f968592bd 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1234,7 +1234,8 @@ static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) of_property_read_u32(node, "ti,pendown-gpio-debounce", &pdata->gpio_pendown_debounce); - pdata->wakeup = of_property_read_bool(node, "linux,wakeup"); + pdata->wakeup = of_property_read_bool(node, "wakeup-source") || + of_property_read_bool(node, "linux,wakeup"); pdata->gpio_pendown = of_get_named_gpio(dev->of_node, "pendown-gpio", 0); diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c index f0b954d46a25..71b5a634cf6d 100644 --- a/drivers/input/touchscreen/ar1021_i2c.c +++ b/drivers/input/touchscreen/ar1021_i2c.c @@ -166,7 +166,6 @@ MODULE_DEVICE_TABLE(of, ar1021_i2c_of_match); static struct i2c_driver ar1021_i2c_driver = { .driver = { .name = "ar1021_i2c", - .owner = THIS_MODULE, .pm = &ar1021_i2c_pm, .of_match_table = ar1021_i2c_of_match, }, diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index dfc7309e3d38..c5622058c22b 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -22,34 +22,20 @@ #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/of.h> #include <linux/slab.h> #include <asm/unaligned.h> -/* Version */ -#define MXT_VER_20 20 -#define MXT_VER_21 21 -#define MXT_VER_22 22 - /* Firmware files */ #define MXT_FW_NAME "maxtouch.fw" #define MXT_CFG_NAME "maxtouch.cfg" #define MXT_CFG_MAGIC "OBP_RAW V1" /* Registers */ -#define MXT_INFO 0x00 -#define MXT_FAMILY_ID 0x00 -#define MXT_VARIANT_ID 0x01 -#define MXT_VERSION 0x02 -#define MXT_BUILD 0x03 -#define MXT_MATRIX_X_SIZE 0x04 -#define MXT_MATRIX_Y_SIZE 0x05 -#define MXT_OBJECT_NUM 0x06 #define MXT_OBJECT_START 0x07 - #define MXT_OBJECT_SIZE 6 #define MXT_INFO_CHECKSUM_SIZE 3 #define MXT_MAX_BLOCK_WRITE 256 @@ -103,21 +89,16 @@ #define MXT_T6_STATUS_COMSERR (1 << 2) /* MXT_GEN_POWER_T7 field */ -#define MXT_POWER_IDLEACQINT 0 -#define MXT_POWER_ACTVACQINT 1 -#define MXT_POWER_ACTV2IDLETO 2 - -/* MXT_GEN_ACQUIRE_T8 field */ -#define MXT_ACQUIRE_CHRGTIME 0 -#define MXT_ACQUIRE_TCHDRIFT 2 -#define MXT_ACQUIRE_DRIFTST 3 -#define MXT_ACQUIRE_TCHAUTOCAL 4 -#define MXT_ACQUIRE_SYNC 5 -#define MXT_ACQUIRE_ATCHCALST 6 -#define MXT_ACQUIRE_ATCHCALSTHR 7 +struct t7_config { + u8 idle; + u8 active; +} __packed; + +#define MXT_POWER_CFG_RUN 0 +#define MXT_POWER_CFG_DEEPSLEEP 1 /* MXT_TOUCH_MULTI_T9 field */ -#define MXT_TOUCH_CTRL 0 +#define MXT_T9_CTRL 0 #define MXT_T9_ORIENT 9 #define MXT_T9_RANGE 18 @@ -139,51 +120,10 @@ struct t9_range { /* MXT_TOUCH_MULTI_T9 orient */ #define MXT_T9_ORIENT_SWITCH (1 << 0) -/* MXT_PROCI_GRIPFACE_T20 field */ -#define MXT_GRIPFACE_CTRL 0 -#define MXT_GRIPFACE_XLOGRIP 1 -#define MXT_GRIPFACE_XHIGRIP 2 -#define MXT_GRIPFACE_YLOGRIP 3 -#define MXT_GRIPFACE_YHIGRIP 4 -#define MXT_GRIPFACE_MAXTCHS 5 -#define MXT_GRIPFACE_SZTHR1 7 -#define MXT_GRIPFACE_SZTHR2 8 -#define MXT_GRIPFACE_SHPTHR1 9 -#define MXT_GRIPFACE_SHPTHR2 10 -#define MXT_GRIPFACE_SUPEXTTO 11 - -/* MXT_PROCI_NOISE field */ -#define MXT_NOISE_CTRL 0 -#define MXT_NOISE_OUTFLEN 1 -#define MXT_NOISE_GCAFUL_LSB 3 -#define MXT_NOISE_GCAFUL_MSB 4 -#define MXT_NOISE_GCAFLL_LSB 5 -#define MXT_NOISE_GCAFLL_MSB 6 -#define MXT_NOISE_ACTVGCAFVALID 7 -#define MXT_NOISE_NOISETHR 8 -#define MXT_NOISE_FREQHOPSCALE 10 -#define MXT_NOISE_FREQ0 11 -#define MXT_NOISE_FREQ1 12 -#define MXT_NOISE_FREQ2 13 -#define MXT_NOISE_FREQ3 14 -#define MXT_NOISE_FREQ4 15 -#define MXT_NOISE_IDLEGCAFVALID 16 - /* MXT_SPT_COMMSCONFIG_T18 */ #define MXT_COMMS_CTRL 0 #define MXT_COMMS_CMD 1 -/* MXT_SPT_CTECONFIG_T28 field */ -#define MXT_CTE_CTRL 0 -#define MXT_CTE_CMD 1 -#define MXT_CTE_MODE 2 -#define MXT_CTE_IDLEGCAFDEPTH 3 -#define MXT_CTE_ACTVGCAFDEPTH 4 -#define MXT_CTE_VOLTAGE 5 - -#define MXT_VOLTAGE_DEFAULT 2700000 -#define MXT_VOLTAGE_STEP 10000 - /* Define for MXT_GEN_COMMAND_T6 */ #define MXT_BOOT_VALUE 0xa5 #define MXT_RESET_VALUE 0x01 @@ -291,6 +231,7 @@ struct mxt_data { u8 last_message_count; u8 num_touchids; u8 multitouch; + struct t7_config t7_cfg; /* Cached parameters from object table */ u16 T5_address; @@ -997,16 +938,15 @@ static irqreturn_t mxt_process_messages_t44(struct mxt_data *data) count = data->msg_buf[0]; - if (count == 0) { - /* - * This condition is caused by the CHG line being configured - * in Mode 0. It results in unnecessary I2C operations but it - * is benign. - */ - dev_dbg(dev, "Interrupt triggered but zero messages\n"); + /* + * This condition may be caused by the CHG line being configured in + * Mode 0. It results in unnecessary I2C operations but it is benign. + */ + if (count == 0) return IRQ_NONE; - } else if (count > data->max_reportid) { - dev_err(dev, "T44 count %d exceeded max report id\n", count); + + if (count > data->max_reportid) { + dev_warn(dev, "T44 count %d exceeded max report id\n", count); count = data->max_reportid; } @@ -1157,7 +1097,9 @@ static int mxt_soft_reset(struct mxt_data *data) struct device *dev = &data->client->dev; int ret = 0; - dev_info(dev, "Resetting chip\n"); + dev_info(dev, "Resetting device\n"); + + disable_irq(data->irq); reinit_completion(&data->reset_completion); @@ -1165,6 +1107,11 @@ static int mxt_soft_reset(struct mxt_data *data) if (ret) return ret; + /* Ignore CHG line for 100ms after reset */ + msleep(100); + + enable_irq(data->irq); + ret = mxt_wait_for_completion(data, &data->reset_completion, MXT_RESET_TIMEOUT); if (ret) @@ -1361,6 +1308,8 @@ static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start, return 0; } +static int mxt_init_t7_power_cfg(struct mxt_data *data); + /* * mxt_update_cfg - download configuration to chip * @@ -1508,6 +1457,9 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) dev_info(dev, "Config successfully updated\n"); + /* T7 config may have changed */ + mxt_init_t7_power_cfg(data); + release_mem: kfree(config_mem); return ret; @@ -1533,7 +1485,7 @@ static int mxt_get_info(struct mxt_data *data) int error; /* Read 7-byte info block starting at address 0 */ - error = __mxt_read_reg(client, MXT_INFO, sizeof(*info), info); + error = __mxt_read_reg(client, 0, sizeof(*info), info); if (error) return error; @@ -1905,6 +1857,8 @@ static int mxt_initialize_input_device(struct mxt_data *data) if (pdata->t19_num_keys) { mxt_set_up_as_touchpad(input_dev, data); mt_flags |= INPUT_MT_POINTER; + } else { + mt_flags |= INPUT_MT_DIRECT; } /* For multi touch */ @@ -2051,6 +2005,60 @@ err_free_object_table: return error; } +static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) +{ + struct device *dev = &data->client->dev; + int error; + struct t7_config *new_config; + struct t7_config deepsleep = { .active = 0, .idle = 0 }; + + if (sleep == MXT_POWER_CFG_DEEPSLEEP) + new_config = &deepsleep; + else + new_config = &data->t7_cfg; + + error = __mxt_write_reg(data->client, data->T7_address, + sizeof(data->t7_cfg), new_config); + if (error) + return error; + + dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n", + new_config->active, new_config->idle); + + return 0; +} + +static int mxt_init_t7_power_cfg(struct mxt_data *data) +{ + struct device *dev = &data->client->dev; + int error; + bool retry = false; + +recheck: + error = __mxt_read_reg(data->client, data->T7_address, + sizeof(data->t7_cfg), &data->t7_cfg); + if (error) + return error; + + if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) { + if (!retry) { + dev_dbg(dev, "T7 cfg zero, resetting\n"); + mxt_soft_reset(data); + retry = true; + goto recheck; + } else { + dev_dbg(dev, "T7 cfg zero after reset, overriding\n"); + data->t7_cfg.active = 20; + data->t7_cfg.idle = 100; + return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + } + } + + dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n", + data->t7_cfg.active, data->t7_cfg.idle); + return 0; +} + static int mxt_configure_objects(struct mxt_data *data, const struct firmware *cfg) { @@ -2058,6 +2066,12 @@ static int mxt_configure_objects(struct mxt_data *data, struct mxt_info *info = &data->info; int error; + error = mxt_init_t7_power_cfg(data); + if (error) { + dev_err(dev, "Failed to initialize power cfg\n"); + return error; + } + if (cfg) { error = mxt_update_cfg(data, cfg); if (error) @@ -2346,14 +2360,41 @@ static const struct attribute_group mxt_attr_group = { static void mxt_start(struct mxt_data *data) { - /* Touch enable */ - mxt_write_object(data, data->multitouch, MXT_TOUCH_CTRL, 0x83); + switch (data->pdata->suspend_mode) { + case MXT_SUSPEND_T9_CTRL: + mxt_soft_reset(data); + + /* Touch enable */ + /* 0x83 = SCANEN | RPTEN | ENABLE */ + mxt_write_object(data, + MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83); + break; + + case MXT_SUSPEND_DEEP_SLEEP: + default: + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + + /* Recalibrate since chip has been in deep sleep */ + mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + break; + } + } static void mxt_stop(struct mxt_data *data) { - /* Touch disable */ - mxt_write_object(data, data->multitouch, MXT_TOUCH_CTRL, 0); + switch (data->pdata->suspend_mode) { + case MXT_SUSPEND_T9_CTRL: + /* Touch disable */ + mxt_write_object(data, + MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0); + break; + + case MXT_SUSPEND_DEEP_SLEEP: + default: + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + break; + } } static int mxt_input_open(struct input_dev *dev) @@ -2376,19 +2417,18 @@ static void mxt_input_close(struct input_dev *dev) static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client) { struct mxt_platform_data *pdata; + struct device_node *np = client->dev.of_node; u32 *keymap; - u32 keycode; - int proplen, i, ret; + int proplen, ret; - if (!client->dev.of_node) + if (!np) return ERR_PTR(-ENOENT); pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); - if (of_find_property(client->dev.of_node, "linux,gpio-keymap", - &proplen)) { + if (of_find_property(np, "linux,gpio-keymap", &proplen)) { pdata->t19_num_keys = proplen / sizeof(u32); keymap = devm_kzalloc(&client->dev, @@ -2397,18 +2437,17 @@ static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client) if (!keymap) return ERR_PTR(-ENOMEM); - for (i = 0; i < pdata->t19_num_keys; i++) { - ret = of_property_read_u32_index(client->dev.of_node, - "linux,gpio-keymap", i, &keycode); - if (ret) - keycode = KEY_RESERVED; - - keymap[i] = keycode; - } + ret = of_property_read_u32_array(np, "linux,gpio-keymap", + keymap, pdata->t19_num_keys); + if (ret) + dev_warn(&client->dev, + "Couldn't read linux,gpio-keymap: %d\n", ret); pdata->t19_keymap = keymap; } + pdata->suspend_mode = MXT_SUSPEND_DEEP_SLEEP; + return pdata; } #else @@ -2609,6 +2648,9 @@ static int __maybe_unused mxt_suspend(struct device *dev) struct mxt_data *data = i2c_get_clientdata(client); struct input_dev *input_dev = data->input_dev; + if (!input_dev) + return 0; + mutex_lock(&input_dev->mutex); if (input_dev->users) @@ -2625,7 +2667,8 @@ static int __maybe_unused mxt_resume(struct device *dev) struct mxt_data *data = i2c_get_clientdata(client); struct input_dev *input_dev = data->input_dev; - mxt_soft_reset(data); + if (!input_dev) + return 0; mutex_lock(&input_dev->mutex); @@ -2666,7 +2709,6 @@ MODULE_DEVICE_TABLE(i2c, mxt_id); static struct i2c_driver mxt_driver = { .driver = { .name = "atmel_mxt_ts", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mxt_of_match), .acpi_match_table = ACPI_PTR(mxt_acpi_id), .pm = &mxt_pm_ops, diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 40e02dd5b2f9..38c06f754acd 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -686,7 +686,6 @@ MODULE_DEVICE_TABLE(of, auo_pixcir_ts_dt_idtable); static struct i2c_driver auo_pixcir_driver = { .driver = { - .owner = THIS_MODULE, .name = "auo_pixcir_ts", .pm = &auo_pixcir_pm_ops, .of_match_table = of_match_ptr(auo_pixcir_ts_dt_idtable), diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c index b9b5ddad6658..931417eb4f5a 100644 --- a/drivers/input/touchscreen/bu21013_ts.c +++ b/drivers/input/touchscreen/bu21013_ts.c @@ -716,7 +716,6 @@ MODULE_DEVICE_TABLE(i2c, bu21013_id); static struct i2c_driver bu21013_driver = { .driver = { .name = DRIVER_TP, - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &bu21013_dev_pm_ops, #endif diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c index 32e9db0e04bf..22a6fead8cfb 100644 --- a/drivers/input/touchscreen/chipone_icn8318.c +++ b/drivers/input/touchscreen/chipone_icn8318.c @@ -300,7 +300,6 @@ MODULE_DEVICE_TABLE(i2c, icn8318_i2c_id); static struct i2c_driver icn8318_driver = { .driver = { - .owner = THIS_MODULE, .name = "chipone_icn8318", .pm = &icn8318_pm_ops, .of_match_table = icn8318_of_match, diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index f2119ee0e21b..cc1d1350074e 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -347,7 +347,6 @@ MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable); static struct i2c_driver cy8ctmg110_driver = { .driver = { - .owner = THIS_MODULE, .name = CY8CTMG110_DRIVER_NAME, .pm = &cy8ctmg110_pm, }, diff --git a/drivers/input/touchscreen/cyttsp4_i2c.c b/drivers/input/touchscreen/cyttsp4_i2c.c index 8e2012c79058..9a323dd915de 100644 --- a/drivers/input/touchscreen/cyttsp4_i2c.c +++ b/drivers/input/touchscreen/cyttsp4_i2c.c @@ -74,7 +74,6 @@ MODULE_DEVICE_TABLE(i2c, cyttsp4_i2c_id); static struct i2c_driver cyttsp4_i2c_driver = { .driver = { .name = CYTTSP4_I2C_NAME, - .owner = THIS_MODULE, .pm = &cyttsp4_pm_ops, }, .probe = cyttsp4_i2c_probe, diff --git a/drivers/input/touchscreen/cyttsp_i2c.c b/drivers/input/touchscreen/cyttsp_i2c.c index 63104a86a9bd..519e2de2f8df 100644 --- a/drivers/input/touchscreen/cyttsp_i2c.c +++ b/drivers/input/touchscreen/cyttsp_i2c.c @@ -74,7 +74,6 @@ MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id); static struct i2c_driver cyttsp_i2c_driver = { .driver = { .name = CY_I2C_NAME, - .owner = THIS_MODULE, .pm = &cyttsp_pm_ops, }, .probe = cyttsp_i2c_probe, diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 394b1de9a2a3..48de1e8b3c93 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -1041,7 +1041,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, 0, tsdata->num_y * 64 - 1, 0, 0); if (!pdata) - touchscreen_parse_of_params(input, true); + touchscreen_parse_properties(input, true); error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, INPUT_MT_DIRECT); if (error) { @@ -1134,7 +1134,6 @@ MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match); static struct i2c_driver edt_ft5x06_ts_driver = { .driver = { - .owner = THIS_MODULE, .name = "edt_ft5x06", .of_match_table = of_match_ptr(edt_ft5x06_of_match), .pm = &edt_ft5x06_ts_pm_ops, diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index 4c56299284ef..1afc08b08155 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -264,11 +264,11 @@ static const struct of_device_id egalax_ts_dt_ids[] = { { .compatible = "eeti,egalax_ts" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, egalax_ts_dt_ids); static struct i2c_driver egalax_ts_driver = { .driver = { .name = "egalax_ts", - .owner = THIS_MODULE, .pm = &egalax_ts_pm_ops, .of_match_table = egalax_ts_dt_ids, }, diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c index 0efd766a545b..ddac134b25b1 100644 --- a/drivers/input/touchscreen/elants_i2c.c +++ b/drivers/input/touchscreen/elants_i2c.c @@ -38,6 +38,8 @@ #include <linux/input/mt.h> #include <linux/acpi.h> #include <linux/of.h> +#include <linux/gpio/consumer.h> +#include <linux/regulator/consumer.h> #include <asm/unaligned.h> /* Device, Driver information */ @@ -102,6 +104,9 @@ /* calibration timeout definition */ #define ELAN_CALI_TIMEOUT_MSEC 10000 +#define ELAN_POWERON_DELAY_USEC 500 +#define ELAN_RESET_DELAY_MSEC 20 + enum elants_state { ELAN_STATE_NORMAL, ELAN_WAIT_QUEUE_HEADER, @@ -118,6 +123,10 @@ struct elants_data { struct i2c_client *client; struct input_dev *input; + struct regulator *vcc33; + struct regulator *vccio; + struct gpio_desc *reset_gpio; + u16 fw_version; u8 test_version; u8 solution_version; @@ -141,6 +150,7 @@ struct elants_data { u8 buf[MAX_PACKET_SIZE]; bool wake_irq_enabled; + bool keep_power_in_suspend; }; static int elants_i2c_send(struct i2c_client *client, @@ -605,6 +615,7 @@ static int elants_i2c_do_update_firmware(struct i2c_client *client, const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 }; const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 }; const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc }; + const u8 close_idle[] = {0x54, 0x2c, 0x01, 0x01}; u8 buf[HEADER_SIZE]; u16 send_id; int page, n_fw_pages; @@ -617,8 +628,13 @@ static int elants_i2c_do_update_firmware(struct i2c_client *client, } else { /* Start IAP Procedure */ dev_dbg(&client->dev, "Normal IAP procedure\n"); + /* Close idle mode */ + error = elants_i2c_send(client, close_idle, sizeof(close_idle)); + if (error) + dev_err(&client->dev, "Failed close idle: %d\n", error); + msleep(60); elants_i2c_sw_reset(client); - + msleep(20); error = elants_i2c_send(client, enter_iap, sizeof(enter_iap)); } @@ -1052,6 +1068,67 @@ static void elants_i2c_remove_sysfs_group(void *_data) sysfs_remove_group(&ts->client->dev.kobj, &elants_attribute_group); } +static int elants_i2c_power_on(struct elants_data *ts) +{ + int error; + + /* + * If we do not have reset gpio assume platform firmware + * controls regulators and does power them on for us. + */ + if (IS_ERR_OR_NULL(ts->reset_gpio)) + return 0; + + gpiod_set_value_cansleep(ts->reset_gpio, 1); + + error = regulator_enable(ts->vcc33); + if (error) { + dev_err(&ts->client->dev, + "failed to enable vcc33 regulator: %d\n", + error); + goto release_reset_gpio; + } + + error = regulator_enable(ts->vccio); + if (error) { + dev_err(&ts->client->dev, + "failed to enable vccio regulator: %d\n", + error); + regulator_disable(ts->vcc33); + goto release_reset_gpio; + } + + /* + * We need to wait a bit after powering on controller before + * we are allowed to release reset GPIO. + */ + udelay(ELAN_POWERON_DELAY_USEC); + +release_reset_gpio: + gpiod_set_value_cansleep(ts->reset_gpio, 0); + if (error) + return error; + + msleep(ELAN_RESET_DELAY_MSEC); + + return 0; +} + +static void elants_i2c_power_off(void *_data) +{ + struct elants_data *ts = _data; + + if (!IS_ERR_OR_NULL(ts->reset_gpio)) { + /* + * Activate reset gpio to prevent leakage through the + * pin once we shut off power to the controller. + */ + gpiod_set_value_cansleep(ts->reset_gpio, 1); + regulator_disable(ts->vccio); + regulator_disable(ts->vcc33); + } +} + static int elants_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1066,13 +1143,6 @@ static int elants_i2c_probe(struct i2c_client *client, return -ENXIO; } - /* Make sure there is something at this address */ - if (i2c_smbus_xfer(client->adapter, client->addr, 0, - I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0) { - dev_err(&client->dev, "nothing at this address\n"); - return -ENXIO; - } - ts = devm_kzalloc(&client->dev, sizeof(struct elants_data), GFP_KERNEL); if (!ts) return -ENOMEM |
