diff options
| -rw-r--r-- | Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt | 53 | ||||
| -rw-r--r-- | drivers/input/touchscreen/ft5x06_ts.c | 157 | ||||
| -rw-r--r-- | include/linux/input/ft5x06_ts.h | 24 |
3 files changed, 226 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt new file mode 100644 index 000000000000..1c7c2c5ea99f --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt @@ -0,0 +1,53 @@ +FocalTech touch controller + +The focaltech controller is connected to host processor +via i2c. The controller generates interrupts when the +user touches the panel. The host controller is expected +to read the touch coordinates over i2c and pass the coordinates +to the rest of the system. + +Required properties: + + - compatible : should be "focaltech,5x06". + - reg : i2c slave address of the device. + - interrupt-parent : parent of interrupt. + - interrupts : touch sample interrupt to indicate presense or release + of fingers on the panel. + - vdd-supply : Power supply needed to power up the device. + - vcc_i2c-supply : Power source required to power up i2c bus. + - focaltech,family-id : family identification of the controller. + - focaltech,irq-gpio : irq gpio which is to provide interrupts to host, + same as "interrupts" node. It will also + contain active low or active high information. + - focaltech,reset-gpio : reset gpio to control the reset of chip. + - focaltech,display-coords : display coordinates in pixels. It is a four + tuple consisting of min x, min y, max x and + max y values. + +Optional properties: + + - focaltech,panel-coords : panel coordinates for the chip in pixels. + It is a four tuple consisting of min x, + min y, max x and max y values. + - focaltech,i2c-pull-up : to specify pull up is required. + - focaltech,no-force-update : to specify force update is allowed. + - focaltech,button-map : button map of key codes. The number + of key codes depend on panel. + +Example: + i2c@f9924000 { + ft5x06_ts@38 { + compatible = "focaltech,5x06"; + reg = <0x38>; + interrupt-parent = <&msmgpio>; + interrupts = <61 0x2>; + vdd-supply = <&pm8941_l22>; + vcc_i2c-supply = <&pm8941_s3>; + focaltech,reset-gpio = <&msmgpio 60 0x00>; + focaltech,irq-gpio = <&msmgpio 61 0x00>; + focaltech,panel-coords = <0 0 480 800>; + focaltech,display-coords = <0 0 480 800>; + focaltech,button-map= <158 102 139 217>; + focaltech,family-id = <0x0a>; + }; + }; diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c index d619c1d06e9e..79aadf4507b9 100644 --- a/drivers/input/touchscreen/ft5x06_ts.c +++ b/drivers/input/touchscreen/ft5x06_ts.c @@ -3,7 +3,7 @@ * FocalTech ft5x06 TouchScreen driver. * * Copyright (c) 2010 Focal tech Ltd. - * Copyright (c) 2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -24,6 +24,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/regulator/consumer.h> #include <linux/input/ft5x06_ts.h> @@ -51,6 +52,7 @@ #define POINT_READ_BUF (3 + FT_TOUCH_STEP * CFG_MAX_TOUCH_POINTS) /*register address*/ +#define FT5X06_REG_ID 0xA3 #define FT5X06_REG_PMODE 0xA5 #define FT5X06_REG_FW_VER 0xA6 #define FT5X06_REG_POINT_RATE 0x88 @@ -67,6 +69,9 @@ #define FT5X06_I2C_VTG_MIN_UV 1800000 #define FT5X06_I2C_VTG_MAX_UV 1800000 +#define FT5X06_COORDS_ARR_SIZE 4 +#define MAX_BUTTONS 4 + struct ts_event { u16 x[CFG_MAX_TOUCH_POINTS]; /*x coordinate */ u16 y[CFG_MAX_TOUCH_POINTS]; /*y coordinate */ @@ -399,16 +404,137 @@ static const struct dev_pm_ops ft5x06_ts_pm_ops = { }; #endif +#ifdef CONFIG_OF +static int ft5x06_get_dt_coords(struct device *dev, char *name, + struct ft5x06_ts_platform_data *pdata) +{ + u32 coords[FT5X06_COORDS_ARR_SIZE]; + struct property *prop; + struct device_node *np = dev->of_node; + int coords_size, rc; + + prop = of_find_property(np, name, NULL); + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + + coords_size = prop->length / sizeof(u32); + if (coords_size != FT5X06_COORDS_ARR_SIZE) { + dev_err(dev, "invalid %s\n", name); + return -EINVAL; + } + + rc = of_property_read_u32_array(np, name, coords, coords_size); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read %s\n", name); + return rc; + } + + if (!strcmp(name, "focaltech,panel-coords")) { + pdata->panel_minx = coords[0]; + pdata->panel_miny = coords[1]; + pdata->panel_maxx = coords[2]; + pdata->panel_maxy = coords[3]; + } else if (!strcmp(name, "focaltech,display-coords")) { + pdata->x_min = coords[0]; + pdata->y_min = coords[1]; + pdata->x_max = coords[2]; + pdata->y_max = coords[3]; + } else { + dev_err(dev, "unsupported property %s\n", name); + return -EINVAL; + } + + return 0; +} + +static int ft5x06_parse_dt(struct device *dev, + struct ft5x06_ts_platform_data *pdata) +{ + int rc; + struct device_node *np = dev->of_node; + struct property *prop; + u32 temp_val, num_buttons; + u32 button_map[MAX_BUTTONS]; + + rc = ft5x06_get_dt_coords(dev, "focaltech,panel-coords", pdata); + if (rc && (rc != -EINVAL)) + return rc; + + rc = ft5x06_get_dt_coords(dev, "focaltech,display-coords", pdata); + if (rc) + return rc; + + pdata->i2c_pull_up = of_property_read_bool(np, + "focaltech,i2c-pull-up"); + + pdata->no_force_update = of_property_read_bool(np, + "focaltech,no-force-update"); + /* reset, irq gpio info */ + pdata->reset_gpio = of_get_named_gpio_flags(np, "focaltech,reset-gpio", + 0, &pdata->reset_gpio_flags); + if (pdata->reset_gpio < 0) + return pdata->reset_gpio; + + pdata->irq_gpio = of_get_named_gpio_flags(np, "focaltech,irq-gpio", + 0, &pdata->irq_gpio_flags); + if (pdata->irq_gpio < 0) + return pdata->irq_gpio; + + rc = of_property_read_u32(np, "focaltech,family-id", &temp_val); + if (!rc) + pdata->family_id = temp_val; + else + return rc; + + prop = of_find_property(np, "focaltech,button-map", NULL); + if (prop) { + num_buttons = prop->length / sizeof(temp_val); + if (num_buttons > MAX_BUTTONS) + return -EINVAL; + + rc = of_property_read_u32_array(np, + "focaltech,button-map", button_map, + num_buttons); + if (rc) { + dev_err(dev, "Unable to read key codes\n"); + return rc; + } + } + + return 0; +} +#else +static int ft5x06_parse_dt(struct device *dev, + struct ft5x06_ts_platform_data *pdata) +{ + return -ENODEV; +} +#endif + static int ft5x06_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct ft5x06_ts_platform_data *pdata = client->dev.platform_data; + struct ft5x06_ts_platform_data *pdata; struct ft5x06_ts_data *data; struct input_dev *input_dev; u8 reg_value; u8 reg_addr; int err; + if (client->dev.of_node) { + pdata = devm_kzalloc(&client->dev, + sizeof(struct ft5x06_ts_platform_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + err = ft5x06_parse_dt(&client->dev, pdata); + if (err) + return err; + } else + pdata = client->dev.platform_data; + if (!pdata) { dev_err(&client->dev, "Invalid pdata\n"); return -EINVAL; @@ -446,9 +572,9 @@ static int ft5x06_ts_probe(struct i2c_client *client, __set_bit(BTN_TOUCH, input_dev->keybit); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, + input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min, pdata->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min, pdata->y_max, 0, 0); input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, CFG_MAX_TOUCH_POINTS, 0, 0); @@ -523,6 +649,19 @@ static int ft5x06_ts_probe(struct i2c_client *client, /* make sure CTP already finish startup process */ msleep(FT_STARTUP_DLY); + /* check the controller id */ + reg_addr = FT5X06_REG_ID; + err = ft5x06_i2c_read(client, ®_addr, 1, ®_value, 1); + if (err < 0) { + dev_err(&client->dev, "version read failed"); + return err; + } + + if (pdata->family_id != reg_value) { + dev_err(&client->dev, "%s:Unsupported controller\n", __func__); + goto free_reset_gpio; + } + /*get some register information */ reg_addr = FT5X06_REG_FW_VER; err = ft5x06_i2c_read(client, ®_addr, 1, ®_value, 1); @@ -625,12 +764,22 @@ static const struct i2c_device_id ft5x06_ts_id[] = { MODULE_DEVICE_TABLE(i2c, ft5x06_ts_id); +#ifdef CONFIG_OF +static const struct of_device_id ft5x06_match_table[] = { + { .compatible = "focaltech,5x06",}, + { }, +}; +#else +#define ft5x06_match_table NULL +#endif + static struct i2c_driver ft5x06_ts_driver = { .probe = ft5x06_ts_probe, .remove = __devexit_p(ft5x06_ts_remove), .driver = { .name = "ft5x06_ts", .owner = THIS_MODULE, + .of_match_table = ft5x06_match_table, #ifdef CONFIG_PM .pm = &ft5x06_ts_pm_ops, #endif diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h index a9577b62cb07..08ccbc9bd71c 100644 --- a/include/linux/input/ft5x06_ts.h +++ b/include/linux/input/ft5x06_ts.h @@ -3,7 +3,7 @@ * FocalTech ft5x06 TouchScreen driver header file. * * Copyright (c) 2010 Focal tech Ltd. - * Copyright (c) 2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -18,12 +18,28 @@ #ifndef __LINUX_FT5X06_TS_H__ #define __LINUX_FT5X06_TS_H__ +#define FT5X06_ID 0x55 +#define FT5X16_ID 0x0A +#define FT5X36_ID 0x14 +#define FT6X06_ID 0x06 + struct ft5x06_ts_platform_data { - unsigned long irqflags; - u32 x_max; - u32 y_max; + u32 irqflags; u32 irq_gpio; + u32 irq_gpio_flags; u32 reset_gpio; + u32 reset_gpio_flags; + u32 family_id; + u32 x_max; + u32 y_max; + u32 x_min; + u32 y_min; + u32 panel_minx; + u32 panel_miny; + u32 panel_maxx; + u32 panel_maxy; + bool no_force_update; + bool i2c_pull_up; int (*power_init)(bool); int (*power_on)(bool); }; |
