diff mbox

[1/3] input: tsc2007: Add pre-calibration, flipping and rotation

Message ID 1412108254-19234-2-git-send-email-marek@goldelico.com (mailing list archive)
State New, archived
Headers show

Commit Message

Marek Belisko Sept. 30, 2014, 8:17 p.m. UTC
This patch adds new parameters that allow to address typical hardware
design differences: touch screens may be wired or oriented differently
(portrait or landscape). And usually the active area of the touch is a
little larger than the active area of the LCD. This results in the touch
coordinates that have some significant deviation from LCD coordinates.
Usually this is addressed in user space by a calibration tool (e.g. tslib
or xinput-calibrator) but some systems don't have these tools or require
that the screen is already roughly calibrated (e.g. Replicant) to operate
the device until a better calibration can be done. And, some systems
react very strangely if the touch event stream reports coordinates
outside of the active area.

This makes it necessry to be able to configure:
1. swapping x and y wires (coordinate values)
2. flipping of x (left - right) or y (top - bottom) or even both
3. define an active area so that an uncalibrated screen already
roughly matches the LCD to be useful.
4. clip reported coordinates to the active area.

If none of the new parameters is defined (in DT) or set in a board file,
the driver behaves the same as without this patch.

Author (1&2): H. Nikolaus Schaller <hns@goldelico.com>
Author (3&4): Paul Kocialkowski <contact@paulk.fr>

Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 drivers/input/touchscreen/tsc2007.c | 89 +++++++++++++++++++++++++++++++++++--
 include/linux/i2c/tsc2007.h         |  6 +++
 2 files changed, 91 insertions(+), 4 deletions(-)

Comments

Belisko Marek Jan. 10, 2015, 2:15 p.m. UTC | #1
Ping for input maintainer. DT changes was acked. Thanks.

On Tue, Sep 30, 2014 at 10:17 PM, Marek Belisko <marek@goldelico.com> wrote:
> This patch adds new parameters that allow to address typical hardware
> design differences: touch screens may be wired or oriented differently
> (portrait or landscape). And usually the active area of the touch is a
> little larger than the active area of the LCD. This results in the touch
> coordinates that have some significant deviation from LCD coordinates.
> Usually this is addressed in user space by a calibration tool (e.g. tslib
> or xinput-calibrator) but some systems don't have these tools or require
> that the screen is already roughly calibrated (e.g. Replicant) to operate
> the device until a better calibration can be done. And, some systems
> react very strangely if the touch event stream reports coordinates
> outside of the active area.
>
> This makes it necessry to be able to configure:
> 1. swapping x and y wires (coordinate values)
> 2. flipping of x (left - right) or y (top - bottom) or even both
> 3. define an active area so that an uncalibrated screen already
> roughly matches the LCD to be useful.
> 4. clip reported coordinates to the active area.
>
> If none of the new parameters is defined (in DT) or set in a board file,
> the driver behaves the same as without this patch.
>
> Author (1&2): H. Nikolaus Schaller <hns@goldelico.com>
> Author (3&4): Paul Kocialkowski <contact@paulk.fr>
>
> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> ---
>  drivers/input/touchscreen/tsc2007.c | 89 +++++++++++++++++++++++++++++++++++--
>  include/linux/i2c/tsc2007.h         |  6 +++
>  2 files changed, 91 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
> index 1bf9906..cc0cc3c 100644
> --- a/drivers/input/touchscreen/tsc2007.c
> +++ b/drivers/input/touchscreen/tsc2007.c
> @@ -74,6 +74,12 @@ struct tsc2007 {
>
>         u16                     model;
>         u16                     x_plate_ohms;
> +       bool                    swap_xy;        /* swap x and y axis */
> +       u16                     min_x;
> +       u16                     min_y;
> +       u16                     min_rt;
> +       u16                     max_x;
> +       u16                     max_y;
>         u16                     max_rt;
>         unsigned long           poll_period;
>         int                     fuzzx;
> @@ -193,11 +199,50 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
>                         break;
>                 }
>
> -               if (rt <= ts->max_rt) {
> +               if (rt <= max(ts->min_rt, ts->max_rt)) {
>                         dev_dbg(&ts->client->dev,
>                                 "DOWN point(%4d,%4d), pressure (%4u)\n",
>                                 tc.x, tc.y, rt);
>
> +                       if (ts->swap_xy) {
> +                               /* swap before applying the range limits */
> +                               u16 h = tc.x;
> +
> +                               tc.x = tc.y;
> +                               tc.y = h;
> +                       }
> +
> +                       /* flip and/or clip X */
> +                       if (ts->max_x < ts->min_x)
> +                               tc.x = (ts->min_x - tc.x) + ts->max_x;
> +
> +                       if (tc.x > max(ts->min_x, ts->max_x))
> +                               tc.x = max(ts->min_x, ts->max_x);
> +                       else if (tc.x < min(ts->min_x, ts->max_x))
> +                               tc.x = min(ts->min_x, ts->max_x);
> +
> +                       /* flip and/or clip Y */
> +                       if (ts->max_y < ts->min_y)
> +                               tc.y = (ts->min_y - tc.y) + ts->max_y;
> +
> +                       if (tc.y > max(ts->min_y, ts->max_y))
> +                               tc.y = max(ts->min_y, ts->max_y);
> +                       else if (tc.y < min(ts->min_y, ts->max_y))
> +                               tc.y = min(ts->min_y, ts->max_y);
> +
> +                       /* clip Z */
> +                       if (ts->max_rt < ts->min_rt)
> +                               rt = (ts->min_rt - rt) + ts->max_rt;
> +
> +                       if (rt > max(ts->min_rt, ts->max_rt))
> +                               rt = max(ts->min_rt, ts->max_rt);
> +                       else if (rt < min(ts->min_rt, ts->max_rt))
> +                               rt = min(ts->min_rt, ts->max_rt);
> +
> +                       dev_dbg(&ts->client->dev,
> +                                       "shaped point(%4d,%4d), pressure (%4u)\n",
> +                                       tc.x, tc.y, rt);
> +
>                         input_report_key(input, BTN_TOUCH, 1);
>                         input_report_abs(input, ABS_X, tc.x);
>                         input_report_abs(input, ABS_Y, tc.y);
> @@ -299,6 +344,24 @@ static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
>                 return -EINVAL;
>         }
>
> +       ts->swap_xy = of_property_read_bool(np, "ti,swap-xy");
> +
> +       if (!of_property_read_u32(np, "ti,min-x", &val32))
> +               ts->min_x = val32;
> +       if (!of_property_read_u32(np, "ti,max-x", &val32))
> +               ts->max_x = val32;
> +       else
> +               ts->max_x = MAX_12BIT;
> +
> +       if (!of_property_read_u32(np, "ti,min-y", &val32))
> +               ts->min_y = val32;
> +       if (!of_property_read_u32(np, "ti,max-y", &val32))
> +               ts->max_y = val32;
> +       else
> +               ts->max_y = MAX_12BIT;
> +
> +       if (!of_property_read_u32(np, "ti,min-rt", &val32))
> +               ts->min_rt = val32;
>         if (!of_property_read_u32(np, "ti,max-rt", &val32))
>                 ts->max_rt = val32;
>         else
> @@ -325,6 +388,16 @@ static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
>                 return -EINVAL;
>         }
>
> +       dev_dbg(&client->dev,
> +                       "min/max_x (%4d,%4d)\n",
> +                       ts->min_x, ts->max_x);
> +       dev_dbg(&client->dev,
> +                       "min/max_y (%4d,%4d)\n",
> +                       ts->min_y, ts->max_y);
> +       dev_dbg(&client->dev,
> +                       "min/max_rt (%4d,%4d)\n",
> +                       ts->min_rt, ts->max_rt);
> +
>         ts->gpio = of_get_gpio(np, 0);
>         if (gpio_is_valid(ts->gpio))
>                 ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
> @@ -349,6 +422,12 @@ static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
>  {
>         ts->model             = pdata->model;
>         ts->x_plate_ohms      = pdata->x_plate_ohms;
> +       ts->swap_xy           = pdata->swap_xy;
> +       ts->min_x             = pdata->min_x ? : 0;
> +       ts->min_y             = pdata->min_y ? : 0;
> +       ts->min_rt            = pdata->min_rt ? : 0;
> +       ts->max_x             = pdata->max_x ? : MAX_12BIT;
> +       ts->max_y             = pdata->max_y ? : MAX_12BIT;
>         ts->max_rt            = pdata->max_rt ? : MAX_12BIT;
>         ts->poll_period       = pdata->poll_period ? : 1;
>         ts->get_pendown_state = pdata->get_pendown_state;
> @@ -422,9 +501,11 @@ static int tsc2007_probe(struct i2c_client *client,
>         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
>         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
>
> -       input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
> -       input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
> -       input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
> +       input_set_abs_params(input_dev, ABS_X, min(ts->min_x, ts->max_x),
> +                            max(ts->min_x, ts->max_x), ts->fuzzx, 0);
> +       input_set_abs_params(input_dev, ABS_Y, min(ts->min_y, ts->max_y),
> +                            max(ts->min_y, ts->max_y), ts->fuzzy, 0);
> +       input_set_abs_params(input_dev, ABS_PRESSURE, ts->min_rt, ts->max_rt,
>                              ts->fuzzz, 0);
>
>         if (pdata) {
> diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h
> index 4f35b6a..5ce7b79 100644
> --- a/include/linux/i2c/tsc2007.h
> +++ b/include/linux/i2c/tsc2007.h
> @@ -6,6 +6,12 @@
>  struct tsc2007_platform_data {
>         u16     model;                          /* 2007. */
>         u16     x_plate_ohms;   /* must be non-zero value */
> +       bool    swap_xy;        /* swap x and y axis */
> +       u16     min_x;  /* min and max values to reported to user space */
> +       u16     min_y;
> +       u16     min_rt;
> +       u16     max_x;
> +       u16     max_y;
>         u16     max_rt; /* max. resistance above which samples are ignored */
>         unsigned long poll_period; /* time (in ms) between samples */
>         int     fuzzx; /* fuzz factor for X, Y and pressure axes */
> --
> 1.9.3
>

BR,

marek
Dmitry Torokhov Jan. 15, 2015, 12:59 a.m. UTC | #2
On Sat, Jan 10, 2015 at 03:15:39PM +0100, Belisko Marek wrote:
> Ping for input maintainer. DT changes was acked. Thanks.
> 
> On Tue, Sep 30, 2014 at 10:17 PM, Marek Belisko <marek@goldelico.com> wrote:
> > This patch adds new parameters that allow to address typical hardware
> > design differences: touch screens may be wired or oriented differently
> > (portrait or landscape). And usually the active area of the touch is a
> > little larger than the active area of the LCD. This results in the touch
> > coordinates that have some significant deviation from LCD coordinates.
> > Usually this is addressed in user space by a calibration tool (e.g. tslib
> > or xinput-calibrator) but some systems don't have these tools or require
> > that the screen is already roughly calibrated (e.g. Replicant) to operate
> > the device until a better calibration can be done. And, some systems
> > react very strangely if the touch event stream reports coordinates
> > outside of the active area.
> >
> > This makes it necessry to be able to configure:
> > 1. swapping x and y wires (coordinate values)
> > 2. flipping of x (left - right) or y (top - bottom) or even both
> > 3. define an active area so that an uncalibrated screen already
> > roughly matches the LCD to be useful.
> > 4. clip reported coordinates to the active area.
> >
> > If none of the new parameters is defined (in DT) or set in a board file,
> > the driver behaves the same as without this patch.
> >
> > Author (1&2): H. Nikolaus Schaller <hns@goldelico.com>
> > Author (3&4): Paul Kocialkowski <contact@paulk.fr>
> >
> > Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>

OK, I was hesitant of adding these as normally we have tslib to perform
the conversion, but maybe it is time to allow it in the kernel and
standardize users. However, this seems like a general issue and we
should:

1. Perform conversion in input core rather than individual drivers. I
think we should allocate a new bitmaps for some transformations and have
the code do X/Y flip/clip of the coordinates.

2. Standardize on bindings. We already have of-touchscreen.c doing
rudimentary parsing, we shoudl look into extending it rather than
creating myriad of driver-specific bindings.

Also, do we need swap and flip or do we simply need rotation (like the
proposed Broadcom iproc driver has)?

Thanks.
H. Nikolaus Schaller Jan. 15, 2015, 7:36 a.m. UTC | #3
Hi,

Am 15.01.2015 um 01:59 schrieb Dmitry Torokhov <dmitry.torokhov@gmail.com>:

> On Sat, Jan 10, 2015 at 03:15:39PM +0100, Belisko Marek wrote:
>> Ping for input maintainer. DT changes was acked. Thanks.
>> 
>> On Tue, Sep 30, 2014 at 10:17 PM, Marek Belisko <marek@goldelico.com> wrote:
>>> This patch adds new parameters that allow to address typical hardware
>>> design differences: touch screens may be wired or oriented differently
>>> (portrait or landscape). And usually the active area of the touch is a
>>> little larger than the active area of the LCD. This results in the touch
>>> coordinates that have some significant deviation from LCD coordinates.
>>> Usually this is addressed in user space by a calibration tool (e.g. tslib
>>> or xinput-calibrator) but some systems don't have these tools or require
>>> that the screen is already roughly calibrated (e.g. Replicant) to operate
>>> the device until a better calibration can be done. And, some systems
>>> react very strangely if the touch event stream reports coordinates
>>> outside of the active area.
>>> 
>>> This makes it necessry to be able to configure:
>>> 1. swapping x and y wires (coordinate values)
>>> 2. flipping of x (left - right) or y (top - bottom) or even both
>>> 3. define an active area so that an uncalibrated screen already
>>> roughly matches the LCD to be useful.
>>> 4. clip reported coordinates to the active area.
>>> 
>>> If none of the new parameters is defined (in DT) or set in a board file,
>>> the driver behaves the same as without this patch.
>>> 
>>> Author (1&2): H. Nikolaus Schaller <hns@goldelico.com>
>>> Author (3&4): Paul Kocialkowski <contact@paulk.fr>
>>> 
>>> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> 
> OK, I was hesitant of adding these as normally we have tslib to perform
> the conversion, but maybe it is time to allow it in the kernel and
> standardize users.

Well, tslib isn’t a good replacement for this problem any more and
pre-initializing tslib makes some deep hardware dependency visible
in user space (each board needs a different tslib config and pointercal
default - and on some user spaces tslib is broken with Xorg).

But the issue to be solved is more hardware related, i.e. if the Y- and Y+
pins of the controller are connected in a swapped way to the resistor
ends of the panel.

Hence in a DT based system, this must IMHO be described by the DT
and can not be left to some user-space functions any more.

> However, this seems like a general issue and we
> should:
> 
> 1. Perform conversion in input core rather than individual drivers. I
> think we should allocate a new bitmaps for some transformations and have
> the code do X/Y flip/clip of the coordinates.

Do you have a suggestion where this should be (I have no clue how
the input system works or is structured - we just know how to extend a
driver that uses it)?

> 
> 2. Standardize on bindings. We already have of-touchscreen.c doing
> rudimentary parsing, we shoudl look into extending it rather than
> creating myriad of driver-specific bindings.

Ok, looks reasonable.

> 
> Also, do we need swap and flip or do we simply need rotation (like the
> proposed Broadcom iproc driver has)?

Well, since the DT should describe hardware, there are 3 sets of wires which
can have a cross-over: X+ and X-, Y+ and Y-, X and Y.

So IMHO hardware has no “rotation”, just crossover of wires. Rotation is an
interpretation of the result of these connections in combination with some
panel the touch is glued to and should therefore not be represented in the DT.

As a result we have proposed a scheme without explicit rotation. We specify what
coordinates X- and X+ should report at their ends (min, max) because the DT
programmer has to specify them anyways. Flipping is a result of defining these
coordinates in an ascending or descending way. Only swapping of the X and Y
wires can’t be implicitly defined so it has its own property. So the scheme we
have proposed tries to optimize the efforts needed to adapt new boards and write
DTs and focus the DT on hardware description.

As a bonus we also specify the min and max value to be reported for the touch
pressure (Z axis) using the same basic principle.

And it is a pure add-on on top of the existing driver so that it attempts not
to break existing device trees.

Maybe could you accept it as a first step for this specific driver (and let’s do
the big standardization work later on)?

— hns


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sebastian Reichel Jan. 15, 2015, 2:38 p.m. UTC | #4
Hi,

On Thu, Jan 15, 2015 at 08:36:44AM +0100, Dr. H. Nikolaus Schaller wrote:
> > 1. Perform conversion in input core rather than individual drivers. I
> > think we should allocate a new bitmaps for some transformations and have
> > the code do X/Y flip/clip of the coordinates.
> 
> Do you have a suggestion where this should be (I have no clue how
> the input system works or is structured - we just know how to extend a
> driver that uses it)?
> 
> > 2. Standardize on bindings. We already have of-touchscreen.c doing
> > rudimentary parsing, we shoudl look into extending it rather than
> > creating myriad of driver-specific bindings.
> 
> Ok, looks reasonable.

Documentation is in 

Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt

> > Also, do we need swap and flip or do we simply need rotation (like the
> > proposed Broadcom iproc driver has)?
> 
> Well, since the DT should describe hardware, there are 3 sets of wires which
> can have a cross-over: X+ and X-, Y+ and Y-, X and Y.
>
> So IMHO hardware has no “rotation”, just crossover of wires. Rotation is an
> interpretation of the result of these connections in combination with some
> panel the touch is glued to and should therefore not be represented in the DT.
> 
> As a result we have proposed a scheme without explicit rotation. We specify what
> coordinates X- and X+ should report at their ends (min, max) because the DT
> programmer has to specify them anyways. Flipping is a result of defining these
> coordinates in an ascending or descending way. Only swapping of the X and Y
> wires can’t be implicitly defined so it has its own property. So the scheme we
> have proposed tries to optimize the efforts needed to adapt new boards and write
> DTs and focus the DT on hardware description.
> 
> As a bonus we also specify the min and max value to be reported for the touch
> pressure (Z axis) using the same basic principle.
> 
> And it is a pure add-on on top of the existing driver so that it attempts not
> to break existing device trees.

from what I can see there are no in-tree-users using any of the
new properties.

> Maybe could you accept it as a first step for this specific driver (and let’s do
> the big standardization work later on)?

That does not work, since you create an ABI.

-- Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
H. Nikolaus Schaller Jan. 15, 2015, 3:04 p.m. UTC | #5
Hi,

Am 15.01.2015 um 15:38 schrieb Sebastian Reichel <sre@kernel.org>:

> Hi,
> 
> On Thu, Jan 15, 2015 at 08:36:44AM +0100, Dr. H. Nikolaus Schaller wrote:
>>> 1. Perform conversion in input core rather than individual drivers. I
>>> think we should allocate a new bitmaps for some transformations and have
>>> the code do X/Y flip/clip of the coordinates.
>> 
>> Do you have a suggestion where this should be (I have no clue how
>> the input system works or is structured - we just know how to extend a
>> driver that uses it)?
>> 
>>> 2. Standardize on bindings. We already have of-touchscreen.c doing
>>> rudimentary parsing, we shoudl look into extending it rather than
>>> creating myriad of driver-specific bindings.
>> 
>> Ok, looks reasonable.
> 
> Documentation is in 
> 
> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
> 
>>> Also, do we need swap and flip or do we simply need rotation (like the
>>> proposed Broadcom iproc driver has)?
>> 
>> Well, since the DT should describe hardware, there are 3 sets of wires which
>> can have a cross-over: X+ and X-, Y+ and Y-, X and Y.
>> 
>> So IMHO hardware has no “rotation”, just crossover of wires. Rotation is an
>> interpretation of the result of these connections in combination with some
>> panel the touch is glued to and should therefore not be represented in the DT.
>> 
>> As a result we have proposed a scheme without explicit rotation. We specify what
>> coordinates X- and X+ should report at their ends (min, max) because the DT
>> programmer has to specify them anyways. Flipping is a result of defining these
>> coordinates in an ascending or descending way. Only swapping of the X and Y
>> wires can’t be implicitly defined so it has its own property. So the scheme we
>> have proposed tries to optimize the efforts needed to adapt new boards and write
>> DTs and focus the DT on hardware description.
>> 
>> As a bonus we also specify the min and max value to be reported for the touch
>> pressure (Z axis) using the same basic principle.
>> 
>> And it is a pure add-on on top of the existing driver so that it attempts not
>> to break existing device trees.
> 
> from what I can see there are no in-tree-users using any of the
> new properties.

Not yet. But our [patch 2/3] of this series defines the DT entry for the GTA04 devices:

https://lkml.org/lkml/2014/9/30/663

> 
>> Maybe could you accept it as a first step for this specific driver (and let’s do
>> the big standardization work later on)?
> 
> That does not work, since you create an ABI.

Hm. I don’t understand what you mean with creating an ABI?




--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
H. Nikolaus Schaller Jan. 15, 2015, 4:14 p.m. UTC | #6
Am 15.01.2015 um 15:38 schrieb Sebastian Reichel <sre@kernel.org>:

> Hi,
> 
> On Thu, Jan 15, 2015 at 08:36:44AM +0100, Dr. H. Nikolaus Schaller wrote:
>>> 1. Perform conversion in input core rather than individual drivers. I
>>> think we should allocate a new bitmaps for some transformations and have
>>> the code do X/Y flip/clip of the coordinates.
>> 
>> Do you have a suggestion where this should be (I have no clue how
>> the input system works or is structured - we just know how to extend a
>> driver that uses it)?
>> 
>>> 2. Standardize on bindings. We already have of-touchscreen.c doing
>>> rudimentary parsing, we shoudl look into extending it rather than
>>> creating myriad of driver-specific bindings.
>> 
>> Ok, looks reasonable.
> 
> Documentation is in 
> 
> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt

I did look into it now. Unfortunately, it does not fit well into my view of how bindings
should be. They should describe hardware (as we are told for many other kernel
subsystems).

Pixels and resolutions are IMHO related to the screen it is glued on - and that is
quite independent.

So I don’t see how they do describe the different ways the touch screen can be
wired to a tsc2007 controller.

Please can you add minimum and maximum properties for us?

Then, inverted-x and inverted-y is redundant because it is the same as having
an expected higher value from the ADC for the minimum coordinate and a lower
for the maximum.

> 
>>> Also, do we need swap and flip or do we simply need rotation (like the
>>> proposed Broadcom iproc driver has)?
>> 
>> Well, since the DT should describe hardware, there are 3 sets of wires which
>> can have a cross-over: X+ and X-, Y+ and Y-, X and Y.
>> 
>> So IMHO hardware has no “rotation”, just crossover of wires. Rotation is an
>> interpretation of the result of these connections in combination with some
>> panel the touch is glued to and should therefore not be represented in the DT.
>> 
>> As a result we have proposed a scheme without explicit rotation. We specify what
>> coordinates X- and X+ should report at their ends (min, max) because the DT
>> programmer has to specify them anyways. Flipping is a result of defining these
>> coordinates in an ascending or descending way. Only swapping of the X and Y
>> wires can’t be implicitly defined so it has its own property. So the scheme we
>> have proposed tries to optimize the efforts needed to adapt new boards and write
>> DTs and focus the DT on hardware description.
>> 
>> As a bonus we also specify the min and max value to be reported for the touch
>> pressure (Z axis) using the same basic principle.
>> 
>> And it is a pure add-on on top of the existing driver so that it attempts not
>> to break existing device trees.
> 
> from what I can see there are no in-tree-users using any of the
> new properties.
> 
>> Maybe could you accept it as a first step for this specific driver (and let’s do
>> the big standardization work later on)?
> 
> That does not work, since you create an ABI.
> 
> -- Sebastian

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Torokhov Jan. 15, 2015, 6:16 p.m. UTC | #7
On Thu, Jan 15, 2015 at 05:14:38PM +0100, Dr. H. Nikolaus Schaller wrote:
> 
> Am 15.01.2015 um 15:38 schrieb Sebastian Reichel <sre@kernel.org>:
> 
> > Hi,
> > 
> > On Thu, Jan 15, 2015 at 08:36:44AM +0100, Dr. H. Nikolaus Schaller wrote:
> >>> 1. Perform conversion in input core rather than individual drivers. I
> >>> think we should allocate a new bitmaps for some transformations and have
> >>> the code do X/Y flip/clip of the coordinates.
> >> 
> >> Do you have a suggestion where this should be (I have no clue how
> >> the input system works or is structured - we just know how to extend a
> >> driver that uses it)?
> >> 
> >>> 2. Standardize on bindings. We already have of-touchscreen.c doing
> >>> rudimentary parsing, we shoudl look into extending it rather than
> >>> creating myriad of driver-specific bindings.
> >> 
> >> Ok, looks reasonable.
> > 
> > Documentation is in 
> > 
> > Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
> 
> I did look into it now. Unfortunately, it does not fit well into my view of how bindings
> should be. They should describe hardware (as we are told for many other kernel
> subsystems).
> 
> Pixels and resolutions are IMHO related to the screen it is glued on - and that is
> quite independent.

Well, I think pixels was the wrong word to be used there. It is meant to
be native units, as opposed to millimeters, inches, points, etc.

> 
> So I don’t see how they do describe the different ways the touch screen can be
> wired to a tsc2007 controller.
> 
> Please can you add minimum and maximum properties for us?
> 
> Then, inverted-x and inverted-y is redundant because it is the same as having
> an expected higher value from the ADC for the minimum coordinate and a lower
> for the maximum.

I'd rather not add minimum and maximum, but add the touchscreen-start-x and
touchscreen-start-y instead so that we limit the number of obsolete
properties.

Thanks.
H. Nikolaus Schaller Jan. 15, 2015, 6:49 p.m. UTC | #8
Am 15.01.2015 um 19:16 schrieb Dmitry Torokhov <dmitry.torokhov@gmail.com>:

> On Thu, Jan 15, 2015 at 05:14:38PM +0100, Dr. H. Nikolaus Schaller wrote:
>> 
>> Am 15.01.2015 um 15:38 schrieb Sebastian Reichel <sre@kernel.org>:
>> 
>>> Hi,
>>> 
>>> On Thu, Jan 15, 2015 at 08:36:44AM +0100, Dr. H. Nikolaus Schaller wrote:
>>>>> 1. Perform conversion in input core rather than individual drivers. I
>>>>> think we should allocate a new bitmaps for some transformations and have
>>>>> the code do X/Y flip/clip of the coordinates.
>>>> 
>>>> Do you have a suggestion where this should be (I have no clue how
>>>> the input system works or is structured - we just know how to extend a
>>>> driver that uses it)?
>>>> 
>>>>> 2. Standardize on bindings. We already have of-touchscreen.c doing
>>>>> rudimentary parsing, we shoudl look into extending it rather than
>>>>> creating myriad of driver-specific bindings.
>>>> 
>>>> Ok, looks reasonable.
>>> 
>>> Documentation is in 
>>> 
>>> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>> 
>> I did look into it now. Unfortunately, it does not fit well into my view of how bindings
>> should be. They should describe hardware (as we are told for many other kernel
>> subsystems).
>> 
>> Pixels and resolutions are IMHO related to the screen it is glued on - and that is
>> quite independent.
> 
> Well, I think pixels was the wrong word to be used there. It is meant to
> be native units, as opposed to millimeters, inches, points, etc.

ok.

> 
>> 
>> So I don’t see how they do describe the different ways the touch screen can be
>> wired to a tsc2007 controller.
>> 
>> Please can you add minimum and maximum properties for us?
>> 
>> Then, inverted-x and inverted-y is redundant because it is the same as having
>> an expected higher value from the ADC for the minimum coordinate and a lower
>> for the maximum.
> 
> I'd rather not add minimum and maximum, but add the touchscreen-start-x and
> touchscreen-start-y instead so that we limit the number of obsolete
> properties.

ok, that should not be too difficult to add.

So we will modify our driver to use the new functions and align omap3-gta04.dtsi accordingly.

BR,
Nikolaus

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 1bf9906..cc0cc3c 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -74,6 +74,12 @@  struct tsc2007 {
 
 	u16			model;
 	u16			x_plate_ohms;
+	bool			swap_xy;	/* swap x and y axis */
+	u16			min_x;
+	u16			min_y;
+	u16			min_rt;
+	u16			max_x;
+	u16			max_y;
 	u16			max_rt;
 	unsigned long		poll_period;
 	int			fuzzx;
@@ -193,11 +199,50 @@  static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
 			break;
 		}
 
-		if (rt <= ts->max_rt) {
+		if (rt <= max(ts->min_rt, ts->max_rt)) {
 			dev_dbg(&ts->client->dev,
 				"DOWN point(%4d,%4d), pressure (%4u)\n",
 				tc.x, tc.y, rt);
 
+			if (ts->swap_xy) {
+				/* swap before applying the range limits */
+				u16 h = tc.x;
+
+				tc.x = tc.y;
+				tc.y = h;
+			}
+
+			/* flip and/or clip X */
+			if (ts->max_x < ts->min_x)
+				tc.x = (ts->min_x - tc.x) + ts->max_x;
+
+			if (tc.x > max(ts->min_x, ts->max_x))
+				tc.x = max(ts->min_x, ts->max_x);
+			else if (tc.x < min(ts->min_x, ts->max_x))
+				tc.x = min(ts->min_x, ts->max_x);
+
+			/* flip and/or clip Y */
+			if (ts->max_y < ts->min_y)
+				tc.y = (ts->min_y - tc.y) + ts->max_y;
+
+			if (tc.y > max(ts->min_y, ts->max_y))
+				tc.y = max(ts->min_y, ts->max_y);
+			else if (tc.y < min(ts->min_y, ts->max_y))
+				tc.y = min(ts->min_y, ts->max_y);
+
+			/* clip Z */
+			if (ts->max_rt < ts->min_rt)
+				rt = (ts->min_rt - rt) + ts->max_rt;
+
+			if (rt > max(ts->min_rt, ts->max_rt))
+				rt = max(ts->min_rt, ts->max_rt);
+			else if (rt < min(ts->min_rt, ts->max_rt))
+				rt = min(ts->min_rt, ts->max_rt);
+
+			dev_dbg(&ts->client->dev,
+					"shaped point(%4d,%4d), pressure (%4u)\n",
+					tc.x, tc.y, rt);
+
 			input_report_key(input, BTN_TOUCH, 1);
 			input_report_abs(input, ABS_X, tc.x);
 			input_report_abs(input, ABS_Y, tc.y);
@@ -299,6 +344,24 @@  static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
 		return -EINVAL;
 	}
 
+	ts->swap_xy = of_property_read_bool(np, "ti,swap-xy");
+
+	if (!of_property_read_u32(np, "ti,min-x", &val32))
+		ts->min_x = val32;
+	if (!of_property_read_u32(np, "ti,max-x", &val32))
+		ts->max_x = val32;
+	else
+		ts->max_x = MAX_12BIT;
+
+	if (!of_property_read_u32(np, "ti,min-y", &val32))
+		ts->min_y = val32;
+	if (!of_property_read_u32(np, "ti,max-y", &val32))
+		ts->max_y = val32;
+	else
+		ts->max_y = MAX_12BIT;
+
+	if (!of_property_read_u32(np, "ti,min-rt", &val32))
+		ts->min_rt = val32;
 	if (!of_property_read_u32(np, "ti,max-rt", &val32))
 		ts->max_rt = val32;
 	else
@@ -325,6 +388,16 @@  static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
 		return -EINVAL;
 	}
 
+	dev_dbg(&client->dev,
+			"min/max_x (%4d,%4d)\n",
+			ts->min_x, ts->max_x);
+	dev_dbg(&client->dev,
+			"min/max_y (%4d,%4d)\n",
+			ts->min_y, ts->max_y);
+	dev_dbg(&client->dev,
+			"min/max_rt (%4d,%4d)\n",
+			ts->min_rt, ts->max_rt);
+
 	ts->gpio = of_get_gpio(np, 0);
 	if (gpio_is_valid(ts->gpio))
 		ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
@@ -349,6 +422,12 @@  static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
 {
 	ts->model             = pdata->model;
 	ts->x_plate_ohms      = pdata->x_plate_ohms;
+	ts->swap_xy           = pdata->swap_xy;
+	ts->min_x             = pdata->min_x ? : 0;
+	ts->min_y             = pdata->min_y ? : 0;
+	ts->min_rt            = pdata->min_rt ? : 0;
+	ts->max_x             = pdata->max_x ? : MAX_12BIT;
+	ts->max_y             = pdata->max_y ? : MAX_12BIT;
 	ts->max_rt            = pdata->max_rt ? : MAX_12BIT;
 	ts->poll_period       = pdata->poll_period ? : 1;
 	ts->get_pendown_state = pdata->get_pendown_state;
@@ -422,9 +501,11 @@  static int tsc2007_probe(struct i2c_client *client,
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
-	input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
-	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
-	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
+	input_set_abs_params(input_dev, ABS_X, min(ts->min_x, ts->max_x),
+			     max(ts->min_x, ts->max_x), ts->fuzzx, 0);
+	input_set_abs_params(input_dev, ABS_Y, min(ts->min_y, ts->max_y),
+			     max(ts->min_y, ts->max_y), ts->fuzzy, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, ts->min_rt, ts->max_rt,
 			     ts->fuzzz, 0);
 
 	if (pdata) {
diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h
index 4f35b6a..5ce7b79 100644
--- a/include/linux/i2c/tsc2007.h
+++ b/include/linux/i2c/tsc2007.h
@@ -6,6 +6,12 @@ 
 struct tsc2007_platform_data {
 	u16	model;				/* 2007. */
 	u16	x_plate_ohms;	/* must be non-zero value */
+	bool	swap_xy;	/* swap x and y axis */
+	u16	min_x;	/* min and max values to reported to user space */
+	u16	min_y;
+	u16	min_rt;
+	u16	max_x;
+	u16	max_y;
 	u16	max_rt; /* max. resistance above which samples are ignored */
 	unsigned long poll_period; /* time (in ms) between samples */
 	int	fuzzx; /* fuzz factor for X, Y and pressure axes */