diff mbox

[v3,1/8] drivers:input:tsc2007: add new common binding names, pre-calibration, flipping and rotation

Message ID 1409ed9845f17445a8a67bd6fb16c902c3e4f69c.1474634475.git.hns@goldelico.com
State Changes Requested, archived
Headers show

Commit Message

H. Nikolaus Schaller Sept. 23, 2016, 12:41 p.m. UTC
commit b98abe52fa8e ("Input: add common DT binding for touchscreens")
introduced common DT bindings for touchscreens [1] and a helper function to
parse the DT.

commit ed7c9870c9bc ("Input: of_touchscreen - add support for inverted / swapped axes")
added another helper for parsing axis inversion and swapping
and applying them to x and y coordinates.

Both helpers have been integrated to accommodate any orientation of the
touch panel in relation to the LCD.

A new feature is to introduce scaling the min/max ADC values to the screen
size.

This makes it possible to pre-calibrate the touch so that is (almost)
exactly matches the LCD pixel coordinates it is glued onto. This allows to
well enough operate the touch before a user space calibration step can
improve the precision.

Finally, calculate_pressure has been renamed to calculate_resistance
because that is what it is doing.

[1]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt

Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 .../bindings/input/touchscreen/tsc2007.txt         |  20 ++--
 drivers/input/touchscreen/tsc2007.c                | 126 +++++++++++++++++----
 include/linux/i2c/tsc2007.h                        |   8 ++
 3 files changed, 123 insertions(+), 31 deletions(-)

Comments

Rob Herring (Arm) Sept. 23, 2016, 10:47 p.m. UTC | #1
On Fri, Sep 23, 2016 at 02:41:09PM +0200, H. Nikolaus Schaller wrote:
> commit b98abe52fa8e ("Input: add common DT binding for touchscreens")
> introduced common DT bindings for touchscreens [1] and a helper function to
> parse the DT.
> 
> commit ed7c9870c9bc ("Input: of_touchscreen - add support for inverted / swapped axes")
> added another helper for parsing axis inversion and swapping
> and applying them to x and y coordinates.
> 
> Both helpers have been integrated to accommodate any orientation of the
> touch panel in relation to the LCD.
> 
> A new feature is to introduce scaling the min/max ADC values to the screen
> size.
> 
> This makes it possible to pre-calibrate the touch so that is (almost)
> exactly matches the LCD pixel coordinates it is glued onto. This allows to
> well enough operate the touch before a user space calibration step can
> improve the precision.
> 
> Finally, calculate_pressure has been renamed to calculate_resistance
> because that is what it is doing.

Seems like you are breaking compatibility with old DTs. I can't tell for 
sure though.

> 
> [1]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
> 
> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> ---
>  .../bindings/input/touchscreen/tsc2007.txt         |  20 ++--
>  drivers/input/touchscreen/tsc2007.c                | 126 +++++++++++++++++----
>  include/linux/i2c/tsc2007.h                        |   8 ++
>  3 files changed, 123 insertions(+), 31 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> index ec365e1..6e9fd55 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> @@ -6,6 +6,7 @@ Required properties:
>  - ti,x-plate-ohms: X-plate resistance in ohms.
>  
>  Optional properties:
> +- generic touch screen properties: see touchscreen binding [2].
>  - gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
>    The penirq pin goes to low when the panel is touched.
>    (see GPIO binding[1] for more details).
> @@ -13,17 +14,20 @@ Optional properties:
>    (see interrupt binding[0]).
>  - interrupts: (gpio) interrupt to which the chip is connected
>    (see interrupt binding[0]).
> -- ti,max-rt: maximum pressure.
> -- ti,fuzzx: specifies the absolute input fuzz x value.
> -  If set, it will permit noise in the data up to +- the value given to the fuzz
> -  parameter, that is used to filter noise from the event stream.
> -- ti,fuzzy: specifies the absolute input fuzz y value.
> -- ti,fuzzz: specifies the absolute input fuzz z value.
> +- ti,max-rt: maximum pressure resistance above which samples are ignored
> +  (default: 4095).
> +- ti,report-resistance: report resistance (no pressure = max_rt) instead
> +  of pressure (no pressure = 0).
> +- ti,min-x: minimum value reported by X axis ADC (default 0).
> +- ti,max-x: maximum value reported by X axis ADC (default 4095).
> +- ti,min-y: minimum value reported by Y axis ADC (default 0).
> +- ti,max-y: maximum value reported by Y axis ADC (default 4095).

Seems like these could be common too. They make more sense than giving x 
and y sizes in pixel units which really should come from the panel.

>  - ti,poll-period: how much time to wait (in milliseconds) before reading again the
> -  values from the tsc2007.
> +  values from the tsc2007 (default 1).
>  
>  [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
>  [1]: Documentation/devicetree/bindings/gpio/gpio.txt
> +[2]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>  
>  Example:
>  	&i2c1 {
> @@ -35,6 +39,8 @@ Example:
>  			interrupts = <0x0 0x8>;
>  			gpios = <&gpio4 0 0>;
>  			ti,x-plate-ohms = <180>;
> +			touchscreen-size-x = <640>;
> +			touchscreen-size-y = <480>;
>  		};
>  
>  		/* ... */
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sebastian Reichel Sept. 24, 2016, 12:31 a.m. UTC | #2
On Fri, Sep 23, 2016 at 05:47:26PM -0500, Rob Herring wrote:
> On Fri, Sep 23, 2016 at 02:41:09PM +0200, H. Nikolaus Schaller wrote:
> > commit b98abe52fa8e ("Input: add common DT binding for touchscreens")
> > introduced common DT bindings for touchscreens [1] and a helper function to
> > parse the DT.
> > 
> > commit ed7c9870c9bc ("Input: of_touchscreen - add support for inverted / swapped axes")
> > added another helper for parsing axis inversion and swapping
> > and applying them to x and y coordinates.
> > 
> > Both helpers have been integrated to accommodate any orientation of the
> > touch panel in relation to the LCD.
> > 
> > A new feature is to introduce scaling the min/max ADC values to the screen
> > size.
> > 
> > This makes it possible to pre-calibrate the touch so that is (almost)
> > exactly matches the LCD pixel coordinates it is glued onto. This allows to
> > well enough operate the touch before a user space calibration step can
> > improve the precision.
> > 
> > Finally, calculate_pressure has been renamed to calculate_resistance
> > because that is what it is doing.
> 
> Seems like you are breaking compatibility with old DTs. I can't tell for 
> sure though.
> 
> > 
> > [1]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
> > 
> > Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> > ---
> >  .../bindings/input/touchscreen/tsc2007.txt         |  20 ++--
> >  drivers/input/touchscreen/tsc2007.c                | 126 +++++++++++++++++----
> >  include/linux/i2c/tsc2007.h                        |   8 ++
> >  3 files changed, 123 insertions(+), 31 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> > index ec365e1..6e9fd55 100644
> > --- a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> > +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> > @@ -6,6 +6,7 @@ Required properties:
> >  - ti,x-plate-ohms: X-plate resistance in ohms.
> >  
> >  Optional properties:
> > +- generic touch screen properties: see touchscreen binding [2].
> >  - gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
> >    The penirq pin goes to low when the panel is touched.
> >    (see GPIO binding[1] for more details).
> > @@ -13,17 +14,20 @@ Optional properties:
> >    (see interrupt binding[0]).
> >  - interrupts: (gpio) interrupt to which the chip is connected
> >    (see interrupt binding[0]).
> > -- ti,max-rt: maximum pressure.
> > -- ti,fuzzx: specifies the absolute input fuzz x value.
> > -  If set, it will permit noise in the data up to +- the value given to the fuzz
> > -  parameter, that is used to filter noise from the event stream.
> > -- ti,fuzzy: specifies the absolute input fuzz y value.
> > -- ti,fuzzz: specifies the absolute input fuzz z value.
> > +- ti,max-rt: maximum pressure resistance above which samples are ignored
> > +  (default: 4095).
> > +- ti,report-resistance: report resistance (no pressure = max_rt) instead
> > +  of pressure (no pressure = 0).
> > +- ti,min-x: minimum value reported by X axis ADC (default 0).
> > +- ti,max-x: maximum value reported by X axis ADC (default 4095).
> > +- ti,min-y: minimum value reported by Y axis ADC (default 0).
> > +- ti,max-y: maximum value reported by Y axis ADC (default 4095).
> 
> Seems like these could be common too. They make more sense than giving x 
> and y sizes in pixel units which really should come from the panel.

The generic touchscreen properties are described "(in pixels)" in
the DT, but they are used in the same way.

So ti,max-[xy] is basically the same as touchscreen-size-[xy],
except, that the generic bindings don't support min-[xy] != 0.

So maybe change the generic bindings like this:

touchscreen-min-x: minimum value reported by X axis ADC (default 0)
touchscreen-max-x: maximum value reported by Y axis ADC
touchscreen-min-y: minimum value reported by Y axis ADC (default 0)
touchscreen-max-y: maximum value reported by Y axis ADC
touchscreen-size-x: deprecated alias for touchscreen-max-x
touchscreen-size-y: deprecated alias for touchscreen-max-y

-- Sebastian
H. Nikolaus Schaller Sept. 24, 2016, 5:28 a.m. UTC | #3
Hi,

> Am 24.09.2016 um 00:47 schrieb Rob Herring <robh@kernel.org>:
> 
> On Fri, Sep 23, 2016 at 02:41:09PM +0200, H. Nikolaus Schaller wrote:
>> commit b98abe52fa8e ("Input: add common DT binding for touchscreens")
>> introduced common DT bindings for touchscreens [1] and a helper function to
>> parse the DT.
>> 
>> commit ed7c9870c9bc ("Input: of_touchscreen - add support for inverted / swapped axes")
>> added another helper for parsing axis inversion and swapping
>> and applying them to x and y coordinates.
>> 
>> Both helpers have been integrated to accommodate any orientation of the
>> touch panel in relation to the LCD.
>> 
>> A new feature is to introduce scaling the min/max ADC values to the screen
>> size.
>> 
>> This makes it possible to pre-calibrate the touch so that is (almost)
>> exactly matches the LCD pixel coordinates it is glued onto. This allows to
>> well enough operate the touch before a user space calibration step can
>> improve the precision.
>> 
>> Finally, calculate_pressure has been renamed to calculate_resistance
>> because that is what it is doing.
> 
> Seems like you are breaking compatibility with old DTs. I can't tell for 
> sure though.

There is code to take missing values as 0 or maximum. So this will scale 1:1
and should not break old DTs.

> 
>> 
>> [1]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>> 
>> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
>> ---
>> .../bindings/input/touchscreen/tsc2007.txt         |  20 ++--
>> drivers/input/touchscreen/tsc2007.c                | 126 +++++++++++++++++----
>> include/linux/i2c/tsc2007.h                        |   8 ++
>> 3 files changed, 123 insertions(+), 31 deletions(-)
>> 
>> diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
>> index ec365e1..6e9fd55 100644
>> --- a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
>> +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
>> @@ -6,6 +6,7 @@ Required properties:
>> - ti,x-plate-ohms: X-plate resistance in ohms.
>> 
>> Optional properties:
>> +- generic touch screen properties: see touchscreen binding [2].
>> - gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
>>   The penirq pin goes to low when the panel is touched.
>>   (see GPIO binding[1] for more details).
>> @@ -13,17 +14,20 @@ Optional properties:
>>   (see interrupt binding[0]).
>> - interrupts: (gpio) interrupt to which the chip is connected
>>   (see interrupt binding[0]).
>> -- ti,max-rt: maximum pressure.
>> -- ti,fuzzx: specifies the absolute input fuzz x value.
>> -  If set, it will permit noise in the data up to +- the value given to the fuzz
>> -  parameter, that is used to filter noise from the event stream.
>> -- ti,fuzzy: specifies the absolute input fuzz y value.
>> -- ti,fuzzz: specifies the absolute input fuzz z value.
>> +- ti,max-rt: maximum pressure resistance above which samples are ignored
>> +  (default: 4095).
>> +- ti,report-resistance: report resistance (no pressure = max_rt) instead
>> +  of pressure (no pressure = 0).
>> +- ti,min-x: minimum value reported by X axis ADC (default 0).
>> +- ti,max-x: maximum value reported by X axis ADC (default 4095).
>> +- ti,min-y: minimum value reported by Y axis ADC (default 0).
>> +- ti,max-y: maximum value reported by Y axis ADC (default 4095).
> 
> Seems like these could be common too. They make more sense than giving x 
> and y sizes in pixel units which really should come from the panel.

No. They have a different purpose!

You need to scale values like this:

ti,min-x   ->   0
x          ->   some value between 0 and touchscreen-size-x
ti,max-x   ->   touchscreen-size-x

So the ti, values describe the ADC raw values while the common bindings
describe the size in input-event coordinates.

So we need both specified: raw values and pixel values.

> 
>> - ti,poll-period: how much time to wait (in milliseconds) before reading again the
>> -  values from the tsc2007.
>> +  values from the tsc2007 (default 1).
>> 
>> [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
>> [1]: Documentation/devicetree/bindings/gpio/gpio.txt
>> +[2]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>> 
>> Example:
>> 	&i2c1 {
>> @@ -35,6 +39,8 @@ Example:
>> 			interrupts = <0x0 0x8>;
>> 			gpios = <&gpio4 0 0>;
>> 			ti,x-plate-ohms = <180>;
>> +			touchscreen-size-x = <640>;
>> +			touchscreen-size-y = <480>;
>> 		};
>> 
>> 		/* ... */

BR,
Nikolaus

--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 Sept. 24, 2016, 5:55 a.m. UTC | #4
Hi,

> Am 24.09.2016 um 02:31 schrieb Sebastian Reichel <sre@kernel.org>:
> 
> On Fri, Sep 23, 2016 at 05:47:26PM -0500, Rob Herring wrote:
>> On Fri, Sep 23, 2016 at 02:41:09PM +0200, H. Nikolaus Schaller wrote:
>>> commit b98abe52fa8e ("Input: add common DT binding for touchscreens")
>>> introduced common DT bindings for touchscreens [1] and a helper function to
>>> parse the DT.
>>> 
>>> commit ed7c9870c9bc ("Input: of_touchscreen - add support for inverted / swapped axes")
>>> added another helper for parsing axis inversion and swapping
>>> and applying them to x and y coordinates.
>>> 
>>> Both helpers have been integrated to accommodate any orientation of the
>>> touch panel in relation to the LCD.
>>> 
>>> A new feature is to introduce scaling the min/max ADC values to the screen
>>> size.
>>> 
>>> This makes it possible to pre-calibrate the touch so that is (almost)
>>> exactly matches the LCD pixel coordinates it is glued onto. This allows to
>>> well enough operate the touch before a user space calibration step can
>>> improve the precision.
>>> 
>>> Finally, calculate_pressure has been renamed to calculate_resistance
>>> because that is what it is doing.
>> 
>> Seems like you are breaking compatibility with old DTs. I can't tell for
>> sure though.
>> 
>>> 
>>> [1]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>>> 
>>> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
>>> ---
>>> .../bindings/input/touchscreen/tsc2007.txt         |  20 ++--
>>> drivers/input/touchscreen/tsc2007.c                | 126 +++++++++++++++++----
>>> include/linux/i2c/tsc2007.h                        |   8 ++
>>> 3 files changed, 123 insertions(+), 31 deletions(-)
>>> 
>>> diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
>>> index ec365e1..6e9fd55 100644
>>> --- a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
>>> +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
>>> @@ -6,6 +6,7 @@ Required properties:
>>> - ti,x-plate-ohms: X-plate resistance in ohms.
>>> 
>>> Optional properties:
>>> +- generic touch screen properties: see touchscreen binding [2].
>>> - gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
>>>   The penirq pin goes to low when the panel is touched.
>>>   (see GPIO binding[1] for more details).
>>> @@ -13,17 +14,20 @@ Optional properties:
>>>   (see interrupt binding[0]).
>>> - interrupts: (gpio) interrupt to which the chip is connected
>>>   (see interrupt binding[0]).
>>> -- ti,max-rt: maximum pressure.
>>> -- ti,fuzzx: specifies the absolute input fuzz x value.
>>> -  If set, it will permit noise in the data up to +- the value given to the fuzz
>>> -  parameter, that is used to filter noise from the event stream.
>>> -- ti,fuzzy: specifies the absolute input fuzz y value.
>>> -- ti,fuzzz: specifies the absolute input fuzz z value.
>>> +- ti,max-rt: maximum pressure resistance above which samples are ignored
>>> +  (default: 4095).
>>> +- ti,report-resistance: report resistance (no pressure = max_rt) instead
>>> +  of pressure (no pressure = 0).
>>> +- ti,min-x: minimum value reported by X axis ADC (default 0).
>>> +- ti,max-x: maximum value reported by X axis ADC (default 4095).
>>> +- ti,min-y: minimum value reported by Y axis ADC (default 0).
>>> +- ti,max-y: maximum value reported by Y axis ADC (default 4095).
>> 
>> Seems like these could be common too. They make more sense than giving x
>> and y sizes in pixel units which really should come from the panel.
> 
> The generic touchscreen properties are described "(in pixels)" in
> the DT, but they are used in the same way.
> 
> So ti,max-[xy] is basically the same as touchscreen-size-[xy],

No it is not the same and should be kept separate.

> except, that the generic bindings don't support min-[xy] != 0.

What would be the purpose of this? Every user-space I know
about (X11, Replicant) expects coordinates in some range
0..max so setting min in device tree makes no sense to me.

> 
> So maybe change the generic bindings like this:
> 
> touchscreen-min-x: minimum value reported by X axis ADC (default 0)
> touchscreen-max-x: maximum value reported by Y axis ADC
> touchscreen-min-y: minimum value reported by Y axis ADC (default 0)
> touchscreen-max-y: maximum value reported by Y axis ADC
> touchscreen-size-x: deprecated alias for touchscreen-max-x
> touchscreen-size-y: deprecated alias for touchscreen-max-y
> 

Initially I had thought about this but it does not solve the problems
with touch pre-calibration. Since it mixes raw coordinates with
system coordinates.

To achieve the goal of having a roughly precalibrated touch which
should provide (0,0) at the lower left corner and (touchscreen-size-x,touchscreen-size-y)
in pixel coordinates of the panel. Hence it roughly works without
a calibration matrix in user space (e.g. xorg.conf or Replicant).

Why do we need pre-calibration? Because some systems might need
touch interaction before they can offer (force) the user into
a touch calibration step. We use these drivers and approach in
our production kernels for GTA04, OpenPandora and Pyra for a while
and nobody was even missing a user-space calibration tool any more.

The underlaying problem is that you can have the same controller chip
in different board designs and there are different touch panel types.
Each one has certain physical properties but they can differ.
But you certainly want touchscreen-size-x/y to be a constant.

Now if we make touchscreen-max-x/y the same as touchscreen-size-x/y
and change the panel, we have to adjust user space transformation
each time we change the panel. This does not seem to be right
and can be done better by keeping them separately.

This is what this approach does: the roughly correct scaling of
raw values to pixel values.

ti,min-x   ->   0
...
x          ->   some value between 0 and touchscreen-size-x
                calculated by
			touchscreen-size-x * (x - min-x) / (max-x - min-x)
...
ti,max-x   ->   touchscreen-size-x

Hence the ti,min/max values describe the range of expected input
values from the ADC and the touchscreen-size-x describes the touch
in LCD pixels passed as input events.

Example:

ti,min-x = 64
ti,max-x = 4016
touchscreen-size-x = 480

If we change the panel type which presents a slightly different ADC range:

ti,min-x = 100
ti,max-x = 3900
touchscreen-size-x = 480

and we still get a coordinate range (0 .. 480).

Note that this feature can be effectively disabled if ti,min-x=0 and
ti,max-x=4095 and touchscreen-size-x=4095, i.e. reports the full
range of ADC values because then it multiplies by 1.

Our proposed driver does use these values if they are missing from DT
and therefore it should not break old DT files which expect raw values
to be reported.

I hope this clarifies what we need to achieve and you can
agree.

BR and thanks,
Nikolaus
Sebastian Reichel Sept. 30, 2016, 2:16 p.m. UTC | #5
Hi,

On Sat, Sep 24, 2016 at 07:55:27AM +0200, H. Nikolaus Schaller wrote:
> > So ti,max-[xy] is basically the same as touchscreen-size-[xy],
> 
> No it is not the same and should be kept separate.
> 
> > except, that the generic bindings don't support min-[xy] != 0.
> 
> What would be the purpose of this? Every user-space I know
> about (X11, Replicant) expects coordinates in some range
> 0..max so setting min in device tree makes no sense to me.
> 
> > 
> > So maybe change the generic bindings like this:
> > 
> > touchscreen-min-x: minimum value reported by X axis ADC (default 0)
> > touchscreen-max-x: maximum value reported by Y axis ADC
> > touchscreen-min-y: minimum value reported by Y axis ADC (default 0)
> > touchscreen-max-y: maximum value reported by Y axis ADC
> > touchscreen-size-x: deprecated alias for touchscreen-max-x
> > touchscreen-size-y: deprecated alias for touchscreen-max-y
> > 
> 
> Initially I had thought about this but it does not solve the problems
> with touch pre-calibration. Since it mixes raw coordinates with
> system coordinates.

touchscreen-size-x was actually refering to your definition of
touchscreen-max-x and not system coordinates. For that it would
make much more sense to use a phandle to the screen IMHO.

> To achieve the goal of having a roughly precalibrated touch which
> should provide (0,0) at the lower left corner and
> (touchscreen-size-x,touchscreen-size-y) in pixel coordinates of
> the panel. Hence it roughly works without a calibration matrix in
> user space (e.g. xorg.conf or Replicant).

well I did not mean to use touchscreen-size-x/y for describing the
size of screen, as visible in n900.dts (first implementation of the
common binding), which sets the value to 4096.

> Why do we need pre-calibration? Because some systems might need
> touch interaction before they can offer (force) the user into
> a touch calibration step. We use these drivers and approach in
> our production kernels for GTA04, OpenPandora and Pyra for a while
> and nobody was even missing a user-space calibration tool any more.

I have nothing against the feature. OTOH I'm quite in of kernel
based TS calibration. Note, that you can only add it for hardware
without pre-existing touchscreen support, since you break peoples
systems otherwise (We have that problem for N900).

> The underlaying problem is that you can have the same controller chip
> in different board designs and there are different touch panel types.
> Each one has certain physical properties but they can differ.
> But you certainly want touchscreen-size-x/y to be a constant.
>
> Now if we make touchscreen-max-x/y the same as touchscreen-size-x/y
> and change the panel, we have to adjust user space transformation
> each time we change the panel. This does not seem to be right
> and can be done better by keeping them separately.
>
> This is what this approach does: the roughly correct scaling of
> raw values to pixel values.
> 
> ti,min-x   ->   0
> ...
> x          ->   some value between 0 and touchscreen-size-x
>                 calculated by
> 			touchscreen-size-x * (x - min-x) / (max-x - min-x)
> ...
> ti,max-x   ->   touchscreen-size-x
> 
> Hence the ti,min/max values describe the range of expected input
> values from the ADC and the touchscreen-size-x describes the touch
> in LCD pixels passed as input events.

so basically you use touchscreen-size-x to describe the screen and
not the touchscreen. When I added it, I did mean the max ADC value.
Actually I was under the impression, that X drivers would scale this
to screen size automatically. Since all my touchscreen HW required
calibration I did never test this, though.

> Example:
> 
> ti,min-x = 64
> ti,max-x = 4016
> touchscreen-size-x = 480
> 
> If we change the panel type which presents a slightly different ADC range:
> 
> ti,min-x = 100
> ti,max-x = 3900
> touchscreen-size-x = 480
> 
> and we still get a coordinate range (0 .. 480).
> 
> Note that this feature can be effectively disabled if ti,min-x=0 and
> ti,max-x=4095 and touchscreen-size-x=4095, i.e. reports the full
> range of ADC values because then it multiplies by 1.
> 
> Our proposed driver does use these values if they are missing from DT
> and therefore it should not break old DT files which expect raw values
> to be reported.
> 
> I hope this clarifies what we need to achieve and you can
> agree.

I did understand what you want, but I disagreed about
using touchscreen-size-x/y for system coordinates. I
now see, that it's too late for that, as other people
already did so.

I do agree with Rob, that the ti,min/max-x/y should become common,
though. Also I would do s/minimum value/minimum raw value/g.
Additionally touchscreen-size-x/y should mention, that it's used to
scale the raw values.

-- Sebastian
H. Nikolaus Schaller Sept. 30, 2016, 2:40 p.m. UTC | #6
Hi Sebastian,

> Am 30.09.2016 um 16:16 schrieb Sebastian Reichel <sre@kernel.org>:
> 
> Hi,
> 
> On Sat, Sep 24, 2016 at 07:55:27AM +0200, H. Nikolaus Schaller wrote:
>>> So ti,max-[xy] is basically the same as touchscreen-size-[xy],
>> 
>> No it is not the same and should be kept separate.
>> 
>>> except, that the generic bindings don't support min-[xy] != 0.
>> 
>> What would be the purpose of this? Every user-space I know
>> about (X11, Replicant) expects coordinates in some range
>> 0..max so setting min in device tree makes no sense to me.
>> 
>>> 
>>> So maybe change the generic bindings like this:
>>> 
>>> touchscreen-min-x: minimum value reported by X axis ADC (default 0)
>>> touchscreen-max-x: maximum value reported by Y axis ADC
>>> touchscreen-min-y: minimum value reported by Y axis ADC (default 0)
>>> touchscreen-max-y: maximum value reported by Y axis ADC
>>> touchscreen-size-x: deprecated alias for touchscreen-max-x
>>> touchscreen-size-y: deprecated alias for touchscreen-max-y
>>> 
>> 
>> Initially I had thought about this but it does not solve the problems
>> with touch pre-calibration. Since it mixes raw coordinates with
>> system coordinates.
> 
> touchscreen-size-x was actually refering to your definition of
> touchscreen-max-x and not system coordinates.

Ah, ok I see. It looks as if you have provided a hidden feature by mis-using
it to describe LCD size.

> For that it would
> make much more sense to use a phandle to the screen IMHO.

Well... phandles are evil as I have learned in different context.
And, there are many LCD devices that do not specify screen sizes in
pixels.

I would more see it as a definition like a key matrix. You still have
both, the x/y raw coordinates and the processed KEY_something codes
in a single table.

> 
>> To achieve the goal of having a roughly precalibrated touch which
>> should provide (0,0) at the lower left corner and
>> (touchscreen-size-x,touchscreen-size-y) in pixel coordinates of
>> the panel. Hence it roughly works without a calibration matrix in
>> user space (e.g. xorg.conf or Replicant).
> 
> well I did not mean to use touchscreen-size-x/y for describing the
> size of screen, as visible in n900.dts (first implementation of the
> common binding), which sets the value to 4096.

Well, for my scheme it still works if you use it that way. Like keycodes
which can still be mapped in user space to anything desired.

> 
>> Why do we need pre-calibration? Because some systems might need
>> touch interaction before they can offer (force) the user into
>> a touch calibration step. We use these drivers and approach in
>> our production kernels for GTA04, OpenPandora and Pyra for a while
>> and nobody was even missing a user-space calibration tool any more.
> 
> I have nothing against the feature. OTOH I'm quite in of kernel
> based TS calibration. Note, that you can only add it for hardware
> without pre-existing touchscreen support, since you break peoples
> systems otherwise (We have that problem for N900).

Unless it takes missing ADC values as the same defaults that have been
the assumption. I.e. if it is missing, take e.g. 0 and 4095.

> 
>> The underlaying problem is that you can have the same controller chip
>> in different board designs and there are different touch panel types.
>> Each one has certain physical properties but they can differ.
>> But you certainly want touchscreen-size-x/y to be a constant.
>> 
>> Now if we make touchscreen-max-x/y the same as touchscreen-size-x/y
>> and change the panel, we have to adjust user space transformation
>> each time we change the panel. This does not seem to be right
>> and can be done better by keeping them separately.
>> 
>> This is what this approach does: the roughly correct scaling of
>> raw values to pixel values.
>> 
>> ti,min-x   ->   0
>> ...
>> x          ->   some value between 0 and touchscreen-size-x
>>                calculated by
>> 			touchscreen-size-x * (x - min-x) / (max-x - min-x)
>> ...
>> ti,max-x   ->   touchscreen-size-x
>> 
>> Hence the ti,min/max values describe the range of expected input
>> values from the ADC and the touchscreen-size-x describes the touch
>> in LCD pixels passed as input events.
> 
> so basically you use touchscreen-size-x to describe the screen and
> not the touchscreen.

> When I added it, I did mean the max ADC value.
> Actually I was under the impression, that X drivers would scale this
> to screen size automatically.

There is some default calibration or it can be set by entries in xorg.conf,
but since there is no intermediate "constant" scale, you promote any hardware
variation (different ADC max values) to user space.

> Since all my touchscreen HW required
> calibration I did never test this, though.
> 
>> Example:
>> 
>> ti,min-x = 64
>> ti,max-x = 4016
>> touchscreen-size-x = 480
>> 
>> If we change the panel type which presents a slightly different ADC range:
>> 
>> ti,min-x = 100
>> ti,max-x = 3900
>> touchscreen-size-x = 480
>> 
>> and we still get a coordinate range (0 .. 480).
>> 
>> Note that this feature can be effectively disabled if ti,min-x=0 and
>> ti,max-x=4095 and touchscreen-size-x=4095, i.e. reports the full
>> range of ADC values because then it multiplies by 1.
>> 
>> Our proposed driver does use these values if they are missing from DT
>> and therefore it should not break old DT files which expect raw values
>> to be reported.
>> 
>> I hope this clarifies what we need to achieve and you can
>> agree.
> 
> I did understand what you want, but I disagreed about
> using touchscreen-size-x/y for system coordinates. I
> now see, that it's too late for that, as other people
> already did so.
> 
> I do agree with Rob, that the ti,min/max-x/y should become common,
> though. Also I would do s/minimum value/minimum raw value/g.

Yes, that is a good idea!

To me it seems as if "minimum-raw-value-x", "maximum-raw-value-y" could be good.

Or is the string too long (then we can drop the "-value" or the "imum")? It
might blow up the DTB and string constant for finding the property?

If we come to some consensus on this, I can update the patch set.

> Additionally touchscreen-size-x/y should mention, that it's used to
> scale the raw values.

Ok. It is also used as the default for maximim-raw-value-x/y if not specified
which means 1:1 scaling.

BR and thanks,
Nikolaus
Christ van Willegen Sept. 30, 2016, 4:23 p.m. UTC | #7
Hi,

I saw this earlier, but didn't think it important to mention, but:


On Fri, Sep 23, 2016 at 2:41 PM, H. Nikolaus Schaller <hns@goldelico.com> wrote:

> diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
> index 5d0cd51..9a11509 100644
> --- a/drivers/input/touchscreen/tsc2007.c
> +++ b/drivers/input/touchscreen/tsc2007.c

> +                       /* scale ADC values to desired output range */
> +                       sx = (ts->prop.max_x * (tc.x - ts->min_x))
> +                               / (ts->max_x - ts->min_x);
> +                       sy = (ts->prop.max_y * (tc.y - ts->min_y))
> +                               / (ts->max_y - ts->min_y);
> +                       rt = (input->absinfo[ABS_PRESSURE].maximum * rt) /
> +                               ts->max_rt;

If ts->max_rt is zero, or ts->max_x == ts->min_x, or ts->max_y ==
ts->min_y, these yield a division by zero error.

Ofcourse, this is under control of the DT-maintainer(s) of the device
(if I'm not mistaking), but throwing an error on DT parse if (one of)
these condition(s) is met yields better info to the DT-maintainer than
a /0 error...

If you (or others) agree, could you add this to the patch?

Regards,

Christ van Willegen
--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 Sept. 30, 2016, 4:36 p.m. UTC | #8
Hi Christ,

> Am 30.09.2016 um 18:23 schrieb Christ van Willegen <cvwillegen@gmail.com>:
> 
> Hi,
> 
> I saw this earlier, but didn't think it important to mention, but:
> 
> 
> On Fri, Sep 23, 2016 at 2:41 PM, H. Nikolaus Schaller <hns@goldelico.com> wrote:
> 
>> diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
>> index 5d0cd51..9a11509 100644
>> --- a/drivers/input/touchscreen/tsc2007.c
>> +++ b/drivers/input/touchscreen/tsc2007.c
> 
>> +                       /* scale ADC values to desired output range */
>> +                       sx = (ts->prop.max_x * (tc.x - ts->min_x))
>> +                               / (ts->max_x - ts->min_x);
>> +                       sy = (ts->prop.max_y * (tc.y - ts->min_y))
>> +                               / (ts->max_y - ts->min_y);
>> +                       rt = (input->absinfo[ABS_PRESSURE].maximum * rt) /
>> +                               ts->max_rt;
> 
> If ts->max_rt is zero, or ts->max_x == ts->min_x, or ts->max_y ==
> ts->min_y, these yield a division by zero error.

Ah, that is a good observation!

> 
> Ofcourse, this is under control of the DT-maintainer(s) of the device
> (if I'm not mistaking)

Yes, the DT should be designed properly.

> , but throwing an error on DT parse if (one of)
> these condition(s) is met yields better info to the DT-maintainer than
> a /0 error...

Yes, but I wonder how likely it is to happen at all.

In an case there is an indicative message (either /0 or an explaining one) in
the boot log which goes away as soon as it has been fixed.

This is already better than in many other cases where things simply fail without
any message...

So I would weight the likelihood of happening vs. the additional code
to check every time.

> 
> If you (or others) agree, could you add this to the patch?

If maintainers request, I can easily add it. But personally I do not see
it as absolutely necessary.

BR and many thanks,
Nikolaus

--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 Oct. 17, 2016, 1:57 p.m. UTC | #9
Hi Sebastian,
I did wait for the 4.9-rc1 merge window to be closed until I bring up this patch
set again.

> Am 30.09.2016 um 16:40 schrieb H. Nikolaus Schaller <hns@goldelico.com>:
>> 
>> I do agree with Rob, that the ti,min/max-x/y should become common,
>> though. Also I would do s/minimum value/minimum raw value/g.
> 
> Yes, that is a good idea!
> 
> To me it seems as if "minimum-raw-value-x", "maximum-raw-value-y" could be good.
> 
> Or is the string too long (then we can drop the "-value" or the "imum")? It
> might blow up the DTB and string constant for finding the property?
> 
> If we come to some consensus on this, I can update the patch set.

Now when updating the patch set, I found that using ti,min/max-x/y was not really
a new invention. It is already upstream for a while for the ads7846/2046 driver!

This means: by introducing these properties to the tsc2007 as well we just extend the
already defined use of ti,min/max-x/y.

Simply changing that as well to use some minimum-raw-value-x etc. would break ads7846/2046
boards not in mainline or need ugly code to handle property alias names.

And since they are raw data and quite chip-specific, I think there is no urgent need
for harmonization of raw device data. While using the common bindings for output
scaling and fuzz, swap etc. is very important and helpful for board designers.

So I would prefer if we can keep it as is for the moment. And make property name
harmonization and evolution a separate task and discussion.

I will submit v4 in a couple of minutes. It contains some other small fixes as
suggested by the previous discussion.

BR and thanks,
Nikolaus
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
index ec365e1..6e9fd55 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
@@ -6,6 +6,7 @@  Required properties:
 - ti,x-plate-ohms: X-plate resistance in ohms.
 
 Optional properties:
+- generic touch screen properties: see touchscreen binding [2].
 - gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
   The penirq pin goes to low when the panel is touched.
   (see GPIO binding[1] for more details).
@@ -13,17 +14,20 @@  Optional properties:
   (see interrupt binding[0]).
 - interrupts: (gpio) interrupt to which the chip is connected
   (see interrupt binding[0]).
-- ti,max-rt: maximum pressure.
-- ti,fuzzx: specifies the absolute input fuzz x value.
-  If set, it will permit noise in the data up to +- the value given to the fuzz
-  parameter, that is used to filter noise from the event stream.
-- ti,fuzzy: specifies the absolute input fuzz y value.
-- ti,fuzzz: specifies the absolute input fuzz z value.
+- ti,max-rt: maximum pressure resistance above which samples are ignored
+  (default: 4095).
+- ti,report-resistance: report resistance (no pressure = max_rt) instead
+  of pressure (no pressure = 0).
+- ti,min-x: minimum value reported by X axis ADC (default 0).
+- ti,max-x: maximum value reported by X axis ADC (default 4095).
+- ti,min-y: minimum value reported by Y axis ADC (default 0).
+- ti,max-y: maximum value reported by Y axis ADC (default 4095).
 - ti,poll-period: how much time to wait (in milliseconds) before reading again the
-  values from the tsc2007.
+  values from the tsc2007 (default 1).
 
 [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
 [1]: Documentation/devicetree/bindings/gpio/gpio.txt
+[2]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
 
 Example:
 	&i2c1 {
@@ -35,6 +39,8 @@  Example:
 			interrupts = <0x0 0x8>;
 			gpios = <&gpio4 0 0>;
 			ti,x-plate-ohms = <180>;
+			touchscreen-size-x = <640>;
+			touchscreen-size-y = <480>;
 		};
 
 		/* ... */
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 5d0cd51..9a11509 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -29,6 +29,7 @@ 
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/input/touchscreen.h>
 
 #define TSC2007_MEASURE_TEMP0		(0x0 << 4)
 #define TSC2007_MEASURE_AUX		(0x2 << 4)
@@ -74,6 +75,14 @@  struct tsc2007 {
 
 	u16			model;
 	u16			x_plate_ohms;
+
+	struct touchscreen_properties prop;
+
+	bool			report_resistance;
+	u16			min_x;
+	u16			min_y;
+	u16			max_x;
+	u16			max_y;
 	u16			max_rt;
 	unsigned long		poll_period; /* in jiffies */
 	int			fuzzx;
@@ -128,7 +137,8 @@  static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc)
 	tsc2007_xfer(tsc, PWRDOWN);
 }
 
-static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
+static u32 tsc2007_calculate_resistance(struct tsc2007 *tsc,
+					struct ts_event *tc)
 {
 	u32 rt = 0;
 
@@ -177,12 +187,13 @@  static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
 	struct ts_event tc;
 	u32 rt;
 
+	dev_dbg(&ts->client->dev, "soft irq %d\n", irq);
 	while (!ts->stopped && tsc2007_is_pen_down(ts)) {
 
 		/* pen is down, continue with the measurement */
 		tsc2007_read_values(ts, &tc);
 
-		rt = tsc2007_calculate_pressure(ts, &tc);
+		rt = tsc2007_calculate_resistance(ts, &tc);
 
 		if (!rt && !ts->get_pendown_state) {
 			/*
@@ -194,21 +205,45 @@  static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
 		}
 
 		if (rt <= ts->max_rt) {
+			int sx, sy;
+
 			dev_dbg(&ts->client->dev,
 				"DOWN 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);
+			if (!ts->report_resistance)
+				rt = ts->max_rt - rt;
+
+			/* scale ADC values to desired output range */
+			sx = (ts->prop.max_x * (tc.x - ts->min_x))
+				/ (ts->max_x - ts->min_x);
+			sy = (ts->prop.max_y * (tc.y - ts->min_y))
+				/ (ts->max_y - ts->min_y);
+			rt = (input->absinfo[ABS_PRESSURE].maximum * rt) /
+				ts->max_rt;
+
+			dev_dbg(&ts->client->dev,
+				"Scaled point(%4d,%4d), pressure (%4u)\n",
+				sx, sy, rt);
+
+			/* report event */
+			if (!ts->pendown) {
+				input_report_key(input, BTN_TOUCH, 1);
+				ts->pendown = true;
+			}
+
+			touchscreen_report_pos(ts->input, &ts->prop,
+						(unsigned int) sx,
+						(unsigned int) sy,
+						false);
 			input_report_abs(input, ABS_PRESSURE, rt);
 
 			input_sync(input);
 
 		} else {
 			/*
-			 * Sample found inconsistent by debouncing or pressure is
-			 * beyond the maximum. Don't report it to user space,
+			 * Sample found inconsistent by debouncing or resistance
+			 * is beyond the maximum. Don't report it to user space,
 			 * repeat at least once more the measurement.
 			 */
 			dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
@@ -233,6 +268,7 @@  static irqreturn_t tsc2007_hard_irq(int irq, void *handle)
 {
 	struct tsc2007 *ts = handle;
 
+	dev_dbg(&ts->client->dev, "hard irq %d\n", irq);
 	if (tsc2007_is_pen_down(ts))
 		return IRQ_WAKE_THREAD;
 
@@ -303,14 +339,24 @@  static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
 	else
 		ts->max_rt = MAX_12BIT;
 
-	if (!of_property_read_u32(np, "ti,fuzzx", &val32))
-		ts->fuzzx = val32;
+	ts->report_resistance =
+		       of_property_read_bool(np, "ti,report-resistance");
 
-	if (!of_property_read_u32(np, "ti,fuzzy", &val32))
-		ts->fuzzy = val32;
+	touchscreen_parse_properties(ts->input, false, &ts->prop);
 
-	if (!of_property_read_u32(np, "ti,fuzzz", &val32))
-		ts->fuzzz = val32;
+	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_u64(np, "ti,poll-period", &val64))
 		ts->poll_period = msecs_to_jiffies(val64);
@@ -332,6 +378,22 @@  static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
 			 "GPIO not specified in DT (of_get_gpio returned %d)\n",
 			 ts->gpio);
 
+	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,
+			"max_rt (%4d)\n",
+			ts->max_rt);
+	dev_dbg(&client->dev,
+			"size (%4d,%4d)\n",
+			ts->prop.max_x, ts->prop.max_y);
+	dev_dbg(&client->dev,
+			"ts-gpio: %d\n",
+			ts->gpio);
+
 	return 0;
 }
 #else
@@ -349,6 +411,14 @@  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->max_rt            = pdata->max_rt ? : MAX_12BIT;
+	ts->prop.swap_x_y     = pdata->swap_xy;
+	ts->prop.invert_x     = pdata->invert_x;
+	ts->prop.invert_y     = pdata->invert_y;
+	ts->report_resistance = pdata->report_resistance;
+	ts->min_x             = pdata->min_x ? : 0;
+	ts->min_y             = pdata->min_y ? : 0;
+	ts->max_x             = pdata->max_x ? : MAX_12BIT;
+	ts->max_y             = pdata->max_y ? : MAX_12BIT;
 	ts->poll_period       = msecs_to_jiffies(pdata->poll_period ? : 1);
 	ts->get_pendown_state = pdata->get_pendown_state;
 	ts->clear_penirq      = pdata->clear_penirq;
@@ -388,13 +458,6 @@  static int tsc2007_probe(struct i2c_client *client,
 	if (!ts)
 		return -ENOMEM;
 
-	if (pdata)
-		err = tsc2007_probe_pdev(client, ts, pdata, id);
-	else
-		err = tsc2007_probe_dt(client, ts);
-	if (err)
-		return err;
-
 	input_dev = devm_input_allocate_device(&client->dev);
 	if (!input_dev)
 		return -ENOMEM;
@@ -419,12 +482,25 @@  static int tsc2007_probe(struct i2c_client *client,
 	input_set_drvdata(input_dev, ts);
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+				BIT_MASK(ABS_PRESSURE);
 	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,
-			     ts->fuzzz, 0);
+	if (pdata) {
+		err = tsc2007_probe_pdev(client, ts, pdata, id);
+		if (err)
+			return err;
+		input_set_abs_params(input_dev, ABS_X, 0, ts->max_x-ts->min_x,
+							  ts->fuzzx, 0);
+		input_set_abs_params(input_dev, ABS_Y, 0, ts->max_y-ts->min_y,
+							  ts->fuzzy, 0);
+		input_set_abs_params(input_dev, ABS_PRESSURE, 0, ts->max_rt,
+							  ts->fuzzz, 0);
+	} else {
+		err = tsc2007_probe_dt(client, ts);
+		if (err)
+			return err;
+	}
 
 	if (pdata) {
 		if (pdata->exit_platform_hw) {
@@ -443,6 +519,8 @@  static int tsc2007_probe(struct i2c_client *client,
 			pdata->init_platform_hw();
 	}
 
+	dev_dbg(&client->dev, "request irq %d\n",
+			ts->irq);
 	err = devm_request_threaded_irq(&client->dev, ts->irq,
 					tsc2007_hard_irq, tsc2007_soft_irq,
 					IRQF_ONESHOT,
diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h
index 4f35b6a..632db20 100644
--- a/include/linux/i2c/tsc2007.h
+++ b/include/linux/i2c/tsc2007.h
@@ -6,6 +6,14 @@ 
 struct tsc2007_platform_data {
 	u16	model;				/* 2007. */
 	u16	x_plate_ohms;	/* must be non-zero value */
+	bool	swap_xy;	/* swap x and y axis */
+	bool	invert_x;
+	bool	invert_y;
+	bool	report_resistance;
+	u16	min_x;	/* min and max values reported by ADC */
+	u16	min_y;
+	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 */