mbox series

[0/2,RFC] input: touchscreen: ads7846.c: re-write

Message ID 20190312082145.8906-1-david@protonic.nl (mailing list archive)
Headers show
Series input: touchscreen: ads7846.c: re-write | expand

Message

David Jander March 12, 2019, 8:21 a.m. UTC
This is a near complete re-write of the ads7846 touchscreen driver,
fixing many issues the current implementation has. Unfortunately due
to the nature of the problems, separate patches addressing the
individual issues would have been too big of a task and not really
practical. For instance re-implementing the sampling code while
keeping the filter code would already require a lot changes to the
filtering code in order to work with the new way of sampling, only
to throw everything away in the next patch.
The only patch that is separate, and that can be used without the
rest is the addition of device-tree parameters to allow for inversion
of X/Y axes.
Here is a summary of all the issues with the current code that are
addressed in the second patch:

 - Excessive CPU usage. The new driver has almost 100x lower CPU
   usage in some cases. This was due to the fact that the original
   driver submits a chain of many small SPI transfers that cause a
   lot of context switching in the SPI work-queue. All touchscreen
   measurements can be done in a single SPI transfer using the
   16 clocks-per-conversion timing mode described in the data-sheets.
   The driver also relied on spi_transfer->delay_usecs, which in
   worst-case can busy-wait, and in best case introduces a few more
   context switches.
   The new driver implementes settling-delays by inserting dummy
   samples into the SPI transfer. Since the SPI transfer is handled
   by hardware (either DMA or FIFOs), the CPU is freed even further.
   While this can increse the SPI traffic a bit on the SPI bus, in
   practice that bit of extra bandwidth that was available before
   could not have been used due to system latency anyway.

 - Unreadable filter code. The filtering code was implemented in
   a quirky and hard to follow manner, due to the way the samples
   get extracted one by one from the chain of SPI messages. The new
   code extracts all data from X, Y and pressure at once and delivers
   the complete set of samples to the filter. This way the filter
   knows what X, Y or pressure data is respectively.

 - Potential integer overflow in the pressure calculation, resulting
   in fake high-pressure touches on bigger touch-panels, where the
   x-plate resistance is higher (800-1000 Ohm or more).

 - Each time a HWMON measurement is done from one of the temperature
   or aux inputs of the chip while the screen is touched, a pen-up
   and pen-down event was generated. This is now solved by using the
   lock also in the interrupt thread.

 - Improved filter performance: Mark samples that signify a big
   displacement as suspects and wait for the next sample to decide
   if it is valid (fast slide) or not. Moving average of up to 4
   deemed-good samples. Also on bad touch-panels, the pen contact
   can be glitchy. There is a new filter parameter to enable a
   separate touch contact glitch filter.

Due to the new filter architecture, the DT layout needed to change.
This patch is an RFC, so no changes have been made yet to the
affected device-trees. These will be done before the final version
of this patch.

David Jander (2):
  input: touchscreen: ads7846.c: Add support for invert_x/y in dt
  input: touchscreen: ads7846.c: Re-write sampling and filtering
    functions

 .../bindings/input/touchscreen/ads7846.txt    |  34 +-
 drivers/input/touchscreen/ads7846.c           | 874 +++++++-----------
 include/linux/spi/ads7846.h                   |  29 +-
 3 files changed, 386 insertions(+), 551 deletions(-)