From de901cc31d151c4c855346c29fb61eaf5ffac3ad Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 15 Jan 2017 14:51:12 -0800 Subject: Input: mpr121 - switch to device tree probe This driver currently only supports legacy platform data probe. This change adds device tree support and gets rid of platform data probe code since no one is actually using mpr121 platform data in the mainline. The device tree property parsing code is based on the work of atmel_captouch driver. Signed-off-by: Akinobu Mita Signed-off-by: Dmitry Torokhov --- include/linux/i2c/mpr121_touchkey.h | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 include/linux/i2c/mpr121_touchkey.h (limited to 'include') diff --git a/include/linux/i2c/mpr121_touchkey.h b/include/linux/i2c/mpr121_touchkey.h deleted file mode 100644 index f0bcc38bbb97..000000000000 --- a/include/linux/i2c/mpr121_touchkey.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Header file for Freescale MPR121 Capacitive Touch Sensor */ - -#ifndef _MPR121_TOUCHKEY_H -#define _MPR121_TOUCHKEY_H - -/** - * struct mpr121_platform_data - platform data for mpr121 sensor - * @keymap: pointer to array of KEY_* values representing keymap - * @keymap_size: size of the keymap - * @wakeup: configure the button as a wake-up source - * @vdd_uv: VDD voltage in uV - */ -struct mpr121_platform_data { - const unsigned short *keymap; - unsigned int keymap_size; - bool wakeup; - int vdd_uv; -}; - -#endif /* _MPR121_TOUCHKEY_H */ -- cgit v1.2.3 From aef01aad89e457e34a60ff6e8fd69ff6740cf201 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 11 Nov 2016 12:43:12 -0800 Subject: Input: matrix-keypad - switch to using generic device properties Instead of being OF-specific, let's switch to using generic device properties, which will make this code usable on ACPI, device tree and legacy boards that use property sets. As part of the change let's rename matrix_keypad_parse_of_params() to matrix_keypad_parse_properties(). Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/bcm-keypad.c | 2 +- drivers/input/keyboard/cros_ec_keyb.c | 3 +- drivers/input/keyboard/lpc32xx-keys.c | 2 +- drivers/input/keyboard/omap4-keypad.c | 4 +- drivers/input/keyboard/pmic8xxx-keypad.c | 2 +- drivers/input/keyboard/pxa27x_keypad.c | 2 +- drivers/input/keyboard/st-keyscan.c | 4 +- drivers/input/keyboard/stmpe-keypad.c | 2 +- drivers/input/keyboard/tca8418_keypad.c | 2 +- drivers/input/keyboard/twl4030_keypad.c | 4 +- drivers/input/matrix-keymap.c | 109 ++++++++++++++++--------------- include/linux/input/matrix_keypad.h | 21 +----- 12 files changed, 73 insertions(+), 84 deletions(-) (limited to 'include') diff --git a/drivers/input/keyboard/bcm-keypad.c b/drivers/input/keyboard/bcm-keypad.c index 2b4e63d81e6d..e1cf63ee148f 100644 --- a/drivers/input/keyboard/bcm-keypad.c +++ b/drivers/input/keyboard/bcm-keypad.c @@ -213,7 +213,7 @@ static int bcm_kp_matrix_key_parse_dt(struct bcm_kp *kp) /* Initialize the KPCR Keypad Configuration Register */ kp->kpcr = KPCR_STATUSFILTERENABLE | KPCR_COLFILTERENABLE; - error = matrix_keypad_parse_of_params(dev, &kp->n_rows, &kp->n_cols); + error = matrix_keypad_parse_properties(dev, &kp->n_rows, &kp->n_cols); if (error) { dev_err(dev, "failed to parse kp params\n"); return error; diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 87d071ae21da..780977dcf92d 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -229,7 +229,8 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; - err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols); + + err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols); if (err) return err; diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 632523d4f5dc..1dd57ac0e7a2 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -145,7 +145,7 @@ static int lpc32xx_parse_dt(struct device *dev, u32 rows = 0, columns = 0; int err; - err = matrix_keypad_parse_of_params(dev, &rows, &columns); + err = matrix_keypad_parse_properties(dev, &rows, &columns); if (err) return err; if (rows != columns) { diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 9ecb16701b13..ebc67ba41fe2 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -223,8 +223,8 @@ static int omap4_keypad_parse_dt(struct device *dev, struct device_node *np = dev->of_node; int err; - err = matrix_keypad_parse_of_params(dev, &keypad_data->rows, - &keypad_data->cols); + err = matrix_keypad_parse_properties(dev, &keypad_data->rows, + &keypad_data->cols); if (err) return err; diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 5c68e3f096bc..97c5424f49b9 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -515,7 +515,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) int rc; unsigned int ctrl_val; - rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); + rc = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols); if (rc) return rc; diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index e24443376e75..3841fa30db33 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -126,7 +126,7 @@ static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad, u32 rows, cols; int error; - error = matrix_keypad_parse_of_params(dev, &rows, &cols); + error = matrix_keypad_parse_properties(dev, &rows, &cols); if (error) return error; diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c index de7be4f03d91..babcfb165e4f 100644 --- a/drivers/input/keyboard/st-keyscan.c +++ b/drivers/input/keyboard/st-keyscan.c @@ -106,8 +106,8 @@ static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data) struct device_node *np = dev->of_node; int error; - error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows, - &keypad_data->n_cols); + error = matrix_keypad_parse_properties(dev, &keypad_data->n_rows, + &keypad_data->n_cols); if (error) { dev_err(dev, "failed to parse keypad params\n"); return error; diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index fe6e3f22eed7..8c6c0b9109c7 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -354,7 +354,7 @@ static int stmpe_keypad_probe(struct platform_device *pdev) input->id.bustype = BUS_I2C; input->dev.parent = &pdev->dev; - error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); + error = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols); if (error) return error; diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 9f6308fac0b4..ccff9d1b7135 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -295,7 +295,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, struct device_node *np = dev->of_node; int err; - err = matrix_keypad_parse_of_params(dev, &rows, &cols); + err = matrix_keypad_parse_properties(dev, &rows, &cols); if (err) return err; rep = of_property_read_bool(np, "keypad,autorepeat"); diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 29396ca69416..39e72b3219d8 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -374,8 +374,8 @@ static int twl4030_kp_probe(struct platform_device *pdev) kp->autorepeat = pdata->rep; keymap_data = pdata->keymap_data; } else { - error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows, - &kp->n_cols); + error = matrix_keypad_parse_properties(&pdev->dev, &kp->n_rows, + &kp->n_cols); if (error) return error; diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 08b61f506db6..8ccefc15c7a4 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c @@ -14,18 +14,18 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * */ #include +#include #include -#include -#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include static bool matrix_keypad_map_key(struct input_dev *input_dev, unsigned int rows, unsigned int cols, @@ -49,18 +49,22 @@ static bool matrix_keypad_map_key(struct input_dev *input_dev, return true; } -#ifdef CONFIG_OF -int matrix_keypad_parse_of_params(struct device *dev, - unsigned int *rows, unsigned int *cols) +/** + * matrix_keypad_parse_properties() - Read properties of matrix keypad + * + * @dev: Device containing properties + * @rows: Returns number of matrix rows + * @cols: Returns number of matrix columns + * @return 0 if OK, <0 on error + */ +int matrix_keypad_parse_properties(struct device *dev, + unsigned int *rows, unsigned int *cols) { - struct device_node *np = dev->of_node; + *rows = *cols = 0; + + device_property_read_u32(dev, "keypad,num-rows", rows); + device_property_read_u32(dev, "keypad,num-columns", cols); - if (!np) { - dev_err(dev, "missing DT data"); - return -EINVAL; - } - of_property_read_u32(np, "keypad,num-rows", rows); - of_property_read_u32(np, "keypad,num-columns", cols); if (!*rows || !*cols) { dev_err(dev, "number of keypad rows/columns not specified\n"); return -EINVAL; @@ -68,62 +72,61 @@ int matrix_keypad_parse_of_params(struct device *dev, return 0; } -EXPORT_SYMBOL_GPL(matrix_keypad_parse_of_params); +EXPORT_SYMBOL_GPL(matrix_keypad_parse_properties); -static int matrix_keypad_parse_of_keymap(const char *propname, - unsigned int rows, unsigned int cols, - struct input_dev *input_dev) +static int matrix_keypad_parse_keymap(const char *propname, + unsigned int rows, unsigned int cols, + struct input_dev *input_dev) { struct device *dev = input_dev->dev.parent; - struct device_node *np = dev->of_node; unsigned int row_shift = get_count_order(cols); unsigned int max_keys = rows << row_shift; - unsigned int proplen, i, size; - const __be32 *prop; - - if (!np) - return -ENOENT; + u32 *keys; + int i; + int size; + int retval; if (!propname) propname = "linux,keymap"; - prop = of_get_property(np, propname, &proplen); - if (!prop) { - dev_err(dev, "OF: %s property not defined in %s\n", - propname, np->full_name); - return -ENOENT; + size = device_property_read_u32_array(dev, propname, NULL, 0); + if (size <= 0) { + dev_err(dev, "missing or malformed property %s: %d\n", + propname, size); + return size < 0 ? size : -EINVAL; } - if (proplen % sizeof(u32)) { - dev_err(dev, "OF: Malformed keycode property %s in %s\n", - propname, np->full_name); + if (size > max_keys) { + dev_err(dev, "%s size overflow (%d vs max %u)\n", + propname, size, max_keys); return -EINVAL; } - size = proplen / sizeof(u32); - if (size > max_keys) { - dev_err(dev, "OF: %s size overflow\n", propname); - return -EINVAL; + keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL); + if (!keys) + return -ENOMEM; + + retval = device_property_read_u32_array(dev, propname, keys, size); + if (retval) { + dev_err(dev, "failed to read %s property: %d\n", + propname, retval); + goto out; } for (i = 0; i < size; i++) { - unsigned int key = be32_to_cpup(prop + i); - if (!matrix_keypad_map_key(input_dev, rows, cols, - row_shift, key)) - return -EINVAL; + row_shift, keys[i])) { + retval = -EINVAL; + goto out; + } } - return 0; -} -#else -static int matrix_keypad_parse_of_keymap(const char *propname, - unsigned int rows, unsigned int cols, - struct input_dev *input_dev) -{ - return -ENOSYS; + retval = 0; + +out: + kfree(keys); + return retval; } -#endif /** * matrix_keypad_build_keymap - convert platform keymap into matrix keymap @@ -192,8 +195,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, return -EINVAL; } } else { - error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols, - input_dev); + error = matrix_keypad_parse_keymap(keymap_name, rows, cols, + input_dev); if (error) return error; } diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 27e06acc509a..37b04a0fdea4 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -80,24 +80,9 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, unsigned int rows, unsigned int cols, unsigned short *keymap, struct input_dev *input_dev); +int matrix_keypad_parse_properties(struct device *dev, + unsigned int *rows, unsigned int *cols); -#ifdef CONFIG_OF -/** - * matrix_keypad_parse_of_params() - Read parameters from matrix-keypad node - * - * @dev: Device containing of_node - * @rows: Returns number of matrix rows - * @cols: Returns number of matrix columns - * @return 0 if OK, <0 on error - */ -int matrix_keypad_parse_of_params(struct device *dev, - unsigned int *rows, unsigned int *cols); -#else -static inline int matrix_keypad_parse_of_params(struct device *dev, - unsigned int *rows, unsigned int *cols) -{ - return -ENOSYS; -} -#endif /* CONFIG_OF */ +#define matrix_keypad_parse_of_params matrix_keypad_parse_properties #endif /* _MATRIX_KEYPAD_H */ -- cgit v1.2.3 From 8b1a315b35a961198336b944635c6936321b4a77 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 17 Jan 2017 14:18:50 -0800 Subject: Input: tca8418 - switch to using generic device properties Let's drop legacy platform data support (there are no users in mainline) and switch to using generic device properties, which will make the driver simpler (non-OF boards can use property sets to describe hardware). Reviewed-by: Maxime Ripard Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tca8418_keypad.c | 90 ++++++++++----------------------- include/linux/input/tca8418_keypad.h | 44 ---------------- 2 files changed, 26 insertions(+), 108 deletions(-) delete mode 100644 include/linux/input/tca8418_keypad.h (limited to 'include') diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index ccff9d1b7135..44dd7689c571 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -24,18 +24,17 @@ * alternative licensing inquiries. */ -#include -#include -#include #include -#include -#include -#include -#include #include +#include #include -#include +#include +#include +#include #include +#include +#include +#include /* TCA8418 hardware limits */ #define TCA8418_MAX_ROWS 8 @@ -264,43 +263,25 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data, } static int tca8418_keypad_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct device *dev = &client->dev; - const struct tca8418_keypad_platform_data *pdata = - dev_get_platdata(dev); struct tca8418_keypad *keypad_data; struct input_dev *input; - const struct matrix_keymap_data *keymap_data = NULL; u32 rows = 0, cols = 0; - bool rep = false; - bool irq_is_gpio = false; - int irq; int error, row_shift, max_keys; - unsigned long trigger = 0; - /* Copy the platform data */ - if (pdata) { - if (!pdata->keymap_data) { - dev_err(dev, "no keymap data defined\n"); - return -EINVAL; - } - keymap_data = pdata->keymap_data; - rows = pdata->rows; - cols = pdata->cols; - rep = pdata->rep; - irq_is_gpio = pdata->irq_is_gpio; - trigger = IRQF_TRIGGER_FALLING; - } else { - struct device_node *np = dev->of_node; - int err; - - err = matrix_keypad_parse_properties(dev, &rows, &cols); - if (err) - return err; - rep = of_property_read_bool(np, "keypad,autorepeat"); + /* Check i2c driver capabilities */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { + dev_err(dev, "%s adapter not supported\n", + dev_driver_string(&client->adapter->dev)); + return -ENODEV; } + error = matrix_keypad_parse_properties(dev, &rows, &cols); + if (error) + return error; + if (!rows || rows > TCA8418_MAX_ROWS) { dev_err(dev, "invalid rows\n"); return -EINVAL; @@ -311,13 +292,6 @@ static int tca8418_keypad_probe(struct i2c_client *client, return -EINVAL; } - /* Check i2c driver capabilities */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { - dev_err(dev, "%s adapter not supported\n", - dev_driver_string(&client->adapter->dev)); - return -ENODEV; - } - row_shift = get_count_order(cols); max_keys = rows << row_shift; @@ -347,23 +321,20 @@ static int tca8418_keypad_probe(struct i2c_client *client, input->id.product = 0x001; input->id.version = 0x0001; - error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, - NULL, input); + error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL, input); if (error) { dev_err(dev, "Failed to build keymap\n"); return error; } - if (rep) + if (device_property_read_bool(dev, "keypad,autorepeat")) __set_bit(EV_REP, input->evbit); - input_set_capability(input, EV_MSC, MSC_SCAN); - irq = client->irq; - if (irq_is_gpio) - irq = gpio_to_irq(irq); + input_set_capability(input, EV_MSC, MSC_SCAN); - error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, - trigger | IRQF_SHARED | IRQF_ONESHOT, + error = devm_request_threaded_irq(dev, client->irq, + NULL, tca8418_irq_handler, + IRQF_SHARED | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", @@ -382,30 +353,21 @@ static int tca8418_keypad_probe(struct i2c_client *client, } static const struct i2c_device_id tca8418_id[] = { - { TCA8418_NAME, 8418, }, + { "tca8418", 8418, }, { } }; MODULE_DEVICE_TABLE(i2c, tca8418_id); -#ifdef CONFIG_OF static const struct of_device_id tca8418_dt_ids[] = { { .compatible = "ti,tca8418", }, { } }; MODULE_DEVICE_TABLE(of, tca8418_dt_ids); -/* - * The device tree based i2c loader looks for - * "i2c:" + second_component_of(property("compatible")) - * and therefore we need an alias to be found. - */ -MODULE_ALIAS("i2c:tca8418"); -#endif - static struct i2c_driver tca8418_keypad_driver = { .driver = { - .name = TCA8418_NAME, - .of_match_table = of_match_ptr(tca8418_dt_ids), + .name = "tca8418_keypad", + .of_match_table = tca8418_dt_ids, }, .probe = tca8418_keypad_probe, .id_table = tca8418_id, diff --git a/include/linux/input/tca8418_keypad.h b/include/linux/input/tca8418_keypad.h deleted file mode 100644 index e71a85dc2cbd..000000000000 --- a/include/linux/input/tca8418_keypad.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * TCA8418 keypad platform support - * - * Copyright (C) 2011 Fuel7, Inc. All rights reserved. - * - * Author: Kyle Manna - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * If you can't comply with GPLv2, alternative licensing terms may be - * arranged. Please contact Fuel7, Inc. (http://fuel7.com/) for proprietary - * alternative licensing inquiries. - */ - -#ifndef _TCA8418_KEYPAD_H -#define _TCA8418_KEYPAD_H - -#include -#include - -#define TCA8418_I2C_ADDR 0x34 -#define TCA8418_NAME "tca8418_keypad" - -struct tca8418_keypad_platform_data { - const struct matrix_keymap_data *keymap_data; - unsigned rows; - unsigned cols; - bool rep; - bool irq_is_gpio; -}; - -#endif -- cgit v1.2.3 From 19ba1eb15a2a9b7298d1d984043025ab9496fbfb Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 7 Feb 2017 23:58:02 -0800 Subject: Input: psmouse - add a custom serio protocol to send extra information The tracksticks on the Lenovo thinkpads have their buttons connected through the touchpad device. We already fixed that in synaptics.c, but when we switch the device into RMI4 mode to have proper support, the pass-through functionality can't deal with them easily. We add a new PS/2 flag and protocol designed for psmouse. The RMI4 F03 pass-through can then emit a special set of commands to notify psmouse the state of the buttons. This patch implements the protocol in psmouse, while an other will do the same for rmi4-f03. Signed-off-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 41 +++++++++++++++++++++++++++++++++++--- drivers/input/mouse/psmouse.h | 5 +++++ include/uapi/linux/serio.h | 7 ++++--- 3 files changed, 47 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index bee267424972..a598b7223cef 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -127,6 +127,13 @@ struct psmouse_protocol { int (*init)(struct psmouse *); }; +static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons) +{ + input_report_key(dev, BTN_LEFT, buttons & BIT(0)); + input_report_key(dev, BTN_MIDDLE, buttons & BIT(2)); + input_report_key(dev, BTN_RIGHT, buttons & BIT(1)); +} + /* * psmouse_process_byte() analyzes the PS/2 data stream and reports * relevant events to the input module once full packet has arrived. @@ -199,9 +206,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) } /* Generic PS/2 Mouse */ - input_report_key(dev, BTN_LEFT, packet[0] & 1); - input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); - input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); + psmouse_report_standard_buttons(dev, + packet[0] | psmouse->extra_buttons); input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); @@ -282,6 +288,30 @@ static int psmouse_handle_byte(struct psmouse *psmouse) return 0; } +static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data) +{ + switch (psmouse->oob_data_type) { + case PSMOUSE_OOB_NONE: + psmouse->oob_data_type = data; + break; + + case PSMOUSE_OOB_EXTRA_BTNS: + psmouse_report_standard_buttons(psmouse->dev, data); + input_sync(psmouse->dev); + + psmouse->extra_buttons = data; + psmouse->oob_data_type = PSMOUSE_OOB_NONE; + break; + + default: + psmouse_warn(psmouse, + "unknown OOB_DATA type: 0x%02x\n", + psmouse->oob_data_type); + psmouse->oob_data_type = PSMOUSE_OOB_NONE; + break; + } +} + /* * psmouse_interrupt() handles incoming characters, either passing them * for normal processing or gathering them as command response. @@ -306,6 +336,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, goto out; } + if (flags & SERIO_OOB_DATA) { + psmouse_handle_oob_data(psmouse, data); + goto out; + } + if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK)) if (ps2_handle_ack(&psmouse->ps2dev, data)) goto out; diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index e0ca6cda3d16..8c83b8e2505c 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -1,6 +1,9 @@ #ifndef _PSMOUSE_H #define _PSMOUSE_H +#define PSMOUSE_OOB_NONE 0x00 +#define PSMOUSE_OOB_EXTRA_BTNS 0x01 + #define PSMOUSE_CMD_SETSCALE11 0x00e6 #define PSMOUSE_CMD_SETSCALE21 0x00e7 #define PSMOUSE_CMD_SETRES 0x10e8 @@ -53,6 +56,8 @@ struct psmouse { unsigned char pktcnt; unsigned char pktsize; unsigned char type; + unsigned char oob_data_type; + unsigned char extra_buttons; bool ignore_parity; bool acks_disable_command; unsigned int model; diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h index f2447a83ac8d..ccd0ccd00f47 100644 --- a/include/uapi/linux/serio.h +++ b/include/uapi/linux/serio.h @@ -17,9 +17,10 @@ /* * bit masks for use in "interrupt" flags (3rd argument) */ -#define SERIO_TIMEOUT 1 -#define SERIO_PARITY 2 -#define SERIO_FRAME 4 +#define SERIO_TIMEOUT BIT(0) +#define SERIO_PARITY BIT(1) +#define SERIO_FRAME BIT(2) +#define SERIO_OOB_DATA BIT(3) /* * Serio types -- cgit v1.2.3 From d0d89493bff8b7c7bf580197a44a1d49c50395b3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 10 Feb 2017 15:18:07 -0800 Subject: Input: tsc2004/5 - switch to using generic device properties Instead of supporting legacy platform data (of which we have no mainline users) and OF-based properties, let's switch to generic device properties. This will still allow legacy boards to use the driver (by defining property sets and attaching them to the drivers) and will simplify probe and make driver usable on ACPI-based systems as well. Reviewed-By: Sebastian Reichel Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tsc200x-core.c | 93 +++++++++++--------------------- include/linux/spi/tsc2005.h | 34 ------------ 2 files changed, 30 insertions(+), 97 deletions(-) delete mode 100644 include/linux/spi/tsc2005.h (limited to 'include') diff --git a/drivers/input/touchscreen/tsc200x-core.c b/drivers/input/touchscreen/tsc200x-core.c index 1c14a38e3748..88ea5e1b72ae 100644 --- a/drivers/input/touchscreen/tsc200x-core.c +++ b/drivers/input/touchscreen/tsc200x-core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -114,7 +113,6 @@ struct tsc200x { struct regulator *vio; struct gpio_desc *reset_gpio; - void (*set_reset)(bool enable); int (*tsc200x_cmd)(struct device *dev, u8 cmd); int irq; }; @@ -227,12 +225,13 @@ static void tsc200x_stop_scan(struct tsc200x *ts) ts->tsc200x_cmd(ts->dev, TSC200X_CMD_STOP); } -static void tsc200x_set_reset(struct tsc200x *ts, bool enable) +static void tsc200x_reset(struct tsc200x *ts) { - if (ts->reset_gpio) - gpiod_set_value_cansleep(ts->reset_gpio, enable); - else if (ts->set_reset) - ts->set_reset(enable); + if (ts->reset_gpio) { + gpiod_set_value_cansleep(ts->reset_gpio, 1); + usleep_range(100, 500); /* only 10us required */ + gpiod_set_value_cansleep(ts->reset_gpio, 0); + } } /* must be called with ts->mutex held */ @@ -253,7 +252,7 @@ static void __tsc200x_enable(struct tsc200x *ts) { tsc200x_start_scan(ts); - if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) { + if (ts->esd_timeout && ts->reset_gpio) { ts->last_valid_interrupt = jiffies; schedule_delayed_work(&ts->esd_work, round_jiffies_relative( @@ -310,9 +309,7 @@ static ssize_t tsc200x_selftest_show(struct device *dev, } /* hardware reset */ - tsc200x_set_reset(ts, false); - usleep_range(100, 500); /* only 10us required */ - tsc200x_set_reset(ts, true); + tsc200x_reset(ts); if (!success) goto out; @@ -354,7 +351,7 @@ static umode_t tsc200x_attr_is_visible(struct kobject *kobj, umode_t mode = attr->mode; if (attr == &dev_attr_selftest.attr) { - if (!ts->set_reset && !ts->reset_gpio) + if (!ts->reset_gpio) mode = 0; } @@ -404,9 +401,7 @@ static void tsc200x_esd_work(struct work_struct *work) tsc200x_update_pen_state(ts, 0, 0, 0); - tsc200x_set_reset(ts, false); - usleep_range(100, 500); /* only 10us required */ - tsc200x_set_reset(ts, true); + tsc200x_reset(ts); enable_irq(ts->irq); tsc200x_start_scan(ts); @@ -454,26 +449,12 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, struct regmap *regmap, int (*tsc200x_cmd)(struct device *dev, u8 cmd)) { - const struct tsc2005_platform_data *pdata = dev_get_platdata(dev); - struct device_node *np = dev->of_node; - struct tsc200x *ts; struct input_dev *input_dev; - unsigned int max_x = MAX_12BIT; - unsigned int max_y = MAX_12BIT; - unsigned int max_p = MAX_12BIT; - unsigned int fudge_x = TSC200X_DEF_X_FUZZ; - unsigned int fudge_y = TSC200X_DEF_Y_FUZZ; - unsigned int fudge_p = TSC200X_DEF_P_FUZZ; - unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR; - unsigned int esd_timeout; + u32 x_plate_ohm; + u32 esd_timeout; int error; - if (!np && !pdata) { - dev_err(dev, "no platform data\n"); - return -ENODEV; - } - if (irq <= 0) { dev_err(dev, "no irq\n"); return -ENODEV; @@ -487,23 +468,6 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, return -ENODEV; } - if (pdata) { - fudge_x = pdata->ts_x_fudge; - fudge_y = pdata->ts_y_fudge; - fudge_p = pdata->ts_pressure_fudge; - max_x = pdata->ts_x_max; - max_y = pdata->ts_y_max; - max_p = pdata->ts_pressure_max; - x_plate_ohm = pdata->ts_x_plate_ohm; - esd_timeout = pdata->esd_timeout_ms; - } else { - x_plate_ohm = TSC200X_DEF_RESISTOR; - of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm); - esd_timeout = 0; - of_property_read_u32(np, "ti,esd-recovery-timeout-ms", - &esd_timeout); - } - ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; @@ -517,8 +481,13 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, ts->idev = input_dev; ts->regmap = regmap; ts->tsc200x_cmd = tsc200x_cmd; - ts->x_plate_ohm = x_plate_ohm; - ts->esd_timeout = esd_timeout; + + error = device_property_read_u32(dev, "ti,x-plate-ohms", &x_plate_ohm); + ts->x_plate_ohm = error ? TSC200X_DEF_RESISTOR : x_plate_ohm; + + error = device_property_read_u32(dev, "ti,esd-recovery-timeout-ms", + &esd_timeout); + ts->esd_timeout = error ? 0 : esd_timeout; ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ts->reset_gpio)) { @@ -534,9 +503,6 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, return error; } - if (!ts->reset_gpio && pdata) - ts->set_reset = pdata->set_reset; - mutex_init(&ts->mutex); spin_lock_init(&ts->lock); @@ -559,22 +525,23 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, input_dev->phys = ts->phys; input_dev->id = *tsc_id; - input_dev->dev.parent = dev; - input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - - input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0); - input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); - - if (np) - touchscreen_parse_properties(input_dev, false, NULL); input_dev->open = tsc200x_open; input_dev->close = tsc200x_close; input_set_drvdata(input_dev, ts); + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); + + input_set_abs_params(input_dev, ABS_X, + 0, MAX_12BIT, TSC200X_DEF_X_FUZZ, 0); + input_set_abs_params(input_dev, ABS_Y, + 0, MAX_12BIT, TSC200X_DEF_Y_FUZZ, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, + 0, MAX_12BIT, TSC200X_DEF_P_FUZZ, 0); + + touchscreen_parse_properties(input_dev, false, NULL); + /* Ensure the touchscreen is off */ tsc200x_stop_scan(ts); diff --git a/include/linux/spi/tsc2005.h b/include/linux/spi/tsc2005.h deleted file mode 100644 index 563b3b1799a8..000000000000 --- a/include/linux/spi/tsc2005.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of TSC2005 touchscreen driver - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _LINUX_SPI_TSC2005_H -#define _LINUX_SPI_TSC2005_H - -#include - -struct tsc2005_platform_data { - int ts_pressure_max; - int ts_pressure_fudge; - int ts_x_max; - int ts_x_fudge; - int ts_y_max; - int ts_y_fudge; - int ts_x_plate_ohm; - unsigned int esd_timeout_ms; - void (*set_reset)(bool enable); -}; - -#endif -- cgit v1.2.3