Re: [PATCH 2/2] Input: add touchscreen support for TS-4800
Hi Damien, On Thu, Dec 10, 2015 at 11:11:12AM -0500, Damien Riegel wrote: > On this board, the touchscreen, an ads7843, is not handled directly by > Linux but by a companion FPGA. This FPGA is memory-mapped and the IP > design is very similar to the mk712. > > This commit adds the support for this IP. > > Signed-off-by: Damien Riegel > --- > drivers/input/touchscreen/Kconfig | 15 +++ > drivers/input/touchscreen/Makefile| 1 + > drivers/input/touchscreen/ts4800-ts.c | 238 > ++ > 3 files changed, 254 insertions(+) > create mode 100644 drivers/input/touchscreen/ts4800-ts.c > > diff --git a/drivers/input/touchscreen/Kconfig > b/drivers/input/touchscreen/Kconfig > index deb14c1..2d3b2f2 100644 > --- a/drivers/input/touchscreen/Kconfig > +++ b/drivers/input/touchscreen/Kconfig > @@ -914,6 +914,21 @@ config TOUCHSCREEN_TOUCHIT213 >To compile this driver as a module, choose M here: the >module will be called touchit213. > > +config TOUCHSCREEN_TS4800 > + tristate "TS-4800 touchscreen" > + depends on HAS_IOMEM && OF > + select MFD_SYSCON You also need "select INPUT_POLLDEV" here. > + help > + Say Y here if you have a touchscreen on a TS-4800 board. > + > + On TS-4800, the touchscreen is not handled directly by Linux but by > + a companion FPGA. > + > + If unsure, say N. > + > + To compile this driver as a module, choose M here: the > + module will be called ts4800_ts. > + > config TOUCHSCREEN_TSC_SERIO > tristate "TSC-10/25/40 serial touchscreen support" > select SERIO > diff --git a/drivers/input/touchscreen/Makefile > b/drivers/input/touchscreen/Makefile > index 1b79cc0..5d81ba8c 100644 > --- a/drivers/input/touchscreen/Makefile > +++ b/drivers/input/touchscreen/Makefile > @@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o > obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o > obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o > obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o > +obj-$(CONFIG_TOUCHSCREEN_TS4800) += ts4800-ts.o > obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO) += tsc40.o > obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o > obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o > diff --git a/drivers/input/touchscreen/ts4800-ts.c > b/drivers/input/touchscreen/ts4800-ts.c > new file mode 100644 > index 000..1e81b17 > --- /dev/null > +++ b/drivers/input/touchscreen/ts4800-ts.c > @@ -0,0 +1,238 @@ > +/* > + * Touchscreen driver for the TS-4800 board > + * > + * Copyright (c) 2015 - Savoir-faire Linux > + * > + * This file is licensed under the terms of the GNU General Public > + * License version 2. This program is licensed "as is" without any > + * warranty of any kind, whether express or implied. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* polling interval in ms*/ > +#define POLL_INTERVAL 3 > + > +/* sensor values are 12-bit wide */ > +#define MAX_12BIT ((1 << 12) - 1) > + > +#define PENDOWN_MASK0x1 > + > +#define X_OFFSET0x0 > +#define Y_OFFSET0x2 > + > +struct ts4800_ts { > + struct input_polled_dev *poll_dev; > + struct device *dev; > + charphys[32]; > + > + void __iomem*base; > + struct regmap *regmap; > + unsigned intreg; > + unsigned intbit; > + > + boolpendown; > + int debounce; > +}; > + > +static void ts4800_ts_open(struct input_polled_dev *dev) > +{ > + struct ts4800_ts *ts = dev->private; > + int ret; > + > + ret = regmap_update_bits(ts->regmap, ts->reg, > + 1 << ts->bit, 1 << ts->bit); Instead of doing shift every time you can store already shifted value in ts->bit. > + if (ret) > + dev_warn(ts->dev, "Failed to enable touchscreen\n"); > +} > + > +static void ts4800_ts_close(struct input_polled_dev *dev) > +{ > + struct ts4800_ts *ts = dev->private; > + int ret; > + > + ret = regmap_update_bits(ts->regmap, ts->reg, > + 1 << ts->bit, 0); > + if (ret) > + dev_warn(ts->dev, "Failed to disable touchscreen\n"); > + > +} > + > +static void ts4800_ts_poll(struct input_polled_dev *dev) > +{ > + struct input_dev *input_dev = dev->input; > + struct ts4800_ts *ts = dev->private; > + u16 last_x = readw(ts->base + X_OFFSET); > + u16 last_y = readw(ts->base + Y_OFFSET); > + bool pendown = last_x & PENDOWN_MASK; > + > + if (!pendown && ts->pendown) { > + ts->pendown = false; > + ts->debounce = 1; > + input_report_key(input_dev, BTN_TOUCH, 0); > + input_sync(input_dev); > + } > + > + if (pendown) { > + if (ts->debounce) { > + ts->debounce = 0; This looks like a boolean, but I think having a counter for debounce is more natural. > + return; > + } > + > + if (!ts->pendown) { > + input_report_key(input_dev, BTN_TOUCH, 1); > + ts->pendown = true; > + } > + > + last_x = ((~last_x) >> 4) & MAX_12BIT; > + last_y = ((~last_y) >> 4) & MAX_12BI
Re: [PATCH 2/2] Input: add touchscreen support for TS-4800
Hi Dmitry On Sat, Dec 12, 2015 at 08:58:58PM -0800, Dmitry Torokhov wrote: > Hi Damien, > > On Thu, Dec 10, 2015 at 11:11:12AM -0500, Damien Riegel wrote: > > On this board, the touchscreen, an ads7843, is not handled directly by > > Linux but by a companion FPGA. This FPGA is memory-mapped and the IP > > design is very similar to the mk712. > > ... > > > + > > + poll_dev = devm_input_allocate_polled_device(&pdev->dev); > > + if (!poll_dev) > > + return -ENOMEM; > > I wonder how useful touchscreen implemented as polling device is. Isn't > there an interrupt line for it? There is an interrupt line between the touchscreen and the FGPA, but not between the FPGA and the SoC. I agree it is a bit peculiar. Hopefully on more recent boards, they changed their design to handle the touchscreen directly with Linux. Thanks, Damien > Thanks. > > -- > Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] Input: add touchscreen support for TS-4800
Hi Damien, On Thu, Dec 10, 2015 at 11:11:12AM -0500, Damien Riegel wrote: > On this board, the touchscreen, an ads7843, is not handled directly by > Linux but by a companion FPGA. This FPGA is memory-mapped and the IP > design is very similar to the mk712. ... > + > + poll_dev = devm_input_allocate_polled_device(&pdev->dev); > + if (!poll_dev) > + return -ENOMEM; I wonder how useful touchscreen implemented as polling device is. Isn't there an interrupt line for it? Thanks. -- Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] Input: add touchscreen support for TS-4800
On this board, the touchscreen, an ads7843, is not handled directly by Linux but by a companion FPGA. This FPGA is memory-mapped and the IP design is very similar to the mk712. This commit adds the support for this IP. Signed-off-by: Damien Riegel --- drivers/input/touchscreen/Kconfig | 15 +++ drivers/input/touchscreen/Makefile| 1 + drivers/input/touchscreen/ts4800-ts.c | 238 ++ 3 files changed, 254 insertions(+) create mode 100644 drivers/input/touchscreen/ts4800-ts.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index deb14c1..2d3b2f2 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -914,6 +914,21 @@ config TOUCHSCREEN_TOUCHIT213 To compile this driver as a module, choose M here: the module will be called touchit213. +config TOUCHSCREEN_TS4800 + tristate "TS-4800 touchscreen" + depends on HAS_IOMEM && OF + select MFD_SYSCON + help + Say Y here if you have a touchscreen on a TS-4800 board. + + On TS-4800, the touchscreen is not handled directly by Linux but by + a companion FPGA. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called ts4800_ts. + config TOUCHSCREEN_TSC_SERIO tristate "TSC-10/25/40 serial touchscreen support" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 1b79cc0..5d81ba8c 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o +obj-$(CONFIG_TOUCHSCREEN_TS4800) += ts4800-ts.o obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO)+= tsc40.o obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o diff --git a/drivers/input/touchscreen/ts4800-ts.c b/drivers/input/touchscreen/ts4800-ts.c new file mode 100644 index 000..1e81b17 --- /dev/null +++ b/drivers/input/touchscreen/ts4800-ts.c @@ -0,0 +1,238 @@ +/* + * Touchscreen driver for the TS-4800 board + * + * Copyright (c) 2015 - Savoir-faire Linux + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* polling interval in ms*/ +#define POLL_INTERVAL 3 + +/* sensor values are 12-bit wide */ +#define MAX_12BIT ((1 << 12) - 1) + +#define PENDOWN_MASK0x1 + +#define X_OFFSET0x0 +#define Y_OFFSET0x2 + +struct ts4800_ts { + struct input_polled_dev *poll_dev; + struct device *dev; + charphys[32]; + + void __iomem*base; + struct regmap *regmap; + unsigned intreg; + unsigned intbit; + + boolpendown; + int debounce; +}; + +static void ts4800_ts_open(struct input_polled_dev *dev) +{ + struct ts4800_ts *ts = dev->private; + int ret; + + ret = regmap_update_bits(ts->regmap, ts->reg, +1 << ts->bit, 1 << ts->bit); + if (ret) + dev_warn(ts->dev, "Failed to enable touchscreen\n"); +} + +static void ts4800_ts_close(struct input_polled_dev *dev) +{ + struct ts4800_ts *ts = dev->private; + int ret; + + ret = regmap_update_bits(ts->regmap, ts->reg, +1 << ts->bit, 0); + if (ret) + dev_warn(ts->dev, "Failed to disable touchscreen\n"); + +} + +static void ts4800_ts_poll(struct input_polled_dev *dev) +{ + struct input_dev *input_dev = dev->input; + struct ts4800_ts *ts = dev->private; + u16 last_x = readw(ts->base + X_OFFSET); + u16 last_y = readw(ts->base + Y_OFFSET); + bool pendown = last_x & PENDOWN_MASK; + + if (!pendown && ts->pendown) { + ts->pendown = false; + ts->debounce = 1; + input_report_key(input_dev, BTN_TOUCH, 0); + input_sync(input_dev); + } + + if (pendown) { + if (ts->debounce) { + ts->debounce = 0; + return; + } + + if (!ts->pendown) { + input_report_key(input_dev, BTN_TOUCH, 1); + ts->pendown = true; + } + + last_x = ((~last_x) >> 4) & MAX_12BIT; + last_y = ((~last_y) >> 4) & MAX_12BIT; + +