From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: linux-input@vger.kernel.org, linux-iio@vger.kernel.org,
sameo@linux.intel.com, jic23@cam.ac.uk, balbi@ti.com
Subject: Re: [PATCH 2/5] input/ti_am335x_adc: use only FIFO0 and clean up a little
Date: Tue, 4 Jun 2013 09:52:24 -0700 [thread overview]
Message-ID: <20130604165223.GF26400@core.coreip.homeip.net> (raw)
In-Reply-To: <1369847397-27451-3-git-send-email-bigeasy@linutronix.de>
On Wed, May 29, 2013 at 07:09:53PM +0200, Sebastian Andrzej Siewior wrote:
> The driver programs a threshold of "steps-to-configure" say 5. The
> REG_FIFO0THR registers says it should it be programmed to "threshold
> minus one". The driver does not expect just 5 coordinates but 5 * 2 + 2.
> Multiplied by two because 5 for X and 5 for Y. Plus 2 because we have
> two Z.
> The whole thing works because It reads the 5 coordinates for X and Y and
> split over FIFO0 and FIFO1 and the last element in each FIFO is ignored
> within the loop and read later.
> Nothing guaranties that FIFO1 is ready by the time it is read. In fact I
> could see that that FIFO1 reaturns for Y channels 8,9, 10, 12, 6 and for
> Y channel 7 for Z. The problem is that channel 7 and channel 12 got
> somehow mixed up. The variance filter here maybe tries to get rid of the
> wrong Y values, dunno.
> The other Problem is that FIFO1 is also used by the IIO part leading to
> not wrong results if both (tsc & adc) are used.
>
> The patch tries to clean up the whole thing a little:
> - Name it "coordiante-readouts" and not "steps-to-configure" and
> document it properly. Point out that it the hardware does a total of
> "5 * 2 + 2" reads / steps and not just what is configured.
>
> - Remove the +1 and -1 in REG_STEPCONFIG, REG_STEPDELAY and its counter
> part in the for loop. This is just confusing.
>
> - Use only FIFO0 in TSC. The fifo has space for 64 entries so should be
> fine.
>
> - Read the whole FIFO in one function and check the channel.
>
> - in case we dawdle around, make sure we only read a multiple of our
> coordinate set. On the second interrupt we will cleanup the remaining
> enties.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
> .../bindings/input/touchscreen/ti-tsc-adc.txt | 15 ++--
> arch/arm/boot/dts/am335x-evm.dts | 2 +-
> drivers/iio/adc/ti_am335x_adc.c | 2 +-
> drivers/input/touchscreen/ti_am335x_tsc.c | 87 ++++++++++----------
> include/linux/mfd/ti_am335x_tscadc.h | 4 +-
> 5 files changed, 58 insertions(+), 52 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
> index e533e9d..80e04e3 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
> @@ -6,10 +6,15 @@
> ti,wires: Wires refer to application modes i.e. 4/5/8 wire touchscreen
> support on the platform.
> ti,x-plate-resistance: X plate resistance
> - ti,steps-to-configure: The sequencer supports a total of 16
> - programmable steps. A step configured to read a
> - single co-ordinate value. Can be applied more
> - number of times for better results.
> + ti,coordiante-readouts: The sequencer supports a total of 16
> + programmable steps each step is used to
> + read a single coordinate. A single
> + readout is enough but multiple reads can
> + increase the quality.
> + A value of 5 means, 5 reads for X, 5 for
> + Y and 2 for Z (always). This utilises 12
> + of the 16 software steps available. The
> + remaining 4 can be used by the ADC.
> ti,wire-config: Different boards could have a different order for
> connecting wires on touchscreen. We need to provide an
> 8 bit number where in the 1st four bits represent the
> @@ -28,7 +33,7 @@
> tsc {
> ti,wires = <4>;
> ti,x-plate-resistance = <200>;
> - ti,steps-to-configure = <5>;
> + ti,coordiante-readouts = <5>;
> ti,wire-config = <0x00 0x11 0x22 0x33>;
> };
>
> diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
> index be6a5b2..26fea97 100644
> --- a/arch/arm/boot/dts/am335x-evm.dts
> +++ b/arch/arm/boot/dts/am335x-evm.dts
> @@ -250,7 +250,7 @@
> tsc {
> ti,wires = <4>;
> ti,x-plate-resistance = <200>;
> - ti,steps-to-configure = <5>;
> + ti,coordiante-readouts = <5>;
> ti,wire-config = <0x00 0x11 0x22 0x33>;
> };
>
> diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
> index b2f27de..2988840 100644
> --- a/drivers/iio/adc/ti_am335x_adc.c
> +++ b/drivers/iio/adc/ti_am335x_adc.c
> @@ -72,7 +72,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
>
> stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
>
> - for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
> + for (i = steps; i < TOTAL_STEPS; i++) {
> tiadc_writel(adc_dev, REG_STEPCONFIG(i),
> stepconfig | STEPCONFIG_INP(channels));
> tiadc_writel(adc_dev, REG_STEPDELAY(i),
> diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
> index 2921163..7c97fc7 100644
> --- a/drivers/input/touchscreen/ti_am335x_tsc.c
> +++ b/drivers/input/touchscreen/ti_am335x_tsc.c
> @@ -58,7 +58,7 @@ struct titsc {
> unsigned int bckup_x;
> unsigned int bckup_y;
> bool pen_down;
> - int steps_to_configure;
> + int coordiante_readouts;
> u32 config_inp[4];
> int bit_xp, bit_xn, bit_yp, bit_yn;
> int inp_xp, inp_xn, inp_yp, inp_yn;
> @@ -168,11 +168,8 @@ static int titsc_config_wires(struct titsc *ts_dev)
> static void titsc_step_config(struct titsc *ts_dev)
> {
> unsigned int config;
> - unsigned int stepenable = 0;
> - int i, total_steps;
> -
> - /* Configure the Step registers */
> - total_steps = 2 * ts_dev->steps_to_configure;
> + int i;
> + int end_step;
>
> config = STEPCONFIG_MODE_HWSYNC |
> STEPCONFIG_AVG_16 | ts_dev->bit_xp;
> @@ -190,7 +187,9 @@ static void titsc_step_config(struct titsc *ts_dev)
> break;
> }
>
> - for (i = 1; i <= ts_dev->steps_to_configure; i++) {
> + /* 1 … coordiante_readouts is for X */
> + end_step = ts_dev->coordiante_readouts;
> + for (i = 0; i < end_step; i++) {
> titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
> titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
> }
> @@ -198,7 +197,7 @@ static void titsc_step_config(struct titsc *ts_dev)
> config = 0;
> config = STEPCONFIG_MODE_HWSYNC |
> STEPCONFIG_AVG_16 | ts_dev->bit_yn |
> - STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
> + STEPCONFIG_INM_ADCREFM;
> switch (ts_dev->wires) {
> case 4:
> config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
> @@ -212,12 +211,13 @@ static void titsc_step_config(struct titsc *ts_dev)
> break;
> }
>
> - for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) {
> + /* coordiante_readouts … coordiante_readouts * 2 is for Y */
> + end_step = ts_dev->coordiante_readouts * 2;
> + for (i = ts_dev->coordiante_readouts; i < end_step; i++) {
> titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
> titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
> }
>
> - config = 0;
> /* Charge step configuration */
> config = ts_dev->bit_xp | ts_dev->bit_yn |
> STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
> @@ -226,37 +226,40 @@ static void titsc_step_config(struct titsc *ts_dev)
> titsc_writel(ts_dev, REG_CHARGECONFIG, config);
> titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
>
> - config = 0;
> - /* Configure to calculate pressure */
> + /* coordiante_readouts * 2 … coordiante_readouts * 2 + 2 is for Z */
> config = STEPCONFIG_MODE_HWSYNC |
> STEPCONFIG_AVG_16 | ts_dev->bit_yp |
> ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
> STEPCONFIG_INP(ts_dev->inp_xp);
> - titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
> - titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
> + titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
> + titsc_writel(ts_dev, REG_STEPDELAY(end_step),
> STEPCONFIG_OPENDLY);
>
> - config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1;
> - titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
> - titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
> + end_step++;
> + config |= STEPCONFIG_INP(ts_dev->inp_yn);
> + titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
> + titsc_writel(ts_dev, REG_STEPDELAY(end_step),
> STEPCONFIG_OPENDLY);
>
> - for (i = 0; i <= (total_steps + 2); i++)
> - stepenable |= 1 << i;
> - ts_dev->enable_bits = stepenable;
> + /* The steps1 … end and bit 0 for TS_Charge */
> + ts_dev->enable_bits = (1 << (end_step + 2)) - 1;
>
> titsc_writel(ts_dev, REG_SE, ts_dev->enable_bits);
> }
>
> static void titsc_read_coordinates(struct titsc *ts_dev,
> - unsigned int *x, unsigned int *y)
> + u32 *x, u32 *y, u32 *z1, u32 *z2)
> {
> unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT);
> unsigned int prev_val_x = ~0, prev_val_y = ~0;
> unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
> unsigned int read, diff;
> unsigned int i, channel;
> + unsigned int creads = ts_dev->coordiante_readouts;
>
> + *z1 = *z2 = 0;
> + if (fifocount % (creads * 2 + 2))
> + fifocount -= fifocount % (creads * 2 + 2);
> /*
> * Delta filter is used to remove large variations in sampled
> * values from ADC. The filter tries to predict where the next
> @@ -265,32 +268,31 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
> * algorithm compares the difference with that of a present value,
> * if true the value is reported to the sub system.
> */
> - for (i = 0; i < fifocount - 1; i++) {
> + for (i = 0; i < fifocount; i++) {
> read = titsc_readl(ts_dev, REG_FIFO0);
> - channel = read & 0xf0000;
> - channel = channel >> 0x10;
> - if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) {
> - read &= 0xfff;
> + channel = (read & 0xf0000) >> 16;
> + read &= 0xfff;
> + if (channel < creads) {
> diff = abs(read - prev_val_x);
> if (diff < prev_diff_x) {
> prev_diff_x = diff;
> *x = read;
> }
> prev_val_x = read;
> - }
>
> - read = titsc_readl(ts_dev, REG_FIFO1);
> - channel = read & 0xf0000;
> - channel = channel >> 0x10;
> - if ((channel >= ts_dev->steps_to_configure) &&
> - (channel < (2 * ts_dev->steps_to_configure - 1))) {
> - read &= 0xfff;
> + } else if (channel < creads * 2) {
> diff = abs(read - prev_val_y);
> if (diff < prev_diff_y) {
> prev_diff_y = diff;
> *y = read;
> }
> prev_val_y = read;
> +
> + } else if (channel < creads * 2 + 1) {
> + *z1 = read;
> +
> + } else if (channel < creads * 2 + 2) {
> + *z2 = read;
> }
> }
> }
> @@ -307,26 +309,24 @@ static irqreturn_t titsc_irq(int irq, void *dev)
>
> status = titsc_readl(ts_dev, REG_IRQSTATUS);
> if (status & IRQENB_FIFO0THRES) {
> - titsc_read_coordinates(ts_dev, &x, &y);
> +
> + titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
>
> diffx = abs(x - (ts_dev->bckup_x));
> diffy = abs(y - (ts_dev->bckup_y));
> ts_dev->bckup_x = x;
> ts_dev->bckup_y = y;
>
> - z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
> - z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
> -
> if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
> /*
> * Calculate pressure using formula
> * Resistance(touch) = x plate resistance *
> * x postion/4096 * ((z2 / z1) - 1)
> */
> - z = z2 - z1;
> + z = z1 - z2;
> z *= x;
> z *= ts_dev->x_plate_resistance;
> - z /= z1;
> + z /= z2;
> z = (z + 2047) >> 12;
>
> if ((diffx < TSCADC_DELTA_X) &&
> @@ -399,8 +399,8 @@ static int titsc_parse_dt(struct ti_tscadc_dev *tscadc_dev,
> if (err < 0)
> return err;
>
> - err = of_property_read_u32(node, "ti,steps-to-configure",
> - &ts_dev->steps_to_configure);
> + err = of_property_read_u32(node, "ti,coordiante-readouts",
> + &ts_dev->coordiante_readouts);
> if (err < 0)
> return err;
>
> @@ -454,7 +454,8 @@ static int titsc_probe(struct platform_device *pdev)
> goto err_free_irq;
> }
> titsc_step_config(ts_dev);
> - titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
> + titsc_writel(ts_dev, REG_FIFO0THR,
> + ts_dev->coordiante_readouts * 2 + 2 - 1);
>
> input_dev->name = "ti-tsc";
> input_dev->dev.parent = &pdev->dev;
> @@ -526,7 +527,7 @@ static int titsc_resume(struct device *dev)
> }
> titsc_step_config(ts_dev);
> titsc_writel(ts_dev, REG_FIFO0THR,
> - ts_dev->steps_to_configure);
> + ts_dev->coordiante_readouts * 2 + 2 - 1);
> return 0;
> }
>
> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> index c985262..4ec52b0 100644
> --- a/include/linux/mfd/ti_am335x_tscadc.h
> +++ b/include/linux/mfd/ti_am335x_tscadc.h
> @@ -30,8 +30,8 @@
> #define REG_IDLECONFIG 0x058
> #define REG_CHARGECONFIG 0x05C
> #define REG_CHARGEDELAY 0x060
> -#define REG_STEPCONFIG(n) (0x64 + ((n - 1) * 8))
> -#define REG_STEPDELAY(n) (0x68 + ((n - 1) * 8))
> +#define REG_STEPCONFIG(n) (0x64 + ((n) * 8))
> +#define REG_STEPDELAY(n) (0x68 + ((n) * 8))
> #define REG_FIFO0CNT 0xE4
> #define REG_FIFO0THR 0xE8
> #define REG_FIFO1CNT 0xF0
> --
> 1.7.10.4
>
--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2013-06-04 16:52 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-29 17:09 am335x adc & tsc, second batch Sebastian Andrzej Siewior
2013-05-29 17:09 ` [PATCH 1/5] drivers/iio: am335x_adc: cleanup on missing DT nodes Sebastian Andrzej Siewior
[not found] ` <1369847397-27451-2-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2013-06-02 17:56 ` Jonathan Cameron
[not found] ` <51AB8758.5010705-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-04 10:38 ` Sebastian Andrzej Siewior
[not found] ` <1369847397-27451-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2013-05-29 17:09 ` [PATCH 2/5] input/ti_am335x_adc: use only FIFO0 and clean up a little Sebastian Andrzej Siewior
2013-06-04 16:52 ` Dmitry Torokhov [this message]
2013-05-29 17:09 ` [PATCH 5/5] iio/ti_am335x_adc: check if we found the value Sebastian Andrzej Siewior
[not found] ` <1369847397-27451-6-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2013-06-02 18:03 ` Jonathan Cameron
2013-05-29 17:09 ` [PATCH 3/5] input/ti_am335x_tsc: fold regbit_map() and simplfy Sebastian Andrzej Siewior
2013-06-04 16:53 ` Dmitry Torokhov
2013-05-29 17:09 ` [PATCH 4/5] iio/ti_am335x_adc: Allow to specify input line Sebastian Andrzej Siewior
[not found] ` <1369847397-27451-5-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2013-06-02 18:02 ` Jonathan Cameron
[not found] ` <51AB88BE.6040109-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-04 10:39 ` Sebastian Andrzej Siewior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130604165223.GF26400@core.coreip.homeip.net \
--to=dmitry.torokhov@gmail.com \
--cc=balbi@ti.com \
--cc=bigeasy@linutronix.de \
--cc=jic23@cam.ac.uk \
--cc=linux-iio@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=sameo@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).